diff --git a/pk3DS/Util.cs b/pk3DS/Util.cs index 09d3184..d934d3b 100644 --- a/pk3DS/Util.cs +++ b/pk3DS/Util.cs @@ -623,7 +623,7 @@ internal static void packMini(string path, string ident, string fileName, string { // Write File Offset uint fileOffset = (uint)(dataout.Position + dataOffset); - bo.Write((uint)fileOffset); + bo.Write(fileOffset); // Write File to Stream bd.Write(File.ReadAllBytes(files[i])); @@ -648,6 +648,51 @@ internal static void packMini(string path, string ident, string fileName, string } } } + internal static byte[] packMini(byte[][] fileData, string ident) + { + // Create new Binary with the relevant header bytes + byte[] data = new byte[4]; + data[0] = (byte)ident[0]; + data[1] = (byte)ident[1]; + Array.Copy(BitConverter.GetBytes((ushort)fileData.Length), 0, data, 2, 2); + + int count = fileData.Length; + int dataOffset = 4 + 4 + count * 4; + + // Start the data filling. + using (MemoryStream dataout = new MemoryStream()) + using (MemoryStream offsetMap = new MemoryStream()) + using (BinaryWriter bd = new BinaryWriter(dataout)) + using (BinaryWriter bo = new BinaryWriter(offsetMap)) + { + // For each file... + for (int i = 0; i < count; i++) + { + // Write File Offset + uint fileOffset = (uint)(dataout.Position + dataOffset); + bo.Write(fileOffset); + + // Write File to Stream + bd.Write(fileData[i]); + + // Pad the Data MemoryStream with Zeroes until len%4=0; + while (dataout.Length % 4 != 0) + bd.Write((byte)0); + // File Offset will be updated as the offset is based off of the Data length. + } + // Cap the File + bo.Write((uint)(dataout.Position + dataOffset)); + + using (var newPack = new MemoryStream()) + using (var header = new MemoryStream(data)) + { + header.WriteTo(newPack); + offsetMap.WriteTo(newPack); + dataout.WriteTo(newPack); + return newPack.ToArray(); + } + } + } internal static void unpackMini(string path, string ident, string outFolder = null) { if (outFolder == null) outFolder = Path.GetDirectoryName(path); @@ -689,5 +734,43 @@ internal static void unpackMini(string path, string ident, string outFolder = nu } File.Delete(path); // File is unpacked. } + internal static byte[][] unpackMini(byte[] fileData, string ident) + { + using (var s = new MemoryStream(fileData)) + using (var br = new BinaryReader(s)) + { + string fx = new string(br.ReadChars(2)); + + if (fx != ident) return null; + + ushort count = br.ReadUInt16(); + byte[][] returnData = new byte[count][]; + + uint[] offsets = new uint[count + 1]; + for (int i = 0; i < count; i++) + offsets[i] = br.ReadUInt32(); + + uint length = br.ReadUInt32(); + offsets[offsets.Length - 1] = length; + + for (int i = 0; i < count; i++) + { + br.BaseStream.Seek(offsets[i], SeekOrigin.Begin); + using (MemoryStream dataout = new MemoryStream()) + { + byte[] data = new byte[0]; + s.CopyTo(dataout, (int)offsets[i]); + int len = (int)offsets[i + 1] - (int)offsets[i]; + + if (len != 0) + { + data = dataout.ToArray(); + Array.Resize(ref data, len); + } + returnData[i] = data; + } + } + } + } } }