예제 #1
0
        public unsafe int Write(TElement[] value, ref DirectBuffer destination, uint offset = 0u, MemoryStream temporaryStream = null, CompressionMethod compression = CompressionMethod.DefaultOrNone)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (temporaryStream != null)
            {
                throw new NotSupportedException("BlittableArrayBinaryConverter does not work with temp streams.");
            }
            if (ItemSize > 0)
            {
                var totalSize = 8 + ItemSize * value.Length;
                if (!destination.HasCapacity(offset, totalSize))
                {
                    return((int)BinaryConverterErrorCode.NotEnoughCapacity);
                }
                var ptr = destination.Data + (int)offset;

                var pinnedArray = GCHandle.Alloc(value, GCHandleType.Pinned);
                // size
                Marshal.WriteInt32(ptr, totalSize);
                // version
                Marshal.WriteByte(ptr + 4, Version);
                if (value.Length > 0)
                {
                    var source = Marshal.UnsafeAddrOfPinnedArrayElement(value, 0);
                    ByteUtil.MemoryCopy((byte *)(ptr + 8), (byte *)source, checked ((uint)(ItemSize * value.Length)));
                }
                pinnedArray.Free();
                return(totalSize);
            }
            throw new InvalidOperationException("BlittableArrayBinaryConverter must be called only on blittable types");
        }
예제 #2
0
        public unsafe int Write(MemoryStream value, ref DirectBuffer destination, uint offset, MemoryStream temporaryStream = null, CompressionMethod compression = CompressionMethod.DefaultOrNone)
        {
            if (temporaryStream != null)
            {
                throw new NotSupportedException("MemoryStreamBinaryConverter does not work with temp streams.");
            }

            if (value.Length > int.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(temporaryStream), "Memory stream is too large");
            }

            var totalLength = checked ((int)value.Length + 8);

            if (!destination.HasCapacity(offset, totalLength))
            {
                return((int)BinaryConverterErrorCode.NotEnoughCapacity);
            }
            var ptr = destination.Data + (int)offset;

            // size
            Marshal.WriteInt32(ptr, totalLength);
            // version
            Marshal.WriteInt32(ptr + 4, Version);

            // payload
            ptr = ptr + 8;

            value.WriteToPtr(ptr);
            return(totalLength);
        }
예제 #3
0
 public int Write(byte[] value, ref DirectBuffer destination, uint offset = 0, MemoryStream temporaryStream = null, CompressionMethod compression = CompressionMethod.DefaultOrNone)
 {
     if (compression == CompressionMethod.DefaultOrNone)
     {
         if (temporaryStream != null)
         {
             throw new NotSupportedException("ByteArrayBinaryConverter does not work with temp streams.");
         }
         var totalSize = value.Length + 8;
         if (!destination.HasCapacity(offset, totalSize))
         {
             return((int)BinaryConverterErrorCode.NotEnoughCapacity);
         }
         var ptr = destination.Data + (int)offset;
         // size
         Marshal.WriteInt32(ptr, totalSize);
         // version
         Marshal.WriteByte(ptr + 4, Version);
         // payload
         Marshal.Copy(value, 0, ptr + 8, value.Length);
         return(totalSize);
     }
     else
     {
         return(CompressedArrayBinaryConverter <byte> .Instance.Write(value, 0, value.Length, ref destination,
                                                                      offset, temporaryStream, compression));
     }
 }
예제 #4
0
        public unsafe int Write(string value, ref DirectBuffer destination, uint offset = 0u, MemoryStream temporaryStream = null, CompressionMethod compression = CompressionMethod.DefaultOrNone)
        {
            if (compression == CompressionMethod.DefaultOrNone)
            {
                if (temporaryStream == null)
                {
                    fixed(char *charPtr = value)
                    {
                        var totalLength = 8 + Encoding.UTF8.GetByteCount(charPtr, value.Length);

                        if (!destination.HasCapacity(offset, totalLength))
                        {
                            return((int)BinaryConverterErrorCode.NotEnoughCapacity);
                        }
                        var ptr = destination.Data + (int)offset;

                        // size
                        Marshal.WriteInt32(ptr, totalLength);
                        // version
                        Marshal.WriteByte(ptr + 4, Version);
                        // payload
                        var len = Encoding.UTF8.GetBytes(charPtr, value.Length, (byte *)ptr + 8, totalLength);

                        Debug.Assert(totalLength == len + 8);
                        return(len + 8);
                    }
                }
                else
                {
                    throw new NotSupportedException("StringBinaryConverter does not work with temp streams.");
                    //throw new NotImplementedException();
                    //temporaryStream.WriteToPtr(ptr);
                    //return checked((int)temporaryStream.Length);
                }
            }
            else
            {
                throw new NotImplementedException("TODO string compression");
            }
        }