public void PeekFirstSequence_WithEmptyInput_ReturnsEmptyValidity() { // Act var buffer = NativeMemory.Allocate(0, PoisonPagePlacement.AfterSpan); var validity = Utf8Utility.PeekFirstSequence(buffer.Span, out var numBytesConsumed, out var scalarValue); // Assert Assert.Equal(SequenceValidity.Empty, validity); Assert.Equal(0, numBytesConsumed); Assert.Equal(UnicodeScalar.ReplacementChar, scalarValue); buffer.Dispose(); }
public static void RunSample() { Console.WriteLine($"*** {nameof(WrapNativeMemory)} ***"); Console.WriteLine($"Allocated as part of the operation"); // in this case we pretend that we cannot know the size of the tensor up front and require the native library to allocate it and tell us the size. var multTable = GetMultiplicationTable(5); Console.WriteLine("Multiplication table:"); Console.WriteLine(multTable.GetArrayString()); Console.WriteLine("Sums:"); for (int row = 0; row < multTable.Dimensions[0]; row++) { Console.WriteLine(GetRowSum(multTable, row)); } // the memory will be freed when the GC decides to collect the Tensor, we can *try* to force it but no garuntee. multTable = null; Console.WriteLine("Forcing GC."); GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine($"Allocated prior to the operation"); // in this case we'll assume we can know the size of the buffer up front and manage the lifetime explicitly using (var nativeMemory = NativeMemory <double> .Allocate(5 * 5)) { Span <int> dimensions = stackalloc int[2]; dimensions[0] = dimensions[1] = 5; var tensor = new DenseTensor <double>(nativeMemory.Memory, dimensions); GetMultiplicationTablePreallocated(5, tensor); Console.WriteLine("Sums:"); for (int row = 0; row < tensor.Dimensions[0]; row++) { Console.WriteLine(GetRowSum(tensor, row)); } } }
/// <summary> /// 序列化对象,并将序列化数据写入指定的缓冲区中 /// </summary> /// <typeparam name="T">序列化的对象类型</typeparam> /// <param name="obj">被序列化的对象</param> /// <param name="buffer">用于接受序列化数据的缓冲区</param> /// <param name="index"><paramref name="buffer"/>开始写入的索引</param> /// <param name="encoding">序列化使用的字符编码</param> /// <param name="endian">序列化使用的字节序</param> /// <returns>序列化数据的大小</returns> /// <exception cref="ArgumentException">字节数组容量不足</exception> public static int Serialize <T>(T obj, byte[] buffer, int index, Encoding encoding = Encoding.UTF8, Endian endian = Endian.BigEndian) { InternalTypeCache <T> .OnBeforeSerializationCallbacks?.Invoke(ref obj); int memSize = InternalTypeCache <T> .ApproximateMemorySize; NativeMemory mem = NativeMemory.Allocate(ref memSize); AccelWriter writer = new AccelWriter(&mem, encoding, endian == Endian.LittleEndian); writer.WriteGlobalConfig(encoding, endian); try { InternalTypeCache <T> .Serializer.Serialize(obj, ref writer); return(mem.CopyToArray(writer.ByteCount, buffer, index)); } finally { mem.Dispose(); } }
/// <summary> /// 序列化对象,并返回序列化数据 /// </summary> /// <typeparam name="T">序列化的对象类型</typeparam> /// <param name="obj">被序列化的对象</param> /// <param name="encoding">序列化使用的字符编码</param> /// <param name="endian">序列化使用的字节序</param> /// <returns>保存了对象序列化数据的一块非托管缓冲区</returns> public static NativeBuffer Serialize <T>(T obj, Encoding encoding = Encoding.UTF8, Endian endian = Endian.BigEndian) { InternalTypeCache <T> .OnBeforeSerializationCallbacks?.Invoke(ref obj); int memSize = InternalTypeCache <T> .ApproximateMemorySize; NativeMemory mem = NativeMemory.Allocate(ref memSize); AccelWriter writer = new AccelWriter(&mem, encoding, endian == Endian.LittleEndian); writer.WriteGlobalConfig(encoding, endian); try { InternalTypeCache <T> .Serializer.Serialize(obj, ref writer); return(mem.ToNativeBufferNoCopy(writer.ByteCount)); } catch { mem.Dispose(); throw; } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="index"></param> /// <param name="value"></param> public void WriteValue <T>(int index, T value) { ITypeSerializer <T> serializer = InternalTypeCache <T> .Serializer; if (serializer is IBuiltinTypeSerializer) { Index = index; serializer.Serialize(value, ref this); } else { int memSize = InternalTypeCache <T> .ApproximateMemorySize; NativeMemory mem = NativeMemory.Allocate(ref memSize); AccelWriter writer = new AccelWriter(&mem, m_Encoding, m_IsLittleEndian); try { serializer.Serialize(value, ref writer); int byteCount = writer.m_ByteCount; ObjectType type = GetObjectTypeByLength(byteCount); WriteTag(index, type); if (type == ObjectType.LengthPrefixed) { WriteUInt32Variant((uint)byteCount); } WriteBytes(writer.m_Memory->GetPointer(), byteCount); } finally { mem.Dispose(); } } }