public static unsafe byte[] GetByteArray(NativeCollectionGetter getter, int size = 0) { // Initially called with size = 0, we make a native call just to get the size of the buffer. var bytes = new byte[size]; bool isNull; NativeException nativeException; int actualSize; fixed(byte *buffer = bytes) { actualSize = (int)getter((IntPtr)buffer, (IntPtr)size, out isNull, out nativeException); } nativeException.ThrowIfNecessary(); if (isNull) { return(null); } if (actualSize > size) { return(GetByteArray(getter, actualSize)); } return(bytes); }
public static string GetString(NativeCollectionGetter getter) { // TODO: rework to use GetCollection var bufferSize = 128; // First alloc this thread var stringGetBuffer = Marshal.AllocHGlobal((IntPtr)(bufferSize * sizeof(char))); try { // try to read var bytesRead = (int)getter(stringGetBuffer, (IntPtr)bufferSize, out var isNull, out var nativeException); nativeException.ThrowIfNecessary(); if (bytesRead == -1) { throw new RealmInvalidDatabaseException("Corrupted string data"); } // need a bigger buffer if (bytesRead > bufferSize) { bufferSize = bytesRead; Marshal.FreeHGlobal(stringGetBuffer); stringGetBuffer = Marshal.AllocHGlobal((IntPtr)(bufferSize * sizeof(char))); // try to read with big buffer bytesRead = (int)getter(stringGetBuffer, (IntPtr)bufferSize, out isNull, out nativeException); nativeException.ThrowIfNecessary(); // bad UTF-8 in full string if (bytesRead == -1) { throw new RealmInvalidDatabaseException("Corrupted string data"); } Debug.Assert(bytesRead <= bufferSize, "Buffer must have overflowed."); } // needed re-read with expanded buffer return(bytesRead != 0 ? Marshal.PtrToStringUni(stringGetBuffer, bytesRead) : (isNull ? null : string.Empty)); } finally { Marshal.FreeHGlobal(stringGetBuffer); } }
public static T[] GetCollection <T>(NativeCollectionGetter <T> getter, int bufferSize) where T : struct { var buffer = new T[bufferSize]; var itemsRead = (int)getter(buffer, (IntPtr)bufferSize, out var nativeException); nativeException.ThrowIfNecessary(); if (itemsRead > bufferSize) { bufferSize = itemsRead; buffer = new T[bufferSize]; itemsRead = (int)getter(buffer, (IntPtr)bufferSize, out nativeException); nativeException.ThrowIfNecessary(); Debug.Assert(itemsRead <= bufferSize, "Buffer must have overflowed."); } Array.Resize(ref buffer, itemsRead); return(buffer); }