コード例 #1
0
        public ArchiveListing Read()
        {
            ArchiveListingHeaderV2 header;

            using (Stream input = Decrypt(out header))
            {
                _progressTotalChanged.NullSafeInvoke(header.EntriesCount);

                short blockNumber = -1;
                bool? flag        = null;

                ArchiveListingEntryInfoV2[] entries = new ArchiveListingEntryInfoV2[header.EntriesCount];
                for (int i = 0; i < entries.Length; i++)
                {
                    entries[i] = input.ReadContent <ArchiveListingEntryInfoV2>();
                    if (entries[i].Flag != flag)
                    {
                        flag = entries[i].Flag;
                        blockNumber++;
                    }
                    entries[i].BlockNumber = blockNumber;
                }

                ArchiveListingCompressedData data = new ArchiveListingCompressedData(header);
                data.ReadFromStream(input);

                ArchiveListing result = new ArchiveListing(_accessor, header);
                ParseEntries(entries, data, result);
                return(result);
            }
        }
コード例 #2
0
        private void ParseEntries(ArchiveListingEntryInfoV2[] entries, ArchiveListingCompressedData data, ArchiveListing result)
        {
            byte[] buff = new byte[0];

            for (int currentBlock = -1, i = 0; i < entries.Length; i++)
            {
                ArchiveListingEntryInfoV2 entryInfoV2 = entries[i];
                if (entryInfoV2.BlockNumber != currentBlock)
                {
                    currentBlock = entryInfoV2.BlockNumber;
                    buff         = data.AcquireData(currentBlock);
                }

                string name;
                long   sector, uncompressedSize, compressedSize;
                ParseInfo(entryInfoV2, buff, out sector, out uncompressedSize, out compressedSize, out name);

                ArchiveEntry entry = new ArchiveEntry(name, sector, compressedSize, uncompressedSize)
                {
                    UnknownNumber = entryInfoV2.UnknownNumber,
                    UnknownValue  = entryInfoV2.UnknownValue,
                    UnknownData   = entryInfoV2.UnknownData
                };

                result.Add(entry);
                _progressIncrement.NullSafeInvoke(1);
            }
        }
コード例 #3
0
        private void ParseInfo(ArchiveListingEntryInfoV2 entryInfo, byte[] uncompressedData, out long sector, out long uncompressedSize, out long compressedSize, out string name)
        {
            string[] info;
            unsafe
            {
                fixed(byte *ptr = &uncompressedData[entryInfo.Offset])
                {
                    string str = new string((sbyte *)ptr);

                    info = str.Split(':');
                }
            }

            if (info.Length < 4)
            {
                name             = String.Join(":", info);
                sector           = -1;
                uncompressedSize = -1;
                compressedSize   = -1;
            }
            else
            {
                sector           = long.Parse(info[0], NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                uncompressedSize = long.Parse(info[1], NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                compressedSize   = long.Parse(info[2], NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                name             = info[3];
            }
        }
コード例 #4
0
        public ArchiveListing Read()
        {
            ArchiveListingHeaderV2 header;
            Stream input = Decrypt(out header);

            _progressTotalChanged.NullSafeInvoke(header.EntriesCount);

            short blockNumber = -1;
            bool? flag = null;

            ArchiveListingEntryInfoV2[] entries = new ArchiveListingEntryInfoV2[header.EntriesCount];
            for (int i = 0; i < entries.Length; i++)
            {
                entries[i] = input.ReadContent<ArchiveListingEntryInfoV2>();
                if (entries[i].Flag != flag)
                {
                    flag = entries[i].Flag;
                    blockNumber++;
                }
                entries[i].BlockNumber = blockNumber;
            }

            ArchiveListingCompressedData data = new ArchiveListingCompressedData(header);
            data.ReadFromStream(input);

            ArchiveListing result = new ArchiveListing(_accessor, header.EntriesCount);
            ParseEntries(entries, data, result);
            return result;
        }
コード例 #5
0
        public void Write(ArchiveListing listing, out ArchiveListingBlockInfo[] blocksInfo, out ArchiveListingEntryInfoV2[] entriesInfoV2)
        {
            using (MemoryStream ms = new MemoryStream(32768))
            {
                int blockNumber = 0, unpackedBlockOffset = 0;
                entriesInfoV2 = new ArchiveListingEntryInfoV2[listing.Count];
                List <ArchiveListingBlockInfo> blocks = new List <ArchiveListingBlockInfo>(128);
                using (FormattingStreamWriter sw = new FormattingStreamWriter(ms, Encoding.ASCII, 4096, true, CultureInfo.InvariantCulture))
                {
                    sw.AutoFlush = true;
                    for (int i = 0; i < listing.Count; i++)
                    {
                        ArchiveEntry entry = listing[i];

                        ArchiveListingEntryInfoV2 info = new ArchiveListingEntryInfoV2 {
                            BlockNumber = (short)(ms.Position / 8192)
                        };
                        info.Flag = (info.BlockNumber % 2 != 0);

                        entriesInfoV2[i] = info;

                        if (blockNumber != info.BlockNumber)
                        {
                            int blockSize = (int)(ms.Position - unpackedBlockOffset);
                            ms.Position = unpackedBlockOffset;
                            ArchiveListingBlockInfo block = new ArchiveListingBlockInfo {
                                Offset = (int)_output.Position, UncompressedSize = blockSize
                            };
                            block.CompressedSize = ZLibHelper.Compress(ms, _output, block.UncompressedSize);
                            blocks.Add(block);

                            blockNumber++;
                            unpackedBlockOffset = (int)ms.Position;
                            sw.Write("{0:x}:{1:x}:{2:x}:{3}\0", entry.Sector, entry.UncompressedSize, entry.Size, entry.Name);
                        }
                        else if (i == listing.Count - 1)
                        {
                            info.Offset = (short)(ms.Position - unpackedBlockOffset);
                            sw.Write("{0:x}:{1:x}:{2:x}:{3}\0end\0", entry.Sector, entry.UncompressedSize, entry.Size, entry.Name);
                            int blockSize = (int)(ms.Position - unpackedBlockOffset);
                            ms.Position = unpackedBlockOffset;
                            ArchiveListingBlockInfo block = new ArchiveListingBlockInfo {
                                Offset = (int)_output.Position, UncompressedSize = blockSize
                            };
                            block.CompressedSize = ZLibHelper.Compress(ms, _output, block.UncompressedSize);
                            blocks.Add(block);
                        }
                        else
                        {
                            info.Offset = (short)(ms.Position - unpackedBlockOffset);
                            sw.Write("{0:x}:{1:x}:{2:x}:{3}\0", entry.Sector, entry.UncompressedSize, entry.Size, entry.Name);
                        }
                    }
                }
                blocksInfo = blocks.ToArray();
            }
        }
コード例 #6
0
        public void Write()
        {
            using (MemoryStream headerBuff = new MemoryStream(32768))
                using (MemoryStream textBuff = new MemoryStream(32768))
                {
                    ArchiveListingBlockInfo[]   blocksInfo;
                    ArchiveListingEntryInfoV2[] entriesInfoV2;
                    ArchiveListingTextWriterV2  textWriter = new ArchiveListingTextWriterV2(textBuff);
                    textWriter.Write(_listing, out blocksInfo, out entriesInfoV2);

                    for (int i = 0; i < entriesInfoV2.Length; i++)
                    {
                        ArchiveListingEntryInfoV2 info = entriesInfoV2[i];
                        ArchiveEntry entry             = _listing[i];
                        info.UnknownNumber = entry.UnknownNumber;
                        info.UnknownValue  = entry.UnknownValue;
                        info.UnknownData   = entry.UnknownData;
                    }

                    byte[] buff       = new byte[8192];
                    int    blocksSize = (int)textBuff.Position;
                    textBuff.Position = 0;

                    ArchiveListingHeaderV2 header = (ArchiveListingHeaderV2)_listing.Header;
                    header.EntriesCount   = entriesInfoV2.Length;
                    header.RawBlockOffset = entriesInfoV2.Length * 8 + 12;
                    header.RawInfoOffset  = header.RawBlockOffset + blocksInfo.Length * 12;

                    headerBuff.WriteContent(header);
                    foreach (ArchiveListingEntryInfoV2 entry in entriesInfoV2)
                    {
                        headerBuff.WriteContent(entry);
                    }
                    foreach (ArchiveListingBlockInfo block in blocksInfo)
                    {
                        headerBuff.WriteStruct(block);
                    }

                    int hederSize = (int)headerBuff.Length;
                    headerBuff.Position = 0;

                    if (header.IsEncrypted)
                    {
                        RecreateEncryptedListing(headerBuff, hederSize, textBuff, blocksSize, buff);
                    }
                    else
                    {
                        using (Stream output = _accessor.RecreateListing(hederSize + blocksSize))
                        {
                            headerBuff.CopyToStream(output, hederSize, buff);
                            textBuff.CopyToStream(output, blocksSize, buff);
                        }
                    }
                }
        }
コード例 #7
0
        public void Write(ArchiveListing listing, out ArchiveListingBlockInfo[] blocksInfo, out ArchiveListingEntryInfoV2[] entriesInfoV2)
        {
            using (MemoryStream ms = new MemoryStream(32768))
            {
                int blockNumber = 0, unpackedBlockOffset = 0;
                entriesInfoV2 = new ArchiveListingEntryInfoV2[listing.Count];
                List<ArchiveListingBlockInfo> blocks = new List<ArchiveListingBlockInfo>(128);
                using (FormattingStreamWriter sw = new FormattingStreamWriter(ms, Encoding.ASCII, 4096, true, CultureInfo.InvariantCulture))
                {
                    sw.AutoFlush = true;
                    for (int i = 0; i < listing.Count; i++)
                    {
                        ArchiveEntry entry = listing[i];

                        ArchiveListingEntryInfoV2 info = new ArchiveListingEntryInfoV2 { BlockNumber = (short)(ms.Position / 8192) };
                        info.Flag = (info.BlockNumber % 2 != 0);

                        entriesInfoV2[i] = info;

                        if (blockNumber != info.BlockNumber)
                        {
                            int blockSize = (int)(ms.Position - unpackedBlockOffset);
                            ms.Position = unpackedBlockOffset;
                            ArchiveListingBlockInfo block = new ArchiveListingBlockInfo {Offset = (int)_output.Position, UncompressedSize = blockSize};
                            block.CompressedSize = ZLibHelper.Compress(ms, _output, block.UncompressedSize);
                            blocks.Add(block);

                            blockNumber++;
                            unpackedBlockOffset = (int)ms.Position;
                            sw.Write("{0:x}:{1:x}:{2:x}:{3}\0", entry.Sector, entry.UncompressedSize, entry.Size, entry.Name);
                        }
                        else if (i == listing.Count - 1)
                        {
                            info.Offset = (short)(ms.Position - unpackedBlockOffset);
                            sw.Write("{0:x}:{1:x}:{2:x}:{3}\0end\0", entry.Sector, entry.UncompressedSize, entry.Size, entry.Name);
                            int blockSize = (int)(ms.Position - unpackedBlockOffset);
                            ms.Position = unpackedBlockOffset;
                            ArchiveListingBlockInfo block = new ArchiveListingBlockInfo {Offset = (int)_output.Position, UncompressedSize = blockSize};
                            block.CompressedSize = ZLibHelper.Compress(ms, _output, block.UncompressedSize);
                            blocks.Add(block);
                        }
                        else
                        {
                            info.Offset = (short)(ms.Position - unpackedBlockOffset);
                            sw.Write("{0:x}:{1:x}:{2:x}:{3}\0", entry.Sector, entry.UncompressedSize, entry.Size, entry.Name);
                        }
                    }
                }
                blocksInfo = blocks.ToArray();
            }
        }
コード例 #8
0
        private void ParseInfo(ArchiveListingEntryInfoV2 entryInfo, byte[] uncompressedData, out long sector, out long uncompressedSize, out long compressedSize, out string name)
        {
            string[] info;
            unsafe
            {
                fixed (byte* ptr = &uncompressedData[entryInfo.Offset])
                {
                    string str = new string((sbyte*)ptr);
                    info = str.Split(':');
                }
            }

            if (info.Length < 4)
            {
                name = String.Join(":", info);
                sector = -1;
                uncompressedSize = -1;
                compressedSize = -1;
            }
            else
            {
                sector = long.Parse(info[0], NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                uncompressedSize = long.Parse(info[1], NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                compressedSize = long.Parse(info[2], NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                name = info[3];
            }
        }
コード例 #9
0
        private void ParseEntries(ArchiveListingEntryInfoV2[] entries, ArchiveListingCompressedData data, ArchiveListing result)
        {
            byte[] buff = new byte[0];

            for (int currentBlock = -1, i = 0; i < entries.Length; i++)
            {
                ArchiveListingEntryInfoV2 entryInfoV2 = entries[i];
                if (entryInfoV2.BlockNumber != currentBlock)
                {
                    currentBlock = entryInfoV2.BlockNumber;
                    buff = data.AcquireData(currentBlock);
                }

                string name;
                long sector, uncompressedSize, compressedSize;
                ParseInfo(entryInfoV2, buff, out sector, out uncompressedSize, out compressedSize, out name);

                ArchiveEntry entry = new ArchiveEntry(name, sector, compressedSize, uncompressedSize)
                {
                    UnknownNumber = entryInfoV2.UnknownNumber,
                    UnknownValue = entryInfoV2.UnknownValue
                };

                result.Add(entry);
                _progressIncrement.NullSafeInvoke(1);
            }
        }