예제 #1
0
        public void PackFiles(Stream strm, List<PackFileEntry> filesToPack, Callbacks callbacks)
        {
            BinaryWriter bw = new BinaryWriter(strm);
            Int32 FileOffset;

            bw.Write(new char[] { 'Y', 'P', 'A', 'C' });
            bw.Write((Int32)1);
            bw.Write((Int32)filesToPack.Count);
            bw.Write((Int32)0);

            // write the directory
            FileOffset = 16 + 7 * 16 * filesToPack.Count; // this will be the offset for the first file
            for (int i = 0; i < filesToPack.Count; i++)
            {
                string targetFileName = "\\" + filesToPack[i];
                byte[] nameBuf = new byte[6 * 16];
                Int64 Length;

                Encoding.ASCII.GetBytes(targetFileName, 0, targetFileName.Length, nameBuf, 0);
                bw.Write(nameBuf);
                bw.Write((Int64)FileOffset);
                Length = filesToPack[i].fileSize;
                bw.Write((Int64)Length);
                FileOffset += (Int32)Length;
            }

            // write the actual file data
            for (int i = 0; i < filesToPack.Count; i++)
            {
                byte[] fileData = callbacks.ReadData(filesToPack[i].relativePathName);
                strm.Write(fileData, 0, fileData.Length);
            }
        }
예제 #2
0
파일: ZIPUnpacker.cs 프로젝트: darkstar/gus
        public void PackFiles(Stream strm, List<PackFileEntry> filesToPack, Callbacks callbacks)
        {
            SetupZIPParams();
            using (ZipOutputStream zstrm = new ZipOutputStream(strm, false))
            {
                // always use multithreaded compression
                zstrm.ParallelDeflateThreshold = 0;

                foreach (PackFileEntry pfe in filesToPack)
                {
                    zstrm.PutNextEntry(pfe.relativePathName);
                    byte[] data = callbacks.ReadData(pfe.relativePathName);
                    zstrm.Write(data, 0, data.Length);
                }
            }
            // stream is closed automatically
        }
예제 #3
0
        public void PackFiles(Stream strm, List<PackFileEntry> filesToPack, Callbacks callbacks)
        {
            int NumFiles = filesToPack.Count;
            BinaryWriter bw = new BinaryWriter(strm);
            uint id;
            bool compressed;
            uint CurrentOffset;
            int CompressedLength = 0;
            IDataTransformer compressor = callbacks.TransformerRegistry.GetTransformer("zlib_cmp");

            bw.Write(grar_magic);
            bw.Write(NumFiles);

            // first pass, write "pseudo-uncompressed" file headers
            for (int i = 0; i < NumFiles; i++)
            {
                string fn = Path.GetFileNameWithoutExtension(filesToPack[i].relativePathName);
                if (!fn.StartsWith("0x"))
                    throw new Exception(String.Format("Invalid filename '{0}', must start with hex id!", fn));

                id = UInt32.Parse(fn.Substring(2, 8), System.Globalization.NumberStyles.AllowHexSpecifier);

                bw.Write(id);
                bw.Write((UInt32)0); // offset not yet defined
                bw.Write((UInt32)0); // compressed length
                bw.Write((UInt32)filesToPack[i].fileSize);
            }

            CurrentOffset = (UInt32)strm.Position;
            // second pass, actually write the files, compressing them on demand
            for (int i = 0; i < NumFiles; i++)
            {
                // first, check if file is to be compressed
                string fn = Path.GetFileNameWithoutExtension(filesToPack[i].relativePathName);
                compressed = fn.EndsWith("P");

                // read the file and optionally compress it
                byte[] buffer = callbacks.ReadData(filesToPack[i].relativePathName);
                if (compressed)
                {
                    byte[] buffer2 = new byte[buffer.Length + 256];

                    CompressedLength = buffer2.Length;
                    compressor.TransformData(buffer, buffer2, buffer.Length, ref CompressedLength);
                    buffer = buffer2;
                }
                else
                {
                    CompressedLength = 0;
                }

                strm.Seek(8 + i * 16, SeekOrigin.Begin); // header = 8 bytes, 16 bytes per entry
                strm.Seek(4, SeekOrigin.Current); // skip ID
                bw.Write(CurrentOffset);

                if (compressed)
                    bw.Write(CompressedLength + 4);

                // finally write the file data
                strm.Seek(CurrentOffset, SeekOrigin.Begin);

                // compressed files specify the uncompressed size again here
                if (compressed)
                {
                    bw.Write((UInt32)filesToPack[i].fileSize);
                    strm.Write(buffer, 0, CompressedLength);
                }
                else
                {
                    strm.Write(buffer, 0, buffer.Length);
                }
                CurrentOffset = (uint)strm.Position;
            }
        }