// Parse the input // Reads each record from the input stream. If the record is a primitive type (A number) // then it doesn't have a BinaryHeaderEnum byte. For this case the expected type // has been previously set to Primitive internal void Run() { try { bool isLoop = true; ReadBegin(); ReadSerializationHeaderRecord(); while (isLoop) { BinaryHeaderEnum binaryHeaderEnum = BinaryHeaderEnum.Object; switch (_expectedType) { case BinaryTypeEnum.ObjectUrt: case BinaryTypeEnum.ObjectUser: case BinaryTypeEnum.String: case BinaryTypeEnum.Object: case BinaryTypeEnum.ObjectArray: case BinaryTypeEnum.StringArray: case BinaryTypeEnum.PrimitiveArray: byte inByte = _dataReader.ReadByte(); binaryHeaderEnum = (BinaryHeaderEnum)inByte; switch (binaryHeaderEnum) { case BinaryHeaderEnum.Assembly: case BinaryHeaderEnum.CrossAppDomainAssembly: ReadAssembly(binaryHeaderEnum); break; case BinaryHeaderEnum.Object: ReadObject(); break; case BinaryHeaderEnum.CrossAppDomainMap: ReadCrossAppDomainMap(); break; case BinaryHeaderEnum.ObjectWithMap: case BinaryHeaderEnum.ObjectWithMapAssemId: ReadObjectWithMap(binaryHeaderEnum); break; case BinaryHeaderEnum.ObjectWithMapTyped: case BinaryHeaderEnum.ObjectWithMapTypedAssemId: ReadObjectWithMapTyped(binaryHeaderEnum); break; case BinaryHeaderEnum.ObjectString: case BinaryHeaderEnum.CrossAppDomainString: ReadObjectString(binaryHeaderEnum); break; case BinaryHeaderEnum.Array: case BinaryHeaderEnum.ArraySinglePrimitive: case BinaryHeaderEnum.ArraySingleObject: case BinaryHeaderEnum.ArraySingleString: ReadArray(binaryHeaderEnum); break; case BinaryHeaderEnum.MemberPrimitiveTyped: ReadMemberPrimitiveTyped(); break; case BinaryHeaderEnum.MemberReference: ReadMemberReference(); break; case BinaryHeaderEnum.ObjectNull: case BinaryHeaderEnum.ObjectNullMultiple256: case BinaryHeaderEnum.ObjectNullMultiple: ReadObjectNull(binaryHeaderEnum); break; case BinaryHeaderEnum.MessageEnd: isLoop = false; ReadMessageEnd(); ReadEnd(); break; default: throw new SerializationException(SR.Format(SR.Serialization_BinaryHeader, inByte)); } break; case BinaryTypeEnum.Primitive: ReadMemberPrimitiveUnTyped(); break; default: throw new SerializationException(SR.Serialization_TypeExpected); } // If an assembly is encountered, don't advance // object Progress, if (binaryHeaderEnum != BinaryHeaderEnum.Assembly) { // End of parse loop. bool isData = false; // Set up loop for next iteration. // If this is an object, and the end of object has been reached, then parse object end. while (!isData) { ObjectProgress op = (ObjectProgress)_stack.Peek(); if (op == null) { // No more object on stack, then the next record is a top level object _expectedType = BinaryTypeEnum.ObjectUrt; _expectedTypeInformation = null; isData = true; } else { // Find out what record is expected next isData = op.GetNext(out op._expectedType, out op._expectedTypeInformation); _expectedType = op._expectedType; _expectedTypeInformation = op._expectedTypeInformation; if (!isData) { // No record is expected next, this is the end of an object or array PRs.Init(); if (op._memberValueEnum == InternalMemberValueE.Nested) { // Nested object PRs._parseTypeEnum = InternalParseTypeE.MemberEnd; PRs._memberTypeEnum = op._memberTypeEnum; PRs._memberValueEnum = op._memberValueEnum; _objectReader.Parse(PRs); } else { // Top level object PRs._parseTypeEnum = InternalParseTypeE.ObjectEnd; PRs._memberTypeEnum = op._memberTypeEnum; PRs._memberValueEnum = op._memberValueEnum; _objectReader.Parse(PRs); } _stack.Pop(); PutOp(op); } } } } } } catch (EndOfStreamException) { // EOF should never be thrown since there is a MessageEnd record to stop parsing throw new SerializationException(SR.Serialization_StreamEnd); } }
// New object encountered in stream private void ParseObject(ParseRecord pr) { if (!_fullDeserialization) { InitFullDeserialization(); } if (pr._objectPositionEnum == InternalObjectPositionE.Top) { _topId = pr._objectId; } if (pr._parseTypeEnum == InternalParseTypeE.Object) { _stack.Push(pr); // Nested objects member names are already on stack } if (pr._objectTypeEnum == InternalObjectTypeE.Array) { ParseArray(pr); return; } // If the Type is null, this means we have a typeload issue // mark the object with TypeLoadExceptionHolder if (pr._dtType == null) { pr._newObj = new TypeLoadExceptionHolder(pr._keyDt); return; } if (ReferenceEquals(pr._dtType, Converter.s_typeofString)) { // String as a top level object if (pr._value != null) { pr._newObj = pr._value; if (pr._objectPositionEnum == InternalObjectPositionE.Top) { TopObject = pr._newObj; return; } else { _stack.Pop(); RegisterObject(pr._newObj, pr, (ParseRecord)_stack.Peek()); return; } } else { // xml Doesn't have the value until later return; } } else { CheckSerializable(pr._dtType); pr._newObj = FormatterServices.GetUninitializedObject(pr._dtType); // Run the OnDeserializing methods _objectManager.RaiseOnDeserializingEvent(pr._newObj); } if (pr._newObj == null) { throw new SerializationException(SR.Format(SR.Serialization_TopObjectInstantiate, pr._dtType)); } if (pr._objectPositionEnum == InternalObjectPositionE.Top) { TopObject = pr._newObj; } if (pr._objectInfo == null) { pr._objectInfo = ReadObjectInfo.Create(pr._dtType, _surrogates, _context, _objectManager, _serObjectInfoInit, _formatterConverter, _isSimpleAssembly); } }
/* * Parse the input * Reads each record from the input stream. If the record is a primitive type (A number) * then it doesn't have a BinaryHeaderEnum byte. For this case the expected type * has been previously set to Primitive * @internalonly */ internal void Run() { try { bool isLoop = true; ReadBegin(); ReadSerializationHeaderRecord(); while (isLoop) { SerTrace.Log(this, "Run loop ", ((Enum)expectedType).ToString()); BinaryHeaderEnum binaryHeaderEnum = BinaryHeaderEnum.Object; switch (expectedType) { case BinaryTypeEnum.ObjectUrt: case BinaryTypeEnum.ObjectUser: case BinaryTypeEnum.String: case BinaryTypeEnum.Object: case BinaryTypeEnum.ObjectArray: case BinaryTypeEnum.StringArray: case BinaryTypeEnum.PrimitiveArray: Byte inByte = dataReader.ReadByte(); binaryHeaderEnum = (BinaryHeaderEnum)inByte; //Console.WriteLine("Beginning of loop "+((Enum)binaryHeaderEnum).ToString()); switch (binaryHeaderEnum) { case BinaryHeaderEnum.Assembly: case BinaryHeaderEnum.CrossAppDomainAssembly: ReadAssembly(binaryHeaderEnum); break; case BinaryHeaderEnum.Object: ReadObject(); break; case BinaryHeaderEnum.CrossAppDomainMap: ReadCrossAppDomainMap(); break; case BinaryHeaderEnum.ObjectWithMap: case BinaryHeaderEnum.ObjectWithMapAssemId: ReadObjectWithMap(binaryHeaderEnum); break; case BinaryHeaderEnum.ObjectWithMapTyped: case BinaryHeaderEnum.ObjectWithMapTypedAssemId: ReadObjectWithMapTyped(binaryHeaderEnum); break; case BinaryHeaderEnum.MethodCall: case BinaryHeaderEnum.MethodReturn: ReadMethodObject(binaryHeaderEnum); break; case BinaryHeaderEnum.ObjectString: case BinaryHeaderEnum.CrossAppDomainString: ReadObjectString(binaryHeaderEnum); break; case BinaryHeaderEnum.Array: case BinaryHeaderEnum.ArraySinglePrimitive: case BinaryHeaderEnum.ArraySingleObject: case BinaryHeaderEnum.ArraySingleString: ReadArray(binaryHeaderEnum); break; case BinaryHeaderEnum.MemberPrimitiveTyped: ReadMemberPrimitiveTyped(); break; case BinaryHeaderEnum.MemberReference: ReadMemberReference(); break; case BinaryHeaderEnum.ObjectNull: case BinaryHeaderEnum.ObjectNullMultiple256: case BinaryHeaderEnum.ObjectNullMultiple: ReadObjectNull(binaryHeaderEnum); break; case BinaryHeaderEnum.MessageEnd: isLoop = false; ReadMessageEnd(); ReadEnd(); break; default: throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_BinaryHeader"), inByte)); } break; case BinaryTypeEnum.Primitive: ReadMemberPrimitiveUnTyped(); break; default: throw new SerializationException(Environment.GetResourceString("Serialization_TypeExpected")); } // If an assembly is encountered, don't advance // object Progress, if (binaryHeaderEnum != BinaryHeaderEnum.Assembly) { // End of parse loop. bool isData = false; // Set up loop for next iteration. // If this is an object, and the end of object has been reached, then parse object end. while (!isData) { ObjectProgress op = (ObjectProgress)stack.Peek(); if (op == null) { // No more object on stack, then the next record is a top level object SerTrace.Log(this, "Run loop op null, top level object"); expectedType = BinaryTypeEnum.ObjectUrt; expectedTypeInformation = null; isData = true; } else { SerTrace.Log(this, "Run loop op not null, continue object"); // Find out what record is expected next isData = op.GetNext(out op.expectedType, out op.expectedTypeInformation); expectedType = op.expectedType; expectedTypeInformation = op.expectedTypeInformation; SerTrace.Log(this, "Run loop opName ", op.name, ", expectedType ", ((Enum)expectedType).ToString(), " expectedTypeInformation, ", expectedTypeInformation); SerTrace.Log(this, "Run ", isData); if (!isData) { // No record is expected next, this is the end of an object or array SerTrace.Log(this, "Run End of Object "); stack.Dump(); prs.Init(); if (op.memberValueEnum == InternalMemberValueE.Nested) { // Nested object prs.PRparseTypeEnum = InternalParseTypeE.MemberEnd; prs.PRmemberTypeEnum = op.memberTypeEnum; prs.PRmemberValueEnum = op.memberValueEnum; objectReader.Parse(prs); } else { // Top level object prs.PRparseTypeEnum = InternalParseTypeE.ObjectEnd; prs.PRmemberTypeEnum = op.memberTypeEnum; prs.PRmemberValueEnum = op.memberValueEnum; objectReader.Parse(prs); } stack.Pop(); PutOp(op); } } } } } } catch (EndOfStreamException) { // EOF should never be thrown since there is a MessageEnd record to stop parsing BCLDebug.Trace("BINARY", "\n*****EOF*************************\n"); throw new SerializationException(Environment.GetResourceString("Serialization_StreamEnd")); } }