コード例 #1
0
        public object ReadValue(IStreamReader reader, ISerializeContext context, bool isReadTypeIdExpected)
        {
            context.Key        = this.Name;
            context.ArrayIndex = null;

            if (isReadTypeIdExpected)
            {
                // read type of property
                uint actualTypeId = reader.ReadUInt32();

                if (TypeId != actualTypeId)
                {
                    if (actualTypeId == (int)ItemType.ComplexObject)
                    {
                        // Special read > only null expected
                        byte contentObjType = reader.ReadUInt8();

                        if (contentObjType == ValueItem.NullValueIdent)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new ArgumentException("ComplexObject type ID is only expected with null!");
                        }
                    }

                    var actualStructure = context.GetByTypeId(actualTypeId);

                    if (actualStructure == null)
                    {
                        // type not in local cache > type meta info exptected
                        actualStructure = TypeMetaStructure.ReadContentTypeMetaInfo(reader, actualTypeId, context);
                    }

                    if (actualStructure.IsTypePrefixExpected)
                    {
                        if (actualStructure is ITypePrefix)
                        {
                            // type id already consumed > do not read again
                            return(((ITypePrefix)actualStructure).ReadValue(reader, context, false));
                        }
                        else
                        {
                            return(actualStructure.ReadValue(reader, context));
                        }
                    }
                    else
                    {
                        // read content type because of unknown strucutre
                        byte contentObjType = reader.ReadUInt8();

                        if (contentObjType == ValueItem.NullValueIdent)
                        {
                            return(null);
                        }
                        else
                        {
                            return(actualStructure.ReadValue(reader, context));
                        }
                    }
                }
            }


            byte contentType = reader.ReadUInt8();

            if (contentType == ValueItem.TypeMetaInfo)
            {
                // type meta data already loaded for type id > skip data
                TypeMetaStructure.SkipTypeMetaInfo(reader);
                contentType = reader.ReadUInt8();
            }

            switch (contentType)
            {
            case ValueItem.SingleObjectIdent:
                object newObject = TypeService.CreateInstance(concreteTargetType);

                object oldParentObj = context.ParentObject;
                context.ParentObject = newObject;

                for (int itemIndex = 0; itemIndex < items.Count; itemIndex++)
                {
                    var item = items[itemIndex];

                    var itemValue = item.ReadValue(reader, context);
                    item.SetItemValue(newObject, itemValue);
                }

                context.ParentObject = oldParentObj;

                return(newObject);

            case ValueItem.NullValueIdent:
                return(null);

            case ValueItem.CollectionObjectIdent:
                throw new NotImplementedException();

            default:
                throw new InvalidOperationException($"Type ident {contentType} not expected!");
            }
        }
コード例 #2
0
        public object ReadValue(IStreamReader reader, ISerializeContext context)
        {
            byte contentType = reader.ReadUInt8();

            context.Key = this.Name;

            if (contentType == ValueItem.CollectionObjectIdent)
            {
                int count = reader.ReadInt32();

                if (isArray)
                {
                    Array array = Array.CreateInstance(itemType, count);

                    if (isByteArray)
                    {
                        return(reader.ReadBytes(count).ToArray());
                    }
                    else
                    {
                        for (int i = 0; i < count; i++)
                        {
                            context.ArrayIndex = i;
                            var item = itemStructure.ReadValue(reader, context);
                            array.SetValue(item, i);
                        }
                        context.ArrayIndex = null;
                    }
                    return(array);
                }
                else if (implementsIList)
                {
                    IList coll = (IList)TypeService.CreateInstance(targetCollectionType);

                    for (int i = 0; i < count; i++)
                    {
                        context.ArrayIndex = i;
                        var item = itemStructure.ReadValue(reader, context);
                        coll.Add(item);
                    }
                    context.ArrayIndex = null;

                    return(coll);
                }
                else
                {
                    object specialColl = TypeService.CreateInstance(targetCollectionType);

                    for (int i = 0; i < count; i++)
                    {
                        context.ArrayIndex = i;
                        var item = itemStructure.ReadValue(reader, context);
                        specialCollAddMethod.Invoke(specialColl, new object[] { item });
                    }
                    context.ArrayIndex = null;

                    return(specialColl);
                }
            }
            else if (contentType == ValueItem.NullValueIdent)
            {
                return(null);
            }
            else if (contentType == ValueItem.TypeMetaInfo)
            {
                TypeMetaStructure.SkipTypeMetaInfo(reader);
                return(this.ReadValue(reader, context));
            }
            else
            {
                throw new InvalidOperationException($"Type ident {contentType} not expected!");
            }
        }
