예제 #1
0
 public void Copy_stream_with_undefined_length()
 {
     var bytes = GetBytes(1000);
     var source = new MemoryStream(bytes);
     var target = new MemoryStream();
     var count = source.CopyToStream(target, -1, new Result<long>()).Wait();
     Assert.AreEqual(bytes.LongLength, count);
     Assert.AreEqual(bytes, target.ToArray());
 }
예제 #2
0
 public void Copy_memorized_stream_chunk()
 {
     var source = new MemoryStream();
     var writer = new StreamWriter(source) { AutoFlush = true };
     writer.Write("abcdefghijklmnop");
     source.Seek(0, SeekOrigin.Begin);
     var target = new MemoryStream();
     Assert.AreEqual(5, source.CopyToStream(target, 5, new Result<long>()).Wait());
     Assert.AreEqual(5, target.Length);
     Assert.AreEqual(5, source.Position);
 }
예제 #3
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);
                    }
                }
            }
        }
예제 #4
0
        public void Write()
        {
            using (MemoryStream headerBuff = new MemoryStream(32768))
            using (MemoryStream textBuff = new MemoryStream(32768))
            {
                ArchiveListingBlockInfo[] blocksInfo;
                ArchiveListingEntryInfoV1[] entriesInfoV1;
                ArchiveListingTextWriter textWriter = new ArchiveListingTextWriter(textBuff);
                textWriter.Write(_listing, out blocksInfo, out entriesInfoV1);

                for (int i = 0; i < entriesInfoV1.Length; i++)
                {
                    entriesInfoV1[i].UnknownNumber = _listing[i].UnknownNumber;
                    entriesInfoV1[i].UnknownValue = _listing[i].UnknownValue;
                }

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

                ArchiveListingHeaderV1 header = new ArchiveListingHeaderV1
                {
                    EntriesCount = entriesInfoV1.Length,
                    BlockOffset = entriesInfoV1.Length * 8 + 12
                };
                header.InfoOffset = header.BlockOffset + blocksInfo.Length * 12;

                headerBuff.WriteStruct(header);
                foreach (ArchiveListingEntryInfoV1 entry in entriesInfoV1)
                    headerBuff.WriteStruct(entry);
                foreach (ArchiveListingBlockInfo block in blocksInfo)
                    headerBuff.WriteStruct(block);

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

                using (Stream output = _accessor.RecreateListing(hederSize + blocksSize))
                {
                    headerBuff.CopyToStream(output, hederSize, buff);
                    textBuff.CopyToStream(output, blocksSize, buff);
                }
            }
        }
예제 #5
0
        private void RecreateEncryptedListing(MemoryStream headerBuff, int hederSize, MemoryStream textBuff, int blocksSize, byte[] buff)
        {
            using (TempFileProvider tmpProvider = new TempFileProvider("filelist", ".win32.bin"))
            {
                using (Stream output = tmpProvider.Create())
                {
                    headerBuff.CopyToStream(output, hederSize, buff);
                    textBuff.CopyToStream(output, blocksSize, buff);
                }

                Process encrypter = new Process
                {
                    StartInfo = new ProcessStartInfo()
                    {
                        FileName = @"Resources\Executable\ffxiiicrypt.exe",
                        Arguments = "-e \"" + tmpProvider.FilePath + "\" 2",
                        CreateNoWindow = true,
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        RedirectStandardError = true
                    }
                };
                encrypter.Start();
                Task<string> erroMessage = encrypter.StandardError.ReadToEndAsync();
                Task<string> outputMessage = encrypter.StandardOutput.ReadToEndAsync();
                encrypter.WaitForExit();
                if (encrypter.ExitCode != 0)
                {
                    StringBuilder sb = new StringBuilder("Decryption error! Code: ");
                    sb.AppendLine(encrypter.ExitCode.ToString());
                    sb.AppendLine("Error: ");
                    sb.AppendLine(erroMessage.Result);
                    sb.AppendLine("Output: ");
                    sb.AppendLine(outputMessage.Result);

                    throw new InvalidDataException(sb.ToString());
                }

                using (Stream input = tmpProvider.OpenRead())
                using (Stream output = _accessor.RecreateListing((Int32)input.Length))
                    input.CopyToStream(output, (Int32)input.Length, buff);
            }
        }
예제 #6
0
        public void OnWritingCompleted(ArchiveEntry entry, MemoryStream ms, bool? compression)
        {
            ms.Position = 0;

            int compressedSize = 0;
            int uncompressedSize = (int)ms.Length;
            byte[] copyBuff = new byte[Math.Min(uncompressedSize, 32 * 1024)];

            try
            {
                bool compress = uncompressedSize > 256 && (compression ?? entry.IsCompressed);
                if (compress)
                {
                    using (SafeUnmanagedArray buff = new SafeUnmanagedArray(uncompressedSize + 256))
                    using (UnmanagedMemoryStream buffStream = buff.OpenStream(FileAccess.ReadWrite))
                    {
                        compressedSize = ZLibHelper.Compress(ms, buffStream, uncompressedSize);
                        if (uncompressedSize - compressedSize > 256)
                        {
                            using (Stream output = OpenOrAppendBinary(entry, compressedSize))
                            {
                                buffStream.Position = 0;
                                buffStream.CopyToStream(output, compressedSize, copyBuff);
                            }
                            return;
                        }
                    }
                }

                ms.Position = 0;
                compressedSize = uncompressedSize;
                using (Stream output = OpenOrAppendBinary(entry, uncompressedSize))
                    ms.CopyToStream(output, uncompressedSize, copyBuff);
            }
            finally
            {
                entry.Size = compressedSize;
                entry.UncompressedSize = uncompressedSize;
            }
        }