Пример #1
0
        public string Analyze()
        {
            int  classCount   = 0;
            int  arrayCount   = 0;
            int  stringCount  = 0;
            long classLength  = 0;
            long arrayLength  = 0;
            long stringLength = 0;
            Dictionary <string, int>  ObjectCounts  = new Dictionary <string, int>();
            Dictionary <string, long> ObjectLengths = new Dictionary <string, long>();

            //we are only interested in top-level objects, not nested ones (otherwise would double-count lengths!).
            foreach (SerialObject someObject in SerialObjectsFound.Values)
            {
                if (someObject.ParentObjectID == null)
                {
                    if (someObject.GetType() == typeof(ClassInfo))
                    {
                        classCount++;
                        classLength += someObject.recordLength;

                        ClassInfo interestingClass = (ClassInfo)someObject;
                        if (interestingClass.ReferencedObject != null)
                        {
                            interestingClass = (ClassInfo)SerialObjectsFound[interestingClass.ReferencedObject.Value];
                        }

                        if (!ObjectCounts.ContainsKey(interestingClass.Name))
                        {
                            ObjectCounts.Add(interestingClass.Name, 0);
                            ObjectLengths.Add(interestingClass.Name, 0);
                        }

                        ObjectCounts[interestingClass.Name]++;
                        ObjectLengths[interestingClass.Name] += someObject.recordLength;
                    }
                    else if (someObject.GetType() == typeof(BinaryArray))
                    {
                        arrayCount++;
                        arrayLength += someObject.recordLength;
                    }
                    else if (someObject.GetType() == typeof(ObjectString))
                    {
                        stringCount++;
                        stringLength += someObject.recordLength;
                    }
                }
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine(string.Format("Total Objects: {0}", SerialObjectsFound.Count));
            sb.AppendLine(string.Format("Total Top-Level Objects: {0}", classCount + arrayCount + stringCount));
            sb.AppendLine(string.Format("Total Top-Level Length: {0}", classLength + arrayLength + stringLength));
            sb.AppendLine();
            sb.AppendLine(string.Format("Top-Level Class Count: {0}", classCount));
            sb.AppendLine(string.Format("Top-Level Class Length: {0}", classLength));
            sb.AppendLine();
            sb.AppendLine(string.Format("Top-Level Array Count: {0}", arrayCount));
            sb.AppendLine(string.Format("Top-Level Array Length: {0}", arrayLength));
            sb.AppendLine();
            sb.AppendLine(string.Format("Top-Level String Count: {0}", stringCount));
            sb.AppendLine(string.Format("Top-Level String Length: {0}", stringLength));
            sb.AppendLine();
            sb.AppendLine("Top-Level Object Counts by Name:");
            foreach (string ClassName in ObjectCounts.Keys)
            {
                sb.AppendLine(string.Format("{0}: {1}", ClassName, ObjectCounts[ClassName]));
            }
            sb.AppendLine();
            sb.AppendLine("Top-Level Object Lengths by Name:");
            foreach (string ClassName in ObjectLengths.Keys)
            {
                sb.AppendLine(string.Format("{0}: {1}", ClassName, ObjectLengths[ClassName]));
            }

            return(sb.ToString());
        }
		internal long? ParseRecord(SerialObject parentObject)
		{
			long? serialObjectReferenceID = null;
			if(PendingNullCounter == 0)
			{
				long startPosition = reader.BaseStream.Position;
				SerialObject si = null;
				RecordTypeEnumeration nextRecordType = (RecordTypeEnumeration)reader.ReadByte();
				switch(nextRecordType)
				{
					case RecordTypeEnumeration.SerializedStreamHeader:
						//header is 4 values that I wouldn't know what to do with (what type of message, what version, etc) - trash.
						reader.ReadBytes(16);
						break;
					case RecordTypeEnumeration.ClassWithID:
						//just two ints, read directly
						si = new ClassInfo();
						si.ObjectID = ReadID();
						((ClassInfo)si).ReferencedObject = ReadID();
						//Use the referenced object definition for data retrieval rules
						// -> this will overwrite the original values in the referenced object, but who cares - the values are trash anyway (for now).
						((ClassInfo)SerialObjectsFound[((ClassInfo)si).ReferencedObject.Value]).ReadValueInfo(this);
						break;
					case RecordTypeEnumeration.SystemClassWithMembers:
						//single structure, read in constructor
						si = new ClassInfo(this);
						//also values.
						si.ReadValueInfo(this);
						break;
					case RecordTypeEnumeration.ClassWithMembers:
						//single structure, read in constructor
						si = new ClassInfo(this);
						//also library ID, read into place.
						((ClassInfo)si).LibraryID = ReadID();
						//also values.
						si.ReadValueInfo(this);
						break;
					case RecordTypeEnumeration.SystemClassWithMembersAndTypes:
						//single structure, read in constructor
						si = new ClassInfo(this);
						//also member type info, read into place.
						((ClassInfo)si).ReadTypeInfo(this);
						//also values.
						si.ReadValueInfo(this);
						break;
					case RecordTypeEnumeration.ClassWithMembersAndTypes:
						//single structure, read in constructor
						si = new ClassInfo(this);
						//also member type info, read into place.
						((ClassInfo)si).ReadTypeInfo(this);
						//also library ID, read into place.
						((ClassInfo)si).LibraryID = ReadID();
						//also values.
						si.ReadValueInfo(this);
						break;
					case RecordTypeEnumeration.BinaryObjectString:
						//simple structure, just an ID and a string
						si = new ObjectString();
						si.ObjectID = ReadID();
						((ObjectString)si).String = reader.ReadString();
						break;
					case RecordTypeEnumeration.BinaryArray:
						//complex process, read in constructor.
						si = new BinaryArray(this);
						//also values.
						si.ReadValueInfo(this);
						break;
					case RecordTypeEnumeration.MemberPrimitiveTyped:
						var junk = new MemberInfo();
						junk.BinaryType = BinaryTypeEnumeration.Primitive;
						junk.PrimitiveType = (PrimitiveTypeEnumeration)reader.ReadByte();
						TypeHelper.GetTypeValue(junk, junk, this);
						break;
					case RecordTypeEnumeration.MemberReference:
						//just return the ID that was referenced.
						serialObjectReferenceID = ReadID();
						break;
					case RecordTypeEnumeration.ObjectNull:
						//a single null; do nothing, as null is the default return value.
						break;
					case RecordTypeEnumeration.MessageEnd:
						//do nothing, quit. Wasn't that fun?
						endRecordReached = true;
						break;
					case RecordTypeEnumeration.BinaryLibrary:
						var newLibraryID = ReadID();
						LibrariesFound.Add(newLibraryID, new BinaryLibrary
						{
							LibraryID = newLibraryID,
							Name = reader.ReadString(),
							recordLength = reader.BaseStream.Position - startPosition,
						});
						break;
					case RecordTypeEnumeration.ObjectNullMultiple256:
						//a sequence of nulls; return null, and start a counter to continue returning N nulls over the next calls.
						PendingNullCounter = reader.ReadByte() - 1;
						break;

					case RecordTypeEnumeration.ObjectNullMultiple:
						//a sequence of nulls; return null, and start a counter to continue returning N nulls over the next calls.
						PendingNullCounter = reader.ReadInt32() - 1;
#if (DEBUG)
						//not yet tested: if it happens, take a look around.
						System.Diagnostics.Debugger.Break();
#endif
						break;
					case RecordTypeEnumeration.ArraySinglePrimitive:
						//This one's pretty easy to build, do locally.
						si = new BinaryArray();
						si.ObjectID = ReadID();
						((BinaryArray)si).ArrayType = BinaryArrayTypeEnumeration.Single;
						((BinaryArray)si).BinaryType = BinaryTypeEnumeration.Primitive;
						((BinaryArray)si).Rank = 1;
						((BinaryArray)si).Lengths = new List<int>();
						((BinaryArray)si).Lengths.Add(reader.ReadInt32());
						((BinaryArray)si).PrimitiveType = (PrimitiveTypeEnumeration)reader.ReadByte();
						//and then read the values.
						si.ReadValueInfo(this);
						break;
					case RecordTypeEnumeration.ArraySingleObject:
						//This should be pretty easy to build, do locally.
						si = new BinaryArray();
						si.ObjectID = ReadID();
						((BinaryArray)si).ArrayType = BinaryArrayTypeEnumeration.Single;
						((BinaryArray)si).BinaryType = BinaryTypeEnumeration.Object;
						((BinaryArray)si).Rank = 1;
						((BinaryArray)si).Lengths = new List<int>();
						((BinaryArray)si).Lengths.Add(reader.ReadInt32());
						//and then read the values.
						si.ReadValueInfo(this);
#if (DEBUG)
						//not yet tested: if it happens, take a look around.
						System.Diagnostics.Debugger.Break();
#endif
						break;
					case RecordTypeEnumeration.ArraySingleString:
						//This should be pretty easy to build, do locally.
						si = new BinaryArray();
						si.ObjectID = ReadID();
						((BinaryArray)si).ArrayType = BinaryArrayTypeEnumeration.Single;
						((BinaryArray)si).BinaryType = BinaryTypeEnumeration.String;
						((BinaryArray)si).Rank = 1;
						((BinaryArray)si).Lengths = new List<int>();
						((BinaryArray)si).Lengths.Add(reader.ReadInt32());
						//and then read the values.
						si.ReadValueInfo(this);
#if (DEBUG)
						//not yet tested: if it happens, take a look around.
						System.Diagnostics.Debugger.Break();
#endif
						break;
					case RecordTypeEnumeration.MethodCall:
						//messages/remoting functionality not implemented
						throw new NotImplementedException(nextRecordType.ToString());
					case RecordTypeEnumeration.MethodReturn:
						//messages/remoting functionality not implemented
						throw new NotImplementedException(nextRecordType.ToString());
					default:
						throw new Exception("Parsing appears to have failed dramatically. Unknown record type, we must be lost in the bytestream!");
				}

				//standard: if this was a serial object, add to list and record its length.
				if(si != null)
				{
					SerialObjectsFound.Add(si.ObjectID, si);
					si.recordLength = reader.BaseStream.Position - startPosition;
					if(parentObject != null) si.ParentObjectID = parentObject.ObjectID;
					return si.ObjectID;
				}
			}
			else
				PendingNullCounter--;
			return serialObjectReferenceID;
		}
Пример #3
0
        internal long?ParseRecord(SerialObject parentObject)
        {
            long?serialObjectReferenceID = null;

            if (PendingNullCounter == 0)
            {
                long                  startPosition  = reader.BaseStream.Position;
                SerialObject          si             = null;
                RecordTypeEnumeration nextRecordType = (RecordTypeEnumeration)reader.ReadByte();
                switch (nextRecordType)
                {
                case RecordTypeEnumeration.SerializedStreamHeader:
                    //header is 4 values that I wouldn't know what to do with (what type of message, what version, etc) - trash.
                    reader.ReadBytes(16);
                    break;

                case RecordTypeEnumeration.ClassWithID:
                    //just two ints, read directly
                    si          = new ClassInfo();
                    si.ObjectID = ReadID();
                    ((ClassInfo)si).ReferencedObject = ReadID();
                    //Use the referenced object definition for data retrieval rules
                    // -> this will overwrite the original values in the referenced object, but who cares - the values are trash anyway (for now).
                    ((ClassInfo)SerialObjectsFound[((ClassInfo)si).ReferencedObject.Value]).ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.SystemClassWithMembers:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.ClassWithMembers:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also library ID, read into place.
                    ((ClassInfo)si).LibraryID = ReadID();
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.SystemClassWithMembersAndTypes:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also member type info, read into place.
                    ((ClassInfo)si).ReadTypeInfo(this);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.ClassWithMembersAndTypes:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also member type info, read into place.
                    ((ClassInfo)si).ReadTypeInfo(this);
                    //also library ID, read into place.
                    ((ClassInfo)si).LibraryID = ReadID();
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.BinaryObjectString:
                    //simple structure, just an ID and a string
                    si          = new ObjectString();
                    si.ObjectID = ReadID();
                    ((ObjectString)si).String = reader.ReadString();
                    break;

                case RecordTypeEnumeration.BinaryArray:
                    //complex process, read in constructor.
                    si = new BinaryArray(this);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.MemberPrimitiveTyped:
                    var junk = new MemberInfo();
                    junk.BinaryType    = BinaryTypeEnumeration.Primitive;
                    junk.PrimitiveType = (PrimitiveTypeEnumeration)reader.ReadByte();
                    TypeHelper.GetTypeValue(junk, junk, this);
                    break;

                case RecordTypeEnumeration.MemberReference:
                    //just return the ID that was referenced.
                    serialObjectReferenceID = ReadID();
                    break;

                case RecordTypeEnumeration.ObjectNull:
                    //a single null; do nothing, as null is the default return value.
                    break;

                case RecordTypeEnumeration.MessageEnd:
                    //do nothing, quit. Wasn't that fun?
                    endRecordReached = true;
                    break;

                case RecordTypeEnumeration.BinaryLibrary:
                    var newLibraryID = ReadID();
                    LibrariesFound.Add(newLibraryID, new BinaryLibrary
                    {
                        LibraryID    = newLibraryID,
                        Name         = reader.ReadString(),
                        recordLength = reader.BaseStream.Position - startPosition,
                    });
                    break;

                case RecordTypeEnumeration.ObjectNullMultiple256:
                    //a sequence of nulls; return null, and start a counter to continue returning N nulls over the next calls.
                    PendingNullCounter = reader.ReadByte() - 1;
                    break;

                case RecordTypeEnumeration.ObjectNullMultiple:
                    //a sequence of nulls; return null, and start a counter to continue returning N nulls over the next calls.
                    PendingNullCounter = reader.ReadInt32() - 1;
#if (DEBUG)
                    //not yet tested: if it happens, take a look around.
                    System.Diagnostics.Debugger.Break();
#endif
                    break;

                case RecordTypeEnumeration.ArraySinglePrimitive:
                    //This one's pretty easy to build, do locally.
                    si          = new BinaryArray();
                    si.ObjectID = ReadID();
                    ((BinaryArray)si).ArrayType  = BinaryArrayTypeEnumeration.Single;
                    ((BinaryArray)si).BinaryType = BinaryTypeEnumeration.Primitive;
                    ((BinaryArray)si).Rank       = 1;
                    ((BinaryArray)si).Lengths    = new List <int>();
                    ((BinaryArray)si).Lengths.Add(reader.ReadInt32());
                    ((BinaryArray)si).PrimitiveType = (PrimitiveTypeEnumeration)reader.ReadByte();
                    //and then read the values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.ArraySingleObject:
                    //This should be pretty easy to build, do locally.
                    si          = new BinaryArray();
                    si.ObjectID = ReadID();
                    ((BinaryArray)si).ArrayType  = BinaryArrayTypeEnumeration.Single;
                    ((BinaryArray)si).BinaryType = BinaryTypeEnumeration.Object;
                    ((BinaryArray)si).Rank       = 1;
                    ((BinaryArray)si).Lengths    = new List <int>();
                    ((BinaryArray)si).Lengths.Add(reader.ReadInt32());
                    //and then read the values.
                    si.ReadValueInfo(this);
#if (DEBUG)
                    //not yet tested: if it happens, take a look around.
                    System.Diagnostics.Debugger.Break();
#endif
                    break;

                case RecordTypeEnumeration.ArraySingleString:
                    //This should be pretty easy to build, do locally.
                    si          = new BinaryArray();
                    si.ObjectID = ReadID();
                    ((BinaryArray)si).ArrayType  = BinaryArrayTypeEnumeration.Single;
                    ((BinaryArray)si).BinaryType = BinaryTypeEnumeration.String;
                    ((BinaryArray)si).Rank       = 1;
                    ((BinaryArray)si).Lengths    = new List <int>();
                    ((BinaryArray)si).Lengths.Add(reader.ReadInt32());
                    //and then read the values.
                    si.ReadValueInfo(this);
#if (DEBUG)
                    //not yet tested: if it happens, take a look around.
                    System.Diagnostics.Debugger.Break();
#endif
                    break;

                case RecordTypeEnumeration.MethodCall:
                    //messages/remoting functionality not implemented
                    throw new NotImplementedException(nextRecordType.ToString());

                case RecordTypeEnumeration.MethodReturn:
                    //messages/remoting functionality not implemented
                    throw new NotImplementedException(nextRecordType.ToString());

                default:
                    throw new Exception("Parsing appears to have failed dramatically. Unknown record type, we must be lost in the bytestream!");
                }

                //standard: if this was a serial object, add to list and record its length.
                if (si != null)
                {
                    SerialObjectsFound.Add(si.ObjectID, si);
                    si.recordLength = reader.BaseStream.Position - startPosition;
                    if (parentObject != null)
                    {
                        si.ParentObjectID = parentObject.ObjectID;
                    }
                    return(si.ObjectID);
                }
            }
            else
            {
                PendingNullCounter--;
            }
            return(serialObjectReferenceID);
        }
        internal int?ParseRecord(SerialObject parentObject)
        {
            int?serialObjectReferenceID = null;

            if (PendingNullCounter == 0)
            {
                long                  startPosition = reader.BaseStream.Position;
                SerialObject          si = null;
                ClassInfo             ci = null, ttccii = null;
                RecordTypeEnumeration nextRecordType = (RecordTypeEnumeration)reader.ReadByte();

                Log("============= " + Enum.GetName(typeof(RecordTypeEnumeration), nextRecordType) + " =================");
                switch (nextRecordType)
                {
                case RecordTypeEnumeration.SerializedStreamHeader:
                    Log(new SerializationHeaderRecord(this));
                    // reader.ReadBytes(16);
                    break;

                case RecordTypeEnumeration.ClassWithID:
                    //just two ints, read directly
                    ci          = new ClassInfo();
                    ci.ObjectID = reader.ReadInt32();
                    LogInternal("ObjectID=" + ci.ObjectID);
                    ci.ReferencedObject = reader.ReadInt32();
                    LogInternal("ReferencedID=" + ci.ReferencedObject);

                    //Use the referenced object definition for data retrieval rules
                    // -> this will overwrite the original values in the referenced object, but who cares - the values are trash anyway (for now).
                    ttccii = (ClassInfo)SerialObjectsFound[ci.ReferencedObject.Value];
                    ttccii.ReadValueInfo(this);
                    si = ci;
                    break;

                case RecordTypeEnumeration.SystemClassWithMembers:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.ClassWithMembers:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also library ID, read into place.
                    ((ClassInfo)si).LibraryID = reader.ReadInt32();
                    LogInternal("LibraryID=" + ((ClassInfo)si).LibraryID);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.SystemClassWithMembersAndTypes:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also member type info, read into place.
                    ((ClassInfo)si).ReadTypeInfo(this);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.ClassWithMembersAndTypes:
                    //single structure, read in constructor
                    si = new ClassInfo(this);
                    //also member type info, read into place.
                    ((ClassInfo)si).ReadTypeInfo(this);
                    //also library ID, read into place.
                    ((ClassInfo)si).LibraryID = reader.ReadInt32();
                    LogInternal("LibraryID=" + ((ClassInfo)si).LibraryID);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.BinaryObjectString:
                    //simple structure, just an ID and a string
                    si          = new ObjectString();
                    si.ObjectID = reader.ReadInt32();
                    LogInternal("ObjectID=" + si.ObjectID);
                    ((ObjectString)si).String = reader.ReadString();
                    LogInternal("String=" + ((ObjectString)si).String);
                    break;

                case RecordTypeEnumeration.BinaryArray:
                    //complex process, read in constructor.
                    si = new BinaryArray(this);
                    //also values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.MemberPrimitiveTyped:
                    MessagePrimitiveTyped msg = new MessagePrimitiveTyped(this);
                    msg.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.MemberReference:
                    //just return the ID that was referenced.
                    serialObjectReferenceID = reader.ReadInt32();
                    Log("::::> Reference=" + serialObjectReferenceID);
                    break;

                case RecordTypeEnumeration.ObjectNull:
                    //a single null; do nothing, as null is the default return value.
                    Log("::::> NULL VALUE");
                    break;

                case RecordTypeEnumeration.MessageEnd:
                    //do nothing, quit. Wasn't that fun?
                    endRecordReached = true;
                    Log(":::::> End-of-message");
                    break;

                case RecordTypeEnumeration.BinaryLibrary:
                    int newLibraryID = reader.ReadInt32();
                    LibrariesFound.Add(newLibraryID, new BinaryLibrary());
                    LibrariesFound[newLibraryID].LibraryID    = newLibraryID;
                    LibrariesFound[newLibraryID].Name         = reader.ReadString();
                    LibrariesFound[newLibraryID].recordLength = reader.BaseStream.Position - startPosition;
                    Log("\t" + LibrariesFound[newLibraryID].ToString());
                    break;

                case RecordTypeEnumeration.ObjectNullMultiple256:
                    //a sequence of nulls; return null, and start a counter to continue returning N nulls over the next calls.
                    PendingNullCounter = reader.ReadByte() - 1;
                    Log("\tPending Null256 Counter=" + (PendingNullCounter + 1));
                    break;

                case RecordTypeEnumeration.ObjectNullMultiple:
                    //a sequence of nulls; return null, and start a counter to continue returning N nulls over the next calls.
                    PendingNullCounter = reader.ReadInt32() - 1;
                    Log("\tPending Null Counter=" + (PendingNullCounter + 1));
#if (DEBUG)
                    //not yet tested: if it happens, take a look around.
                    System.Diagnostics.Debugger.Break();
#endif
                    break;

                case RecordTypeEnumeration.ArraySinglePrimitive:
                    //This one's pretty easy to build, do locally.
                    si          = new BinaryArray();
                    si.ObjectID = reader.ReadInt32();
                    LogInternal("ObjectID=" + si.ObjectID);
                    ((BinaryArray)si).ArrayType = BinaryArrayTypeEnumeration.Single;
                    LogInternal("ArrayType=" + Enum.GetName(typeof(BinaryArrayTypeEnumeration), ((BinaryArray)si).ArrayType));
                    ((BinaryArray)si).BinaryType = BinaryTypeEnumeration.Primitive;
                    LogInternal("BinaryType=" + Enum.GetName(typeof(BinaryTypeEnumeration), ((BinaryArray)si).BinaryType));
                    ((BinaryArray)si).Rank = 1;
                    LogInternal("Rank=" + ((BinaryArray)si).Rank);
                    ((BinaryArray)si).Lengths = new List <int>();
                    ((BinaryArray)si).Lengths.Add(reader.ReadInt32());
                    LogInternal("Lenghts=" + ToString(((BinaryArray)si).Lengths));
                    ((BinaryArray)si).PrimitiveType = (PrimitiveTypeEnumeration)reader.ReadByte();
                    LogInternal("PrimitiveType=" + Enum.GetName(typeof(PrimitiveTypeEnumeration), ((BinaryArray)si).PrimitiveType));
                    //and then read the values.
                    si.ReadValueInfo(this);
                    break;

                case RecordTypeEnumeration.ArraySingleObject:
                    //This should be pretty easy to build, do locally.
                    si          = new BinaryArray();
                    si.ObjectID = reader.ReadInt32();
                    LogInternal("ObjectID=" + si.ObjectID);
                    ((BinaryArray)si).ArrayType = BinaryArrayTypeEnumeration.Single;
                    LogInternal("ArrayType=" + Enum.GetName(typeof(BinaryArrayTypeEnumeration), ((BinaryArray)si).ArrayType));
                    ((BinaryArray)si).BinaryType = BinaryTypeEnumeration.Object;
                    LogInternal("BinaryType=" + Enum.GetName(typeof(BinaryTypeEnumeration), ((BinaryArray)si).BinaryType));
                    ((BinaryArray)si).Rank = 1;
                    LogInternal("Rank=" + ((BinaryArray)si).Rank);
                    ((BinaryArray)si).Lengths = new List <int>();
                    ((BinaryArray)si).Lengths.Add(reader.ReadInt32());
                    LogInternal("Lenghts=" + ToString(((BinaryArray)si).Lengths));
                    //and then read the values.
                    si.ReadValueInfo(this);
#if (DEBUG)
                    //not yet tested: if it happens, take a look around.
                    System.Diagnostics.Debugger.Break();
#endif
                    break;

                case RecordTypeEnumeration.ArraySingleString:
                    //This should be pretty easy to build, do locally.
                    si          = new BinaryArray();
                    si.ObjectID = reader.ReadInt32();
                    LogInternal("ObjectID=" + si.ObjectID);
                    ((BinaryArray)si).ArrayType = BinaryArrayTypeEnumeration.Single;
                    LogInternal("ArrayType=" + Enum.GetName(typeof(BinaryArrayTypeEnumeration), ((BinaryArray)si).ArrayType));
                    ((BinaryArray)si).BinaryType = BinaryTypeEnumeration.String;
                    LogInternal("BinaryType=" + Enum.GetName(typeof(BinaryTypeEnumeration), ((BinaryArray)si).BinaryType));
                    ((BinaryArray)si).Rank = 1;
                    LogInternal("Rank=" + ((BinaryArray)si).Rank);
                    ((BinaryArray)si).Lengths = new List <int>();
                    ((BinaryArray)si).Lengths.Add(reader.ReadInt32());
                    LogInternal("Lenghts=" + ToString(((BinaryArray)si).Lengths));
                    //and then read the values.
                    si.ReadValueInfo(this);
#if (DEBUG)
                    //not yet tested: if it happens, take a look around.
                    System.Diagnostics.Debugger.Break();
#endif
                    break;

                case RecordTypeEnumeration.MethodCall:
                    //messages/remoting functionality not implemented
                    throw new NotImplementedException("Method Call N/A");

                case RecordTypeEnumeration.MethodReturn:
                    //messages/remoting functionality not implemented
                    throw new NotImplementedException("Method Return N/A");

                default:
                    throw new Exception("Parsing appears to have failed dramatically. Unknown record type, we must be lost in the bytestream!");
                }

                //standard: if this was a serial object, add to list and record its length.
                if (si != null)
                {
                    Log(si);
                    SerialObjectsFound.Add(si.ObjectID, si);
                    SerialObjectsFound[si.ObjectID].recordLength = reader.BaseStream.Position - startPosition;
                    if (parentObject != null)
                    {
                        SerialObjectsFound[si.ObjectID].ParentObjectID = parentObject.ObjectID;
                    }
                    return(si.ObjectID);
                }
            }
            else
            {
                PendingNullCounter--;
            }
            return(serialObjectReferenceID);
        }