internal static DBDirectoryEntry ReadFrom(BinaryReader reader, DBEntryAttributes attributes, StringBuilder stringBuilder) { var entry = new DBDirectoryEntry { Attributes = attributes, DataLength = reader.ReadUInt32(), DirectoryNameLength = reader.ReadByte(), DirectoryName = reader.ReadNullTerminatedUtf16String(stringBuilder), ModificationTime = (DBDWord)reader.ReadUInt32(), CreationTime = (DBDWord)reader.ReadUInt32(), LastAccessedDate = (DBDWord)reader.ReadUInt32(), }; return(entry); }
internal static DBFileEntry ReadFrom(BinaryReader reader, DBEntryAttributes attributes, StringBuilder stringBuilder) { var entry = new DBFileEntry { Attributes = attributes, FileNameLength = reader.ReadByte(), FileExtensionIndex = reader.ReadByte(), FileName = reader.ReadNullTerminatedUtf16String(stringBuilder), }; var fileSizeLo = reader.ReadUInt32(); var fileSizeHi = (ulong)reader.ReadUInt16(); entry.FileSize = fileSizeHi << 32 | fileSizeLo; entry.ModificationTime = (DBDWord)reader.ReadUInt32(); entry.CreationTime = (DBDWord)reader.ReadUInt32(); entry.LastAccessedDate = (DBDWord)reader.ReadUInt32(); return(entry); }
/// <summary> /// Read the next entry. /// </summary> /// <returns>The read DBEntry if any; null otherwise.</returns> public DBEntry Read() { switch (state) { case ReaderState.EndOfFile: { return(null); } case ReaderState.ReadHeaderNext: { LastReadEntry = Header = DBHeader.ReadFrom(binaryReader, strBuilder); state = ReaderState.ReadRootDirectoryNext; return(LastReadEntry); } case ReaderState.ReadRootDirectoryNext: { positionBeforeReadRootDirectory = inputStream.Position; LastReadEntry = currentRootDirectory = DBRootDirectoryEntry.ReadFrom(binaryReader, strBuilder); if (currentRootDirectory == null) { state = ReaderState.EndOfFile; return(null); } currentPathStack.Push(currentPath = currentRootDirectory.Path); currentRootDirectory.FullName = currentPath; state = ReaderState.ReadFileOrDirectoryNext; return(LastReadEntry); } case ReaderState.ReadFileOrDirectoryNext: { typeAndAttributes = (DBEntryAttributes)binaryReader.ReadByte(); if (typeAndAttributes != 0 || depth > 0) { if (typeAndAttributes.HasFlag(DBEntryAttributes.Directory)) { positionBeforeReadDirectory = inputStream.Position; var directoryEntry = DBDirectoryEntry.ReadFrom(binaryReader, typeAndAttributes, strBuilder); currentPath += (depth == 0 ? string.Empty : @"\") + directoryEntry.DirectoryName; directoryEntry.ParentDirectory = depth == 0 ? null : dirStack.Peek(); directoryEntry.RootDirectory = currentRootDirectory; directoryEntry.FullName = currentPath; depth++; dirStack.Push(directoryEntry); return(LastReadEntry = directoryEntry); } if (typeAndAttributes != 0) { var fileEntry = DBFileEntry.ReadFrom(binaryReader, typeAndAttributes, strBuilder); fileEntry.ParentDirectory = depth == 0 ? null : dirStack.Peek(); fileEntry.RootDirectory = currentRootDirectory; fileEntry.FullName = currentPath + (depth == 0 ? string.Empty : @"\") + fileEntry.FileName; return(LastReadEntry = fileEntry); } depth--; var poppedDir = dirStack.Pop(); currentPath = poppedDir.ParentDirectory?.FullName ?? poppedDir.RootDirectory?.FullName ?? string.Empty; return(Read()); } var nullByte = binaryReader.ReadByte(); // normally its a dword byte but we should already have read a zero byte before if (nullByte != 0) { throw new ArchiveException($"Was expecting to read a final null-byte, read {nullByte} instead."); } currentPathStack.Pop(); state = ReaderState.ReadRootDirectoryNext; return(Read()); } } LastReadEntry = null; return(null); }