public FieldDecorator(Type forType, FieldInfo field, IProtoSerializer tail) : base(tail) { Helpers.DebugAssert(forType != null); Helpers.DebugAssert(field != null); this.forType = forType; this.field = field; }
public TagDecorator(int fieldNumber, WireType wireType, bool strict, IProtoSerializer tail) : base(tail) { this.fieldNumber = fieldNumber; this.wireType = wireType; this.strict = strict; }
public ListDecorator(Type declaredType, Type concreteType, IProtoSerializer tail, int packedFieldNumber, WireType packedWireType) : base(tail) { this.packedWireType = WireType.None; if (packedFieldNumber != 0) { if (packedFieldNumber < 0) throw new ArgumentOutOfRangeException("packedFieldNumber"); switch(packedWireType) { case WireType.Fixed32: case WireType.Fixed64: case WireType.SignedVariant: case WireType.Variant: break; default: throw new InvalidOperationException("Only simple data-types can use packed encoding"); } this.packedFieldNumber = packedFieldNumber; this.packedWireType = packedWireType; } if (declaredType == null) throw new ArgumentNullException("declaredType"); if (declaredType.IsArray) throw new ArgumentException("Cannot treat arrays as lists", "declaredType"); this.declaredType = declaredType; this.concreteType = concreteType; // look for a public list.Add(typedObject) method add = TypeModel.ResolveListAdd(declaredType, tail.ExpectedType, out isList); if (add == null) throw new InvalidOperationException(); }
public ReflectedUriDecorator(Type type, ProtoBuf.Meta.TypeModel model, IProtoSerializer tail) : base(tail) { expectedType = type; absoluteUriProperty = expectedType.GetProperty("AbsoluteUri"); typeConstructor = expectedType.GetConstructor(new Type[] { typeof(string) }); }
public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull) : base(tail) { this.itemType = arrayType.GetElementType(); Type arg_3E_0 = (!supportNull) ? (Helpers.GetUnderlyingType(this.itemType) ?? this.itemType) : this.itemType; if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) { throw new ArgumentOutOfRangeException("fieldNumber"); } if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) { throw new InvalidOperationException("Only simple data-types can use packed encoding"); } packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) { this.options |= 1; } if (overwriteList) { this.options |= 2; } if (supportNull) { this.options |= 4; } this.arrayType = arrayType; }
public ListDecorator(Type declaredType, Type concreteType, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList) : base(tail) { if (returnList) options |= OPTIONS_ReturnList; if (overwriteList) options |= OPTIONS_OverwriteList; if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); if (!CanPack(packedWireType)) { if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); packedWireType = WireType.None; } this.fieldNumber = fieldNumber; if (writePacked) options |= OPTIONS_WritePacked; this.packedWireType = packedWireType; if (declaredType == null) throw new ArgumentNullException("declaredType"); if (declaredType.IsArray) throw new ArgumentException("Cannot treat arrays as lists", "declaredType"); this.declaredType = declaredType; this.concreteType = concreteType; // look for a public list.Add(typedObject) method bool isList; add = TypeModel.ResolveListAdd(declaredType, tail.ExpectedType, out isList); if (isList) { options |= OPTIONS_IsList; if (declaredType.FullName.StartsWith("System.Data.Linq.EntitySet`1[[")) { // see http://stackoverflow.com/questions/6194639/entityset-is-there-a-sane-reason-that-ilist-add-doesnt-set-assigned options |= OPTIONS_SuppressIList; } } if (add == null) throw new InvalidOperationException(); }
public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull) : base(tail) { Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName); this.itemType = arrayType.GetElementType(); #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = supportNull ? itemType : (Helpers.GetUnderlyingType(itemType) ?? itemType); #endif Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType, "invalid tail"); Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof(byte)), "Should have used BlobSerializer"); if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) options |= OPTIONS_WritePacked; if (overwriteList) options |= OPTIONS_OverwriteList; if (supportNull) options |= OPTIONS_SupportNull; this.arrayType = arrayType; }
public MemberSpecifiedDecorator(MethodInfo getSpecified, MethodInfo setSpecified, IProtoSerializer tail) : base(tail) { if (getSpecified == null && setSpecified == null) throw new InvalidOperationException(); this.getSpecified = getSpecified; this.setSpecified = setSpecified; }
internal ImmutableCollectionDecorator(TypeModel model, Type declaredType, Type concreteType, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, bool supportNull, MethodInfo builderFactory, MethodInfo add, MethodInfo addRange, MethodInfo finish) : base(model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, returnList, overwriteList, supportNull) { this.builderFactory = builderFactory; this.add = add; this.addRange = addRange; this.finish = finish; }
public TypeDescription(Type descriptionForType, IProtoSerializer messageSerializer, IProtoSerializer nestedMessageSerializer) { this.pending = false; this.descriptionForType = descriptionForType; this.serializerForMessage = messageSerializer; this.serializerForNestedMessage = nestedMessageSerializer; this.supported = (messageSerializer != null && nestedMessageSerializer != null); }
public PropertyDecorator(TypeModel model, Type forType, PropertyInfo property, IProtoSerializer tail) : base(tail) { this.forType = forType; this.property = property; PropertyDecorator.SanityCheck(model, property, tail, out this.readOptionsWriteValue, true, true); this.shadowSetter = PropertyDecorator.GetShadowSetter(model, property); }
public PropertyDecorator(Type forType, PropertyInfo property, IProtoSerializer tail) : base(tail) { Helpers.DebugAssert(forType != null); Helpers.DebugAssert(property != null); this.forType = forType; this.property = property; SanityCheck(property, tail, out readOptionsWriteValue, true); }
public DefaultValueDecorator(object defaultValue, IProtoSerializer tail) : base(tail) { if (defaultValue == null) throw new ArgumentNullException("defaultValue"); if (defaultValue.GetType() != tail.ExpectedType) { throw new ArgumentException("Default value is of incorrect type", "defaultValue"); } this.defaultValue = defaultValue; }
public PrimitivesDecorator(IProtoSerializer itemSerializer) { if (itemSerializer == null) { throw new ArgumentNullException("itemSerializer"); } this.itemSerializer = itemSerializer; }
public void Complete(IProtoSerializer messageSerializer, IProtoSerializer nestedMessageSerializer) { if (!this.pending) return; this.serializerForMessage = messageSerializer; this.serializerForNestedMessage = nestedMessageSerializer; this.supported = (messageSerializer != null && nestedMessageSerializer != null); this.pending = false; }
internal static void EmitReadList(ProtoBuf.Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType) { using (Compiler.Local fieldNumber = new Compiler.Local(ctx, typeof(int))) { Compiler.CodeLabel readPacked = packedWireType == WireType.None ? new Compiler.CodeLabel() : ctx.DefineLabel(); if (packedWireType != WireType.None) { ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType")); ctx.LoadValue((int)WireType.String); ctx.BranchIfEqual(readPacked, false); } ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber")); ctx.StoreValue(fieldNumber); Compiler.CodeLabel @continue = ctx.DefineLabel(); ctx.MarkLabel(@continue); EmitReadAndAddItem(ctx, list, tail, add); ctx.LoadReaderWriter(); ctx.LoadValue(fieldNumber); ctx.EmitCall(typeof(ProtoReader).GetMethod("TryReadFieldHeader")); ctx.BranchIfTrue(@continue, false); if (packedWireType != WireType.None) { Compiler.CodeLabel allDone = ctx.DefineLabel(); ctx.Branch(allDone, false); ctx.MarkLabel(readPacked); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoReader).GetMethod("StartSubItem")); Compiler.CodeLabel testForData = ctx.DefineLabel(), noMoreData = ctx.DefineLabel(); ctx.MarkLabel(testForData); ctx.LoadValue((int)packedWireType); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoReader).GetMethod("HasSubValue")); ctx.BranchIfFalse(noMoreData, false); EmitReadAndAddItem(ctx, list, tail, add); ctx.Branch(testForData, false); ctx.MarkLabel(noMoreData); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoReader).GetMethod("EndSubItem")); ctx.MarkLabel(allDone); } } }
private static void SanityCheck(PropertyInfo property, IProtoSerializer tail, out bool writeValue, bool nonPublic) { if(property == null) throw new ArgumentNullException("property"); writeValue = tail.ReturnsValue && (GetShadowSetter(property) != null || (property.CanWrite && Helpers.GetSetMethod(property, nonPublic) != null)); if (!property.CanRead || Helpers.GetGetMethod(property, nonPublic) == null) throw new InvalidOperationException("Cannot serialize property without a get accessor"); if (!writeValue && (!tail.RequiresOldValue || Helpers.IsValueType(tail.ExpectedType))) { // so we can't save the value, and the tail doesn't use it either... not helpful // or: can't write the value, so the struct value will be lost throw new InvalidOperationException("Cannot apply changes to property " + property.DeclaringType.FullName + "." + property.Name); } }
public static ProtoSerializer BuildSerializer(IProtoSerializer head) { Type type = head.ExpectedType; CompilerContext ctx = new CompilerContext(type, true, true); ctx.LoadValue(Local.InputValue); ctx.CastFromObject(type); ctx.WriteNullCheckedTail(type, head, null); ctx.Emit(OpCodes.Ret); return (ProtoSerializer)ctx.method.CreateDelegate( typeof(ProtoSerializer)); }
public TypeSerializer(TypeModel model, Type forType, int[] fieldNumbers, IProtoSerializer[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, CallbackSet callbacks, Type constructType, MethodInfo factory) { Helpers.Sort(fieldNumbers, serializers); bool flag = false; for (int i = 1; i < fieldNumbers.Length; i++) { if (fieldNumbers[i] == fieldNumbers[i - 1]) { throw new InvalidOperationException("Duplicate field-number detected; " + fieldNumbers[i].ToString() + " on: " + forType.FullName); } if (!flag && serializers[i].ExpectedType != forType) { flag = true; } } this.forType = forType; this.factory = factory; if (constructType == null) { constructType = forType; } else if (!forType.IsAssignableFrom(constructType)) { throw new InvalidOperationException(forType.FullName + " cannot be assigned from " + constructType.FullName); } this.constructType = constructType; this.serializers = serializers; this.fieldNumbers = fieldNumbers; this.callbacks = callbacks; this.isRootType = isRootType; this.useConstructor = useConstructor; if (baseCtorCallbacks != null && baseCtorCallbacks.Length == 0) { baseCtorCallbacks = null; } this.baseCtorCallbacks = baseCtorCallbacks; if (Helpers.GetUnderlyingType(forType) != null) { throw new ArgumentException("Cannot create a TypeSerializer for nullable types", "forType"); } if (model.MapType(TypeSerializer.iextensible).IsAssignableFrom(forType)) { if (forType.IsValueType || !isRootType || flag) { throw new NotSupportedException("IExtensible is not supported in structs or classes with inheritance"); } this.isExtensible = true; } this.hasConstructor = (!constructType.IsAbstract && Helpers.GetConstructor(constructType, Helpers.EmptyTypes, true) != null); if (constructType != forType && useConstructor && !this.hasConstructor) { throw new ArgumentException("The supplied default implementation cannot be created: " + constructType.FullName, "constructType"); } }
public DefaultValueDecorator(TypeModel model, object defaultValue, IProtoSerializer tail) : base(tail) { if (defaultValue == null) throw new ArgumentNullException("defaultValue"); Type type = model.MapType(defaultValue.GetType()); if (type != tail.ExpectedType #if FEAT_IKVM // in IKVM, we'll have the default value as an underlying type && !(tail.ExpectedType.IsEnum && type == tail.ExpectedType.GetEnumUnderlyingType()) #endif ) { throw new ArgumentException("Default value is of incorrect type", "defaultValue"); } this.defaultValue = defaultValue; }
private static void SanityCheck(PropertyInfo property, IProtoSerializer tail, out bool writeValue, bool nonPublic) { if(property == null) throw new ArgumentNullException("property"); writeValue = tail.ReturnsValue && property.CanWrite && property.GetSetMethod(nonPublic) != null; if (!property.CanRead || property.GetGetMethod(nonPublic) == null) throw new InvalidOperationException("Cannot serialize property without a get accessor"); if (!tail.RequiresOldValue && !writeValue) { // so we can't save the value, and the tail doesn't use it either... not helpful throw new InvalidOperationException("Cannot apply changes to property"); } if (!writeValue && tail.ExpectedType.IsValueType) { // can't write the value, so the struct value will be lost throw new InvalidOperationException("Cannot apply changes to property"); } }
public NullDecorator(IProtoSerializer tail) : base(tail) { if (!tail.ReturnsValue) throw new NotSupportedException("NullDecorator only supports implementations that return values"); if(tail.ExpectedType.IsValueType) { #if NO_GENERICS throw new NotSupportedException("NullDecorator cannot be used with a struct without generics support"); #else expectedType = typeof (Nullable<>).MakeGenericType(tail.ExpectedType); #endif } else { expectedType = tail.ExpectedType; } }
/*public static ProtoCallback BuildCallback(IProtoTypeSerializer head) { Type type = head.ExpectedType; CompilerContext ctx = new CompilerContext(type, true, true); using (Local typedVal = new Local(ctx, type)) { ctx.LoadValue(Local.InputValue); ctx.CastFromObject(type); ctx.StoreValue(typedVal); CodeLabel[] jumpTable = new CodeLabel[4]; for(int i = 0 ; i < jumpTable.Length ; i++) { jumpTable[i] = ctx.DefineLabel(); } ctx.LoadReaderWriter(); ctx.Switch(jumpTable); ctx.Return(); for(int i = 0 ; i < jumpTable.Length ; i++) { ctx.MarkLabel(jumpTable[i]); if (head.HasCallbacks((TypeModel.CallbackType)i)) { head.EmitCallback(ctx, typedVal, (TypeModel.CallbackType)i); } ctx.Return(); } } ctx.Emit(OpCodes.Ret); return (ProtoCallback)ctx.method.CreateDelegate( typeof(ProtoCallback)); }*/ public static ProtoDeserializer BuildDeserializer(IProtoSerializer head) { Type type = head.ExpectedType; CompilerContext ctx = new CompilerContext(type, false, true); using (Local typedVal = new Local(ctx, type)) { if (!type.IsValueType) { ctx.LoadValue(Local.InputValue); ctx.CastFromObject(type); ctx.StoreValue(typedVal); } else { ctx.LoadValue(Local.InputValue); CodeLabel notNull = ctx.DefineLabel(), endNull = ctx.DefineLabel(); ctx.BranchIfTrue(notNull, true); ctx.LoadAddress(typedVal, type); ctx.EmitCtor(type); ctx.Branch(endNull, true); ctx.MarkLabel(notNull); ctx.LoadValue(Local.InputValue); ctx.CastFromObject(type); ctx.StoreValue(typedVal); ctx.MarkLabel(endNull); } head.EmitRead(ctx, typedVal); if (head.ReturnsValue) { ctx.StoreValue(typedVal); } ctx.LoadValue(typedVal); ctx.CastToObject(type); } ctx.Emit(OpCodes.Ret); return (ProtoDeserializer)ctx.method.CreateDelegate( typeof(ProtoDeserializer)); }
public TypeSerializer(Type forType, int[] fieldNumbers, IProtoSerializer[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, CallbackSet callbacks) { Helpers.DebugAssert(forType != null); Helpers.DebugAssert(fieldNumbers != null); Helpers.DebugAssert(serializers != null); Helpers.DebugAssert(fieldNumbers.Length == serializers.Length); Helpers.Sort(fieldNumbers, serializers); bool hasSubTypes = false; for (int i = 1; i < fieldNumbers.Length; i++) { if (fieldNumbers[i] == fieldNumbers[i - 1]) throw new InvalidOperationException("Duplicate field-number detected; " + fieldNumbers[i].ToString() + " on: " + forType.FullName); if(!hasSubTypes && serializers[i].ExpectedType != forType) { hasSubTypes = true; } } this.forType = forType; this.serializers = serializers; this.fieldNumbers = fieldNumbers; this.callbacks = callbacks; this.isRootType = isRootType; this.useConstructor = useConstructor; if (baseCtorCallbacks != null && baseCtorCallbacks.Length == 0) baseCtorCallbacks = null; this.baseCtorCallbacks = baseCtorCallbacks; #if !NO_GENERICS if (Nullable.GetUnderlyingType(forType) != null) { throw new ArgumentException("Cannot create a TypeSerializer for nullable types", "forType"); } #endif if (typeof(IExtensible).IsAssignableFrom(forType)) { if (forType.IsValueType || !isRootType || hasSubTypes) { throw new NotSupportedException("IExtensible is not supported in structs or classes with inheritance"); } isExtensible = true; } }
public ArrayDecorator(IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList) : base(tail) { Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array"); Helpers.DebugAssert(arrayType.GetElementType() == Tail.ExpectedType, "invalid tail"); Helpers.DebugAssert(Tail.ExpectedType != typeof(byte), "Should have used BlobSerializer"); if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) options |= OPTIONS_WritePacked; if (overwriteList) options |= OPTIONS_OverwriteList; this.arrayType = arrayType; this.itemType = Tail.ExpectedType; }
public NullDecorator(TypeModel model, IProtoSerializer tail) : base(tail) { if (!tail.ReturnsValue) { throw new NotSupportedException("NullDecorator only supports implementations that return values"); } Type type = tail.ExpectedType; if (Helpers.IsValueType(type)) { this.expectedType = model.MapType(typeof(Nullable<>)).MakeGenericType(new Type[] { type }); } else { this.expectedType = type; } }
public static ProtoSerializer BuildSerializer(IProtoSerializer head, TypeModel model) { Type type = head.ExpectedType; try { CompilerContext ctx = new CompilerContext(type, true, true, model, typeof(object)); ctx.LoadValue(ctx.InputValue); ctx.CastFromObject(type); ctx.WriteNullCheckedTail(type, head, null); ctx.Emit(OpCodes.Ret); return (ProtoSerializer)ctx.method.CreateDelegate( typeof(ProtoSerializer)); } catch (Exception ex) { string name = type.FullName; if(string.IsNullOrEmpty(name)) name = type.Name; throw new InvalidOperationException("It was not possible to prepare a serializer for: " + name, ex); } }
public ArrayDecorator(IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull, bool asReference, bool nested) : base(tail) { Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); //Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName); if (!arrayType.IsArray /*|| arrayType.GetArrayRank() != 1*/) { throw new Exception("Temporary exception"); } this.itemType = arrayType.GetElementType(); #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = supportNull ? itemType : (Nullable.GetUnderlyingType(itemType) ?? itemType); #endif Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType || (underlyingItemType.IsInterface && Tail.ExpectedType == typeof(object)), "invalid tail"); Helpers.DebugAssert(Tail.ExpectedType != typeof(byte), "Should have used BlobSerializer"); if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) options |= OPTIONS_WritePacked; if (overwriteList) options |= OPTIONS_OverwriteList; if (supportNull) options |= OPTIONS_SupportNull; if (asReference) options |= OPTIONS_AsReference; if (asReference && writePacked) throw new InvalidOperationException("Cannot be packed and AsReference (not supported yet)"); if (asReference && overwriteList) throw new InvalidOperationException("Cannot be overwriteList and AsReference (not supported yet)"); this.arrayType = arrayType; this.nested = nested; }
public ArrayDecorator(IProtoSerializer tail, int packedFieldNumber, WireType packedWireType) : base(tail) { Helpers.DebugAssert(Tail.ExpectedType != typeof(byte), "Should have used BlobSerializer"); this.packedWireType = WireType.None; if (packedFieldNumber != 0) { if (packedFieldNumber < 0) throw new ArgumentOutOfRangeException("packedFieldNumber"); switch (packedWireType) { case WireType.Fixed32: case WireType.Fixed64: case WireType.SignedVariant: case WireType.Variant: break; default: throw new ArgumentException("Packed buffers are not supported for wire-type: " + packedWireType, "packedFieldNumber"); } this.packedFieldNumber = packedFieldNumber; this.packedWireType = packedWireType; } this.itemType = Tail.ExpectedType; this.arrayType = Helpers.MakeArrayType(itemType); }
public UriDecorator(ProtoBuf.Meta.TypeModel model, IProtoSerializer tail) : base(tail) { }
public void Init(IClient socket, IProtoSerializer serializer) { m_serializer = serializer; m_socket = socket; m_socket.onReceived = OnReceived; }
// Token: 0x060035B6 RID: 13750 RVA: 0x00134E4E File Offset: 0x0013324E public PropertyDecorator(TypeModel model, Type forType, PropertyInfo property, IProtoSerializer tail) : base(tail) { this.forType = forType; this.property = property; PropertyDecorator.SanityCheck(model, property, tail, out readOptionsWriteValue, true, true); shadowSetter = PropertyDecorator.GetShadowSetter(model, property); }
private static void EmitReadAndAddItem(Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add) { ctx.LoadValue(list); Type itemType = tail.ExpectedType; if (tail.RequiresOldValue) { if (itemType.IsValueType || !tail.ReturnsValue) { // going to need a variable using (Compiler.Local item = new Compiler.Local(ctx, itemType)) { if (itemType.IsValueType) { // initialise the struct ctx.LoadAddress(item, itemType); ctx.EmitCtor(itemType); } else { // assign null ctx.LoadNullRef(); ctx.StoreValue(item); } tail.EmitRead(ctx, item); if (!tail.ReturnsValue) { ctx.LoadValue(item); } } } else { // no variable; pass the null on the stack and take the value *off* the stack ctx.LoadNullRef(); tail.EmitRead(ctx, null); } } else { if (tail.ReturnsValue) { // out only (on the stack); just emit it tail.EmitRead(ctx, null); } else { // doesn't take anything in nor return anything! WTF? throw new InvalidOperationException(); } } // our "Add" is chosen either to take the correct type, or to take "object"; // we may need to box the value Type addParamType = add.GetParameters()[0].ParameterType; if (addParamType != itemType) { if (addParamType == typeof(object)) { ctx.CastToObject(itemType); } else { throw new InvalidOperationException("Conflicting item/add type"); } } ctx.EmitCall(add); if (add.ReturnType != typeof(void)) { ctx.DiscardValue(); } }
private IProtoSerializer BuildSerializer() { int opaqueToken = 0; try { model.TakeLock(ref opaqueToken);// check nobody is still adding this type WireType wireType; Type finalType = itemType == null ? memberType : itemType; IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList, true); if (ser == null) { throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); } // apply tags if (itemType != null && SupportNull) { if (IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); ser = new NullDecorator(model, ser); ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); } else { ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); } // apply lists if appropriate if (itemType != null) { #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType; #endif Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType); if (memberType.IsArray) { ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull); } else { ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull); } } else if (defaultValue != null && !IsRequired && getSpecified == null) { // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue, // as does "IsRequired" ser = new DefaultValueDecorator(model, defaultValue, ser); } if (memberType == model.MapType(typeof(Uri))) { ser = new UriDecorator(model, ser); } if (member != null) { PropertyInfo prop = member as PropertyInfo; if (prop != null) { ser = new PropertyDecorator(model, parentType, (PropertyInfo)member, ser); } else { FieldInfo fld = member as FieldInfo; if (fld != null) { ser = new FieldDecorator(parentType, (FieldInfo)member, ser); } else { throw new InvalidOperationException(); } } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } } return(ser); } finally { model.ReleaseLock(opaqueToken); } }
private void CascadeDependents(BasicList list, MetaType metaType) { MetaType tmp; metaType.FinalizeSettingsValue(); if (metaType.IsList) { Type itemType = TypeModel.GetListItemType(this, metaType.Type); WireType defaultWireType; IProtoSerializer coreSerializer = this.ValueSerializerBuilder.TryGetSimpleCoreSerializer(BinaryDataFormat.Default, itemType, out defaultWireType); if (coreSerializer == null) { int index = FindOrAddAuto(itemType, false, false, false); if (index >= 0) { tmp = ((MetaType)_types[index]).GetSurrogateOrBaseOrSelf(false); if (!list.Contains(tmp)) { // could perhaps also implement as a queue, but this should work OK for sane models list.Add(tmp); CascadeDependents(list, tmp); } } } } else { if (metaType.GetFinalSettingsCopy().IsAutoTuple) { MemberInfo[] mapping; if (MetaType.ResolveTupleConstructor(metaType.Type, out mapping) != null) { for (int i = 0; i < mapping.Length; i++) { CscadeDependents_Member(list, (mapping[i] as PropertyInfo)?.PropertyType ?? (mapping[i] as FieldInfo)?.FieldType); } } } else { foreach (ValueMember member in metaType.Fields) { member.Serializer.GetHashCode(); var s = member.GetFinalSettingsCopy(0); Type type = s.Collection.ItemType ?? member.MemberType; var fieldMetaType = FindWithoutAdd(type); if (fieldMetaType != null) { type = fieldMetaType.GetSurrogateOrSelf().Type; } CscadeDependents_Member(list, type); } } if (metaType.HasSubtypes) { foreach (SubType subType in metaType.GetSubtypes()) { tmp = subType.DerivedType.GetSurrogateOrSelf(); // note: exclude base-types! if (!list.Contains(tmp)) { list.Add(tmp); CascadeDependents(list, tmp); } } } tmp = metaType.BaseType; tmp = tmp?.GetSurrogateOrSelf(); // note: already walking base-types; exclude base if (tmp != null && !list.Contains(tmp)) { list.Add(tmp); CascadeDependents(list, tmp); } } }
public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local incoming) { using (Compiler.Local objValue = ctx.GetLocalWithValue(ExpectedType, incoming)) { Compiler.Local[] locals = new Compiler.Local[members.Length]; try { for (int i = 0; i < locals.Length; i++) { Type type = GetMemberType(i); bool store = true; locals[i] = new Compiler.Local(ctx, type); if (!ExpectedType.IsValueType) { // value-types always read the old value if (type.IsValueType) { switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Boolean: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: case ProtoTypeCode.SByte: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: ctx.LoadValue(0); break; case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: ctx.LoadValue(0L); break; case ProtoTypeCode.Single: ctx.LoadValue(0.0F); break; case ProtoTypeCode.Double: ctx.LoadValue(0.0D); break; case ProtoTypeCode.Decimal: ctx.LoadValue(0M); break; case ProtoTypeCode.Guid: ctx.LoadValue(Guid.Empty); break; default: ctx.LoadAddress(locals[i], type); ctx.EmitCtor(type); store = false; break; } } else { ctx.LoadNullRef(); } if (store) { ctx.StoreValue(locals[i]); } } } Compiler.CodeLabel skipOld = ExpectedType.IsValueType ? new Compiler.CodeLabel() : ctx.DefineLabel(); if (!ExpectedType.IsValueType) { ctx.LoadAddress(objValue, ExpectedType); ctx.BranchIfFalse(skipOld, false); } for (int i = 0; i < members.Length; i++) { ctx.LoadAddress(objValue, ExpectedType); switch (members[i].MemberType) { case MemberTypes.Field: ctx.LoadValue((FieldInfo)members[i]); break; case MemberTypes.Property: ctx.LoadValue((PropertyInfo)members[i]); break; } ctx.StoreValue(locals[i]); } if (!ExpectedType.IsValueType) { ctx.MarkLabel(skipOld); } using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) { Compiler.CodeLabel @continue = ctx.DefineLabel(), processField = ctx.DefineLabel(), notRecognised = ctx.DefineLabel(); ctx.Branch(@continue, false); Compiler.CodeLabel[] handlers = new Compiler.CodeLabel[members.Length]; for (int i = 0; i < members.Length; i++) { handlers[i] = ctx.DefineLabel(); } ctx.MarkLabel(processField); ctx.LoadValue(fieldNumber); ctx.LoadValue(1); ctx.Subtract(); // jump-table is zero-based ctx.Switch(handlers); // and the default: ctx.Branch(notRecognised, false); for (int i = 0; i < handlers.Length; i++) { ctx.MarkLabel(handlers[i]); IProtoSerializer tail = tails[i]; Compiler.Local oldValIfNeeded = tail.RequiresOldValue ? locals[i] : null; ctx.ReadNullCheckedTail(locals[i].Type, tail, oldValIfNeeded); if (tail.ReturnsValue) { if (locals[i].Type.IsValueType) { ctx.StoreValue(locals[i]); } else { Compiler.CodeLabel hasValue = ctx.DefineLabel(), allDone = ctx.DefineLabel(); ctx.CopyValue(); ctx.BranchIfTrue(hasValue, true); // interpret null as "don't assign" ctx.DiscardValue(); ctx.Branch(allDone, true); ctx.MarkLabel(hasValue); ctx.StoreValue(locals[i]); ctx.MarkLabel(allDone); } } ctx.Branch(@continue, false); } ctx.MarkLabel(notRecognised); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); ctx.MarkLabel(@continue); ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); ctx.CopyValue(); ctx.StoreValue(fieldNumber); ctx.LoadValue(0); ctx.BranchIfGreater(processField, false); } for (int i = 0; i < locals.Length; i++) { ctx.LoadValue(locals[i]); } ctx.EmitCtor(ctor); ctx.StoreValue(objValue); } finally { for (int i = 0; i < locals.Length; i++) { if (locals[i] != null) { locals[i].Dispose(); // release for re-use } } } } }
protected ListDecorator(Type declaredType, Type concreteType, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, bool supportNull) : base(tail) { if (returnList) { options |= OPTIONS_ReturnList; } if (overwriteList) { options |= OPTIONS_OverwriteList; } if (supportNull) { options |= OPTIONS_SupportNull; } if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) { throw new ArgumentOutOfRangeException(nameof(fieldNumber)); } if (!CanPack(packedWireType)) { if (writePacked) { throw new InvalidOperationException("Only simple data-types can use packed encoding"); } packedWireType = WireType.None; } this.fieldNumber = fieldNumber; if (writePacked) { options |= OPTIONS_WritePacked; } this.packedWireType = packedWireType; if (declaredType == null) { throw new ArgumentNullException(nameof(declaredType)); } if (declaredType.IsArray) { throw new ArgumentException("Cannot treat arrays as lists", nameof(declaredType)); } this.declaredType = declaredType; this.concreteType = concreteType; // look for a public list.Add(typedObject) method if (RequireAdd) { add = TypeModel.ResolveListAdd(declaredType, tail.ExpectedType, out var isList); if (isList) { options |= OPTIONS_IsList; string fullName = declaredType.FullName; if (fullName != null && fullName.StartsWith("System.Data.Linq.EntitySet`1[[")) { // see http://stackoverflow.com/questions/6194639/entityset-is-there-a-sane-reason-that-ilist-add-doesnt-set-assigned options |= OPTIONS_SuppressIList; } } if (add == null) { throw new InvalidOperationException("Unable to resolve a suitable Add method for " + declaredType.FullName); } } }
private static void EmitReadAndAddItem(Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, bool castListForAdd) { ctx.LoadAddress(list, list.Type); // needs to be the reference in case the list is value-type (static-call) if (castListForAdd) { ctx.Cast(add.DeclaringType); } Type itemType = tail.ExpectedType; bool tailReturnsValue = tail.ReturnsValue; if (tail.RequiresOldValue) { if (Helpers.IsValueType(itemType) || !tailReturnsValue) { // going to need a variable using (Compiler.Local item = new Compiler.Local(ctx, itemType)) { if (Helpers.IsValueType(itemType)) { // initialise the struct ctx.LoadAddress(item, itemType); ctx.EmitCtor(itemType); } else { // assign null ctx.LoadNullRef(); ctx.StoreValue(item); } tail.EmitRead(ctx, item); if (!tailReturnsValue) { ctx.LoadValue(item); } } } else { // no variable; pass the null on the stack and take the value *off* the stack ctx.LoadNullRef(); tail.EmitRead(ctx, null); } } else { if (tailReturnsValue) { // out only (on the stack); just emit it tail.EmitRead(ctx, null); } else { // doesn't take anything in nor return anything! WTF? throw new InvalidOperationException(); } } // our "Add" is chosen either to take the correct type, or to take "object"; // we may need to box the value Type addParamType = add.GetParameters()[0].ParameterType; if (addParamType != itemType) { if (addParamType == typeof(object)) { ctx.CastToObject(itemType); } else if (Helpers.GetUnderlyingType(addParamType) == itemType) { // list is nullable ConstructorInfo ctor = Helpers.GetConstructor(addParamType, new Type[] { itemType }, false); ctx.EmitCtor(ctor); // the itemType on the stack is now a Nullable<ItemType> } else { throw new InvalidOperationException("Conflicting item/add type"); } } ctx.EmitCall(add, list.Type); if (add.ReturnType != typeof(void)) { ctx.DiscardValue(); } }
} // updates field directly #if FEAT_COMPILER void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { Type expected = ExpectedType; using (Compiler.Local loc = ctx.GetLocalWithValue(expected, valueFrom)) { // pre-callbacks EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeSerialize); Compiler.CodeLabel startFields = ctx.DefineLabel(); // inheritance if (CanHaveInheritance) { for (int i = 0; i < serializers.Length; i++) { IProtoSerializer ser = serializers[i]; Type serType = ser.ExpectedType; if (serType != forType) { Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel(); ctx.LoadValue(loc); ctx.TryCast(serType); ctx.CopyValue(); ctx.BranchIfTrue(ifMatch, true); ctx.DiscardValue(); ctx.Branch(nextTest, true); ctx.MarkLabel(ifMatch); ser.EmitWrite(ctx, null); ctx.Branch(startFields, false); ctx.MarkLabel(nextTest); } } if (constructType != null && constructType != forType) { using (Compiler.Local actualType = new Compiler.Local(ctx, ctx.MapType(typeof(System.Type)))) { // would have jumped to "fields" if an expected sub-type, so two options: // a: *exactly* that type, b: an *unexpected* type ctx.LoadValue(loc); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.CopyValue(); ctx.StoreValue(actualType); ctx.LoadValue(forType); ctx.BranchIfEqual(startFields, true); ctx.LoadValue(actualType); ctx.LoadValue(constructType); ctx.BranchIfEqual(startFields, true); } } else { // would have jumped to "fields" if an expected sub-type, so two options: // a: *exactly* that type, b: an *unexpected* type ctx.LoadValue(loc); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.LoadValue(forType); ctx.BranchIfEqual(startFields, true); } // unexpected, then... note that this *might* be a proxy, which // is handled by ThrowUnexpectedSubtype ctx.LoadValue(forType); ctx.LoadValue(loc); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)); } // fields ctx.MarkLabel(startFields); for (int i = 0; i < serializers.Length; i++) { IProtoSerializer ser = serializers[i]; if (ser.ExpectedType == forType) { ser.EmitWrite(ctx, loc); } } // extension data if (isExtensible) { ctx.LoadValue(loc); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData")); } // post-callbacks EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.AfterSerialize); } }
private static void EmitReadAndAddItem(CompilerContext ctx, Local list, IProtoSerializer tail, MethodInfo add, bool castListForAdd) { ctx.LoadAddress(list, list.Type); if (castListForAdd) { ctx.Cast(add.DeclaringType); } Type expectedType = tail.ExpectedType; bool returnsValue = tail.ReturnsValue; if (!tail.RequiresOldValue) { if (!returnsValue) { throw new InvalidOperationException(); } tail.EmitRead(ctx, null); } else if (expectedType.IsValueType || !returnsValue) { using (Local local = new Local(ctx, expectedType)) { if (!expectedType.IsValueType) { ctx.LoadNullRef(); ctx.StoreValue(local); } else { ctx.LoadAddress(local, expectedType); ctx.EmitCtor(expectedType); } tail.EmitRead(ctx, local); if (!returnsValue) { ctx.LoadValue(local); } } } else { ctx.LoadNullRef(); tail.EmitRead(ctx, null); } Type parameterType = add.GetParameters()[0].ParameterType; if (parameterType != expectedType) { if (parameterType != ctx.MapType(typeof(object))) { if (Helpers.GetUnderlyingType(parameterType) != expectedType) { throw new InvalidOperationException("Conflicting item/add type"); } Type[] typeArray = new Type[] { expectedType }; ctx.EmitCtor(Helpers.GetConstructor(parameterType, typeArray, false)); } else { ctx.CastToObject(expectedType); } } ctx.EmitCall(add); if (add.ReturnType != ctx.MapType(typeof(void))) { ctx.DiscardValue(); } }
protected ProtoDecoratorBase(IProtoSerializer tail) { this.Tail = tail; }
internal static ListDecorator Create(TypeModel model, Type declaredType, Type concreteType, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, bool supportNull) { MethodInfo methodInfo; MethodInfo methodInfo1; MethodInfo methodInfo2; MethodInfo methodInfo3; if (!returnList || !ImmutableCollectionDecorator.IdentifyImmutable(model, declaredType, out methodInfo, out methodInfo1, out methodInfo2, out methodInfo3)) { return(new ListDecorator(model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, returnList, overwriteList, supportNull)); } return(new ImmutableCollectionDecorator(model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, returnList, overwriteList, supportNull, methodInfo, methodInfo1, methodInfo2, methodInfo3)); }
internal string GetSchemaTypeName(Type effectiveType, BinaryDataFormat dataFormat, bool asReference, bool dynamicType, ref bool requiresBclImport) { Type tmp = Helpers.GetNullableUnderlyingType(effectiveType); if (tmp != null) { effectiveType = tmp; } if (effectiveType == this.MapType(typeof(byte[]))) { return("bytes"); } WireType wireType; IProtoSerializer ser = this.ValueSerializerBuilder.TryGetSimpleCoreSerializer(dataFormat, effectiveType, out wireType); if (ser == null) { // model type if (asReference || dynamicType) { requiresBclImport = true; return("bcl.NetObjectProxy"); } return(this[effectiveType].GetSurrogateOrBaseOrSelf(true).GetSchemaTypeName()); } if (ser is ParseableSerializer) { if (asReference) { requiresBclImport = true; } return(asReference ? "bcl.NetObjectProxy" : "string"); } switch (Helpers.GetTypeCode(effectiveType)) { case ProtoTypeCode.Boolean: return("bool"); case ProtoTypeCode.Single: return("float"); case ProtoTypeCode.Double: return("double"); case ProtoTypeCode.Type: case ProtoTypeCode.String: if (asReference) { requiresBclImport = true; } return(asReference ? "bcl.NetObjectProxy" : "string"); case ProtoTypeCode.Byte: case ProtoTypeCode.Char: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: switch (dataFormat) { case BinaryDataFormat.FixedSize: return("fixed32"); default: return("uint32"); } case ProtoTypeCode.SByte: case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: switch (dataFormat) { case BinaryDataFormat.ZigZag: return("sint32"); case BinaryDataFormat.FixedSize: return("sfixed32"); default: return("int32"); } case ProtoTypeCode.UInt64: switch (dataFormat) { case BinaryDataFormat.FixedSize: return("fixed64"); default: return("uint64"); } case ProtoTypeCode.Int64: switch (dataFormat) { case BinaryDataFormat.ZigZag: return("sint64"); case BinaryDataFormat.FixedSize: return("sfixed64"); default: return("int64"); } case ProtoTypeCode.DateTime: requiresBclImport = true; return("bcl.DateTime"); case ProtoTypeCode.TimeSpan: requiresBclImport = true; return("bcl.TimeSpan"); case ProtoTypeCode.Decimal: requiresBclImport = true; return("bcl.Decimal"); case ProtoTypeCode.Guid: requiresBclImport = true; return("bcl.Guid"); default: throw new NotSupportedException("No .proto map found for: " + effectiveType.FullName); } }
// Token: 0x0600029C RID: 668 RVA: 0x0000FA88 File Offset: 0x0000DC88 public object Read(object value, ProtoReader source) { if (this.isRootType && value != null) { this.Callback(value, TypeModel.CallbackType.BeforeDeserialize, source.Context); } int num = 0; int num2 = 0; int num3; while ((num3 = source.ReadFieldHeader()) > 0) { bool flag = false; if (num3 < num) { num2 = (num = 0); } for (int i = num2; i < this.fieldNumbers.Length; i++) { if (this.fieldNumbers[i] == num3) { IProtoSerializer protoSerializer = this.serializers[i]; Type expectedType = protoSerializer.ExpectedType; if (value == null) { if (expectedType == this.forType) { value = this.CreateInstance(source, true); } } else if (expectedType != this.forType && ((IProtoTypeSerializer)protoSerializer).CanCreateInstance() && expectedType.IsSubclassOf(value.GetType())) { value = ProtoReader.Merge(source, value, ((IProtoTypeSerializer)protoSerializer).CreateInstance(source)); } if (protoSerializer.ReturnsValue) { value = protoSerializer.Read(value, source); } else { protoSerializer.Read(value, source); } num2 = i; num = num3; flag = true; break; } } if (!flag) { if (value == null) { value = this.CreateInstance(source, true); } if (this.isExtensible) { source.AppendExtensionData((IExtensible)value); } else { source.SkipField(); } } } if (value == null) { value = this.CreateInstance(source, true); } if (this.isRootType) { this.Callback(value, TypeModel.CallbackType.AfterDeserialize, source.Context); } return(value); }
public PropertyDecorator(TypeModel model, Type forType, PropertyInfo property, IProtoSerializer tail) : base(tail) { Helpers.DebugAssert(forType != null); Helpers.DebugAssert(property != null); this.forType = forType; this.property = property; SanityCheck(model, property, tail, out readOptionsWriteValue, true, true); shadowSetter = GetShadowSetter(model, property); }
private IProtoSerializer BuildSerializer() { int opaqueToken = 0; try { model.TakeLock(ref opaqueToken); Type type = (itemType == (Type)null) ? memberType : itemType; IProtoSerializer protoSerializer = TryGetCoreSerializer(model, dataFormat, type, out WireType wireType, asReference, dynamicType, OverwriteList, true); if (protoSerializer == null) { throw new InvalidOperationException("No serializer defined for type: " + type.FullName); } if (itemType != (Type)null && SupportNull) { if (IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } protoSerializer = new TagDecorator(1, wireType, IsStrict, protoSerializer); protoSerializer = new NullDecorator(model, protoSerializer); protoSerializer = new TagDecorator(fieldNumber, WireType.StartGroup, false, protoSerializer); } else { protoSerializer = new TagDecorator(fieldNumber, wireType, IsStrict, protoSerializer); } if (itemType != (Type)null) { if (!SupportNull) { if ((object)Helpers.GetUnderlyingType(itemType) == null) { Type itemType2 = itemType; } } else { Type itemType3 = itemType; } protoSerializer = ((!memberType.IsArray) ? ((ProtoDecoratorBase)ListDecorator.Create(model, memberType, defaultType, protoSerializer, fieldNumber, IsPacked, wireType, member != (MemberInfo)null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull)) : ((ProtoDecoratorBase) new ArrayDecorator(model, protoSerializer, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull))); } else if (defaultValue != null && !IsRequired && getSpecified == (MethodInfo)null) { protoSerializer = new DefaultValueDecorator(model, defaultValue, protoSerializer); } if (memberType == model.MapType(typeof(Uri))) { protoSerializer = new UriDecorator(model, protoSerializer); } if (member != (MemberInfo)null) { if (member as PropertyInfo != (PropertyInfo)null) { protoSerializer = new PropertyDecorator(model, parentType, (PropertyInfo)member, protoSerializer); goto IL_0278; } if (member as FieldInfo != (FieldInfo)null) { protoSerializer = new FieldDecorator(parentType, (FieldInfo)member, protoSerializer); goto IL_0278; } throw new InvalidOperationException(); } goto IL_02a7; IL_0278: if (getSpecified != (MethodInfo)null || setSpecified != (MethodInfo)null) { protoSerializer = new MemberSpecifiedDecorator(getSpecified, setSpecified, protoSerializer); } goto IL_02a7; IL_02a7: return(protoSerializer); } finally { model.ReleaseLock(opaqueToken); } }
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) { Type underlyingType = Helpers.GetUnderlyingType(type); if (underlyingType != (Type)null) { type = underlyingType; } if (Helpers.IsEnum(type)) { if (allowComplexTypes && model != null) { defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } defaultWireType = WireType.None; return(null); } switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int32Serializer(model)); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt32Serializer(model)); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new Int64Serializer(model)); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new UInt64Serializer(model)); case ProtoTypeCode.String: defaultWireType = WireType.String; if (asReference) { return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); } return(new StringSerializer(model)); case ProtoTypeCode.Single: defaultWireType = WireType.Fixed32; return(new SingleSerializer(model)); case ProtoTypeCode.Double: defaultWireType = WireType.Fixed64; return(new DoubleSerializer(model)); case ProtoTypeCode.Boolean: defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); case ProtoTypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(model)); case ProtoTypeCode.Decimal: defaultWireType = WireType.String; return(new DecimalSerializer(model)); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new ByteSerializer(model)); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new SByteSerializer(model)); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new CharSerializer(model)); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int16Serializer(model)); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt16Serializer(model)); case ProtoTypeCode.TimeSpan: defaultWireType = GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer(model)); case ProtoTypeCode.Guid: defaultWireType = WireType.String; return(new GuidSerializer(model)); case ProtoTypeCode.Uri: defaultWireType = WireType.String; return(new StringSerializer(model)); case ProtoTypeCode.ByteArray: defaultWireType = WireType.String; return(new BlobSerializer(model, overwriteList)); case ProtoTypeCode.Type: defaultWireType = WireType.String; return(new SystemTypeSerializer(model)); default: { IProtoSerializer protoSerializer = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; if (protoSerializer != null) { defaultWireType = WireType.String; return(protoSerializer); } if (allowComplexTypes && model != null) { int key = model.GetKey(type, false, true); if (asReference | dynamicType) { defaultWireType = ((dataFormat == DataFormat.Group) ? WireType.StartGroup : WireType.String); BclHelpers.NetObjectOptions netObjectOptions = BclHelpers.NetObjectOptions.None; if (asReference) { netObjectOptions |= BclHelpers.NetObjectOptions.AsReference; } if (dynamicType) { netObjectOptions |= BclHelpers.NetObjectOptions.DynamicType; } if (key >= 0) { if (asReference && Helpers.IsValueType(type)) { string str = "AsReference cannot be used with value-types"; str = ((!(type.Name == "KeyValuePair`2")) ? (str + ": " + type.FullName) : (str + "; please see http://stackoverflow.com/q/14436606/")); throw new InvalidOperationException(str); } MetaType metaType = model[type]; if (asReference && metaType.IsAutoTuple) { netObjectOptions |= BclHelpers.NetObjectOptions.LateSet; } if (metaType.UseConstructor) { netObjectOptions |= BclHelpers.NetObjectOptions.UseConstructor; } } return(new NetObjectSerializer(model, type, key, netObjectOptions)); } if (key >= 0) { defaultWireType = ((dataFormat == DataFormat.Group) ? WireType.StartGroup : WireType.String); return(new SubItemSerializer(type, key, model[type], true)); } } defaultWireType = WireType.None; return(null); } } }
public MemberSpecifiedDecorator(MethodInfo getSpecified, MethodInfo setSpecified, IProtoSerializer tail) : base(tail) { if (getSpecified == null && setSpecified == null) { throw new InvalidOperationException(); } this.getSpecified = getSpecified; this.setSpecified = setSpecified; }
public UriDecorator(ProtoBuf.Meta.TypeModel model, IProtoSerializer tail) : base(tail) { #if FEAT_IKVM expectedType = model.MapType(typeof(Uri)); #endif }
private IProtoSerializer BuildSerializer() { IProtoSerializer serializer2; int opaqueToken = 0; try { WireType type; this.model.TakeLock(ref opaqueToken); Type type2 = (this.itemType == null) ? this.memberType : this.itemType; IProtoSerializer tail = TryGetCoreSerializer(this.model, this.dataFormat, type2, out type, this.asReference, this.dynamicType, this.OverwriteList, true); if (tail == null) { throw new InvalidOperationException("No serializer defined for type: " + type2.FullName); } if ((this.itemType != null) && this.SupportNull) { if (this.IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } tail = new TagDecorator(1, type, this.IsStrict, tail); tail = new NullDecorator(this.model, tail); tail = new TagDecorator(this.fieldNumber, WireType.StartGroup, false, tail); } else { tail = new TagDecorator(this.fieldNumber, type, this.IsStrict, tail); } if (this.itemType != null) { if (!this.SupportNull) { Helpers.GetUnderlyingType(this.itemType); } if (this.memberType.IsArray) { tail = new ArrayDecorator(this.model, tail, this.fieldNumber, this.IsPacked, type, this.memberType, this.OverwriteList, this.SupportNull); } else { tail = new ListDecorator(this.model, this.memberType, this.defaultType, tail, this.fieldNumber, this.IsPacked, type, (this.member != null) && PropertyDecorator.CanWrite(this.model, this.member), this.OverwriteList, this.SupportNull); } } else if (((this.defaultValue != null) && !this.IsRequired) && (this.getSpecified == null)) { tail = new DefaultValueDecorator(this.model, this.defaultValue, tail); } if (this.memberType == this.model.MapType(typeof(Uri))) { tail = new UriDecorator(this.model, tail); } if (this.member != null) { PropertyInfo member = this.member as PropertyInfo; if (member != null) { tail = new PropertyDecorator(this.model, this.parentType, (PropertyInfo)this.member, tail); } else { FieldInfo info2 = this.member as FieldInfo; if (info2 == null) { throw new InvalidOperationException(); } tail = new FieldDecorator(this.parentType, (FieldInfo)this.member, tail); } if ((this.getSpecified != null) || (this.setSpecified != null)) { tail = new MemberSpecifiedDecorator(this.getSpecified, this.setSpecified, tail); } } serializer2 = tail; } finally { this.model.ReleaseLock(opaqueToken); } return(serializer2); }
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) { #if !NO_GENERICS { Type tmp = Helpers.GetUnderlyingType(type); if (tmp != null) { type = tmp; } } #endif if (Helpers.IsEnum(type)) { if (allowComplexTypes && model != null) { // need to do this before checking the typecode; an int enum will report Int32 etc defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } else { // enum is fine for adding as a meta-type defaultWireType = WireType.None; return(null); } } ProtoTypeCode code = Helpers.GetTypeCode(type); switch (code) { case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int32Serializer(model)); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt32Serializer(model)); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new Int64Serializer(model)); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new UInt64Serializer(model)); case ProtoTypeCode.String: defaultWireType = WireType.String; if (asReference) { return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); } return(new StringSerializer(model)); case ProtoTypeCode.Single: defaultWireType = WireType.Fixed32; return(new SingleSerializer(model)); case ProtoTypeCode.Double: defaultWireType = WireType.Fixed64; return(new DoubleSerializer(model)); case ProtoTypeCode.Boolean: defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); case ProtoTypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(dataFormat, model)); case ProtoTypeCode.Decimal: defaultWireType = WireType.String; return(new DecimalSerializer(model)); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new ByteSerializer(model)); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new SByteSerializer(model)); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new CharSerializer(model)); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int16Serializer(model)); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt16Serializer(model)); case ProtoTypeCode.TimeSpan: defaultWireType = GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer(dataFormat, model)); case ProtoTypeCode.Guid: defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; return(new GuidSerializer(model)); case ProtoTypeCode.Uri: defaultWireType = WireType.String; return(new StringSerializer(model)); case ProtoTypeCode.ByteArray: defaultWireType = WireType.String; return(new BlobSerializer(model, overwriteList)); case ProtoTypeCode.Type: defaultWireType = WireType.String; return(new SystemTypeSerializer(model)); } IProtoSerializer parseable = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; if (parseable != null) { defaultWireType = WireType.String; return(parseable); } if (allowComplexTypes && model != null) { int key = model.GetKey(type, false, true); MetaType meta = null; if (key >= 0) { meta = model[type]; if (dataFormat == DataFormat.Default && meta.IsGroup) { dataFormat = DataFormat.Group; } } if (asReference || dynamicType) { BclHelpers.NetObjectOptions options = BclHelpers.NetObjectOptions.None; if (asReference) { options |= BclHelpers.NetObjectOptions.AsReference; } if (dynamicType) { options |= BclHelpers.NetObjectOptions.DynamicType; } if (meta != null) { // exists if (asReference && Helpers.IsValueType(type)) { string message = "AsReference cannot be used with value-types"; if (type.Name == "KeyValuePair`2") { message += "; please see http://stackoverflow.com/q/14436606/"; } else { message += ": " + type.FullName; } throw new InvalidOperationException(message); } if (asReference && meta.IsAutoTuple) { options |= BclHelpers.NetObjectOptions.LateSet; } if (meta.UseConstructor) { options |= BclHelpers.NetObjectOptions.UseConstructor; } } defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; return(new NetObjectSerializer(model, type, key, options)); } if (key >= 0) { defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; return(new SubItemSerializer(type, key, meta, true)); } } defaultWireType = WireType.None; return(null); }
public ClientNetworkManager() { m_eventMgr = new EventManager(); m_serializer = new ProtoSerializer(); }
public object Read(object value, ProtoReader source) { if (isRootType && value != null) { Callback(value, TypeModel.CallbackType.BeforeDeserialize, source.Context); } int fieldNumber, lastFieldNumber = 0, lastFieldIndex = 0; bool fieldHandled; //Helpers.DebugWriteLine(">> Reading fields for " + forType.FullName); while ((fieldNumber = source.ReadFieldHeader()) > 0) { fieldHandled = false; if (fieldNumber < lastFieldNumber) { lastFieldNumber = lastFieldIndex = 0; } for (int i = lastFieldIndex; i < fieldNumbers.Length; i++) { if (fieldNumbers[i] == fieldNumber) { IProtoSerializer ser = serializers[i]; //Helpers.DebugWriteLine(": " + ser.ToString()); Type serType = ser.ExpectedType; if (value == null) { if (serType == forType) { value = CreateInstance(source, true); } } else { if (serType != forType && ((IProtoTypeSerializer)ser).CanCreateInstance() && serType #if WINRT || COREFX .GetTypeInfo() #endif .IsSubclassOf(value.GetType())) { value = ProtoReader.Merge(source, value, ((IProtoTypeSerializer)ser).CreateInstance(source)); } } if (ser.ReturnsValue) { value = ser.Read(value, source); } else // pop { ser.Read(value, source); } lastFieldIndex = i; lastFieldNumber = fieldNumber; fieldHandled = true; break; } } if (!fieldHandled) { //Helpers.DebugWriteLine(": [" + fieldNumber + "] (unknown)"); if (value == null) { value = CreateInstance(source, true); } if (isExtensible) { source.AppendExtensionData((IExtensible)value); } else { source.SkipField(); } } } //Helpers.DebugWriteLine("<< Reading fields for " + forType.FullName); if (value == null) { value = CreateInstance(source, true); } if (isRootType) { Callback(value, TypeModel.CallbackType.AfterDeserialize, source.Context); } return(value); }
private IProtoTypeSerializer BuildSerializer() { if (surrogate != null) { MetaType mt = model[surrogate], mtBase; while ((mtBase = mt.baseType) != null) { mt = mtBase; } return(new SurrogateSerializer(type, surrogate, mt.Serializer)); } Type itemType = TypeModel.GetListItemType(type); if (itemType != null) { ValueMember fakeMember = new ValueMember(model, 1, type, itemType, type, DataFormat.Default); return(new TypeSerializer(type, new int[] { 1 }, new IProtoSerializer[] { fakeMember.Serializer }, null, true, true, null, constructType)); } fields.Trim(); int fieldCount = fields.Count; int subTypeCount = subTypes == null ? 0 : subTypes.Count; int[] fieldNumbers = new int[fieldCount + subTypeCount]; IProtoSerializer[] serializers = new IProtoSerializer[fieldCount + subTypeCount]; int i = 0; if (subTypeCount != 0) { foreach (SubType subType in subTypes) { fieldNumbers[i] = subType.FieldNumber; serializers[i++] = subType.Serializer; } } if (fieldCount != 0) { foreach (ValueMember member in fields) { fieldNumbers[i] = member.FieldNumber; serializers[i++] = member.Serializer; } } BasicList baseCtorCallbacks = null; MetaType tmp = BaseType; while (tmp != null) { MethodInfo method = tmp.HasCallbacks ? tmp.Callbacks.BeforeDeserialize : null; if (method != null) { if (baseCtorCallbacks == null) { baseCtorCallbacks = new BasicList(); } baseCtorCallbacks.Add(method); } tmp = tmp.BaseType; } MethodInfo[] arr = null; if (baseCtorCallbacks != null) { arr = new MethodInfo[baseCtorCallbacks.Count]; baseCtorCallbacks.CopyTo(arr, 0); Array.Reverse(arr); } return(new TypeSerializer(type, fieldNumbers, serializers, arr, baseType == null, UseConstructor, callbacks, constructType)); }
public void EmitRead(CompilerContext ctx, Local incoming) { using (Local local = ctx.GetLocalWithValue(this.ExpectedType, incoming)) { Local[] localArray = new Local[this.members.Length]; try { for (int i = 0; i < localArray.Length; i++) { Type memberType = this.GetMemberType(i); bool flag = true; localArray[i] = new Local(ctx, memberType); if (this.ExpectedType.IsValueType) { continue; } if (memberType.IsValueType) { switch (Helpers.GetTypeCode(memberType)) { case ProtoTypeCode.Boolean: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: ctx.LoadValue(0); goto Label_0108; case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: ctx.LoadValue((long)0L); goto Label_0108; case ProtoTypeCode.Single: ctx.LoadValue((float)0f); goto Label_0108; case ProtoTypeCode.Double: ctx.LoadValue((double)0.0); goto Label_0108; case ProtoTypeCode.Decimal: ctx.LoadValue((decimal)0M); goto Label_0108; case ProtoTypeCode.Guid: ctx.LoadValue(Guid.Empty); goto Label_0108; } ctx.LoadAddress(localArray[i], memberType); ctx.EmitCtor(memberType); flag = false; } else { ctx.LoadNullRef(); } Label_0108: if (flag) { ctx.StoreValue(localArray[i]); } } CodeLabel label = this.ExpectedType.IsValueType ? new CodeLabel() : ctx.DefineLabel(); if (!this.ExpectedType.IsValueType) { ctx.LoadAddress(local, this.ExpectedType); ctx.BranchIfFalse(label, false); } for (int j = 0; j < this.members.Length; j++) { ctx.LoadAddress(local, this.ExpectedType); switch (this.members[j].MemberType) { case MemberTypes.Field: ctx.LoadValue((FieldInfo)this.members[j]); break; case MemberTypes.Property: ctx.LoadValue((PropertyInfo)this.members[j]); break; } ctx.StoreValue(localArray[j]); } if (!this.ExpectedType.IsValueType) { ctx.MarkLabel(label); } using (Local local2 = new Local(ctx, ctx.MapType(typeof(int)))) { CodeLabel label2 = ctx.DefineLabel(); CodeLabel label3 = ctx.DefineLabel(); CodeLabel label4 = ctx.DefineLabel(); ctx.Branch(label2, false); CodeLabel[] jumpTable = new CodeLabel[this.members.Length]; for (int m = 0; m < this.members.Length; m++) { jumpTable[m] = ctx.DefineLabel(); } ctx.MarkLabel(label3); ctx.LoadValue(local2); ctx.LoadValue(1); ctx.Subtract(); ctx.Switch(jumpTable); ctx.Branch(label4, false); for (int n = 0; n < jumpTable.Length; n++) { ctx.MarkLabel(jumpTable[n]); IProtoSerializer tail = this.tails[n]; Local valueFrom = tail.RequiresOldValue ? localArray[n] : null; ctx.ReadNullCheckedTail(localArray[n].Type, tail, valueFrom); if (tail.ReturnsValue) { if (localArray[n].Type.IsValueType) { ctx.StoreValue(localArray[n]); } else { CodeLabel label5 = ctx.DefineLabel(); CodeLabel label6 = ctx.DefineLabel(); ctx.CopyValue(); ctx.BranchIfTrue(label5, true); ctx.DiscardValue(); ctx.Branch(label6, true); ctx.MarkLabel(label5); ctx.StoreValue(localArray[n]); ctx.MarkLabel(label6); } } ctx.Branch(label2, false); } ctx.MarkLabel(label4); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); ctx.MarkLabel(label2); ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); ctx.CopyValue(); ctx.StoreValue(local2); ctx.LoadValue(0); ctx.BranchIfGreater(label3, false); } for (int k = 0; k < localArray.Length; k++) { ctx.LoadValue(localArray[k]); } ctx.EmitCtor(this.ctor); ctx.StoreValue(local); } finally { for (int num6 = 0; num6 < localArray.Length; num6++) { if (localArray[num6] != null) { localArray[num6].Dispose(); } } } } }
internal static void EmitReadList(ProtoBuf.Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType, bool castListForAdd) { using (Compiler.Local fieldNumber = new Compiler.Local(ctx, typeof(int))) { Compiler.CodeLabel readPacked = packedWireType == WireType.None ? new Compiler.CodeLabel() : ctx.DefineLabel(); if (packedWireType != WireType.None) { ctx.LoadReader(false); ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType")); ctx.LoadValue((int)WireType.String); ctx.BranchIfEqual(readPacked, false); } ctx.LoadReader(false); ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber")); ctx.StoreValue(fieldNumber); Compiler.CodeLabel @continue = ctx.DefineLabel(); ctx.MarkLabel(@continue); EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); ctx.LoadReader(true); ctx.LoadValue(fieldNumber); ctx.EmitCall(typeof(ProtoReader).GetMethod("TryReadFieldHeader", new[] { ProtoReader.State.ByRefStateType, typeof(int) })); ctx.BranchIfTrue(@continue, false); if (packedWireType != WireType.None) { Compiler.CodeLabel allDone = ctx.DefineLabel(); ctx.Branch(allDone, false); ctx.MarkLabel(readPacked); ctx.LoadReader(true); ctx.EmitCall(typeof(ProtoReader).GetMethod("StartSubItem", ProtoReader.State.ReaderStateTypeArray)); Compiler.CodeLabel testForData = ctx.DefineLabel(), noMoreData = ctx.DefineLabel(); ctx.MarkLabel(testForData); ctx.LoadValue((int)packedWireType); ctx.LoadReader(false); ctx.EmitCall(typeof(ProtoReader).GetMethod("HasSubValue")); ctx.BranchIfFalse(noMoreData, false); EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); ctx.Branch(testForData, false); ctx.MarkLabel(noMoreData); ctx.LoadReader(true); ctx.EmitCall(typeof(ProtoReader).GetMethod("EndSubItem", new[] { typeof(SubItemToken), typeof(ProtoReader), ProtoReader.State.ByRefStateType })); ctx.MarkLabel(allDone); } } }
protected ListDecorator(TypeModel model, Type declaredType, Type concreteType, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, bool supportNull) : base(tail) { bool flag; if (returnList) { ListDecorator listDecorator = this; listDecorator.options = (byte)(listDecorator.options | 8); } if (overwriteList) { ListDecorator listDecorator1 = this; listDecorator1.options = (byte)(listDecorator1.options | 16); } if (supportNull) { ListDecorator listDecorator2 = this; listDecorator2.options = (byte)(listDecorator2.options | 32); } if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) { throw new ArgumentOutOfRangeException("fieldNumber"); } if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) { throw new InvalidOperationException("Only simple data-types can use packed encoding"); } packedWireType = WireType.None; } this.fieldNumber = fieldNumber; if (writePacked) { ListDecorator listDecorator3 = this; listDecorator3.options = (byte)(listDecorator3.options | 4); } this.packedWireType = packedWireType; if (declaredType == null) { throw new ArgumentNullException("declaredType"); } if (declaredType.IsArray) { throw new ArgumentException("Cannot treat arrays as lists", "declaredType"); } this.declaredType = declaredType; this.concreteType = concreteType; if (this.RequireAdd) { this.@add = TypeModel.ResolveListAdd(model, declaredType, tail.ExpectedType, out flag); if (flag) { ListDecorator listDecorator4 = this; listDecorator4.options = (byte)(listDecorator4.options | 1); string fullName = declaredType.FullName; if (fullName != null && fullName.StartsWith("System.Data.Linq.EntitySet`1[[")) { ListDecorator listDecorator5 = this; listDecorator5.options = (byte)(listDecorator5.options | 2); } } if (this.@add == null) { throw new InvalidOperationException(string.Concat("Unable to resolve a suitable Add method for ", declaredType.FullName)); } } }