XZHeader.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Text;
  5. using SharpCompress.IO;
  6. namespace SharpCompress.Compressors.Xz
  7. {
  8. public class XZHeader
  9. {
  10. private readonly BinaryReader _reader;
  11. private readonly byte[] MagicHeader = { 0xFD, 0x37, 0x7A, 0x58, 0x5a, 0x00 };
  12. public CheckType BlockCheckType { get; private set; }
  13. public int BlockCheckSize => ((((int)BlockCheckType) + 2) / 3) * 4;
  14. public XZHeader(BinaryReader reader)
  15. {
  16. _reader = reader;
  17. }
  18. public static XZHeader FromStream(Stream stream)
  19. {
  20. var header = new XZHeader(new BinaryReader(new NonDisposingStream(stream), Encoding.UTF8));
  21. header.Process();
  22. return header;
  23. }
  24. public void Process()
  25. {
  26. CheckMagicBytes(_reader.ReadBytes(6));
  27. ProcessStreamFlags();
  28. }
  29. private void ProcessStreamFlags()
  30. {
  31. byte[] streamFlags = _reader.ReadBytes(2);
  32. UInt32 crc = _reader.ReadLittleEndianUInt32();
  33. UInt32 calcCrc = Crc32.Compute(streamFlags);
  34. if (crc != calcCrc)
  35. throw new InvalidDataException("Stream header corrupt");
  36. BlockCheckType = (CheckType)(streamFlags[1] & 0x0F);
  37. byte futureUse = (byte)(streamFlags[1] & 0xF0);
  38. if (futureUse != 0 || streamFlags[0] != 0)
  39. throw new InvalidDataException("Unknown XZ Stream Version");
  40. }
  41. private void CheckMagicBytes(byte[] header)
  42. {
  43. if (!header.SequenceEqual(MagicHeader))
  44. throw new InvalidDataException("Invalid XZ Stream");
  45. }
  46. }
  47. }