Files
PCK-Studio/MinecraftUSkinEditor/Classes/IO/PCK/PCKFileWriter.cs
2022-06-09 02:00:09 +02:00

91 lines
2.9 KiB
C#

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