// 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);
}
}