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 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); } } }