示例#1
0
        public Delegate GenerateEncoder(Type type, Func <Type, Delegate> recurse)
        {
            // Get serializer for sub items
            var keyEncoder   = recurse(type.GenericTypeArguments[0]);
            var valueEncoder = recurse(type.GenericTypeArguments[1]);

            return(new Func <IDictionary, EncodeBuffer>(value =>
            {
                // Handle nulls
                if (null == value)
                {
                    return Null;
                }

                // Serialize elements
                var output = new EncodeBuffer();
                var e = value.GetEnumerator();
                UInt64 count = 0;
                while (e.MoveNext())
                {
                    output.Append((EncodeBuffer)keyEncoder.DynamicInvokeTransparent(e.Key));
                    output.Append((EncodeBuffer)valueEncoder.DynamicInvokeTransparent(e.Value));
                    count++;
                }

                // Encode length
                output.SetFirst(UnsignedVlq.Encode(count + 1));

                return output;
            }));
        }
示例#2
0
 public Delegate GenerateEncoder(Type type, Func <Type, Delegate> recurse)
 {
     return(new Func <UInt16, EncodeBuffer>(value =>
     {
         return new EncodeBuffer(UnsignedVlq.Encode(value));
     }));
 }
示例#3
0
 public Delegate GenerateDecoder(Type type, Func <Type, Delegate> recurse)
 {
     return(new Func <DecodeBuffer, UInt16>(input =>
     {
         return (UInt16)UnsignedVlq.Decode(input);
     }));
 }
示例#4
0
        public Delegate GenerateEncoder(Type type, Func <Type, Delegate> recurse)
        {
            // Get serializer for sub items
            var valueEncoder = recurse(type.GenericTypeArguments[0]);

            return(new Func <IList, EncodeBuffer>(value =>
            {
                // Handle nulls
                if (null == value)
                {
                    return Null;
                }

                // Serialize elements
                var output = new EncodeBuffer();
                foreach (var element in value)
                {
                    output.Append((EncodeBuffer)valueEncoder.DynamicInvokeTransparent(element));
                }

                // Encode length
                output.SetFirst(UnsignedVlq.Encode((UInt64)value.Count + 1));

                return output;
            }));
        }
示例#5
0
        public Delegate GenerateEncoder(Type type, Func <Type, Delegate> recurse)
        {
            // Get serializer for sub items
            var valueEncoder = recurse(type.GetElementType());

            return(new Func <Array, EncodeBuffer>(value =>
            {
                // Handle nulls
                if (null == value)
                {
                    return Null;
                }

                // Serialize elements
                var output = new EncodeBuffer();
                foreach (var subValue in value)
                {
                    output.Append((EncodeBuffer)valueEncoder.DynamicInvokeTransparent(subValue));
                }

                // Encode length
                output.SetFirst(UnsignedVlq.Encode((UInt64)value.Length + 1)); // Number of elements, not number of bytes

                return output;
            }));
        }
示例#6
0
        public override EncodeBuffer Encode(Object value)
        {
            var v = value as String;

            if (v == null)
            {
                if (IsNullable)
                {
                    return(Precomputed.Zero);
                }
                else
                {
                    throw new UnexpectedNullValueException();
                }
            }

            var length = (UInt64)v.Length;

            if (IsNullable)
            {
                length++;
            }

            // Encode value
            var output = new EncodeBuffer(2);

            output.Append(new ArraySegment <Byte>(Encoding.UTF8.GetBytes(v)));

            // Prepend length
            output.SetFirst(UnsignedVlq.Encode(length)); // Offset by one, since 0 is NULL

            return(output);
        }
示例#7
0
        public Delegate GenerateDecoder(Type type, Func <Type, Delegate> recurse)
        {
            // Get deserializer for sub items
            var valueDecoder = recurse(type.GenericTypeArguments[0]);

            return(new Func <DecodeBuffer, IList>(input =>
            {
                // Read header
                var header = UnsignedVlq.Decode(input);

                // Handle nulls
                if (header == 0)
                {
                    return null;
                }

                // Determine length
                var count = (Int32)header - 1;

                // Instantiate list
                var output = (IList)Activator.CreateInstance(type); //typeof(List<>).MakeGenericType(type.GenericTypeArguments)

                // Deserialize until we reach length limit
                for (var i = 0; i < count; i++)
                {
                    // Deserialize element
                    var element = valueDecoder.DynamicInvokeTransparent(input);

                    // Add to output
                    output.Add(element);
                }

                return output;
            }));
        }
示例#8
0
        public void UnsignedEncodeNullableNull()
        {
            var coder = new HeliumIntegerUnsigned(0, true, 1, 0);

            coder.Prepare(typeof(UInt32?));
            var encoded = coder.Encode((UInt32?)null);

            Assert.Equal(UnsignedVlq.Encode(UnsignedVlq.MinValue).ToHexString(), encoded.ToHexString());
        }
