protected SNode ParseOne() { EStreamCode check; byte isshared = 0; SNode thisobj = null; SDBRow lastDbRow = null; try { byte type = Reader.ReadByte(); check = (EStreamCode)(type & 0x3f); isshared = (byte)(type & 0x40); } catch (EndOfFileException) { return(null); } #region EStreamCode Switch switch (check) { case EStreamCode.EStreamStart: break; case EStreamCode.ENone: thisobj = new SNone(); break; case EStreamCode.EString: thisobj = new SString(Reader.ReadString(Reader.ReadByte())); break; case EStreamCode.ELong: thisobj = new SLong(Reader.ReadLong()); break; case EStreamCode.EInteger: thisobj = new SInt(Reader.ReadInt()); break; case EStreamCode.EShort: thisobj = new SInt(Reader.ReadShort()); break; case EStreamCode.EByte: thisobj = new SInt(Reader.ReadByte()); break; case EStreamCode.ENeg1Integer: thisobj = new SInt(-1); break; case EStreamCode.E0Integer: thisobj = new SInt(0); break; case EStreamCode.E1Integer: thisobj = new SInt(1); break; case EStreamCode.EReal: thisobj = new SReal(Reader.ReadDouble()); break; case EStreamCode.E0Real: thisobj = new SReal(0); break; case EStreamCode.E0String: thisobj = new SString(null); break; case EStreamCode.EString3: thisobj = new SString(Reader.ReadString(1)); break; case EStreamCode.EString4: goto case EStreamCode.EString; case EStreamCode.EMarker: thisobj = new SMarker((byte)GetLength()); break; case EStreamCode.EUnicodeString: goto case EStreamCode.EString; case EStreamCode.EIdent: thisobj = new SIdent(Reader.ReadString(GetLength())); break; case EStreamCode.ETuple: { int length = GetLength(); thisobj = new STuple((uint)length); Parse(thisobj, length); break; } case EStreamCode.ETuple2: goto case EStreamCode.ETuple; case EStreamCode.EDict: { int len = (GetLength() * 2); SDict dict = new SDict((uint)len); thisobj = dict; Parse(dict, len); break; } case EStreamCode.EObject: thisobj = new SObject(); Parse(thisobj, 2); break; case EStreamCode.ESharedObj: thisobj = ShareGet(GetLength()); break; case EStreamCode.EChecksum: thisobj = new SString("checksum"); Reader.ReadInt(); break; case EStreamCode.EBoolTrue: thisobj = new SInt(1); break; case EStreamCode.EBoolFalse: thisobj = new SInt(0); break; case EStreamCode.EObject22: { SObject obj = new SObject(); thisobj = obj; Parse(thisobj, 1); string oclass = obj.Name; if (oclass == "dbutil.RowList") { SNode row; while ((row = ParseOne()) != null) { obj.AddMember(row); } } break; } case EStreamCode.EObject23: goto case EStreamCode.EObject22; case EStreamCode.E0Tuple: thisobj = new STuple(0); break; case EStreamCode.E1Tuple: thisobj = new STuple(1); Parse(thisobj, 1); break; case EStreamCode.E0Tuple2: goto case EStreamCode.E0Tuple; case EStreamCode.E1Tuple2: goto case EStreamCode.E1Tuple; case EStreamCode.EEmptyString: thisobj = new SString(string.Empty); break; case EStreamCode.EUnicodeString2: /* Single unicode character */ thisobj = new SString(Reader.ReadString(2)); break; case EStreamCode.ECompressedRow: thisobj = GetDBRow(); break; case EStreamCode.ESubstream: { int len = GetLength(); CacheFileReader readerSub = new CacheFileReader(Reader, len); SSubStream ss = new SSubStream(len); thisobj = ss; CacheFileParser sp = new CacheFileParser(readerSub); sp.Parse(); for (int i = 0; i < sp.Streams.Count; i++) { ss.AddMember(sp.Streams[i].Clone()); } Reader.Seek(readerSub.Position, SeekOrigin.Begin); break; } case EStreamCode.E2Tuple: thisobj = new STuple(2); Parse(thisobj, 2); break; case EStreamCode.EString2: goto case EStreamCode.EString; case EStreamCode.ESizedInt: switch (Reader.ReadByte()) { case 8: thisobj = new SLong(Reader.ReadLong()); break; case 4: thisobj = new SInt(Reader.ReadInt()); break; case 3: // The following seems more correct than the forumla used. // int value = (Reader.Char() << 16) + (Reader.ReadByte()); thisobj = new SInt((Reader.ReadByte()) + (Reader.ReadByte() << 16)); break; case 2: thisobj = new SInt(Reader.ReadShort()); break; } break; case (EStreamCode)0x2d: if (Reader.ReadByte() != (byte)0x2d) { throw new ParseException("Didn't encounter a double 0x2d where one was expected at " + (Reader.Position - 2)); } else if (lastDbRow != null) { lastDbRow.IsLast = true; } return(null); case 0: break; default: throw new ParseException("Can't identify type " + String.Format("{0:x2}", (int)check) + " at position " + String.Format("{0:x2}", Reader.Position) + " limit " + Reader.Length); } #endregion if (thisobj == null) { throw new ParseException("no thisobj in parseone"); } if (isshared != 0) { if (thisobj == null) { throw new ParseException("shared flag but no obj"); } ShareAdd(thisobj); } return(thisobj); }
protected SNode ParseOne() { EStreamCode check; byte isshared = 0; SNode thisobj = null; SDBRow lastDbRow = null; try { byte type = Reader.ReadByte(); check = (EStreamCode)(type & 0x3f); isshared = (byte)(type & 0x40); } catch (EndOfFileException) { return null; } #region EStreamCode Switch switch (check) { case EStreamCode.EStreamStart: break; case EStreamCode.ENone: thisobj = new SNone(); break; case EStreamCode.EString: thisobj = new SString(Reader.ReadString(Reader.ReadByte())); break; case EStreamCode.ELong: thisobj = new SLong(Reader.ReadLong()); break; case EStreamCode.EInteger: thisobj = new SInt(Reader.ReadInt()); break; case EStreamCode.EShort: thisobj = new SInt(Reader.ReadShort()); break; case EStreamCode.EByte: thisobj = new SInt(Reader.ReadByte()); break; case EStreamCode.ENeg1Integer: thisobj = new SInt(-1); break; case EStreamCode.E0Integer: thisobj = new SInt(0); break; case EStreamCode.E1Integer: thisobj = new SInt(1); break; case EStreamCode.EReal: thisobj = new SReal(Reader.ReadDouble()); break; case EStreamCode.E0Real: thisobj = new SReal(0); break; case EStreamCode.E0String: thisobj = new SString(null); break; case EStreamCode.EString3: thisobj = new SString(Reader.ReadString(1)); break; case EStreamCode.EString4: goto case EStreamCode.EString; case EStreamCode.EMarker: thisobj = new SMarker((byte)GetLength()); break; case EStreamCode.EUnicodeString: goto case EStreamCode.EString; case EStreamCode.EIdent: thisobj = new SIdent(Reader.ReadString(GetLength())); break; case EStreamCode.ETuple: { int length = GetLength(); thisobj = new STuple((uint)length); Parse(thisobj, length); break; } case EStreamCode.ETuple2: goto case EStreamCode.ETuple; case EStreamCode.EDict: { int len = (GetLength() * 2); SDict dict = new SDict((uint)len); thisobj = dict; Parse(dict, len); break; } case EStreamCode.EObject: thisobj = new SObject(); Parse(thisobj, 2); break; case EStreamCode.ESharedObj: thisobj = ShareGet(GetLength()); break; case EStreamCode.EChecksum: thisobj = new SString("checksum"); Reader.ReadInt(); break; case EStreamCode.EBoolTrue: thisobj = new SInt(1); break; case EStreamCode.EBoolFalse: thisobj = new SInt(0); break; case EStreamCode.EObject22: { SObject obj = new SObject(); thisobj = obj; Parse(thisobj, 1); string oclass = obj.Name; if (oclass == "dbutil.RowList") { SNode row; while ((row = ParseOne()) != null) obj.AddMember(row); } break; } case EStreamCode.EObject23: goto case EStreamCode.EObject22; case EStreamCode.E0Tuple: thisobj = new STuple(0); break; case EStreamCode.E1Tuple: thisobj = new STuple(1); Parse(thisobj, 1); break; case EStreamCode.E0Tuple2: goto case EStreamCode.E0Tuple; case EStreamCode.E1Tuple2: goto case EStreamCode.E1Tuple; case EStreamCode.EEmptyString: thisobj = new SString(string.Empty); break; case EStreamCode.EUnicodeString2: /* Single unicode character */ thisobj = new SString(Reader.ReadString(2)); break; case EStreamCode.ECompressedRow: thisobj = GetDBRow(); break; case EStreamCode.ESubstream: { int len = GetLength(); CacheFileReader readerSub = new CacheFileReader(Reader, len); SSubStream ss = new SSubStream(len); thisobj = ss; CacheFileParser sp = new CacheFileParser(readerSub); sp.Parse(); for (int i = 0; i < sp.Streams.Count; i++) ss.AddMember(sp.Streams[i].Clone()); Reader.Seek(readerSub.Position, SeekOrigin.Begin); break; } case EStreamCode.E2Tuple: thisobj = new STuple(2); Parse(thisobj, 2); break; case EStreamCode.EString2: goto case EStreamCode.EString; case EStreamCode.ESizedInt: switch (Reader.ReadByte()) { case 8: thisobj = new SLong(Reader.ReadLong()); break; case 4: thisobj = new SInt(Reader.ReadInt()); break; case 3: // The following seems more correct than the forumla used. // int value = (Reader.Char() << 16) + (Reader.ReadByte()); thisobj = new SInt((Reader.ReadByte()) + (Reader.ReadByte() << 16)); break; case 2: thisobj = new SInt(Reader.ReadShort()); break; } break; case (EStreamCode)0x2d: if (Reader.ReadByte() != (byte)0x2d) throw new ParseException("Didn't encounter a double 0x2d where one was expected at " + (Reader.Position - 2)); else if (lastDbRow != null) lastDbRow.IsLast = true; return null; case 0: break; default: throw new ParseException("Can't identify type " + String.Format("{0:x2}", (int)check) + " at position " + String.Format("{0:x2}", Reader.Position) + " limit " + Reader.Length); } #endregion if (thisobj == null) throw new ParseException("no thisobj in parseone"); if (isshared != 0) { if (thisobj == null) throw new ParseException("shared flag but no obj"); ShareAdd(thisobj); } return thisobj; }