public Event[] GetAndClearPendingEvents(MemoryPool <byte> pool) { FFIOperationWithVariableLengthReturnBuffer func = (bufOut, bufLength) => { var ffiResult = Interop.test_event_serialization(bufOut, bufLength, out var actualLength); return(ffiResult, actualLength); }; var arr = WithVariableLengthReturnBuffer(pool, func); return(Event.ParseManyUnsafe(arr)); }
private ChannelDetails[] ChannelDetailsInterop() { FFIOperationWithVariableLengthReturnBuffer func = (bufOut, bufLength) => { var ffiResult = Interop.test_channel_details_serialization(bufOut, bufLength, out var actualLen); return(ffiResult, actualLen); }; var arr = WithVariableLengthReturnBuffer(_pool, func); return(ChannelDetails.ParseManyUnsafe(arr)); }
/// <summary> /// Use this function when ffi function returns variable length return value /// It will rent `BUFFER_SIZE_UNIT` bytes from MemoryPool and tries to write a return value /// in to it. If the length was not enough, then it will try again with longer buffer. /// This process continues until the buffer reaches MAX_BUFFER_SIZE, and it will throws FFIException /// When that is even not enough. /// </summary> /// <param name="pool"></param> /// <param name="func"> actual ffi function, first argument is a pointer to a allocated buffer, second is the length of it, and third is a parent SafeHandle class</param> /// <returns></returns> /// <exception cref="FFIException"></exception> internal static byte[] WithVariableLengthReturnBuffer( MemoryPool <byte> pool, FFIOperationWithVariableLengthReturnBuffer func) { var initialBufLength = BUFFER_SIZE_UNIT; var(resultBuf, result, actualBufferLength) = InvokeWithLength(pool, initialBufLength, func); if (actualBufferLength > MAX_BUFFER_SIZE) { throw new FFIException( $"Tried to return too long buffer form rust ({actualBufferLength}). This should never happen.", result); } if (result.IsSuccess) { return(resultBuf[..actualBufferLength]);