Skip to content

Instantly share code, notes, and snippets.

@arekbal
Last active January 3, 2019 22:12
Show Gist options
  • Save arekbal/c6a90d324d2e38da4bb3d0504bfd4393 to your computer and use it in GitHub Desktop.
Save arekbal/c6a90d324d2e38da4bb3d0504bfd4393 to your computer and use it in GitHub Desktop.
struct ProductOrderedDTO
{
IntPtr _ptr;
int _byteSize;
public int ByteSize => _byteSize;
const int QUANTITY_OFFSET = 0;
const int QUANTITY_SIZEOF = sizeof(int);
const int PRODUCT_NAME_COUNT_OFFSET = QUANTITY_OFFSET + QUANTITY_SIZEOF;
const int PRODUCT_NAME_COUNT_SIZEOF = sizeof(ushort);
const int PRODUCT_NAME_DATA_OFFSET = PRODUCT_NAME_OFFSET + PRODUCT_NAME_COUNT_SIZEOF;
public ProductOrderedDTO(IntPtr rawPtrToUnmanagedData, int byteSize)
{
_ptr = rawPtrToUnmanagedData;
_byteSize = byteSize;
}
public int Quantity
{
get
{
unsafe
{
var pQuantity = (int*)_ptr + QUANTITY_OFFSET;
return *pQuantity;
}
}
}
// variable length fields should ideally come last in buffer, they are always harder
public ReadOnlySpan<char> ProductName
{
get
{
unsafe
{
ushort* pNameByteSize = (ushort*)_ptr + PRODUCT_NAME_COUNT_OFFSET;
var sByteSize = *pNameByteSize;
return new ReadOnlySpan<char>((void*)(_ptr + PRODUCT_NAME_DATA_OFFSET), sByteSize);
}
}
}
}
struct OrderProductDTO
{
public static int Create(Span<byte> refBuffer, int quantity, Span<char> productName)
{
// it is clear here how big buffer needs to be, so it is a bit artifical example
int totalByteSize = QUANTITY_SIZEOF + PRODUCT_NAME_COUNT_SIZEOF + productName.Length * sizeof(char);
if (refBuffer.Length < totalByteSize)
return -1;
Unsafe.As<byte, int>(ref refBuffer[0]) = quantity;
var stringByteCount = (ushort)(productName.Length * sizeof(char));
Unsafe.As<byte, ushort>(ref refBuffer[PRODUCT_NAME_COUNT_OFFSET]) = stringByteCount;
Unsafe.CopyBlockUnaligned(ref refBuffer[PRODUCT_NAME_DATA_OFFSET], ref Unsafe.As<char, byte>(ref productName[0]), stringByteCount);
return totalByteSize;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment