12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using SharpCompress.IO;
- namespace SharpCompress.Compressors.Xz
- {
- [CLSCompliant(false)]
- public class XZIndex
- {
- private readonly BinaryReader _reader;
- public long StreamStartPosition { get; private set; }
- public ulong NumberOfRecords { get; private set; }
- public List<XZIndexRecord> Records { get; } = new List<XZIndexRecord>();
- private readonly bool _indexMarkerAlreadyVerified;
- public XZIndex(BinaryReader reader, bool indexMarkerAlreadyVerified)
- {
- _reader = reader;
- _indexMarkerAlreadyVerified = indexMarkerAlreadyVerified;
- StreamStartPosition = reader.BaseStream.Position;
- if (indexMarkerAlreadyVerified)
- StreamStartPosition--;
- }
- public static XZIndex FromStream(Stream stream, bool indexMarkerAlreadyVerified)
- {
- var index = new XZIndex(new BinaryReader(new NonDisposingStream(stream), Encoding.UTF8), indexMarkerAlreadyVerified);
- index.Process();
- return index;
- }
- public void Process()
- {
- if (!_indexMarkerAlreadyVerified)
- VerifyIndexMarker();
- NumberOfRecords = _reader.ReadXZInteger();
- for (ulong i = 0; i < NumberOfRecords; i++)
- {
- Records.Add(XZIndexRecord.FromBinaryReader(_reader));
- }
- SkipPadding();
- VerifyCrc32();
- }
- private void VerifyIndexMarker()
- {
- byte marker = _reader.ReadByte();
- if (marker != 0)
- throw new InvalidDataException("Not an index block");
- }
- private void SkipPadding()
- {
- int bytes = (int)(_reader.BaseStream.Position - StreamStartPosition) % 4;
- if (bytes > 0)
- {
- byte[] paddingBytes = _reader.ReadBytes(4 - bytes);
- if (paddingBytes.Any(b => b != 0))
- throw new InvalidDataException("Padding bytes were non-null");
- }
- }
- private void VerifyCrc32()
- {
- uint crc = _reader.ReadLittleEndianUInt32();
- // TODO verify this matches
- }
- }
- }
|