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); } } }
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); } } }
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); } }
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); } }
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; } }
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); }
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); } }