From 5dcb7b822dc1763cf410d11fe3e6f7e844741a41 Mon Sep 17 00:00:00 2001 From: alcexhim Date: Sat, 4 Oct 2014 15:13:38 -0400 Subject: [PATCH] Added Roxor In the Groove PCK data format (without compression) --- .../FileSystem/Roxor/PCK/PCKDataFormat.cs | 125 ++++++++++++++++++ .../UniversalEditor.Plugins.FileSystem.csproj | 1 + 2 files changed, 126 insertions(+) create mode 100644 CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Roxor/PCK/PCKDataFormat.cs diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Roxor/PCK/PCKDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Roxor/PCK/PCKDataFormat.cs new file mode 100644 index 00000000..dcef00ad --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Roxor/PCK/PCKDataFormat.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using UniversalEditor.IO; +using UniversalEditor.ObjectModels.FileSystem; + +namespace UniversalEditor.DataFormats.FileSystem.Roxor.PCK +{ + public class PCKDataFormat : DataFormat + { + private static DataFormatReference _dfr = null; + public override DataFormatReference MakeReference() + { + if (_dfr == null) + { + _dfr = base.MakeReference(); + _dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All); + _dfr.Filters.Add("Roxor In the Groove PCK archive", new byte?[][] { new byte?[] { (byte)'P', (byte)'C', (byte)'K', (byte)'F' } }, new string[] { "*.pck" }); + _dfr.ExportOptions.Add(new CustomOptionText("Comment", "&Comment: ", String.Empty, 128)); + } + return _dfr; + } + + private string mvarComment = String.Empty; + public string Comment { get { return mvarComment; } set { mvarComment = value; } } + + protected override void LoadInternal(ref ObjectModel objectModel) + { + FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel); + if (fsom == null) throw new ObjectModelNotSupportedException(); + + Reader reader = base.Accessor.Reader; + string signature = reader.ReadFixedLengthString(4); + if (signature != "PCKF") throw new InvalidDataFormatException("File does not begin with 'PCKF'"); + + mvarComment = reader.ReadFixedLengthString(128, Encoding.Windows1252); + mvarComment = mvarComment.TrimNull(); + + uint fileCount = reader.ReadUInt32(); + for (uint i = 0; i < fileCount; i++) + { + uint compressedlength = reader.ReadUInt32(); + uint decompressedLength = reader.ReadUInt32(); + uint offset = reader.ReadUInt32(); + uint fileNameLength = reader.ReadUInt32(); + bool compressed = (reader.ReadUInt32() != 0); + + string fileName = reader.ReadFixedLengthString(fileNameLength, Encoding.Windows1252); + + File file = fsom.AddFile(fileName); + file.Size = decompressedLength; + file.Properties.Add("reader", reader); + file.Properties.Add("offset", offset); + file.Properties.Add("compressed", compressed); + file.Properties.Add("CompressedLength", compressedlength); + file.Properties.Add("DecompressedLength", decompressedLength); + file.DataRequest += file_DataRequest; + } + } + + private void file_DataRequest(object sender, DataRequestEventArgs e) + { + File file = (sender as File); + Reader reader = (Reader)file.Properties["reader"]; + uint offset = (uint)file.Properties["offset"]; + uint compressedLength = (uint)file.Properties["CompressedLength"]; + uint decompressedLength = (uint)file.Properties["DecompressedLength"]; + bool compressed = (bool)file.Properties["compressed"]; + + reader.Seek(offset, SeekOrigin.Begin); + byte[] compressedData = reader.ReadBytes(compressedLength); + byte[] decompressedData = compressedData; + if (compressed) + { + + } + + e.Data = decompressedData; + } + + protected override void SaveInternal(ObjectModel objectModel) + { + FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel); + if (fsom == null) throw new ObjectModelNotSupportedException(); + + Writer writer = base.Accessor.Writer; + writer.WriteFixedLengthString("PCKF"); + writer.WriteFixedLengthString(mvarComment, Encoding.Windows1252, 128); + + File[] files = fsom.GetAllFiles(); + writer.WriteUInt32((uint)files.Length); + + uint offset = 136; + foreach (File file in files) + { + offset += (uint)(20 + file.Name.Length); + } + + byte[][] compressedDatas = new byte[files.Length][]; + for (int i = 0; i < files.Length; i++) + { + File file = files[i]; + bool compressed = false; + byte[] decompressedData = file.GetDataAsByteArray(); + byte[] compressedData = decompressedData; + compressedDatas[i] = compressedData; + + writer.WriteUInt32((uint)compressedData.Length); + writer.WriteUInt32((uint)decompressedData.Length); + writer.WriteUInt32(offset); + writer.WriteUInt32((uint)file.Name.Length); + writer.WriteUInt32((uint)(compressed ? 1 : 0)); + writer.WriteFixedLengthString(file.Name, Encoding.Windows1252, (uint)file.Name.Length); + + offset += (uint)file.Size; + } + for (int i = 0; i < files.Length; i++) + { + writer.WriteBytes(compressedDatas[i]); + } + writer.Flush(); + } + } +} diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj index b4fe5aa4..8536a5f6 100644 --- a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj +++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj @@ -130,6 +130,7 @@ +