internal static short LoadNumberOfColumns(CompressedDataRecord record)
        {
            short columns;

            if ((record.Page.PageData[record.SlotOffset + 1] & 0x80) == 0x80)
            {
                // Check if the first bit is high, if it is it indicates 2-byte int
                record.ColumnCountBytes = 2;

                var noOfColumnsData = new byte[2];

                Array.Copy(record.Page.PageData, record.SlotOffset + 1, noOfColumnsData, 0, 2);

                noOfColumnsData[0] = Convert.ToByte(noOfColumnsData[0] ^ 0x80);

                Array.Reverse(noOfColumnsData);

                columns = BitConverter.ToInt16(noOfColumnsData, 0);
            }
            else
            {
                record.ColumnCountBytes = 1;

                columns = record.Page.PageData[record.SlotOffset + 1];
            }

            // 1/2 byte int located after the status bits (1 byte)
            record.Mark("ColumnCount", record.SlotOffset + sizeof(byte), record.ColumnCountBytes);

            return(columns);
        }
        internal static void LoadStatus(CompressedDataRecord record)
        {
            record.StatusBitsA = new BitArray(new byte[] { record.Page.PageData[record.SlotOffset] });

            record.RecordType = (RecordType)((record.Page.PageData[record.SlotOffset] >> 1) & 7);

            record.HasVariableLengthColumns = record.StatusBitsA[5];
            record.HasNullBitmap            = record.StatusBitsA[4];

            record.Mark("StatusBitsADescription", record.SlotOffset, sizeof(byte));
        }
        public static void Load(CompressedDataRecord record)
        {
            record.ColumnCount = LoadNumberOfColumns(record);

            LoadStatus(record);

            if (record.RecordType == RecordType.Forwarding)
            {
                LoadForwardingRecord(record);
                return;
            }

            var cdArraySize = (int)(record.ColumnCount / 2 + record.ColumnCount % 2);

            LoadCdArray(record);

            record.CompressedSize = 0;

            for (var i = 0; i < record.ColumnCount; i++)
            {
                record.CompressedSize += Convert.ToInt16(GetCdArrayItemSize(record.GetCdByte(i)));
            }

            if (record.HasVariableLengthColumns)
            {
                //record.Unknown = record.Page.PageData[record.SlotOffset + 1 + record.ColumnCountBytes + cdArraySize + record.CompressedSize];

                var varLengthColumnCountOffset = record.SlotOffset + 2 + record.ColumnCountBytes + cdArraySize + record.CompressedSize;

                record.VariableLengthColumnCount = BitConverter.ToUInt16(record.Page.PageData, varLengthColumnCountOffset);

                record.Mark("VariableLengthColumnCount", varLengthColumnCountOffset, sizeof(short));
            }

            LoadShortFields(record);

            if (record.VariableLengthColumnCount > 0 && record.HasVariableLengthColumns)
            {
                var colArrayOffset = record.SlotOffset + (5 + cdArraySize) + record.CompressedSize;

                record.ColOffsetArray = GetOffsetArray(record.Page.PageData,
                                                       record.VariableLengthColumnCount,
                                                       colArrayOffset);

                record.Mark("ColOffsetArrayDescription", colArrayOffset, record.VariableLengthColumnCount * sizeof(short));
            }

            var longStartPos = record.SlotOffset + 4 + record.ColumnCountBytes + cdArraySize + record.CompressedSize + (2 * record.VariableLengthColumnCount);

            LoadLongFields(longStartPos, record);
        }
        public static void LoadLongFields(int startPos, CompressedDataRecord record)
        {
            var  longColIndex = 0;
            bool isLob;
            var  prevLength = 0;

            for (var i = 0; i < record.ColumnCount; i++)
            {
                if (record.GetCdByte(i) == 10)
                {
                    var field = new CompressedRecordField(record.Structure.Columns[i], record);

                    field.Length = DecodeOffset(record.ColOffsetArray[longColIndex]) - prevLength;
                    field.Data   = new byte[field.Length];
                    field.Offset = startPos + prevLength;

                    isLob = (record.ColOffsetArray[longColIndex] & 0x8000) == 0x8000;

                    Array.Copy(record.Page.PageData, field.Offset, field.Data, 0, field.Length);

                    if (record.Page.CompressionInformation != null && record.Page.CompressionInformation.AnchorRecord != null)
                    {
                        field.AnchorField = record.Page.CompressionInformation.AnchorRecord.Fields.Find(
                            delegate(RecordField f)
                        {
                            return(f.Column.ColumnId == i);
                        });
                    }

                    record.Fields.Add(field);

                    if (isLob)
                    {
                        LoadLobField(field, field.Data, field.Offset);
                    }
                    else
                    {
                        field.Mark("Value", field.Offset, field.Length);
                    }

                    record.Mark("FieldsArray", field.Name, record.Fields.Count - 1);

                    prevLength = DecodeOffset(record.ColOffsetArray[longColIndex]);

                    longColIndex++;
                }
            }
        }
        /// <summary>
        /// Loads the CD (column descriptor) Array.
        /// </summary>
        /// <param name="record">The record.</param>
        private static void LoadCdArray(CompressedDataRecord record)
        {
            var bytePos = 1 + record.ColumnCountBytes;

            for (var i = 0; i < Math.Ceiling(record.ColumnCount / 2D); i++)
            {
                record.Mark("CdItemsArray", "CD Array offset " + i, i);

                var cdItem = Convert.ToByte(record.Page.PageData[record.SlotOffset + bytePos]);

                var item = new CdArrayItem(i, cdItem);

                item.Mark("Description", record.SlotOffset + bytePos, sizeof(byte));

                record.CdItems.Add(item);

                bytePos++;
            }
        }
 private static void LoadForwardingRecord(CompressedDataRecord record)
 {
     throw new NotImplementedException();
 }
        public static void LoadShortFields(CompressedDataRecord record, bool hasDownPagePointer)
        {
            int offset;

            var index = 0;

            offset = record.SlotOffset + 1 + record.ColumnCountBytes + (record.ColumnCount / 2) + (record.ColumnCount % 2);

            for (var i = 0; i < record.ColumnCount; i++)
            {
                if (record.GetCdByte(i) != 10)
                {
                    CompressedRecordField field;

                    field            = new CompressedRecordField(record.Structure.Columns[i], record);
                    field.Compressed = true;

                    if (field.Column.DataType == SqlDbType.Bit)
                    {
                        field.Length     = 1;
                        field.Compressed = true;
                        field.Data       = new byte[] { record.GetCdByte(i) };
                    }
                    else
                    {
                        var size = GetCdArrayItemSize(record.GetCdByte(i));

                        field.IsNull = (record.GetCdByte(i) == 0);
                        field.Length = size;

                        field.PageSymbol = (record.GetCdByte(i) > 10);

                        if (size > 0)
                        {
                            field.Data = new byte[size];
                            Array.Copy(record.Page.PageData, offset, field.Data, 0, size);

                            field.Offset = offset;
                            offset      += size;
                        }
                    }

                    if (record.Page.CompressionInformation != null && record.Page.CompressionInformation.AnchorRecord != null)
                    {
                        field.AnchorField = record.Page.CompressionInformation.AnchorRecord.Fields.Find(
                            delegate(RecordField f)
                        {
                            return(f.Column.ColumnId == i + 1);
                        });
                    }

                    field.Mark("Value", field.Offset, field.Length);

                    record.Mark("FieldsArray", field.Name, index);

                    index++;

                    record.Fields.Add(field);
                }
            }
        }
 public static void LoadShortFields(CompressedDataRecord record)
 {
     LoadShortFields(record, false);
 }
