Last active
January 3, 2019 22:12
-
-
Save arekbal/c6a90d324d2e38da4bb3d0504bfd4393 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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