コード例 #1
0
        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);
        }
コード例 #2
0
 public override ArchiveBase GetArchive(string fileName)
 {
     fileName = ArchiveMap.GetFileData(fileName).Key;
     if (string.IsNullOrWhiteSpace(fileName))
     {
         return(null);
     }
     return(GetArchive((Memory.Archive)fileName));
 }
コード例 #3
0
ファイル: Header.cs プロジェクト: hollow87/OpenVIII
            /// <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);
            }
コード例 #4
0
        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;
        }
コード例 #5
0
        /// <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;
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        /// <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);
        }