/// <summary>
        /// 展開準備
        /// prepare to inflate
        /// </summary>
        public void Prepare(byte[] data)
        {
            _stream = new MemoryStream(data);

            //ヘッダ読み取り
            //read szip header
            {
                var binStream = new BinaryReader(_stream);
                _header = new SZipHeader();
                _header.Read(binStream);
            }

            //各コンテンツ情報読み取り
            //read each content information
            {
                //要素情報テーブル解凍
                _stream.Seek(SZipHeader.Size, SeekOrigin.Begin);
                var decompressed = SZipUtility.ZlibDecompress(_stream,
                                                              SZipContent.Size * _header.ContentCount,
                                                              _header.CompressedContentHeaderTableSize);

                _contents = new SZipContent[_header.ContentCount];
                using (MemoryStream stream = new MemoryStream(decompressed))
                {
                    for (int contentIndex = 0; contentIndex < _header.ContentCount; contentIndex++)
                    {
                        var content = new SZipContent();
                        content.Read(new BinaryReader(stream));
                        _contents[contentIndex] = content;
                    }
                }
            }

            //要素名読み取り
            //read each content name
            {
                //要素名前テーブル解凍
                _stream.Seek(SZipHeader.Size + _header.CompressedContentHeaderTableSize, SeekOrigin.Begin);
                var decompressed = SZipUtility.ZlibDecompress(_stream, (int)_header.OriginalContentNameTableSize, (int)_header.CompressedContentNameTableSize);

                _fileNameTable      = new string[_header.ContentCount];
                _contentNameHashSet = new HashSet <string>();
                using (MemoryStream fnameStream = new MemoryStream(decompressed))
                {
                    using (BinaryReader binReader = new BinaryReader(fnameStream))
                    {
                        for (int contentIndex = 0; contentIndex < _header.ContentCount; contentIndex++)
                        {
                            int length      = (int)_contents[contentIndex].NameByteSize;
                            var from        = binReader.ReadBytes(length);
                            var contentName = System.Text.Encoding.UTF8.GetString(from);
                            _fileNameTable[contentIndex] = contentName;
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 圧縮
        /// </summary>
        public byte[] Deflate()
        {
            //データ部圧縮
            //compress datas
            List <int>    originalContentDataSizeTable   = new List <int>();
            List <byte[]> compressedContentDataTable     = new List <byte[]>(_contentFileInfoTable.Count);
            int           compressedContentDataTableSize = 0;

            for (int contentIndex = 0; contentIndex < _contentFileInfoTable.Count; contentIndex++)
            {
                var fileInfo = _contentFileInfoTable[contentIndex];
                var data     = System.IO.File.ReadAllBytes(fileInfo.FullName);
                originalContentDataSizeTable.Add(data.Length);
                var compressed = ZlibStream.CompressBuffer(data);
                compressedContentDataTableSize += compressed.Length;
                compressedContentDataTable.Add(compressed);
            }

            //ファイル名部圧縮
            //compress name table
            byte[] compressedContentNameTable     = null;
            int    compressedContentNameTableSize = 0;

            {
                //全ファイル名結合
                System.Text.StringBuilder builder = new System.Text.StringBuilder();
                foreach (var s in _contentNameTable)
                {
                    builder.Append(s);
                    compressedContentNameTableSize += System.Text.Encoding.UTF8.GetByteCount(s);
                }

                compressedContentNameTable = ZlibStream.CompressString(builder.ToString());
            }

            //コンテンツ情報部圧縮
            //compress contents
            byte[] compressedContentTable = null;
            {
                byte[] headerTable = new byte[SZipContent.Size * _contentFileInfoTable.Count];
                using (MemoryStream stream = new MemoryStream(headerTable))
                {
                    using (BinaryWriter writer = new BinaryWriter(stream))
                    {
                        for (int contentIndex = 0; contentIndex < _contentFileInfoTable.Count; contentIndex++)
                        {
                            var           content = new SZipContent();
                            System.UInt32 crc     = SZipUtility.FNVHash(compressedContentDataTable[contentIndex]);
                            content.Set(_contentNameTable[contentIndex].Length,
                                        originalContentDataSizeTable[contentIndex],
                                        compressedContentDataTable[contentIndex].Length,
                                        crc);
                            content.Write(writer);
                        }
                    }
                }
                compressedContentTable = ZlibStream.CompressBuffer(headerTable);
            }

            //ヘッダ生成
            //create szip header
            var header = new SZipHeader();

            header.Set((System.Int16)_contentFileInfoTable.Count,
                       SZipUtility.FNVHash(compressedContentNameTable),
                       SZipUtility.FNVHash(compressedContentTable),
                       compressedContentTable.Length,
                       compressedContentNameTableSize,
                       compressedContentNameTable.Length);

            //書き込み
            //write to byte[]
            {
                int totalSize = SZipHeader.Size
                                + compressedContentTable.Length
                                + compressedContentNameTable.Length
                                + compressedContentDataTableSize;

                byte[] output = new byte[totalSize];

                using (MemoryStream stream = new MemoryStream(output))
                {
                    using (BinaryWriter writer = new BinaryWriter(stream))
                    {
                        //ヘッダ
                        header.Write(writer);

                        //コンテンツ
                        writer.Write(compressedContentTable);

                        //コンテンツ名
                        writer.Write(compressedContentNameTable);

                        //データ
                        foreach (var data in compressedContentDataTable)
                        {
                            writer.Write(data);
                        }
                    }
                }

                return(output);
            }
        }