public Result Read(out long entriesRead, Span <DirectoryEntry> entryBuffer) { if (!Mode.HasFlag(OpenDirectoryMode.File)) { entriesRead = 0; return(Result.Success); } int entriesRemaining = ParentFileSystem.Files.Length - CurrentIndex; int toRead = Math.Min(entriesRemaining, entryBuffer.Length); for (int i = 0; i < toRead; i++) { PartitionFileEntry fileEntry = ParentFileSystem.Files[CurrentIndex]; ref DirectoryEntry entry = ref entryBuffer[i]; Span <byte> nameUtf8 = Encoding.UTF8.GetBytes(fileEntry.Name); entry.Type = DirectoryEntryType.File; entry.Size = fileEntry.Size; StringUtils.Copy(entry.Name, nameUtf8); entry.Name[PathTools.MaxPathLength] = 0; CurrentIndex++; }
private byte[] BuildMetaData(PartitionFileSystemType type) { if (type == PartitionFileSystemType.Hashed) { CalculateHashes(); } int entryTableSize = Entries.Count * PartitionFileEntry.GetEntrySize(type); int stringTableSize = CalcStringTableSize(HeaderSize + entryTableSize, type); int metaDataSize = HeaderSize + entryTableSize + stringTableSize; var metaData = new byte[metaDataSize]; var writer = new BinaryWriter(new MemoryStream(metaData)); writer.WriteUTF8(GetMagicValue(type)); writer.Write(Entries.Count); writer.Write(stringTableSize); writer.Write(0); int stringOffset = 0; foreach (Entry entry in Entries) { writer.Write(entry.Offset); writer.Write(entry.Length); writer.Write(stringOffset); if (type == PartitionFileSystemType.Standard) { writer.Write(0); } else { writer.Write(entry.HashLength); writer.Write(entry.HashOffset); writer.Write(entry.Hash); } stringOffset += entry.NameLength + 1; } foreach (Entry entry in Entries) { writer.WriteUTF8Z(entry.Name); } return(metaData); }
public PartitionFileSystemHeader(BinaryReader reader) { Magic = reader.ReadAscii(4); NumFiles = reader.ReadInt32(); StringTableSize = reader.ReadInt32(); Reserved = reader.ReadInt32(); switch (Magic) { case "PFS0": Type = PartitionFileSystemType.Standard; break; case "HFS0": Type = PartitionFileSystemType.Hashed; break; default: ThrowHelper.ThrowResult(ResultFs.InvalidPartitionFileSystemMagic, $"Invalid Partition FS type \"{Magic}\""); break; } int entrySize = PartitionFileEntry.GetEntrySize(Type); int stringTableOffset = 16 + entrySize * NumFiles; HeaderSize = stringTableOffset + StringTableSize; Files = new PartitionFileEntry[NumFiles]; for (int i = 0; i < NumFiles; i++) { Files[i] = new PartitionFileEntry(reader, Type) { Index = i }; } for (int i = 0; i < NumFiles; i++) { reader.BaseStream.Position = stringTableOffset + Files[i].StringTableOffset; Files[i].Name = reader.ReadAsciiZ(); } }
public IFile OpenFile(PartitionFileEntry entry, OpenMode mode) { return(new PartitionFile(BaseStorage, HeaderSize + entry.Offset, entry.Size, mode)); }