Example #1
0
		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;
		}