public override object ReadValue(IStreamReader reader, ISerializeContext context) { byte contentType = reader.ReadUInt8(); if (contentType == ValueItem.SingleValueIdent) { uint typeIdValue = reader.ReadUInt32(); var actualStructure = context.GetByTypeId(typeIdValue); Type runtimeType = ValueItem.GetRuntimeType(actualStructure); if (runtimeType != null) { return(runtimeType); } else { throw new InvalidOperationException($"Runtime type for structure \"{actualStructure.Name}\" not found. Type ID: {actualStructure.TypeId}"); } } else if (contentType == ValueItem.TypeMetaInfo) { uint typeIdValue = reader.ReadUInt32(); var actualStructure = TypeMetaStructure.ReadTypeMetaInfo(reader, typeIdValue, context); Type runtimeType = ValueItem.GetRuntimeType(actualStructure); if (runtimeType != null) { return(runtimeType); } else { throw new InvalidOperationException($"Runtime type for structure \"{actualStructure.Name}\" not found. Type ID: {actualStructure.TypeId}"); } } else if (contentType == ValueItem.NullValueIdent) { return(null); } else { throw new InvalidOperationException($"Unexpected content type \"{contentType}\"!"); } }
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!"); } }