예제 #1
0
        public void Deserialize(byte[] buffer, ref int offset, ref List <TItem> value)
        {
            // How many items?
            var itemCount = SerializerBinary.ReadUInt32(buffer, ref offset);

            if (itemCount > _maxSize)
            {
                throw new InvalidOperationException($"The data contains a '{typeof(TItem)}'-List with '{itemCount}' elements, which exceeds the allowed limit of '{_maxSize}'");
            }

            if (value == null)
            {
                value = new List <TItem>((int)itemCount);
            }
            else
            {
                value.Clear();
            }

            var f = _itemFormatter;

            for (int i = 0; i < itemCount; i++)
            {
                TItem item = default;
                f.Deserialize(buffer, ref offset, ref item);
                value.Add(item);
            }
        }
예제 #2
0
        public unsafe void Serialize(ref byte[] buffer, ref int offset, T[] value)
        {
            // Ensure capacity
            int size       = _size;
            int neededSize = size + 5;

            SerializerBinary.EnsureCapacity(ref buffer, offset, neededSize);

            // Count
            int count = value.Length;

            SerializerBinary.WriteUInt32NoCheck(buffer, ref offset, (uint)count);

            int bytes = count * size;

            if (bytes == 0)
            {
                return;

                // Write
                fixed(T *p = value)
                Marshal.Copy(new IntPtr(p), buffer, offset, count);

                offset += bytes;
        }
예제 #3
0
		public void Deserialize(byte[] buffer, ref int offset, ref TCollection value)
		{
			// How many items?
			var itemCount = SerializerBinary.ReadUInt32(buffer, ref offset);

			if (itemCount > _maxSize)
				throw new InvalidOperationException($"The data contains a '{typeof(TCollection)}' with '{itemCount}' entries, which exceeds the allowed limit of '{_maxSize}'");


			if (value == null)
				value = _capacityConstructor((int)itemCount);
			else
			{
				if (value.Count > 0)
					value.Clear();
			}

			if (value.IsReadOnly)
				ThrowReadonly(value);


			var f = _itemFormatter;

			for (int i = 0; i < itemCount; i++)
			{
				TItem item = default;
				f.Deserialize(buffer, ref offset, ref item);
				value.Add(item);
			}
		}
        public async Task SerializeAsync(Stream stream, object message, Type type, CancellationToken cancellationToken = default)
        {
            using (var serializedMemory = SerializeCore(message, type))
            {
                var uncompressed = serializedMemory.Memory;

                var compressedBuff = ArrayPool <byte> .Shared.Rent(LZ4Codec.MaximumOutputSize(uncompressed.Length) + HeaderLength);

                try
                {
                    //write body, skip header
                    var compressedLength = LZ4Codec.Encode(
                        uncompressed.Span,
                        new Span <byte>(compressedBuff, HeaderLength, compressedBuff.Length - HeaderLength));

                    //write header
                    var offset = 0;
                    SerializerBinary.WriteByte(ref compressedBuff, ref offset, Header);
                    SerializerBinary.WriteInt32Fixed(ref compressedBuff, ref offset, compressedLength);
                    SerializerBinary.WriteInt32Fixed(ref compressedBuff, ref offset, uncompressed.Length);

                    await stream.WriteAsync(compressedBuff, 0, compressedLength + HeaderLength, cancellationToken).ConfigureAwait(false);
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(compressedBuff);
                }
            }
        }
예제 #5
0
        public unsafe void Serialize(ref byte[] buffer, ref int offset, T[] value)
        {
            int count = value.Length;

            // Ensure capacity
            int size       = _itemSize;
            int neededSize = (count * size) + 5;

            SerializerBinary.EnsureCapacity(ref buffer, offset, neededSize);

            // Count
            SerializerBinary.WriteUInt32NoCheck(buffer, ref offset, (uint)count);

            int bytes = count * size;

            if (bytes == 0)
            {
                return;

                // Write
                fixed(T *srcAr = &value[0])
                fixed(byte *destAr = &buffer[0])
                {
                    byte *src  = (byte *)srcAr;
                    byte *dest = destAr + offset;

                    SerializerBinary.FastCopy(src, dest, (uint)bytes);
                }


                offset += bytes;
        }
예제 #6
0
        public void Serialize(ref byte[] buffer, ref int offset, TCollection value)
        {
            if (value.IsReadOnly)
            {
                ThrowReadonly(value);
            }

            // Write how many items do we have
            SerializerBinary.WriteUInt32(ref buffer, ref offset, (uint)value.Count);

            // Write each item
            var f = _itemFormatter;
            // Guarantee no boxing
            IEnumerator <TItem> e = value.GetEnumerator();

            try
            {
                while (e.MoveNext())
                {
                    f.Serialize(ref buffer, ref offset, e.Current);
                }
            }
            finally
            {
                e.Dispose();
            }
        }
예제 #7
0
 public void Deserialize(byte[] buffer, ref int offset, ref Person value)
 {
     // Nothing interesting here, all the important stuff is explained in 'Serialize()'
     value.Name   = SerializerBinary.ReadString(buffer, ref offset);
     value.Health = SerializerBinary.ReadInt32(buffer, ref offset);
     PersonFormatter.Deserialize(buffer, ref offset, ref value.BestFriend);
 }
예제 #8
0
        public unsafe void Deserialize(byte[] buffer, ref int offset, ref T[] value)
        {
            // Count
            int count = (int)SerializerBinary.ReadUInt32(buffer, ref offset);

            if (count > _maxCount)
            {
                throw new InvalidOperationException($"The data describes an array with '{count}' elements, which exceeds the allowed limit of '{_maxCount}'");
            }

            // Create target array
            if (value == null || value.Length != count)
            {
                value = new T[count];
            }

            int bytes = count * _size;

            if (bytes == 0)
                return;

            // Read
            fixed(T *ar = &value[0])
            {
                byte *byteAr = (byte *)ar;

                Marshal.Copy(buffer, offset, new IntPtr(byteAr), bytes);
            }

            offset += bytes;
        }
예제 #9
0
        public void Deserialize(byte[] buffer, ref int offset, ref TItem[] ar)
        {
            int length = SerializerBinary.ReadUInt32Bias(buffer, ref offset, 1);

            if (length == -1)
            {
                ar = null;
                return;
            }

            if (length > _maxCount)
            {
                throw new InvalidOperationException($"The data contains a '{typeof(TItem)}'-array of size '{length}', which exceeds the allowed limit of '{_maxCount}'");
            }

            if (ar == null || ar.Length != length)
            {
                ar = new TItem[length];
            }

            var f = _itemFormatter;             // Cache into local to prevent ram fetches

            for (int i = 0; i < length; i++)
            {
                f.Deserialize(buffer, ref offset, ref ar[i]);
            }
        }
예제 #10
0
        public void Deserialize(byte[] buffer, ref int offset, ref int[] ar)
        {
            int length = SerializerBinary.ReadUInt32Bias(buffer, ref offset, 1);

            if (length == -1)
            {
                ar = null;
                return;
            }

            if (length > _maxSize)
            {
                throw new InvalidOperationException($"The data contains a byte-array of size '{length}', which exceeds the allowed limit of '{_maxSize}'");
            }

            if (ar == null || ar.Length != length)
            {
                ar = new int[length];
            }

            int byteLen = length * 4;

            Buffer.BlockCopy(buffer, offset, ar, 0, byteLen);

            offset += byteLen;
        }
예제 #11
0
            public unsafe void Serialize(ref byte[] buffer, ref int offset, Vector3 value)
            {
                const int v3Size = 3 * 4;

                SerializerBinary.EnsureCapacity(ref buffer, offset, v3Size);

                var bufferLocal = buffer;

                fixed(byte *pBuffer = buffer)
                {
                    var ptr = (float *)(pBuffer + offset);

                    *ptr = value.X;
                }

                fixed(byte *pBuffer = buffer)
                {
                    var ptr = (float *)(pBuffer + offset + 4);

                    *ptr = value.Y;
                }

                fixed(byte *pBuffer = buffer)
                {
                    var ptr = (float *)(pBuffer + offset + 8);

                    *ptr = value.Z;
                }

                offset += v3Size;
            }
예제 #12
0
        public void Deserialize(byte[] buffer, ref int offset, ref T value)
        {
            var maxStrLen = _sizeLimits.MaxStringLength;
            var str       = SerializerBinary.ReadStringLimited(buffer, ref offset, maxStrLen);

            value = (T)System.Enum.Parse(typeof(T), str);
        }
예제 #13
0
        public void Deserialize(byte[] buffer, ref int offset, ref Bitmap img)
        {
            // Read data size
            int size = (int)SerializerBinary.ReadUInt32Fixed(buffer, ref offset);

            // Copy data into stream
            if (_sharedMemoryStream == null)
            {
                _sharedMemoryStream = new MemoryStream(size);
            }
            else if (_sharedMemoryStream.Capacity < size)
            {
                _sharedMemoryStream.Capacity = size;
            }

            var ms = _sharedMemoryStream;

            ms.Position = 0;
            var memoryStreamBuffer = ms.GetBuffer();

            if (size > 0)
            {
                SerializerBinary.FastCopy(buffer, offset, memoryStreamBuffer, 0, size);
            }

            // Now we can load the image back from the stream
            ms.Position = 0;

            img = new Bitmap(ms);

            offset += size;
        }
예제 #14
0
        public void Deserialize(byte[] buffer, ref int offset, ref Array baseAr)
        {
            // Dimensions
            int dimensions = (int)SerializerBinary.ReadUInt32(buffer, ref offset);

            // Dimension sizes
            var dimensionSizes = new int[dimensions];

            for (int d = 0; d < dimensions; d++)
            {
                var size = (int)SerializerBinary.ReadUInt32(buffer, ref offset);
                dimensionSizes[d] = size;
            }

            // Count
            int count = dimensionSizes[0];

            for (int d = 1; d < dimensions; d++)
            {
                count *= dimensionSizes[d];
            }

            if (count > _maxCount)
            {
                throw new InvalidOperationException($"The data describes an array with '{count}' elements, which exceeds the allowed limit of '{_maxCount}'");
            }

            // Create array
            baseAr = Array.CreateInstance(typeof(TItem), dimensionSizes);

            // Read
            var indices = new int[dimensions];

            ReadArrayEntry(buffer, ref offset, _itemFormatter, baseAr, indices, dimensionSizes, 0);
        }
        public async Task <object> DeserializeAsync(Stream stream, Type type, CancellationToken cancellationToken = default)
        {
            var headerBuffer = new byte[9];
            await stream.ReadAsync(headerBuffer, 0, HeaderLength, cancellationToken).ConfigureAwait(false);

            var offset = 0;
            var header = SerializerBinary.ReadByte(headerBuffer, ref offset);

            if (header != Header)
            {
                throw new Exception("Not expected header error");
            }
            var compressedLength   = SerializerBinary.ReadInt32Fixed(headerBuffer, ref offset);
            var uncompressedLength = SerializerBinary.ReadInt32Fixed(headerBuffer, ref offset);

            var buffer = ArrayPool <byte> .Shared.Rent(compressedLength + uncompressedLength);

            try
            {
                await stream.ReadAsync(buffer, 0, compressedLength, cancellationToken).ConfigureAwait(false);

                LZ4Codec.Decode(
                    buffer, 0, compressedLength,
                    buffer, compressedLength, uncompressedLength);

                object obj = DeserializeCore(buffer, compressedLength, uncompressedLength);

                return(obj);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }
        }
예제 #16
0
        public void Serialize(ref byte[] buffer, ref int offset, T value)
        {
            SerializerBinary.EnsureCapacity(ref buffer, offset, Unsafe.SizeOf <T>());

            Write_Raw(buffer, offset, ref value);

            offset += Unsafe.SizeOf <T>();
        }
예제 #17
0
        public void Serialize(ref byte[] buffer, ref int offset, T value)
        {
            SerializerBinary.EnsureCapacity(ref buffer, offset, _size);

            Write_Raw(buffer, offset, ref value);

            offset += _size;
        }
예제 #18
0
        public void Deserialize(byte[] buffer, ref int offset, ref Type value)
        {
            int mode = SerializerBinary.ReadUInt32Bias(buffer, ref offset, Bias);

            // Null
            if (mode == Null)
            {
                value = null;
                return;
            }

            var typeCache = _serializer.InstanceData.TypeCache;

            // Existing
            if (mode >= 0)
            {
                var id = mode;
                value = typeCache.GetExistingObject <Type>(id);
                return;
            }


            bool isComposite = mode == NewComposite;

            if (isComposite)             // composite aka "closed generic"
            {
                // Read main type
                var compositeProxy = typeCache.CreateDeserializationProxy <Type>();

                Type baseType = value;
                Deserialize(buffer, ref offset, ref baseType);


                // Read count
                var    argCount    = SerializerBinary.ReadByte(buffer, ref offset);
                Type[] genericArgs = new Type[argCount];
                for (int i = 0; i < argCount; i++)
                {
                    var genericArgProxy = typeCache.CreateDeserializationProxy <Type>();

                    Deserialize(buffer, ref offset, ref genericArgProxy.Value);

                    genericArgs[i] = genericArgProxy.Value;
                }

                value = _typeBinder.GetTypeFromBaseAndAgruments(baseType.FullName, genericArgs);
                compositeProxy.Value = value;                 // make it available for future deserializations
            }
            else
            {
                var proxy = typeCache.CreateDeserializationProxy <Type>();

                string baseTypeName = SerializerBinary.ReadString(buffer, ref offset);
                value = _typeBinder.GetTypeFromBase(baseTypeName);

                proxy.Value = value;
            }
        }
예제 #19
0
        public void Deserialize(byte[] buffer, ref int offset, ref T member)
        {
            // What type?
            Type type = null;

            _typeFormatter.Deserialize(buffer, ref offset, ref type);

            // What kind of member?
            var memberType = (MemberTypes)SerializerBinary.ReadInt32(buffer, ref offset);

            string name = null;

            switch (memberType)
            {
            case MemberTypes.Constructor:
            case MemberTypes.Method:
                _stringFormatter.Deserialize(buffer, ref offset, ref name);
                var numArgs = SerializerBinary.ReadInt32(buffer, ref offset);

                Type[] args = new Type[numArgs];

                for (int i = 0; i < numArgs; i++)
                {
                    _typeFormatter.Deserialize(buffer, ref offset, ref args[i]);
                }

                if (memberType == MemberTypes.Constructor)
                {
                    member = (T)(MemberInfo)type.GetConstructor(args);
                }
                else
                {
                    member = (T)(MemberInfo)type.GetMethod(name, args);
                }

                break;

            case MemberTypes.Field:
            case MemberTypes.Property:
                _stringFormatter.Deserialize(buffer, ref offset, ref name);
                Type fieldOrPropType = null;
                _typeFormatter.Deserialize(buffer, ref offset, ref fieldOrPropType);

                if (memberType == MemberTypes.Field)
                {
                    member = (T)(MemberInfo)type.GetField(name);
                }
                else
                {
                    member = (T)(MemberInfo)type.GetProperty(name, fieldOrPropType);
                }

                break;

            default:
                throw new ArgumentOutOfRangeException("Cannot deserialize member type '" + memberType + "'");
            }
        }
예제 #20
0
            public override void Execute(object target, byte[] buffer, ref int offset)
            {
                var size = SerializerBinary.ReadUInt32Fixed(buffer, ref offset);

                TMember value = default;

                _formatter.Deserialize(buffer, ref offset, ref value);
                _propSetter(target, value);
            }
예제 #21
0
        public void Serialize(ref byte[] buffer, ref int offset, T value)
        {
            if (EqualityComparer <T> .Default.Equals(value, default))
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, Null, Bias);
                return;
            }

            if (value is Type type)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, InlineType, Bias);
                _typeFormatter.Serialize(ref buffer, ref offset, type);
                return;
            }

            if (value is IExternalRootObject externalObj)
            {
                if (!object.ReferenceEquals(_serializer.InstanceData.CurrentRoot, value))
                {
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, ExternalObject, Bias);

                    var refId = externalObj.GetReferenceId();
                    SerializerBinary.WriteInt32(ref buffer, ref offset, refId);

                    _serializer.Config.OnExternalObject?.Invoke(externalObj);

                    return;
                }
            }

            if (_serializer.InstanceData.ObjectCache.TryGetExistingObjectId(value, out int id))
            {
                // Existing value
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, id, Bias);
            }
            else
            {
                // Important: Insert the ID for this value into our dictionary BEFORE calling SerializeFirstTime, as that might recursively call us again (maybe with the same value!)
                _serializer.InstanceData.ObjectCache.RegisterObject(value);

                var specificType = value.GetType();
                if (typeof(T) == specificType)
                {
                    // New value (same type)
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValueSameType, Bias);
                }
                else
                {
                    // New value (type included)
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValue, Bias);
                    _typeFormatter.Serialize(ref buffer, ref offset, specificType);
                }

                // Write the object normally
                GetSpecificSerializerDispatcher(specificType)(ref buffer, ref offset, value);
            }
        }
예제 #22
0
        public override Task AddMessageAsync(IQueueMessage <object, int> message, QueueSettings queueSettings, CancellationToken cancellationToken = default(CancellationToken))
        {
            message.Id = IdInternal;

            Queue.Add(IdInternal, SerializerBinary.CloneStatic(message));
            ++IdInternal;

            return(Task.Delay(0, cancellationToken));
        }
예제 #23
0
        public void Deserialize(byte[] buffer, ref int offset, ref Person value)
        {
            // Just for illustration purposes we'll do exactly the same thing that Ceras would
            // normally generate for us automatically, but instead we're doing it manually here.

            value.Name   = SerializerBinary.ReadString(buffer, ref offset);
            value.Health = SerializerBinary.ReadInt32(buffer, ref offset);
            PersonFormatter.Deserialize(buffer, ref offset, ref value.BestFriend);
        }
예제 #24
0
        public void Serialize(ref byte[] buffer, ref int offset, Ulid value)
        {
            // Ensures that we have enough space to cram in an Ulid
            SerializerBinary.EnsureCapacity(ref buffer, offset, 16);
            var byteSpan = buffer.AsSpan(offset, 16);

            value.TryWriteBytes(byteSpan);
            // Move 128 bits further
            offset += 16;
        }
예제 #25
0
        public override Task <IEnumerable <IQueueMessage <object, int> > > PeekMessagesAsync(QueueSettings queueSettings, CancellationToken cancellationToken = default(CancellationToken))
        {
            var values = Queue
                         .Values
                         .Select(m => SerializerBinary.CloneStatic(m))
                         .ToList()
                         .AsEnumerable();

            return(Task.FromResult(values));
        }
예제 #26
0
            public void Serialize(ref byte[] buffer, ref int offset, Vector3 value)
            {
                const int v3Size = 3 * 4;

                SerializerBinary.EnsureCapacity(ref buffer, offset, v3Size);

                SerializerBinary.WriteFloat32FixedNoCheck(ref buffer, ref offset, value.X);
                SerializerBinary.WriteFloat32FixedNoCheck(ref buffer, ref offset, value.Y);
                SerializerBinary.WriteFloat32FixedNoCheck(ref buffer, ref offset, value.Z);
            }
예제 #27
0
        public void Deserialize(byte[] buffer, ref int offset, ref BitArray value)
        {
            int bits = (int)SerializerBinary.ReadUInt32(buffer, ref offset);

            int[] ar = null;
            _intFormatter.Deserialize(buffer, ref offset, ref ar);

            value        = new BitArray(ar);
            value.Length = bits;
        }
예제 #28
0
        public void Deserialize(byte[] buffer, ref int offset, ref IPAddress value)
        {
            var isIPv4 = SerializerBinary.ReadByte(buffer, ref offset) == 0;
            var bytes  = new byte[isIPv4 ? 4 : 16];

            for (var i = 0; i < bytes.Length; i++)
            {
                bytes[i] = SerializerBinary.ReadByte(buffer, ref offset);
            }
            value = new IPAddress(bytes);
        }
예제 #29
0
        public void Serialize(ref byte[] buffer, ref int offset, TCollection value)
        {
            // Write how many items do we have
            SerializerBinary.WriteUInt32(ref buffer, ref offset, (uint)value.Count);

            // Write each item
            foreach (var item in value)
            {
                _itemFormatter.Serialize(ref buffer, ref offset, item);
            }
        }
예제 #30
0
            public void Serialize(ref byte[] buffer, ref int offset, decimal value)
            {
                SerializerBinary.EnsureCapacity(ref buffer, offset, 16);
                fixed(byte *dst = &buffer[offset])
                {
                    var src = &value;

                    *(decimal *)(dst) = *src;

                    offset += 16;
                }
            }