protected override void ReadRemovedFileMarkers(MetadataBitReader data) { System.Diagnostics.Debug.Assert(mDeletionMarkers == null); System.Diagnostics.Debug.Assert(data.Count == mItemsWithoutStream); mDeletionMarkers = new List <bool>(data.Count); for (int i = 0; i < data.Count; i++) { mDeletionMarkers.Add(data.ReadBit()); } }
protected override void ReadEmptyStreamMarkers(MetadataBitReader data) { System.Diagnostics.Debug.Assert(mItemsWithoutStreamMarkers == null); System.Diagnostics.Debug.Assert(data.Count == mItemCount); mItemsWithoutStream = 0; mItemsWithoutStreamMarkers = new List <bool>(data.Count); for (int i = 0; i < data.Count; i++) { var isItemWithoutStream = data.ReadBit(); mItemsWithoutStreamMarkers.Add(isItemWithoutStream); if (isItemWithoutStream) { mItemsWithoutStream++; } } }
private ArchiveMetadata ReadArchive() { var token = ReadToken(); if (token == ArchiveMetadataToken.ArchiveProperties) { ReadArchiveProperties(); token = ReadToken(); } var streams = ImmutableArray<Stream>.Empty; if (token == ArchiveMetadataToken.AdditionalStreams) { streams = ReadPackedStreams(); token = ReadToken(); } List<long> unpackSizes; List<Checksum?> checksums; ArchiveMetadata metadata; if (token == ArchiveMetadataToken.MainStreams) { metadata = ReadMetadata(streams, true); token = ReadToken(); } else { throw new NotImplementedException(); } int? emptyStreamCount = null; if (token != ArchiveMetadataToken.End) { if (token != ArchiveMetadataToken.Files) throw new InvalidDataException(); var fileCount = ReadNumberAsInt32(); Initialize(fileCount); for (;;) { token = ReadToken(); if (token == ArchiveMetadataToken.End) break; var recordSize = (long)ReadNumber(); if (recordSize < 0) throw new InvalidDataException(); var oldOffset = GetCurrentOffset(); #region File Metadata switch (token) { case ArchiveMetadataToken.Name: using (SelectStream(streams)) { var reader = new MetadataStringReader(this, fileCount); ReadNames(reader); reader.Complete(); } break; case ArchiveMetadataToken.WinAttributes: { var vector = ReadOptionalBitVector(fileCount); using (SelectStream(streams)) { var reader = new MetadataAttributeReader(this, fileCount, vector); ReadAttributes(reader); reader.Complete(); } break; } case ArchiveMetadataToken.EmptyStream: { var emptyStreams = ReadRequiredBitVector(fileCount); emptyStreamCount = emptyStreams.CountSetBits(); var reader = new MetadataBitReader(this, emptyStreams); ReadEmptyStreamMarkers(reader); reader.Complete(); break; } case ArchiveMetadataToken.EmptyFile: { if (emptyStreamCount == null) throw new InvalidDataException(); var reader = new MetadataBitReader(this, ReadRequiredBitVector(emptyStreamCount.Value)); ReadEmptyFileMarkers(reader); reader.Complete(); break; } case ArchiveMetadataToken.Anti: { if (emptyStreamCount == null) throw new InvalidDataException(); var reader = new MetadataBitReader(this, ReadRequiredBitVector(emptyStreamCount.Value)); ReadRemovedFileMarkers(reader); reader.Complete(); break; } case ArchiveMetadataToken.StartPos: { var vector = ReadOptionalBitVector(fileCount); using (SelectStream(streams)) { var reader = new MetadataNumberReader(this, fileCount, vector); ReadOffsets(reader); reader.Complete(); } break; } case ArchiveMetadataToken.CTime: { var vector = ReadOptionalBitVector(fileCount); using (SelectStream(streams)) { var reader = new MetadataDateReader(this, fileCount, vector); ReadCTime(reader); reader.Complete(); } break; } case ArchiveMetadataToken.ATime: { var vector = ReadOptionalBitVector(fileCount); using (SelectStream(streams)) { var reader = new MetadataDateReader(this, fileCount, vector); ReadATime(reader); reader.Complete(); } break; } case ArchiveMetadataToken.MTime: { var vector = ReadOptionalBitVector(fileCount); using (SelectStream(streams)) { var reader = new MetadataDateReader(this, fileCount, vector); ReadMTime(reader); reader.Complete(); } break; } case ArchiveMetadataToken.Padding: // TODO: what does the reference implementation do here? just skip it? then we shouldn't throw an exception! for (int i = 0; i < recordSize; i++) if (ReadByte() != 0) throw new InvalidDataException(); break; default: // TODO: skip data break; } #endregion // Up until version 0.3 there was a bug which could emit invalid record sizes, but it didn't really matter. // Starting from version 0.3 there have been extensions to the file format which require correct record sizes. if (!(mMajorVersion == 0 && mMinorVersion < 3)) { var newOffset = GetCurrentOffset(); if (newOffset - oldOffset != recordSize) throw new InvalidDataException(); } } } return metadata; }
protected virtual void ReadRemovedFileMarkers(MetadataBitReader data) { }
protected virtual void ReadEmptyFileMarkers(MetadataBitReader data) { }
protected virtual void ReadEmptyStreamMarkers(MetadataBitReader data) { }