コード例 #1
0
ファイル: HawkFile.cs プロジェクト: xHailFirex/BizHawk
        /// <summary>Makes a new HawkFile based on the provided path.</summary>
        /// <param name="delayIOAndDearchive">Pass <see langword="true"/> to only populate a few fields (those that can be computed from the string <paramref name="path"/>), which is less computationally expensive.</param>
        /// <param name="nonArchiveExtensions">
        /// These file extensions are assumed to not be archives. Include the leading period in each, and use lowercase.<br/>
        /// Does not apply when <paramref name="delayIOAndDearchive"/> is <see langword="true"/>.<br/>
        /// If <see langword="null"/> is passed (the default), uses <see cref="CommonNonArchiveExtensions"/> which should mitigate false positives caused by weak archive detection signatures.
        /// </param>
        public HawkFile([HawkFilePath] string path, bool delayIOAndDearchive = false, IReadOnlyCollection <string>?nonArchiveExtensions = null)
        {
            if (delayIOAndDearchive)
            {
                var split = SplitArchiveMemberPath(path);
                if (split != null)
                {
                    (path, ArchiveMemberPath) = split.Value;
                    IsArchive = true;                     // we'll assume that the '|' is only used for archives
                }
                FullPathWithoutMember = path;
                return;
            }

            string?autobind = null;
            var    split1   = SplitArchiveMemberPath(path);

            if (split1 != null)
            {
                (path, autobind) = split1.Value;
            }
            FullPathWithoutMember = path;
            Exists = _rootExists = !string.IsNullOrEmpty(path) && new FileInfo(path).Exists;
            if (!_rootExists)
            {
                return;
            }

            if (DearchivalMethod != null &&
                !(nonArchiveExtensions ?? CommonNonArchiveExtensions).Contains(Path.GetExtension(path).ToLowerInvariant()) &&
                DearchivalMethod.CheckSignature(path, out _, out _))
            {
                _extractor = DearchivalMethod.Construct(path);
                try
                {
                    _archiveItems = _extractor.Scan();
                    IsArchive     = true;
                }
                catch
                {
                    _archiveItems = null;
                    _extractor.Dispose();
                    _extractor = null;
                }
            }
            if (_extractor == null)
            {
                _rootStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
                // we could autobind here, but i don't want to
                // bind it later with the desired extensions.
            }

            if (autobind == null)
            {
                // non-archive files can be automatically bound this way
                BindRoot();
            }
            else
            {
                if (_extractor != null)
                {
                    var scanResults = _extractor.Scan();
                    for (int i = 0, l = scanResults.Count; i < l; i++)
                    {
                        if (string.Equals(scanResults[i].Name, autobind, StringComparison.InvariantCultureIgnoreCase))
                        {
                            BindArchiveMember(i);
                            return;
                        }
                    }
                }

                Exists = false;
            }
        }
コード例 #2
0
ファイル: HawkFile.cs プロジェクト: KuSunda/BizHawk
        /// <summary>Opens the file at <paramref name="path"/>. This may take a while if the file is an archive, as it may be accessed and scanned.</summary>
        /// <exception cref="InvalidOperationException">already opened via <see cref="HawkFile(string)"/>, this method, or <see cref="Parse"/></exception>
        public void Open([HawkFilePath] string path)
        {
            if (FullPathWithoutMember != null)
            {
                throw new InvalidOperationException($"Don't reopen a {nameof(HawkFile)}.");
            }

            string?autobind = null;
            var    split    = SplitArchiveMemberPath(path);

            if (split != null)
            {
                (path, autobind) = split.Value;
            }
            _rootExists = new FileInfo(path).Exists;
            if (!_rootExists)
            {
                return;
            }
            FullPathWithoutMember = path;
            Exists = true;

            if (DearchivalMethod != null &&
                !NonArchiveExtensions.Contains(Path.GetExtension(path).ToLowerInvariant()) &&
                DearchivalMethod.CheckSignature(path, out _, out _))
            {
                _extractor = DearchivalMethod.Construct(path);
                try
                {
                    _archiveItems = _extractor.Scan();
                    IsArchive     = true;
                }
                catch
                {
                    _archiveItems = null;
                    _extractor.Dispose();
                    _extractor = null;
                }
            }
            if (_extractor == null)
            {
                _rootStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
                // we could autobind here, but i don't want to
                // bind it later with the desired extensions.
            }

            if (autobind == null)
            {
                // non-archive files can be automatically bound this way
                BindRoot();
            }
            else
            {
                if (_extractor != null)
                {
                    var scanResults = _extractor.Scan();
                    for (int i = 0, l = scanResults.Count; i < l; i++)
                    {
                        if (string.Equals(scanResults[i].Name, autobind, StringComparison.InvariantCultureIgnoreCase))
                        {
                            BindArchiveMember(i);
                            return;
                        }
                    }
                }

                Exists = false;
            }
        }