예제 #9
0
        /// <summary>
        /// Loads a record
        /// </summary>
        /// <param name="offset">The offset.</param>
        private void LoadRecord(ushort offset)
        {
            Record record = null;

            switch (Page.Header.PageType)
            {
            case PageType.Data:

                Structure tableStructure = new TableStructure(Page.Header.AllocationUnitId, Page.Database);

                if (Page.CompressionType == CompressionType.None)
                {
                    record = new DataRecord(Page, offset, tableStructure);
                }
                else
                {
                    record = new CompressedDataRecord(Page, offset, tableStructure);
                }

                allocationViewer.Visible = false;
                markerKeyTable.Visible   = true;
                break;

            case PageType.Index:

                Structure indexStructure = new IndexStructure(Page.Header.AllocationUnitId, Page.Database);

                record = new IndexRecord(Page, offset, indexStructure);

                allocationViewer.Visible = false;
                markerKeyTable.Visible   = true;
                break;

            case PageType.Iam:
            case PageType.Gam:
            case PageType.Sgam:
            case PageType.Bcm:
            case PageType.Dcm:

                allocationViewer.SetAllocationPage(Page.Header.PageAddress,
                                                   Page.Database.Name,
                                                   ConnectionString,
                                                   (Page.Header.PageType == PageType.Iam));

                markerKeyTable.Visible   = false;
                allocationViewer.Visible = true;
                break;

            case PageType.Pfs:

                allocationViewer.SetPfsPage(Page.Header.PageAddress,
                                            Page.Database.Name,
                                            ConnectionString);

                markerKeyTable.Visible   = false;
                allocationViewer.Visible = true;
                break;

            case PageType.Lob3:
            case PageType.Lob4:

                record = new BlobRecord(Page, offset);

                allocationViewer.Visible = false;
                markerKeyTable.Visible   = true;
                break;
            }

            if (record != null)
            {
                var markers = MarkerBuilder.BuildMarkers((Markable)record);

                hexViewer.AddMarkers(markers);

                markerKeyTable.SetMarkers(markers);

                hexViewer.ScrollToOffset(offset);

                offsetTableToolStripTextBox.Text = string.Format("{0:0000}", offset);
            }
        }