object ReadValue(SerializationType etype, DmdType argType, out DmdType realArgType) { if (!IncrementRecursionCounter()) throw new CABlobParserException("Stack overflow"); object result; switch (etype) { case SerializationType.Boolean: realArgType = module.AppDomain.System_Boolean; result = reader.ReadByte() != 0; break; case SerializationType.Char: realArgType = module.AppDomain.System_Char; result = (char)reader.ReadUInt16(); break; case SerializationType.I1: realArgType = module.AppDomain.System_SByte; result = reader.ReadSByte(); break; case SerializationType.U1: realArgType = module.AppDomain.System_Byte; result = reader.ReadByte(); break; case SerializationType.I2: realArgType = module.AppDomain.System_Int16; result = reader.ReadInt16(); break; case SerializationType.U2: realArgType = module.AppDomain.System_UInt16; result = reader.ReadUInt16(); break; case SerializationType.I4: realArgType = module.AppDomain.System_Int32; result = reader.ReadInt32(); break; case SerializationType.U4: realArgType = module.AppDomain.System_UInt32; result = reader.ReadUInt32(); break; case SerializationType.I8: realArgType = module.AppDomain.System_Int64; result = reader.ReadInt64(); break; case SerializationType.U8: realArgType = module.AppDomain.System_UInt64; result = reader.ReadUInt64(); break; case SerializationType.R4: realArgType = module.AppDomain.System_Single; result = reader.ReadSingle(); break; case SerializationType.R8: realArgType = module.AppDomain.System_Double; result = reader.ReadDouble(); break; case SerializationType.String: realArgType = module.AppDomain.System_String; result = ReadUTF8String(); break; // It's ET.ValueType if it's eg. a ctor enum arg type case (SerializationType)DMD.ElementType.ValueType: if ((object)argType == null) throw new CABlobParserException("Invalid element type"); realArgType = argType; result = ReadEnumValue(GetEnumUnderlyingType(argType)); break; // It's ET.Object if it's a ctor object arg type case (SerializationType)DMD.ElementType.Object: case SerializationType.TaggedObject: realArgType = ReadFieldOrPropType(); if (realArgType.IsSZArray) result = ReadArrayArgument(realArgType); else result = ReadValue(ToSerializationType(realArgType), realArgType, out var tmpType); break; // It's ET.Class if it's eg. a ctor System.Type arg type case (SerializationType)DMD.ElementType.Class: if (argType == module.AppDomain.System_Type) { result = ReadValue(SerializationType.Type, argType, out realArgType); break; } else if (argType == module.AppDomain.System_String) { result = ReadValue(SerializationType.String, argType, out realArgType); break; } else if (argType == module.AppDomain.System_Object) { result = ReadValue(SerializationType.TaggedObject, argType, out realArgType); break; } // Assume it's an enum that couldn't be resolved realArgType = argType; result = ReadEnumValue(null); break; case SerializationType.Type: realArgType = argType; result = ReadType(true); break; case SerializationType.Enum: realArgType = ReadType(false); result = ReadEnumValue(GetEnumUnderlyingType(realArgType)); break; default: throw new CABlobParserException("Invalid element type"); } DecrementRecursionCounter(); return result; }