public override byte[] GetBinaryFile(string fileName, bool cache = false) { if (ArchiveMap != null) { lock (BinaryFileLock) { FI fi = ArchiveMap.FindString(ref fileName, out int size); if (!string.IsNullOrWhiteSpace(fileName)) { if (LocalTryGetValue(fileName, out BufferWithAge value)) { Memory.Log.WriteLine($"{nameof(ArchiveZzz)}::{nameof(GetBinaryFile)}::{nameof(CacheTryGetValue)} read from cache {fileName}"); return(value); } else { Stream s; if ((s = OpenStream()) != null) { byte[] buffer = ArchiveMap.GetBinaryFile(fi, s, fileName, size); if (buffer != null && cache && LocalTryAdd(fileName, buffer)) { Memory.Log.WriteLine($"{nameof(ArchiveZzz)}::{nameof(GetBinaryFile)}::{nameof(LocalTryAdd)} caching {fileName}"); } return(buffer); } } } } } Memory.Log.WriteLine($"{nameof(ArchiveZzz)}::{nameof(GetBinaryFile)} FAILED extracting {fileName}"); return(null); }
public override ArchiveBase GetArchive(string fileName) { fileName = ArchiveMap.GetFileData(fileName).Key; if (string.IsNullOrWhiteSpace(fileName)) { return(null); } return(GetArchive((Memory.Archive)fileName)); }
/// <summary> /// Convert ZZZ header to an Archive Map. /// </summary> /// <param name="br">Binary Reader containing raw data</param> /// <returns>ArchiveMap</returns> public static ArchiveMap Load(BinaryReader br) { int capacity = br.ReadInt32(); ArchiveMap r = new ArchiveMap(capacity); for (int i = 0; i < capacity; i++) { r.Add(FileData.Load(br)); } return(r); }
private ArchiveWorker(Memory.Archive archive, StreamWithRangeValues fI, ArchiveBase fS, StreamWithRangeValues fL, bool skipList = false) { ArchiveMap = new ArchiveMap(fI, fL, fS.GetMaxSize(archive)); Archive = archive; FsArchive = fS; //FS = null; if (!skipList) { GetListOfFiles(); } IsOpen = true; }
/// <summary> /// Saves the active archive and file list. /// </summary> /// <param name="archive">Memory.Archive</param> /// <param name="skipList">If list generation is unneeded you can skip it by setting true</param> private ArchiveWorker(Memory.Archive archive, bool skipList = false) { if (archive.IsDir) { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}:: opening directory: {archive}"); IsDir = true; } else { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}:: opening archiveFile: {archive}"); } Archive = archive; ParentPath = FindParentPath(archive); ArchiveBase tempArchive = null; if (ParentPath != null && ParentPath.Count > 0) { foreach (var p in ParentPath) { if (tempArchive != null) { tempArchive = tempArchive.GetArchive(p); } else if (p.IsDir || p.IsFile) { tempArchive = ArchiveBase.Load(p); } } } if (tempArchive != null) { tempArchive.GetArchive(archive, out var fi, out FsArchive, out var fl); ArchiveMap = new ArchiveMap(fi, fl, tempArchive.GetMaxSize(archive)); } if (!skipList) { GetListOfFiles(); } IsOpen = true; }
private StreamWithRangeValues GetStreamWithRangeValues(string fileName, FI inputFi, int size) { void msg() => Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetStreamWithRangeValues)} stream: {fileName}"); if (inputFi != null) { } if (Archive == null) { return(null); } if (string.IsNullOrWhiteSpace(fileName)) { throw new FileNotFoundException("NO FILENAME"); } if (IsDir) { FindFile(ref fileName); msg(); var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); if (inputFi == null) { return(new StreamWithRangeValues(fs, 0, fs.Length)); } return(new StreamWithRangeValues(fs, inputFi.Offset, size, inputFi.CompressionType, inputFi.UncompressedSize)); } Debug.Assert(inputFi == null); var parentFs = Archive.FS; if (ArchiveMap != null && ArchiveMap.Count > 1) { var fi = ArchiveMap.FindString(ref fileName, out size); msg(); if (FsArchive == null) { return(null); } if (fi == null) { return(FsArchive.GetStreamWithRangeValues(fileName)); } var parentFi = FsArchive.ArchiveMap?.FindString(ref parentFs, out var _); return(parentFi == null || parentFi.CompressionType == 0 || (FsArchive is ArchiveZzz) ? new StreamWithRangeValues(FsArchive.GetStreamWithRangeValues(parentFs), fi.Offset, size, fi.CompressionType, fi.UncompressedSize) : new StreamWithRangeValues(new MemoryStream(FsArchive.GetBinaryFile(parentFs, true), false), fi.Offset, size, fi.CompressionType, fi.UncompressedSize)); } var loc = -1; if (File.Exists(Archive.FL)) { using (var fs = new FileStream(Archive.FL, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) loc = FindFile(ref fileName, fs); //File.OpenRead(archive.FL)); } msg(); // read file list if (loc == -1) { Debug.WriteLine($"ArchiveWorker: NO SUCH FILE! :: {Archive.FL}"); //throw new Exception("ArchiveWorker: No such file!"); } else { var fi = GetFi(loc); GetCompressedData(fi, out size, true); return(new StreamWithRangeValues(new FileStream(parentFs, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), fi.Offset, size, fi.CompressionType, fi.UncompressedSize)); } Debug.WriteLine($"ArchiveWorker: NO SUCH FILE! :: Searched {Archive} and could not find {fileName}"); return(null); }
private byte[] GetBinaryFile(string fileName, int loc, bool cache) { fileName = FileList.FirstOrDefault(x => x.IndexOf(fileName, StringComparison.OrdinalIgnoreCase) >= 0); if (LocalTryGetValue(fileName, out var b)) { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} :: read from cache: {fileName}"); return(b); } if (IsDir) { if (FileList == null || FileList.Length == 0) { ProduceFileLists(); } if (!string.IsNullOrWhiteSpace(fileName)) { using (var br = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} :: reading: {fileName}"); var buffer = br.ReadBytes(checked ((int)br.BaseStream.Length)); if (cache && LocalTryAdd(fileName, buffer)) { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} :: cached: {fileName}"); } return(buffer); } } } //read index data var fi = GetFi(loc); //read binary data. var temp = GetCompressedData(fi, out var _); Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} :: extracting: {fileName}"); if (temp != null) { switch (fi.CompressionType) { case CompressionType.None: break; case CompressionType.LZSS: LZSS.DecompressAllNew(temp, fi.UncompressedSize); break; case CompressionType.LZ4: temp = ArchiveMap.Lz4Uncompress(temp, fi.UncompressedSize); break; case CompressionType.LZSS_UnknownSize: LZSS.DecompressAllNew(temp, 0); break; case CompressionType.LZSS_LZSS: LZSS.DecompressAllNew(LZSS.DecompressAllNew(temp, fi.UncompressedSize), 0); break; default: throw new ArgumentOutOfRangeException(); } } if (temp != null && cache && LocalTryAdd(fileName, temp)) { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} :: cached: {fileName}"); } return(temp); }
/// <summary> /// Get binary data /// </summary> /// <param name="fileName">filename you want</param> /// <param name="cache">if true store the data for later</param> /// <returns></returns> public override byte[] GetBinaryFile(string fileName, bool cache = false) { if (string.IsNullOrWhiteSpace(fileName)) { throw new FileNotFoundException("NO FILENAME"); } byte[] FileInTwoArchives() { //if (FS != null && FS.Length > 0) // return ArchiveMap.GetBinaryFile(filename, new MemoryStream(FS)); //else return(FsArchive != null?ArchiveMap.GetBinaryFile(fileName, FsArchive.GetStreamWithRangeValues(Archive.FS)) : null); } if (ArchiveMap != null && ArchiveMap.Count > 0) { if (!cache) { return(FileInTwoArchives()); } var fileNameBackup = fileName; GetListOfFiles(); fileName = FileList.OrderBy(x => fileName.Length).ThenBy(x => fileNameBackup, StringComparer.OrdinalIgnoreCase).FirstOrDefault(x => x.IndexOf(fileNameBackup, StringComparison.OrdinalIgnoreCase) >= 0); if (string.IsNullOrWhiteSpace(fileName)) { throw new NullReferenceException($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} fileName ({fileNameBackup}) not found!"); } if (!LocalTryGetValue(fileName, out var value)) { var buffer = FileInTwoArchives(); if (LocalTryAdd(fileName, buffer)) { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)}::{nameof(LocalTryAdd)} cached {fileName}"); } return(buffer); } Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)}::{nameof(LocalTryGetValue)} read from cache {fileName}"); return(value); } if (!IsDir) { var loc = -1; if (File.Exists(Archive.FL)) { using (var fs = new FileStream(Archive.FL, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) loc = FindFile(ref fileName, fs); //File.OpenRead(archive.FL)); } // read file list if (loc == -1) { Debug.WriteLine($"ArchiveWorker: NO SUCH FILE! :: {Archive.FL}"); //throw new Exception("ArchiveWorker: No such file!"); } else { return(GetBinaryFile(fileName, loc, cache)); } } else { return(GetBinaryFile(fileName, 0, cache)); } Debug.WriteLine($"ArchiveWorker: NO SUCH FILE! :: Searched {Archive} and could not find {fileName}"); return(null); }