BddInfo.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using System.Text;
  4. namespace DiskAccessLibrary
  5. {
  6. public class BddInfo
  7. {
  8. public const int BlockIndexEntrySize = 8;
  9. public string BasedImagePath { get; }
  10. public long Length { get; }
  11. public int BlockSize { get; }
  12. public int NumberOfBlocks { get; }
  13. public long DataOffset { get; }
  14. public long EntryTableOffset { get; }
  15. public BlockEntryAllocateFlagIndexer Allocated { get; }
  16. public BlockEntryOffsetIndexer Offset { get; set; }
  17. public IReadOnlyList<ulong> Entries { get; }
  18. public BddInfo(string snapshotImagePath, bool readEntries = true)
  19. {
  20. using var fs = new FileStream(snapshotImagePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  21. using var reader = new BinaryReader(fs);
  22. int basedPathLength = reader.ReadUInt16(); //2
  23. if (basedPathLength != 0) BasedImagePath = Encoding.UTF8.GetString(reader.ReadBytes(basedPathLength)); //N
  24. BlockSize = reader.ReadInt32(); //4
  25. NumberOfBlocks = reader.ReadInt32(); //4
  26. var snapMatchLength = NumberOfBlocks * (long)BlockSize;
  27. Length = snapMatchLength;
  28. if (false == readEntries) return;
  29. if (null != BasedImagePath)
  30. {
  31. var baseInfo = new FileInfo(BasedImagePath);
  32. if (snapMatchLength != baseInfo.Length)
  33. throw new InvalidDataException("Snapshot size no match to based image");
  34. }
  35. EntryTableOffset = fs.Position;
  36. var arr = new ulong[NumberOfBlocks];
  37. for (var i = 0; i < NumberOfBlocks; i++)
  38. {
  39. arr[i] = reader.ReadUInt64();
  40. }
  41. Entries = arr;
  42. DataOffset = fs.Position;
  43. Allocated = new BlockEntryAllocateFlagIndexer(arr);
  44. Offset = new BlockEntryOffsetIndexer(arr);
  45. }
  46. public static int CalcHeaderSize(string basedImagePath, int blockSize, out int blocks)
  47. {
  48. var baseLength = new FileInfo(basedImagePath).Length;
  49. blocks = (int)(baseLength / blockSize);
  50. return 2 + Encoding.UTF8.GetByteCount(basedImagePath) + 8 + blocks * BlockIndexEntrySize;
  51. }
  52. public static int CalcHeaderSize(long baseLength, int blockSize, out int blocks)
  53. {
  54. blocks = (int)(baseLength / blockSize);
  55. return 2 + +8 + blocks * BlockIndexEntrySize;
  56. }
  57. }
  58. }