using PckStudio.Classes.FileTypes; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PckStudio.Classes.IO { internal class PCKFileWriter { internal bool isLittleEndian = false; internal PCKFile _file; public static void Write(Stream stream, PCKFile file, bool isLittleEndian) { new PCKFileWriter(file, isLittleEndian).WriteFileToStream(stream); } private PCKFileWriter(PCKFile file, bool isLittleEndian) { _file = file; this.isLittleEndian = isLittleEndian; } private void WriteFileToStream(Stream stream) { WriteInt(stream, _file.type); WriteMetaEntries(stream); WriteFileEntries(stream); } internal void WriteInt(Stream stream, int value) { byte[] buffer = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian && !isLittleEndian) Array.Reverse(buffer); stream.Write(buffer, 0, 4); } internal void WriteString(Stream stream, string s) { WriteInt(stream, s.Length); byte[] byteString = Encoding.BigEndianUnicode.GetBytes(s); stream.Write(byteString, 0, byteString.Length); } internal void WriteMetaEntries(Stream stream) { WriteInt(stream, _file.meta_data.Count); bool has_xmlverion_tag = false; foreach (var metaEntry in _file.meta_data) { if (metaEntry == "XMLVERION") has_xmlverion_tag = true; WriteInt(stream, _file.meta_data.IndexOf(metaEntry)); WriteString(stream, metaEntry); WriteInt(stream, 0); } if (has_xmlverion_tag) WriteInt(stream, 0); } internal void WriteFileEntries(Stream stream) { WriteInt(stream, _file.file_entries.Count); foreach (var entry in _file.file_entries) { WriteInt(stream, entry.size); WriteInt(stream, entry.type); WriteString(stream, entry.name); WriteInt(stream, 0); } foreach (var entry in _file.file_entries) { WriteInt(stream, entry.properties.Count); foreach (var property in entry.properties) { if (!_file.meta_data.Contains(property.Item1)) throw new Exception("Tag not in Meta: " + property.Item1); WriteInt(stream, _file.meta_data.IndexOf(property.Item1)); WriteString(stream, property.Item2); WriteInt(stream, 0); } stream.Write(entry.data, 0, entry.size); } } } }