Example #1
0
        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();
        }
Example #2
0
        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));
                }
            }
        }
Example #3
0
        /// <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();
            }
        }
Example #4
0
        /// <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;
            }
        }
Example #5
0
        /// <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();
                }
            }
        }