コード例 #1
0
        /// <summary>
        /// Attempt to extract a stream from an archive
        /// </summary>
        /// <param name="entryName">Name of the entry to be extracted</param>
        /// <param name="realEntry">Output representing the entry name that was found</param>
        /// <returns>MemoryStream representing the entry, null on error</returns>
        public override (MemoryStream, string) CopyToStream(string entryName)
        {
            MemoryStream ms = new MemoryStream();
            string       realEntry;

            try
            {
                // Decompress the _filename stream
                realEntry = Path.GetFileNameWithoutExtension(this.Filename);
                var xz = new XZStream(File.OpenRead(this.Filename));

                // Write the file out
                byte[] xbuffer = new byte[_bufferSize];
                int    xlen;
                while ((xlen = xz.Read(xbuffer, 0, _bufferSize)) > 0)
                {
                    ms.Write(xbuffer, 0, xlen);
                    ms.Flush();
                }

                // Dispose of the streams
                xz.Dispose();
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                ms        = null;
                realEntry = null;
            }

            return(ms, realEntry);
        }
コード例 #2
0
        /// <summary>
        /// Generate a list of DatItem objects from the header values in an archive
        /// </summary>
        /// <returns>List of DatItem objects representing the found data</returns>
        public override List <BaseFile> GetChildren()
        {
            if (_children == null || _children.Count == 0)
            {
                _children = new List <BaseFile>();

                string gamename = Path.GetFileNameWithoutExtension(this.Filename);

                BaseFile possibleTxz = GetTorrentXZFileInfo();

                // If it was, then add it to the outputs and continue
                if (possibleTxz != null && possibleTxz.Filename != null)
                {
                    _children.Add(possibleTxz);
                }
                else
                {
                    try
                    {
                        // Create a blank item for the entry
                        BaseFile xzEntryRom = new BaseFile();

                        // Perform a quickscan, if flagged to
                        if (this.AvailableHashes == Hash.CRC)
                        {
                            xzEntryRom.Filename = gamename;
                            using (BinaryReader br = new BinaryReader(FileExtensions.TryOpenRead(this.Filename)))
                            {
                                br.BaseStream.Seek(-8, SeekOrigin.End);
                                xzEntryRom.CRC  = br.ReadBytesBigEndian(4);
                                xzEntryRom.Size = br.ReadInt32BigEndian();
                            }
                        }
                        // Otherwise, use the stream directly
                        else
                        {
                            var xzStream = new XZStream(File.OpenRead(this.Filename));
                            xzEntryRom          = xzStream.GetInfo(hashes: this.AvailableHashes);
                            xzEntryRom.Filename = gamename;
                            xzStream.Dispose();
                        }

                        // Fill in comon details and add to the list
                        xzEntryRom.Parent = gamename;
                        _children.Add(xzEntryRom);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex);
                        return(null);
                    }
                }
            }

            return(_children);
        }
コード例 #3
0
        /// <summary>
        ///     Extracts an zip file contained in fileEntry.
        /// </summary>
        /// <param name="fileEntry"> FileEntry to extract </param>
        /// <returns> Extracted files </returns>
        public IEnumerable <FileEntry> Extract(FileEntry fileEntry, ExtractorOptions options, ResourceGovernor governor)
        {
            XZStream?xzStream = null;

            try
            {
                xzStream = new XZStream(fileEntry.Content);
            }
            catch (Exception e)
            {
                Logger.Debug(Extractor.DEBUG_STRING, ArchiveFileType.XZ, fileEntry.FullPath, string.Empty, e.GetType());
            }
            if (xzStream != null)
            {
                var newFilename  = Path.GetFileNameWithoutExtension(fileEntry.Name);
                var newFileEntry = new FileEntry(newFilename, xzStream, fileEntry);

                // SharpCompress does not expose metadata without a full read, so we need to decompress first,
                // and then abort if the bytes exceeded the governor's capacity.

                var streamLength = xzStream.Index?.Records?.Select(r => r.UncompressedSize)
                                   .Aggregate((ulong?)0, (a, b) => a + b);

                // BUG: Technically, we're casting a ulong to a long, but we don't expect 9 exabyte steams, so
                // low risk.
                if (streamLength.HasValue)
                {
                    governor.CheckResourceGovernor((long)streamLength.Value);
                }

                if (Extractor.IsQuine(newFileEntry))
                {
                    Logger.Info(Extractor.IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath);
                    throw new OverflowException();
                }

                foreach (var extractedFile in Context.Extract(newFileEntry, options, governor))
                {
                    yield return(extractedFile);
                }
                xzStream.Dispose();
            }
            else
            {
                if (options.ExtractSelfOnFail)
                {
                    yield return(fileEntry);
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Write an input file to a torrent XZ archive
        /// </summary>
        /// <param name="inputStream">Input stream to be moved</param>
        /// <param name="outDir">Output directory to build to</param>
        /// <param name="rom">DatItem representing the new information</param>
        /// <returns>True if the archive was written properly, false otherwise</returns>
        public override bool Write(Stream inputStream, string outDir, Rom rom)
        {
            bool success = false;

            // If the stream is not readable, return
            if (!inputStream.CanRead)
            {
                return(success);
            }

            // Make sure the output directory exists
            if (!Directory.Exists(outDir))
            {
                Directory.CreateDirectory(outDir);
            }

            outDir = Path.GetFullPath(outDir);

            // Now get the Rom info for the file so we have hashes and size
            rom = new Rom(inputStream.GetInfo(keepReadOpen: true));

            // Get the output file name
            string outfile = Path.Combine(outDir, PathExtensions.GetDepotPath(rom.SHA1, Depth));

            outfile = outfile.Replace(".gz", ".xz");

            // Check to see if the folder needs to be created
            if (!Directory.Exists(Path.GetDirectoryName(outfile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(outfile));
            }

            // If the output file exists, don't try to write again
            if (!File.Exists(outfile))
            {
                // Compress the input stream
                XZStream outputStream = new XZStream(FileExtensions.TryCreate(outfile));
                inputStream.CopyTo(outputStream);

                // Dispose of everything
                outputStream.Dispose();
            }

            return(true);
        }
コード例 #5
0
        /// <summary>
        /// Attempt to extract a file as an archive
        /// </summary>
        /// <param name="outDir">Output directory for archive extraction</param>
        /// <returns>True if the extraction was a success, false otherwise</returns>
        public override bool CopyAll(string outDir)
        {
            bool encounteredErrors = true;

            try
            {
                // Create the temp directory
                Directory.CreateDirectory(outDir);

                // Decompress the _filename stream
                FileStream outstream = FileExtensions.TryCreate(Path.Combine(outDir, Path.GetFileNameWithoutExtension(this.Filename)));
                var        xz        = new XZStream(File.OpenRead(this.Filename));
                xz.CopyTo(outstream);

                // Dispose of the streams
                outstream.Dispose();
                xz.Dispose();

                encounteredErrors = false;
            }
            catch (EndOfStreamException ex)
            {
                // Catch this but don't count it as an error because SharpCompress is unsafe
                logger.Verbose(ex);
            }
            catch (InvalidOperationException ex)
            {
                logger.Warning(ex);
                encounteredErrors = true;
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                encounteredErrors = true;
            }

            return(encounteredErrors);
        }