示例#9
0
        public void UnsignedEncodeMax()
        {
            var coder = new HeliumIntegerUnsigned(0, false, 1, 0);

            coder.Prepare(typeof(UInt64));
            var encoded = coder.Encode(UnsignedVlq.MaxValue);

            Assert.Equal(UnsignedVlq.Encode(UnsignedVlq.MaxValue).ToHexString(), encoded.ToHexString());
        }
示例#10
0
        public void UnsignedDecodeNullableNull()
        {
            var coder = new HeliumIntegerUnsigned(0, true, 1, 0);

            coder.Prepare(typeof(UInt32?));
            var decoded = coder.Decode(new DecodeBuffer(UnsignedVlq.Encode(0).ToArray()));

            Assert.Equal((UInt32?)null, decoded);
        }
示例#11
0
        public void UnsignedDecodeMax()
        {
            var coder = new HeliumIntegerUnsigned(0, false, 1, 0);

            coder.Prepare(typeof(UInt64));
            var decoded = coder.Decode(new DecodeBuffer(UnsignedVlq.Encode(UnsignedVlq.MaxValue).ToArray()));

            Assert.Equal(UnsignedVlq.MaxValue, decoded);
        }
示例#12
0
        public void UnsignedDecodeMin()
        {
            var coder = new HeliumIntegerUnsigned(0, false, 1, 0);

            coder.Prepare(typeof(UInt32));
            var decoded = coder.Decode(new DecodeBuffer(UnsignedVlq.Encode(0).ToArray()));

            Assert.Equal((UInt32)0, decoded);
        }
示例#13
0
        public override Object Decode(DecodeBuffer input)
        {
            var v = UnsignedVlq.Decode(input);

            if (IsNullable)
            {
                if (v == 0)
                {
                    return(null);
                }
                v--;
            }
            v *= Increment;
            v += Minimum;

            return(Convert.ChangeType(v, UnderlyingType));
        }
示例#14
0
        public override EncodeBuffer Encode(Object value)
        {
            if (value == null && IsNullable)
            {
                return(Precomputed.Zero);
            }

            var v = Convert.ToUInt64(value);

            v -= Minimum;
            v /= Increment;
            if (IsNullable)
            {
                v++;
            }

            return(new EncodeBuffer(UnsignedVlq.Encode(v)));
        }
示例#15
0
        public override Object Decode(DecodeBuffer input)
        {
            // Decode header
            var header = UnsignedVlq.Decode(input);

            // Handle nulls
            if (IsNullable)
            {
                if (header == 0)
                {
                    return(null);
                }
                header--;
            }

            // Decode value
            return(Encoding.UTF8.GetString(input.Underlying, input.GetIncrementOffset((Int32)header), (Int32)header));
        }
示例#16
0
        public override EncodeBuffer Encode(Object value)
        {
#if DEBUG
            if (null == Records)
            {
                throw new InvalidOperationException("Coder has not yet been prepared.");
            }
#endif

            // Handle nulls
            if (null == value)
            {
                if (!IsNullable)
                {
                    throw new UnexpectedNullValueException();
                }
                return(Precomputed.Zero);
            }

            var output = new EncodeBuffer();

            for (Byte i = 0; i < Records.Length; i++)
            {
                var record = Records[i];

                // Extract value
                var v = record.Field.GetValue(value);

                // Add to output
                output.Append(record.Coder.Encode(v));
            }

            // Increment length if nullable, to allow space for null representation
            var length = (UInt64)output.TotalLength;
            if (IsNullable)
            {
                length++;
            }

            // Encode length
            output.SetFirst(UnsignedVlq.Encode(length));

            return(output);
        }
示例#17
0
        public Delegate GenerateDecoder(Type type, Func <Type, Delegate> recurse)
        {
            return(new Func <DecodeBuffer, String>(input =>
            {
                // Decode header
                var header = UnsignedVlq.Decode(input);

                // Handle nulls
                if (header == 0)
                {
                    return null;
                }

                // Determine length
                var length = (Int32)header - 1;

                // Decode value
                return Encoding.UTF8.GetString(input.Underlying, input.GetIncrementOffset(length), length);
            }));
        }
示例#18
0
        public Delegate GenerateEncoder(Type type, Func <Type, Delegate> recurse)
        {
            return(new Func <String, EncodeBuffer>(value =>
            {
                // Handle nulls
                if (null == value)
                {
                    return Null;
                }

                // Encode value
                var output = new EncodeBuffer(2);
                output.Append(new ArraySegment <Byte>(Encoding.UTF8.GetBytes(value)));

                // Prepend length
                output.SetFirst(UnsignedVlq.Encode((UInt64)output.TotalLength + 1)); // Offset by one, since 0 is NULL

                return output;
            }));
        }
示例#19
0
        public override Object Decode(DecodeBuffer input)
        {
#if DEBUG
            if (null == Records)
            {
                throw new InvalidOperationException("Coder has not yet been prepared.");
            }
#endif

            // Read the length header
            var header = (Int32)UnsignedVlq.Decode(input);

            // Handle nulls
            if (IsNullable)
            {
                if (header == 0)
                {
                    return(null);
                }
                header--;
            }

            // Instantiate output
            var output = Activator.CreateInstance(UnderlyingType);

            // Extract an inner buffer so that if fields are added to the class in the future we ignore them, being backwards compatible
            var innerInput = input.Extract(header);

            // Isolate bytes for body
            foreach (var record in Records)
            {
                // Deserialize value
                var v = record.Coder.Decode(innerInput);

                // Set it on property
                record.Field.SetValue(output, v);
            }

            return(output);
        }
示例#20
0
        public Delegate GenerateDecoder(Type type, Func <Type, Delegate> recurse)
        {
            // Get deserializer for sub items
            var keyDecoder   = recurse(type.GenericTypeArguments[0]);
            var valueDecoder = recurse(type.GenericTypeArguments[1]);

            return(new Func <DecodeBuffer, IDictionary>(input =>
            {
                // Read header
                var header = UnsignedVlq.Decode(input);

                if (header == 0)
                {
                    return null;
                }

                // Get count
                var count = (Int32)header - 1;

                // Instantiate dictionary
                var output = (IDictionary)Activator.CreateInstance(type);

                // Loop through input buffer until depleted
                for (var i = 0; i < count; i++)
                {
                    // Deserialize key
                    var keyValue = keyDecoder.DynamicInvokeTransparent(input);

                    // Deserialize value
                    var valueValue = valueDecoder.DynamicInvokeTransparent(input);

                    // Add to output
                    output[keyValue] = valueValue;
                }

                return output;
            }));
        }
示例#21
0
        public Delegate GenerateDecoder(Type type, Func <Type, Delegate> recurse)
        {
            // Get deserializer for sub items
            var valueDecoder = recurse(type.GetElementType());

            return(new Func <DecodeBuffer, Array>(input =>
            {
                var header = UnsignedVlq.Decode(input);

                if (header == 0)
                {
                    return null;
                }

                // Determine length
                var length = (Int32)header - 1;

                // Instantiate list
                var container = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(type.GetElementType()));

                // Deserialize until we reach length limit
                for (var i = 0; i < length; i++)
                {
                    // Deserialize element
                    var element = valueDecoder.DynamicInvokeTransparent(input);

                    // Add to output
                    container.Add(element);
                }

                // Convert to array and return
                var output = Array.CreateInstance(type.GetElementType(), container.Count);
                container.CopyTo(output, 0);

                return output;
            }));
        }
示例#22
0
 public void BooleanSerializeFalse()
 {
     Assert.Equal(UnsignedVlq.Encode(0), LightWeight.Serialize(false));
 }
示例#23
0
 public void BooleanSerializeTrue()
 {
     Assert.Equal(UnsignedVlq.Encode(1), LightWeight.Serialize(true));
 }
示例#24
0
        public Delegate GenerateEncoder(Type type, Func <Type, Delegate> recurse)
        {
            var records = new Record[Byte.MaxValue];

            // Find all properties decorated with LightWeightProperty attribute
            var fieldCount = -1;

            foreach (var property in type.GetRuntimeFields())
            {
                // Get property attribute which tells us the properties' index
                var attribute = (LightWeightPropertyAttribute)property.GetCustomAttribute(typeof(LightWeightPropertyAttribute), false);
                if (null == attribute)
                {
                    // No attribute found, skip
                    continue;
                }

                // Check for duplicate index
                if (null != records[attribute.Index])
                {
                    throw new DuplicateIndexException($"The index {attribute.Index} is already used and cannot be reused.");
                }

                // Note the max index used
                if (attribute.Index > fieldCount)
                {
                    fieldCount = attribute.Index;
                }

                // Find/create encoder
                var encoder = recurse(property.FieldType);

                // Find floor, if any
                var transformations = property.GetCustomAttributes <TransformationAttribute>(true).ToArray();

                // Store property in lookup
                records[attribute.Index] = new Record()
                {
                    Field           = property,
                    Coder           = encoder,
                    Transformations = transformations
                };
            }

            // If no properties, shortcut the whole thing and return a blank
            if (fieldCount == -1)
            {
                return(new Func <Object, EncodeBuffer>(value =>
                {
                    // Handle nulls
                    if (null == value)
                    {
                        return Null;
                    }

                    return One;
                }));
            }

            // Check that no indexes have been missed
            for (var i = 0; i < fieldCount; i++)
            {
                if (null == records[i])
                {
                    throw new MissingIndexException($"Indexes must not be skipped, however missing index {i}."); // TODO: Make so indexes can be skipped for easier versioning
                }
            }

            return(new Func <Object, EncodeBuffer>(value =>
            {
                // Handle nulls
                if (null == value)
                {
                    return Null;
                }

                var output = new EncodeBuffer();

                for (Byte i = 0; i <= fieldCount; i++)
                {
                    var record = records[i];

                    // Get the serializer for the sub-item
                    var subType = recurse(record.Field.FieldType);

                    // Get it's method info
                    var subMethodInfo = subType.GetMethodInfo();

                    // Extract value
                    var v = record.Field.GetValue(value);

                    // Apply transformations
                    foreach (var transformation in record.Transformations)
                    {
                        v = transformation.ApplyEffect(v);
                    }

                    // Add to output
                    output.Append((EncodeBuffer)record.Coder.DynamicInvokeTransparent(v));
                }

                // Encode length
                output.SetFirst(UnsignedVlq.Encode((UInt64)output.TotalLength + 1)); // Number of bytes

                return output;
            }));
        }
