Ejemplo n.º 1
0
        /// <summary>
        /// ctor: Create class from data returned by the Reader
        /// </summary>
        /// <param name="reader">A binary data reader for this type of data - positioned at last page</param>
        public p4kEndOfCentralDirRecord(p4kRecReader reader)
        {
            // sanity check only
            System.Diagnostics.Trace.Assert(Marshal.SizeOf(typeof(MyRecord)) == RecordLength,
                                            "Record size does not match!(" + Marshal.SizeOf(typeof(MyRecord)).ToString( ) + ")");

            if (reader.IsOpen( ))
            {
                try {
                    long cPos = p4kSignatures.FindSignatureInPage(reader, p4kSignatures.EndOfCentralDirRecord);
                    if (cPos >= 0)
                    {
                        m_recordOffset = cPos;
                        reader.Seek(cPos);
                        m_item      = p4kRecReader.ByteToType <MyRecord>(reader.TheReader);
                        m_itemValid = true;
                    }
                }
                catch {
                    m_itemValid    = false;
                    m_recordOffset = -1;
                }
                finally {
                    if (!m_itemValid)
                    {
                        throw new OperationCanceledException(string.Format("EOF - cannot find EndOfCentralDirRecord"));
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// ctor: Create class from data returned by the Reader; starts reading at current stream position
        /// </summary>
        /// <param name="reader">A binary data reader for this type of data - positioned already</param>
        public p4kDirectoryEntry(p4kRecReader reader)
        {
            // sanity check only
            System.Diagnostics.Trace.Assert(Marshal.SizeOf(typeof(MyRecord)) == RecordLength,
                                            "Record size does not match!(" + Marshal.SizeOf(typeof(MyRecord)).ToString( ) + ")");
            System.Diagnostics.Trace.Assert(Marshal.SizeOf(typeof(MyZ64ExtraRecord)) == Z64ExtraRecordLength,
                                            "Extra Record size does not match!(" + Marshal.SizeOf(typeof(MyZ64ExtraRecord)).ToString( ) + ")");

            if (reader.IsOpen( ))
            {
                try {
                    // get the next Directory record
                    long cPos = p4kSignatures.FindSignatureInPage(reader, p4kSignatures.CentralDirRecord);
                    if (cPos >= 0)
                    {
                        m_recordOffset = cPos;
                        reader.Seek(cPos);
                        m_item      = p4kRecReader.ByteToType <MyRecord>(reader.TheReader);
                        m_itemValid = true; // implicite from Find..
                    }

                    // get some file attributes
                    if (m_itemValid)
                    {
                        if (m_item.FilenameLength > 0)
                        {
                            ReadFilename(reader);
                        }
                        if (m_item.ExtraFieldLength > 0)
                        {
                            ReadExtradata(reader);                                                      // Likely Zip64 extensions
                        }
                        m_fileDateTime = p4kFileTStamp.FromDos(m_item.LastModDate, m_item.LastModTime); // get the file time given in the container

                        // check if standard fields or extension is used for size information
                        if (m_item.CompressedSize < 0xffffffff)
                        {
                            m_fileSizeComp   = m_item.CompressedSize;
                            m_fileSizeUnComp = m_item.UncompressedSize;
                        }
                        else
                        {
                            m_fileSizeComp   = (long)m_z64Item.CompressedSize;
                            m_fileSizeUnComp = (long)m_z64Item.UncompressedSize;
                        }
                    }
                }
                catch (Exception e) {
                    m_itemValid    = false;
                    m_recordOffset = -1;
                }
                finally {
                    if (!m_itemValid)
                    {
                        throw new OperationCanceledException(string.Format("EOF - cannot find CentralDirRec in this page"));
                    }
                }
            }
        }
        /// <summary>
        /// ctor: Create class from data returned by the Reader
        /// </summary>
        /// <param name="reader">A binary data reader for this type of data - positioned at last page</param>
        public p4kEndOfCentralDirRecord(p4kRecReader reader)
        {
            // sanity check only
            System.Diagnostics.Trace.Assert(Marshal.SizeOf(typeof(MyRecord)) == RecordLength,
                                            "Record size does not match!(" + Marshal.SizeOf(typeof(MyRecord)).ToString( ) + ")");

            if (reader.IsOpen( ))
            {
                try {
                    long thisPos = 0;
                    // 20180804BM- fix when the last page is barely used and the sig is one or more pages before
                    //  - backup one or more pages to find end of dir (max 10 times)
                    int tries = 10;
                    while (!m_itemValid && (tries > 0))
                    {
                        thisPos = reader.Position;
                        long cPos = p4kSignatures.FindSignatureInPage(reader, p4kSignatures.EndOfCentralDirRecord);
                        if (cPos >= 0)
                        {
                            m_recordOffset = cPos;
                            reader.Seek(cPos);
                            m_item      = p4kRecReader.ByteToType <MyRecord>(reader.TheReader);
                            m_itemValid = true;
                        }
                        else
                        {
                            // backup one page again
                            reader.Seek(thisPos);
                            reader.BackwardPage( );
                            tries--;
                        }
                    }
                }
                catch {
                    m_itemValid    = false;
                    m_recordOffset = -1;
                }
                finally {
                    if (!m_itemValid)
                    {
                        throw new OperationCanceledException(string.Format("EOF - cannot find EndOfCentralDirRecord"));
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Return the file related to this entry
        /// </summary>
        /// <param name="reader">An open p4k File reader</param>
        /// <returns>The content of the file or an empty string</returns>
        public byte[] GetFile(p4kRecReader reader)
        {
            if (!m_itemValid)
            {
                return new byte[] { }
            }
            ;                                    // ERROR cannot..

            reader.Seek(FileHeaderOffset);
            p4kFileHeader p4Kfh = new p4kFileHeader(reader);

            return(p4Kfh.GetFile(reader));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Scans directory entries and return the a file descriptor (string.EndsWith is used)
        /// </summary>
        /// <param name="p4kFilename">The p4k file</param>
        /// <param name="filename">The filename to look for</param>
        public p4kFile ScanDirectoryFor(string p4kFilename, string filename)
        {
            if (!File.Exists(p4kFilename))
            {
                return(null);
            }

            using (p4kRecReader reader = new p4kRecReader(p4kFilename)) {
                // work from the end of the file
                reader.GotoLastPage( );
                m_endOfCentralDirRecord = new p4kEndOfCentralDirRecord(reader);

                // position first
                reader.Seek(m_endOfCentralDirRecord.RecordOffset - p4kRecReader.PageSize);
                m_z64EndOfCentralDirLocator = new p4kZ64EndOfCentralDirLocator(reader);

                // for the next the position should be found already - seek it
                reader.Seek(m_z64EndOfCentralDirLocator.Z64EndOfCentralDir);
                m_z64EndOfCentralDirRecord = new p4kZ64EndOfCentralDirRecord(reader);
                // now we should have the start of the directory entries...


                // position first
                reader.Seek(m_z64EndOfCentralDirRecord.Z64StartOfCentralDir);
                // loop all file - as per dir reporting
                for (long i = 0; i < m_z64EndOfCentralDirRecord.NumberOfEntries; i++)
                {
                    p4kDirectoryEntry de = new p4kDirectoryEntry(reader);
                    if (!string.IsNullOrEmpty(filename) && de.Filename.ToLower( ).EndsWith(filename.ToLower( )))
                    {
                        var p = new p4kFile(de); // FOUND
                        reader.TheReader.Close( );
                        return(p);               // bail out if found
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Scans directory entries and return the a list of matching file descriptors (string.Contains is used)
        /// </summary>
        /// <param name="p4kFilename">The p4k file</param>
        /// <param name="filenamepart">The filename part to look for</param>
        public IList <p4kFile> ScanDirectoryContaining(string p4kFilename, string filenamepart)
        {
            if (!File.Exists(p4kFilename))
            {
                return(null);
            }

            List <p4kFile> fileList = new List <p4kFile>( );

            using (p4kRecReader reader = new p4kRecReader(p4kFilename)) {
                // work from the end of the file
                reader.GotoLastPage( );
                m_endOfCentralDirRecord = new p4kEndOfCentralDirRecord(reader);

                // position first
                reader.Seek(m_endOfCentralDirRecord.RecordOffset - p4kRecReader.PageSize);
                m_z64EndOfCentralDirLocator = new p4kZ64EndOfCentralDirLocator(reader);

                // for the next the position should be found already - seek it
                reader.Seek(m_z64EndOfCentralDirLocator.Z64EndOfCentralDir);
                m_z64EndOfCentralDirRecord = new p4kZ64EndOfCentralDirRecord(reader);
                // now we should have the start of the directory entries...

                // position first
                reader.Seek(m_z64EndOfCentralDirRecord.Z64StartOfCentralDir);
                // loop all file - as per dir reporting
                for (long i = 0; i < m_z64EndOfCentralDirRecord.NumberOfEntries; i++)
                {
                    p4kDirectoryEntry de = new p4kDirectoryEntry(reader);
                    if (!string.IsNullOrEmpty(filenamepart) && de.Filename.ToLower( ).Contains(filenamepart.ToLower( )))
                    {
                        var p = new p4kFile(de); // FOUND
                        fileList.Add(p);
                    }
                }
            }
            return(fileList);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Return the file related to this entry
        /// </summary>
        /// <param name="reader">An open p4k File reader</param>
        /// <returns>The content of the file or an empty string</returns>
        public byte[] GetFile(p4kRecReader reader)
        {
            if (!m_itemValid)
            {
                return new byte[] { }
            }
            ;                                    // ERROR cannot..

            reader.Seek(m_fileOffset);
            // ?? big files may have trouble here - may be we need to read and write chunks for this
            // but for now we only want to get XMLs out and that is OK with byte alloc on the heap
            byte[] fileBytes = new byte[m_fileSizeComp];
            fileBytes = reader.ReadBytes(fileBytes.Length);

            byte[] decompFile = null;
            if (m_item.CompressionMethod == 0x64)
            {
                // this indicates p4k ZStd compression
                using (var decompressor = new Decompressor( )) {
                    try {
                        decompFile = decompressor.Unwrap(fileBytes);
                        return(decompFile);
                    }
                    catch (ZstdException e) {
                        Console.WriteLine("ZStd - Cannot decode file: " + m_filename);
                        Console.WriteLine("Error: " + e.Message);
                        //Console.ReadLine();
                        return(new byte[] { });
                    }
                }
            }
            else
            {
                // plain write - might be wrong if another compression was applied..
                decompFile = fileBytes;

                return(decompFile);
            }
        }