protected override void ReadNames(MetadataStringReader data) { System.Diagnostics.Debug.Assert(mFileNames == null); System.Diagnostics.Debug.Assert(data.Count == mItemCount); mFileNames = new List <string>(data.Count); for (int i = 0; i < data.Count; i++) { mFileNames.Add(data.ReadString()); } }
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 ReadNames(MetadataStringReader data) { }