internal CellEventArgs(UInt64 cellNumber, CellHeader cellHeader) { this.CellNumber = cellNumber; this.CellHeader = cellHeader; }
public void ParsePage(UInt64 pageNumber) { this._pageReader.LoadPage(pageNumber); if (1 == pageNumber) { this._pageReader.Position = 100; } var pageType = (PageType)this._pageReader.Read8(); if (PageType.Unused == pageType) { return; } var pageHeader = new PageHeader(); pageHeader.PageType = pageType; pageHeader.FirstFreeblockOffset = this._pageReader.Read16(); pageHeader.CellCount = this._pageReader.Read16(); pageHeader.CellContentAreaOffset = this._pageReader.Read16(); pageHeader.FragmentedFreeBytesCount = this._pageReader.Read8(); if ((PageType.IndexInterior == pageType) || (PageType.TableInterior == pageType)) { pageHeader.RightMostPointer = this._pageReader.Read32(); } var pageEventArgs = new PageEventArgs(pageNumber, pageHeader); this.PageStarted?.Invoke(this, pageEventArgs); var cellPointerArrayOffset = this._pageReader.Position; for (var cellNumber = 0UL; cellNumber < pageHeader.CellCount; cellNumber++) { var cellHeader = new CellHeader(); cellHeader.PageType = pageType; this._pageReader.Position = cellPointerArrayOffset; cellPointerArrayOffset += 2; var cellOffset = this._pageReader.Read16(); this._pageReader.Position = cellOffset; if (PageType.IndexInterior == pageType) { cellHeader.LeftChildPage = this._pageReader.Read32(); cellHeader.PayloadSize = this._pageReader.Decode64(); } else if (PageType.TableInterior == pageType) { cellHeader.LeftChildPage = this._pageReader.Read32(); cellHeader.Rowid = this._pageReader.Decode64(); } else if (PageType.IndexLeaf == pageType) { cellHeader.PayloadSize = this._pageReader.Decode64(); } else if (PageType.TableLeaf == pageType) { cellHeader.PayloadSize = this._pageReader.Decode64(); cellHeader.Rowid = this._pageReader.Decode64(); } else { // TODO } this.CellStarted?.Invoke(this, new CellEventArgs(cellNumber, cellHeader)); if ((PageType.IndexInterior == pageType) || (PageType.IndexLeaf == pageType) || (PageType.TableLeaf == pageType)) { this.ParsePayload(pageNumber, cellNumber, cellHeader); } this.CellFinished?.Invoke(this, new CellEventArgs(cellNumber, cellHeader)); } this.PageFinished?.Invoke(this, pageEventArgs); }
internal PayloadEventArgs(UInt64 cellNumber, CellHeader cellHeader, Field[] fields) { this.CellNumber = cellNumber; this.CellHeader = cellHeader; this.Fields = fields; }
private void ParsePayload(UInt64 pageNumber, UInt64 cellNumber, CellHeader cellHeader) { // create header reader var payloadPosition = this._pageReader.Position; var headerReader = new PayloadReader(this._pageLoader, pageNumber, payloadPosition, 0, cellHeader.PayloadSize); // read header size var headerSize = headerReader.Decode64(); // create body reader var dataReader = new PayloadReader(this._pageLoader, pageNumber, payloadPosition, headerSize, cellHeader.PayloadSize); var bodyPosition = payloadPosition + headerSize; // header size includes header size field itself var fieldNumber = 0UL; var fields = new List <Field>(); // read fields while (headerReader.Position < bodyPosition) { var serialTypeValue = headerReader.Decode64(); var serialType = (FieldType)serialTypeValue; switch (serialType) { case FieldType.Null: InvokeFieldReadEvent(null); break; case FieldType.Integer8: InvokeFieldReadEvent(dataReader.Read8()); break; case FieldType.Integer16: InvokeFieldReadEvent((UInt16)dataReader.Read16()); break; case FieldType.Integer24: InvokeFieldReadEvent((UInt32)dataReader.Read24()); break; case FieldType.Integer32: InvokeFieldReadEvent((UInt32)dataReader.Read32()); break; case FieldType.Integer48: InvokeFieldReadEvent((UInt64)dataReader.Read48()); break; case FieldType.Integer64: InvokeFieldReadEvent((UInt64)dataReader.Read64()); break; case FieldType.Float64: var integer = dataReader.Read64(); InvokeFieldReadEvent(integer.ToDouble()); break; case FieldType.Zero: InvokeFieldReadEvent(0); break; case FieldType.One: InvokeFieldReadEvent(1); break; case FieldType.Internal1: InvokeFieldReadEvent(null); break; case FieldType.Internal2: InvokeFieldReadEvent(null); break; default: if ((serialTypeValue >= 13) && (1 == (serialTypeValue % 2))) // string { var length = (serialTypeValue - 13) / 2; var str = dataReader.ReadString(length); InvokeFieldReadEvent2(FieldType.String, str); } else if ((serialTypeValue >= 12) && (0 == (serialTypeValue % 2))) // blob { var length = (serialTypeValue - 13) / 2; if (this.ReportBlobSizesOnly) { dataReader.Skip(length); InvokeFieldReadEvent2(FieldType.Blob, length); } else { var blob = dataReader.ReadBlob(length); InvokeFieldReadEvent2(FieldType.Blob, blob); } } else // unknown type { InvokeFieldReadEvent(null); } break; } void InvokeFieldReadEvent(Object value) { InvokeFieldReadEvent2(serialType, value); } void InvokeFieldReadEvent2(FieldType serialType2, Object value2) { fields.Add(new Field(serialType2, value2)); this.FieldRead?.Invoke(this, new FieldEventArgs(fieldNumber, serialType2, value2)); fieldNumber++; } } this.PayloadRead?.Invoke(this, new PayloadEventArgs(cellNumber, cellHeader, fields.ToArray())); }