public ArchiveFileStream CreateFile(string name, bool deleteExisting = false) { if (Files.ContainsKey(name)) { if (!deleteExisting) { return(OpenFile(name, true)); } Files[name].CloseAll(); Files.Remove(name); return(OpenFile(name, true)); } var file = new ArchiveFile(this, name, 0, 0); file.MarkDirty(); Files[name] = file; return(file.Open(true)); }
internal static Dictionary <string, ArchiveFile> ReadIndex(Archive archive, BinaryReader r) { int count = (int)(archive.Header.IndexLength / EntrySize); var index = new List <ArchiveEntry>(); r.Seek(archive.Header.IndexOffset); for (int i = 0; i < count; i++) { index.Add(ReadIndexEntry(r)); } var dict = new Dictionary <string, ArchiveFile>(count, StringComparer.InvariantCultureIgnoreCase); foreach (var entry in index) { var name = r.Seek(entry.NameOffset).ReadString(entry.NameLength); var file = new ArchiveFile(archive, name, entry.DataOffset, entry.DataLength); dict[name] = file; } return(dict); }
internal ArchiveFileStream(ArchiveFile file, Stream baseStream) { File = file; BaseStream = baseStream; }
internal bool SaveFile(ArchiveFile file, MemoryStream data) { lock (_syncRoot) { var w = new BinaryWriter(Stream); switch (SaveMode) { case ArchiveSaveMode.Explicit: // mark file as dirty, but don't save to disk MarkDirty(); file.MarkDirty(); file.NewData = data.ToArray(); file.DataLength = file.NewData.Length; return(true); case ArchiveSaveMode.Flush: MarkDirty(); // if index and the old file data are in the back of the file (this file was last updated), overwrite them. // otherwise, the old file data will be kept until Flush() is called and the entire archive is written again. long newFileOffset = Stream.Length; if (Header.IndexOffset + Header.IndexLength == newFileOffset) { // Index is at the end of the file, overwrite it newFileOffset = Header.IndexOffset; } if (file.DataOffset + file.DataLength == newFileOffset) { // Old file data is at the end, overwrite it newFileOffset = file.DataOffset; } file.DataOffset = newFileOffset; file.DataLength = data.Length; // write file data Stream.SetLength(newFileOffset); Stream.Seek(newFileOffset); data.Seek(0).CopyTo(Stream); // write index Header.IndexOffset = (uint)Stream.Position; ArchiveHelpers.WriteIndex(Files, w); // update header Stream.Seek(0); ArchiveHelpers.WriteHeader(Header, w); Stream.Flush(); return(true); case ArchiveSaveMode.Immediate: MarkDirty(); Stream.Seek(0, SeekOrigin.End); // write file name file.NameOffset = (uint)Stream.Position; w.WriteNullTerminatedString(file.Name); // write file data file.DataOffset = (uint)Stream.Position; data.Seek(0).CopyTo(Stream); file.DataLength = (uint)(Stream.Position - file.DataOffset); return(true); default: return(false); } } }