コード例 #3
0
        public void WriteValue(IStreamWriter writer, ISerializeContext context, object value)
        {
            // Complex structure
            // TypeID UInt32
            // ContentType Byte
            context.Key = this.Name;
            if (isObject)
            {
                // property or collection does not specify a target type
                // determine object type
                if (value != null)
                {
                    Type valType = value.GetType();

                    IValueItem item;
                    var        differentTargetStructure = context.DetermineSpecialInterfaceType(value.GetType(), type);
                    if (differentTargetStructure != null)
                    {
                        item = differentTargetStructure;
                    }
                    else
                    {
                        item = context.GetByType(valType);
                    }

                    if (!item.IsTypePrefixExpected)
                    {
                        // Write type id for value types as well (unknown structure)
                        writer.WriteUInt32(item.TypeId);

                        writer.WriteUInt8(ValueItem.SingleValueIdent);
                    }

                    item.WriteValue(writer, context, value);
                }
                else
                {
                    // write complex object type id for null value
                    writer.WriteInt32((int)ItemType.ComplexObject);
                    writer.WriteUInt8(ValueItem.NullValueIdent);
                }
            }
            else if (value == null)
            {
                // Write null
                writer.WriteUInt32(this.TypeId);
                writer.WriteUInt8(ValueItem.NullValueIdent);
            }
            else
            {
                IValueItem differentTargetStructure = null;
                if (CheckDifferentType)
                {
                    differentTargetStructure = context.DetermineSpecialInterfaceType(value.GetType(), type);
                }

                if (differentTargetStructure != null)
                {
                    // Special target interface type serialization
                    differentTargetStructure.WriteValue(writer, context, value);
                }
                else
                {
                    // Just write type properties
                    writer.WriteUInt32(this.TypeId);

                    if (context.IsWriteTypeMetaInfoRequired(this.TypeId))
                    {
                        // serialize type meta info at the first time
                        TypeMetaStructure.WriteTypeMetaInfo(writer, this);
                    }

                    writer.WriteUInt8(ValueItem.SingleObjectIdent);

                    object oldParentObj = context.ParentObject;
                    context.ParentObject = value;

                    for (int itemIndex = 0; itemIndex < items.Count; itemIndex++)
                    {
                        var item = items[itemIndex];

                        var valueItem = item.GetItemValue(value);

                        item.WriteValue(writer, context, valueItem);
                    }

                    context.ParentObject = oldParentObj;
                }
            }
        }
コード例 #4
0
        public void WriteValue(IStreamWriter writer, ISerializeContext context, object value)
        {
            // Collection structure:
            // TypeID UInt32
            // ContentType Byte
            // Count Int32
            // Items...
            if (getter == null)
            {
                writer.WriteUInt32(this.TypeId); // only write collection type if element is root object

                if (context.IsWriteTypeMetaInfoRequired(this.TypeId))
                {
                    // serialize type meta info at the first time
                    TypeMetaStructure.WriteTypeMetaInfo(writer, this);
                }
            }

            if (value == null)
            {
                writer.WriteUInt8(ValueItem.NullValueIdent);
            }
            else
            {
                writer.WriteUInt8(ValueItem.CollectionObjectIdent);

                IEnumerable items;
                if (isArray)
                {
                    Array array = (Array)value;
                    writer.WriteInt32(array.Length);
                    items = array;

                    if (isByteArray)
                    {
                        writer.WriteBytes(new ArraySegment <byte>((byte[])array));
                        return;
                    }
                }
                else if (value is ICollection)
                {
                    ICollection collection = (ICollection)value;
                    writer.WriteInt32(collection.Count);
                    items = collection;
                }
                else
                {
                    items = (IEnumerable)value;

                    int count = 0;
                    foreach (var item in items)
                    {
                        count++;
                    }
                    writer.WriteInt32(count);
                }

                context.Key = this.Name;

                int index = 0;
                foreach (var item in items)
                {
                    context.ArrayIndex = index;
                    itemStructure.WriteValue(writer, context, item);
                    index++;
                }
                context.ArrayIndex = null;
            }
        }