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