public object Deserialize(Stream serializationStream)
        {
            Buffer.BitArray buffer;

            using (StreamReader sr = new StreamReader(serializationStream))
            {
                var data = new byte[serializationStream.Length];
                serializationStream.Read(data, 0, (int)serializationStream.Length);
                buffer = new Buffer.BitArray(data);
            }
            object result = new T();

            DeserializeContractInternal(ref result, buffer);

            return(result);
        }
        public void Serialize(Stream serializationStream, object graph)
        {
            Buffer.BitArray buffer = new Buffer.BitArray();

            if (graph == null)
            {
                throw new ArgumentNullException();
            }

            if (!graph.GetType().HasAttribute(typeof(BinaryEncodingContractAttribute)))
            {
                throw new ArgumentException("Needs to be a BinaryEncodingContract type");
            }

            SerializeContractInternal(graph, buffer);
            var bufferData = buffer.ToByteArray();

            serializationStream.Write(bufferData, 0, bufferData.Length);
            serializationStream.Flush();
        }
        private void DeserializeContractInternal(ref object graph, Buffer.BitArray buffer)
        {
            foreach (var member in graph.GetType().GetOrderedSerializableProperties())
            {
                if (member.PropertyType.HasAttribute(typeof(BinaryEncodingContractAttribute)))
                {
                    object temp = Activator.CreateInstance(member.PropertyType);
                    DeserializeContractInternal(ref temp, buffer);
                    member.SetValue(graph, temp);
                }
                else
                {
                    object temp;
                    if (member.PropertyType.IsArray)
                    {
                        var length = member.GetPropertyArraySize(graph);
                        if (length == Const.READTOEND)
                        {
                            //read all remaining data
                            byte[] bytes = buffer.Pop(Const.READTOEND);
                            temp = bytes;
                        }
                        else
                        {
                            temp = Activator.CreateInstance(member.PropertyType, new object[] { length });

                            int elementSize = member.PropertyType.GetElementType().GetContractBitsCount(graph);
                            if (elementSize != 0)
                            {
                                var tempArray = (object[])temp;

                                for (int i = 0; i < tempArray.Length; i++)
                                {
                                    var element = Activator.CreateInstance(member.PropertyType.GetElementType());
                                    DeserializeContractInternal(ref element, buffer);
                                    tempArray[i] = element;
                                }
                            }
                        }
                    }
                    else
                    {
                        temp = Activator.CreateInstance(member.PropertyType);

                        int lengthInBits = member.GetPropertyBitsLength(graph);
                        if (lengthInBits == 0)
                        {
                            continue;
                        }

                        byte[] bytes = buffer.Pop(lengthInBits);

                        switch (Type.GetTypeCode(member.PropertyType))
                        {
                        case TypeCode.Int32:
                            temp = Buffer.BitConverter.ToInt32(bytes);
                            break;

                        case TypeCode.Int64:
                            temp = Buffer.BitConverter.ToInt64(bytes);
                            break;

                        case TypeCode.Byte:
                            temp = Buffer.BitConverter.ToByte(bytes);
                            break;

                        default: throw new NotImplementedException();
                        }
                    }
                    member.SetValue(graph, temp);
                }
            }
        }
示例#4
0
        public static bool TryParseContract(DynamicContractDescription contract,
                                            Buffer.BitArray buffer, out DynamicContractValue msg)
        {
            msg = new DynamicContractValue(contract);
            foreach (var property in contract.Members)
            {
                if (property.Value.IsConditional)
                {
                    if (!property.Value.Condition.Evaluate(msg.Data))
                    {
                        if (msg.Data.ContainsKey(property.Value.Name))
                        {
                            msg.Data.Remove(property.Value.Name);
                        }
                        continue;
                    }
                }

                if (property.Value.IsContract)
                {
                    if (property.Value.IsArray)
                    {
                        int length      = 0;
                        var arrayLength = property.Value.ArrayLength;
                        if (!Int32.TryParse(arrayLength, out length))
                        {
                            //is reference value
                            length = (int)msg.Data[arrayLength].Value;
                        }
                        object[] temp = new object[length];

                        IDynamicMemberValue propValue = new DynamicMemberValue(property.Value, null);

                        for (int i = 0; i < length; i++)
                        {
                            DynamicContractValue value;

                            if (!TryParseContract(property.Value.ContractDescription, buffer, out value))
                            {
                                return(false);
                            }
                            temp[i] = value;
                        }
                        propValue.Value = temp;
                        msg.Data[property.Value.Name] = propValue;
                    }
                    else
                    {
                        DynamicContractValue value;

                        if (!TryParseContract(property.Value.ContractDescription, buffer, out value))
                        {
                            return(false);
                        }

                        msg.Data[property.Value.Name] = value;
                    }
                }
                else
                {
                    IDynamicMemberValue value;
                    if (!property.Value.TryParseDynamicPropertyValue(buffer, msg, out value))
                    {
                        return(false);
                    }
                    msg.Data[value.Description.Name] = value;
                }
            }
            return(true);
        }