Skip to content

Instantly share code, notes, and snippets.

@poizan42
Last active August 29, 2015 13:56
Show Gist options
  • Save poizan42/9084227 to your computer and use it in GitHub Desktop.
Save poizan42/9084227 to your computer and use it in GitHub Desktop.
ClrHacks. Kids, don't try this at home.
// StreamTools.h
#pragma once
#include "StdAfx.h"
using namespace System;
using namespace System::IO;
using namespace System::Runtime::InteropServices;
namespace ClrHacks {
[StructLayout(LayoutKind::Sequential)]
private value class SZARRAYHeader
{
public:
IntPtr SyncBlock;
IntPtr MethodTable;
int32_t Length;
};
template<typename T>
[StructLayout(LayoutKind::Sequential)]
private value class AnyRef
{
public:
T Ref;
};
template<typename T, typename U>
T managed_cast(U ptr)
{
#pragma warning( push )
#pragma warning( disable : 4669 )
return reinterpret_cast<AnyRef<T>*>(&ptr)->Ref;
#pragma warning( pop )
}
public ref class StreamTools
{
public:
static void WriteLargeBlock(Stream^ stream, uint8_t* buffer, int32_t offset, int32_t count)
{
;
}
static void WriteLargeBlockUnsafe(Stream^ stream, uint8_t* buffer, int32_t offset, int32_t count)
{
array<uint8_t>^ dummy_arr = gcnew array<uint8_t>(1);
pin_ptr<uint8_t> dummy_arr_pin = &dummy_arr[0];
SZARRAYHeader* dummy_arr_header = reinterpret_cast<SZARRAYHeader*>(dummy_arr_pin - sizeof(SZARRAYHeader));
SZARRAYHeader* header = reinterpret_cast<SZARRAYHeader*>(buffer + offset - sizeof(SZARRAYHeader));
header->SyncBlock = dummy_arr_header->SyncBlock;
header->MethodTable = dummy_arr_header->MethodTable; //array<uint8_t>::typeid->TypeHandle.Value;
Console::WriteLine(header->MethodTable);
Console::WriteLine(array<uint8_t>::typeid->TypeHandle.Value);
header->Length = count;
array<uint8_t>^ tmp_arr = managed_cast<array<uint8_t>^>(&header->MethodTable);
/*pin_ptr<uint8_t> t = &tmp_arr[0];
Console::WriteLine(IntPtr(t));
Console::WriteLine(IntPtr(buffer + offset));
Console::WriteLine(IntPtr(t - (buffer + offset)));
Console::WriteLine("Length: {0:X2}, Rank: {1:X2}, lower bound: {2:X2}", tmp_arr->Length, tmp_arr->Rank, tmp_arr->GetLowerBound(0));
Console::WriteLine("Type: {0}", tmp_arr->GetType()->FullName);*/
stream->Write(tmp_arr, 0, count);
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment