Esempio n. 1
0
        public void WriteV10(FileStream mainStream)
        {
            using (var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true))
            {
                var header = new LSPKHeader10
                {
                    Version      = (uint)Version,
                    NumFiles     = (UInt32)_package.Files.Count,
                    FileListSize = (UInt32)(Marshal.SizeOf(typeof(FileEntry13)) * _package.Files.Count)
                };
                header.DataOffset = (UInt32)Marshal.SizeOf(typeof(LSPKHeader10)) + 4 + header.FileListSize;
                int paddingLength = PaddingLength();
                if (header.DataOffset % paddingLength > 0)
                {
                    header.DataOffset += (UInt32)(paddingLength - header.DataOffset % paddingLength);
                }

                // Write a placeholder instead of the actual headers; we'll write them after we
                // compressed and flushed all files to disk
                var placeholder = new byte[header.DataOffset];
                writer.Write(placeholder);

                long totalSize    = _package.Files.Sum(p => (long)p.Size());
                long currentSize  = 0;
                var  writtenFiles = new List <PackagedFileInfo>();
                foreach (AbstractFileInfo file in _package.Files)
                {
                    WriteProgress(file, currentSize, totalSize);
                    writtenFiles.Add(WriteFile(file));
                    currentSize += file.Size();
                }

                mainStream.Seek(0, SeekOrigin.Begin);
                writer.Write(Package.Signature);
                header.NumParts    = (UInt16)_streams.Count;
                header.SomePartVar = 0; // ???
                BinUtils.WriteStruct(writer, ref header);

                foreach (PackagedFileInfo file in writtenFiles)
                {
                    FileEntry13 entry = file.MakeEntryV13();
                    if (entry.ArchivePart == 0)
                    {
                        entry.OffsetInFile -= header.DataOffset;
                    }

                    // v10 packages don't support compression level in the flags field
                    entry.Flags &= 0x0f;
                    BinUtils.WriteStruct(writer, ref entry);
                }
            }
        }
Esempio n. 2
0
        public void WriteV7(FileStream mainStream)
        {
            if (Compression == CompressionMethod.LZ4)
            {
                throw new ArgumentException("LZ4 compression is only supported by V10 and later package versions");
            }

            using (var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true))
            {
                var header = new LSPKHeader7();
                header.Version      = Version;
                header.NumFiles     = (UInt32)package.Files.Count;
                header.FileListSize = (UInt32)(Marshal.SizeOf(typeof(FileEntry7)) * package.Files.Count);
                header.DataOffset   = (UInt32)Marshal.SizeOf(typeof(LSPKHeader7)) + header.FileListSize;
                var paddingLength = PaddingLength();
                if (header.DataOffset % paddingLength > 0)
                {
                    header.DataOffset += (UInt32)(paddingLength - (header.DataOffset % paddingLength));
                }

                // Write a placeholder instead of the actual headers; we'll write them after we
                // compressed and flushed all files to disk
                var placeholder = new byte[header.DataOffset];
                writer.Write(placeholder);

                long totalSize   = package.Files.Sum(p => (long)p.Size());
                long currentSize = 0;
                List <PackagedFileInfo> writtenFiles = new List <PackagedFileInfo>();
                foreach (var file in this.package.Files)
                {
                    writeProgress(file, currentSize, totalSize);
                    writtenFiles.Add(WriteFile(file));
                    currentSize += file.Size();
                }

                mainStream.Seek(0, SeekOrigin.Begin);
                header.LittleEndian = 0;
                header.NumParts     = (UInt16)streams.Count;
                BinUtils.WriteStruct <LSPKHeader7>(writer, ref header);

                foreach (var file in writtenFiles)
                {
                    var entry = file.MakeEntryV7();
                    if (entry.ArchivePart == 0)
                    {
                        entry.OffsetInFile -= header.DataOffset;
                    }

                    BinUtils.WriteStruct <FileEntry7>(writer, ref entry);
                }
            }
        }
Esempio n. 3
0
        public void WriteV13(FileStream mainStream)
        {
            long totalSize   = _package.Files.Sum(p => (long)p.Size());
            long currentSize = 0;

            var writtenFiles = new List <PackagedFileInfo>();

            foreach (AbstractFileInfo file in _package.Files)
            {
                WriteProgress(file, currentSize, totalSize);
                writtenFiles.Add(WriteFile(file));
                currentSize += file.Size();
            }

            using (var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true))
            {
                var header = new LSPKHeader13
                {
                    Version        = (uint)Version,
                    FileListOffset = (UInt32)mainStream.Position
                };

                writer.Write((UInt32)writtenFiles.Count);

                var fileList       = new MemoryStream();
                var fileListWriter = new BinaryWriter(fileList);
                foreach (PackagedFileInfo file in writtenFiles)
                {
                    FileEntry13 entry = file.MakeEntryV13();
                    BinUtils.WriteStruct(fileListWriter, ref entry);
                }

                byte[] fileListBuf = fileList.ToArray();
                fileListWriter.Dispose();
                byte[] compressedFileList = LZ4Codec.EncodeHC(fileListBuf, 0, fileListBuf.Length);

                writer.Write(compressedFileList);

                header.FileListSize = (UInt32)mainStream.Position - header.FileListOffset;
                header.NumParts     = (UInt16)_streams.Count;
                header.Priority     = _package.Metadata.Priority;
                header.Flags        = (byte)_package.Metadata.Flags;
                header.Md5          = ComputeArchiveHash();
                BinUtils.WriteStruct(writer, ref header);

                writer.Write((UInt32)(8 + Marshal.SizeOf(typeof(LSPKHeader13))));
                writer.Write(Package.Signature);
            }
        }
Esempio n. 4
0
        public void WriteV13(FileStream mainStream)
        {
            long totalSize   = package.Files.Sum(p => (long)p.Size());
            long currentSize = 0;
            List <PackagedFileInfo> writtenFiles = new List <PackagedFileInfo>();

            foreach (var file in this.package.Files)
            {
                writeProgress(file, currentSize, totalSize);
                writtenFiles.Add(WriteFile(file));
                currentSize += file.Size();
            }

            using (var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true))
            {
                var header = new LSPKHeader13();
                header.Version        = Version;
                header.FileListOffset = (UInt32)mainStream.Position;

                writer.Write((UInt32)writtenFiles.Count);

                var fileList       = new MemoryStream();
                var fileListWriter = new BinaryWriter(fileList);
                foreach (var file in writtenFiles)
                {
                    var entry = file.MakeEntryV13();
                    BinUtils.WriteStruct <FileEntry13>(fileListWriter, ref entry);
                }

                var fileListBuf = fileList.ToArray();
                fileListWriter.Dispose();
                var compressedFileList = LZ4Codec.EncodeHC(fileListBuf, 0, fileListBuf.Length);

                writer.Write(compressedFileList);

                header.FileListSize = (UInt32)mainStream.Position - header.FileListOffset;
                header.NumParts     = (UInt16)streams.Count;
                header.SomePartVar  = 0; // ???
                header.ArchiveGuid  = Guid.NewGuid();
                BinUtils.WriteStruct <LSPKHeader13>(writer, ref header);

                writer.Write((UInt32)(8 + Marshal.SizeOf(typeof(LSPKHeader13))));
                writer.Write(Package.Signature);
            }
        }
Esempio n. 5
0
        private void WriteNodeAttributesV2(Node node)
        {
            UInt32 lastOffset = (UInt32)ValueStream.Position;

            foreach (KeyValuePair <string, NodeAttribute> entry in node.Attributes)
            {
                WriteAttributeValue(ValueWriter, entry.Value);

                var attributeInfo = new AttributeEntryV2();
                var length        = (UInt32)ValueStream.Position - lastOffset;
                attributeInfo.TypeAndLength      = (UInt32)entry.Value.Type | (length << 6);
                attributeInfo.NameHashTableIndex = AddStaticString(entry.Key);
                attributeInfo.NodeIndex          = NextNodeIndex;
                BinUtils.WriteStruct <AttributeEntryV2>(AttributeWriter, ref attributeInfo);
                NextAttributeIndex++;

                lastOffset = (UInt32)ValueStream.Position;
            }
        }
Esempio n. 6
0
        private void WriteFileListV15(BinaryWriter metadataWriter, List <PackagedFileInfo> files)
        {
            byte[] fileListBuf;
            using (var fileList = new MemoryStream())
                using (var fileListWriter = new BinaryWriter(fileList))
                {
                    foreach (PackagedFileInfo file in files)
                    {
                        FileEntry15 entry = file.MakeEntryV15();
                        BinUtils.WriteStruct(fileListWriter, ref entry);
                    }

                    fileListBuf = fileList.ToArray();
                }

            byte[] compressedFileList = LZ4Codec.EncodeHC(fileListBuf, 0, fileListBuf.Length);

            metadataWriter.Write((UInt32)files.Count);
            metadataWriter.Write((UInt32)compressedFileList.Length);
            metadataWriter.Write(compressedFileList);
        }
Esempio n. 7
0
        public void Write(Resource resource)
        {
            Compression      = CompressionMethod.LZ4;
            CompressionLevel = CompressionLevel.MaxCompression;

            using (this.Writer = new BinaryWriter(Stream, Encoding.Default, true))
                using (this.NodeStream = new MemoryStream())
                    using (this.NodeWriter = new BinaryWriter(NodeStream))
                        using (this.AttributeStream = new MemoryStream())
                            using (this.AttributeWriter = new BinaryWriter(AttributeStream))
                                using (this.ValueStream = new MemoryStream())
                                    using (this.ValueWriter = new BinaryWriter(ValueStream))
                                    {
                                        NextNodeIndex      = 0;
                                        NextAttributeIndex = 0;
                                        NodeIndices        = new Dictionary <Node, int>();
                                        StringHashMap      = new List <List <string> >(StringHashMapSize);
                                        while (StringHashMap.Count < StringHashMapSize)
                                        {
                                            StringHashMap.Add(new List <string>());
                                        }

                                        WriteRegions(resource);

                                        byte[] stringBuffer = null;
                                        using (var stringStream = new MemoryStream())
                                            using (var stringWriter = new BinaryWriter(stringStream))
                                            {
                                                WriteStaticStrings(stringWriter);
                                                stringBuffer = stringStream.ToArray();
                                            }

                                        var nodeBuffer      = NodeStream.ToArray();
                                        var attributeBuffer = AttributeStream.ToArray();
                                        var valueBuffer     = ValueStream.ToArray();

                                        var header = new Header();
                                        header.Magic         = BitConverter.ToUInt32(Header.Signature, 0);
                                        header.Version       = Version;
                                        header.EngineVersion = (resource.Metadata.majorVersion << 24) |
                                                               (resource.Metadata.minorVersion << 16) |
                                                               (resource.Metadata.revision << 8) |
                                                               resource.Metadata.buildNumber;

                                        bool   chunked              = header.Version >= (ulong)FileVersion.VerChunkedCompress;
                                        byte[] stringsCompressed    = BinUtils.Compress(stringBuffer, Compression, CompressionLevel);
                                        byte[] nodesCompressed      = BinUtils.Compress(nodeBuffer, Compression, CompressionLevel, chunked);
                                        byte[] attributesCompressed = BinUtils.Compress(attributeBuffer, Compression, CompressionLevel, chunked);
                                        byte[] valuesCompressed     = BinUtils.Compress(valueBuffer, Compression, CompressionLevel, chunked);

                                        header.StringsUncompressedSize    = (UInt32)stringBuffer.Length;
                                        header.StringsSizeOnDisk          = (UInt32)stringsCompressed.Length;
                                        header.NodesUncompressedSize      = (UInt32)nodeBuffer.Length;
                                        header.NodesSizeOnDisk            = (UInt32)nodesCompressed.Length;
                                        header.AttributesUncompressedSize = (UInt32)attributeBuffer.Length;
                                        header.AttributesSizeOnDisk       = (UInt32)attributesCompressed.Length;
                                        header.ValuesUncompressedSize     = (UInt32)valueBuffer.Length;
                                        header.ValuesSizeOnDisk           = (UInt32)valuesCompressed.Length;
                                        header.CompressionFlags           = BinUtils.MakeCompressionFlags(Compression, CompressionLevel);
                                        header.Unknown2 = 0;
                                        header.Unknown3 = 0;
                                        header.Extended = ExtendedNodes ? 1u : 0u;
                                        BinUtils.WriteStruct <Header>(Writer, ref header);

                                        Writer.Write(stringsCompressed, 0, stringsCompressed.Length);
                                        Writer.Write(nodesCompressed, 0, nodesCompressed.Length);
                                        Writer.Write(attributesCompressed, 0, attributesCompressed.Length);
                                        Writer.Write(valuesCompressed, 0, valuesCompressed.Length);
                                    }
        }