示例#25
0
        public Delegate GenerateDecoder(Type type, Func <Type, Delegate> recurse)
        {
            var records = new Record[Byte.MaxValue];

            // Find all properties decorated with LightWeightProperty attribute

            var maxIndex = -1;

            foreach (var property in type.GetRuntimeFields())
            {
                // Get property attribute which tells us the properties' index
                var attribute = (LightWeightPropertyAttribute)property.GetCustomAttribute(typeof(LightWeightPropertyAttribute), false);
                if (null == attribute)
                {
                    // No attribute found, skip
                    continue;
                }

                // Check for duplicate index
                if (null != records[attribute.Index])
                {
                    throw new DuplicateIndexException($"The index {attribute.Index} is already used and cannot be reused.");
                }

                // Note the max index used
                if (attribute.Index > maxIndex)
                {
                    maxIndex = attribute.Index;
                }

                // Find/create encoder
                var decoder = recurse(property.FieldType);

                // Find floor, if any
                var transformations = property.GetCustomAttributes <TransformationAttribute>(true).ToArray();

                // Store property in lookup
                records[attribute.Index] = new Record()
                {
                    Field           = property,
                    Coder           = decoder,
                    Transformations = transformations
                };
            }

            // Check that no indexes have been missed
            for (var i = 0; i < maxIndex; i++)
            {
                if (null == records[i])
                {
                    throw new MissingIndexException($"Indexes must not be skipped, however missing index {i}.");
                }
            }

            return(new Func <DecodeBuffer, Object>(input =>
            {
                // Read the length header
                var header = (Int32)UnsignedVlq.Decode(input);

                // Handle nulls
                if (header == 0)
                {
                    return null;
                }

                // Determine length
                var length = header - 1;

                // Instantiate output
                var output = Activator.CreateInstance(type);

                // Extract an inner buffer so that if fields are added to the class in the future we ignore them, being backwards compatible
                var innerInput = input.Extract(length);

                // Isolate bytes for body
                for (var i = 0; i <= maxIndex; i++)
                {
                    var record = records[i];

                    // Deserialize value
                    var v = record.Coder.DynamicInvokeTransparent(innerInput);

                    // Apply transformations
                    foreach (var transformation in record.Transformations)
                    {
                        v = transformation.RemoveEffect(v);
                    }

                    // Set it on property
                    record.Field.SetValue(output, v);
                }

                return output;
            }));
        }
示例#26
0
 public void UInt32DeserializeEnum()
 {
     Assert.Equal(TestEnum.B, LightWeight.Deserialize <TestEnum>(UnsignedVlq.Encode((UInt32)TestEnum.B).ToArray()));
 }
示例#27
0
 public void UInt32DeserializeMax()
 {
     Assert.Equal(UInt32.MaxValue, LightWeight.Deserialize <UInt32>(UnsignedVlq.Encode(UInt32.MaxValue).ToArray()));
 }
示例#28
0
 public void UInt32SerializeEnum()
 {
     Assert.Equal(UnsignedVlq.Encode((UInt32)TestEnum.B), LightWeight.Serialize(TestEnum.B));
 }
示例#29
0
 public void UInt32SerializeMax()
 {
     Assert.Equal(UnsignedVlq.Encode(UInt32.MaxValue), LightWeight.Serialize(UInt32.MaxValue));
 }
示例#30
0
 public void BooleanDeserializeFalse()
 {
     Assert.False(LightWeight.Deserialize <Boolean>(UnsignedVlq.Encode(0).ToArray()));
 }