/* Copyright (C) 2014 Tal Aloni . All rights reserved. * * You can redistribute this program and/or modify it under the terms of * the GNU Lesser Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. */ using System; using System.Collections.Generic; using System.Text; using Utilities; namespace DiskAccessLibrary.LogicalDiskManager { // This class represents a single VBLK block (record can span multiple VBLK blocks) public class DatabaseRecordFragment { public const int HeaderLength = 16; public string Signature = "VBLK"; // VBLK public uint SequenceNumber; // each fragment have different SequenceNumber, SequenceNumber starts from 4 ( 0-3 are taken by the VMDB) public uint GroupNumber; // same for all fragments of the same record public ushort NumberInGroup; // (x of y), Zero-based public ushort FragmentCount; // Number of fragments in group public byte[] Data; public DatabaseRecordFragment() { } protected DatabaseRecordFragment(byte[] buffer) { Signature = ByteReader.ReadAnsiString(buffer, 0x00, 4); SequenceNumber = BigEndianConverter.ToUInt32(buffer, 0x04); GroupNumber = BigEndianConverter.ToUInt32(buffer, 0x08); NumberInGroup = BigEndianConverter.ToUInt16(buffer, 0x0C); FragmentCount = BigEndianConverter.ToUInt16(buffer, 0x0E); Data = new byte[buffer.Length - HeaderLength]; Array.Copy(buffer, 0x10, Data, 0, buffer.Length - HeaderLength); } public byte[] GetBytes(int blockSize) { byte[] buffer = new byte[blockSize]; ByteWriter.WriteAnsiString(buffer, 0, Signature, 4); BigEndianWriter.WriteUInt32(buffer, 0x04, SequenceNumber); BigEndianWriter.WriteUInt32(buffer, 0x08, GroupNumber); BigEndianWriter.WriteUInt16(buffer, 0x0C, NumberInGroup); BigEndianWriter.WriteUInt16(buffer, 0x0E, FragmentCount); ByteWriter.WriteBytes(buffer, 0x10, Data, Math.Min(Data.Length, blockSize - HeaderLength)); return buffer; } public static DatabaseRecordFragment GetDatabaseRecordFragment(byte[] buffer) { string signature = ByteReader.ReadAnsiString(buffer, 0x00, 4); ushort fragmentCount = BigEndianConverter.ToUInt16(buffer, 0x0E); if (fragmentCount == 0 || signature != "VBLK") { return null; } else { return new DatabaseRecordFragment(buffer); } } /// /// Free fragment from record data (the result can be used to overwrite this fragment) /// public void Clear() { this.GroupNumber = 0; this.NumberInGroup = 0; this.FragmentCount = 0; this.Data = new byte[0]; } } }