Gibbed.MassEffect3.FileFormats.CoalescedFile.Deserialize C# (CSharp) Method

Deserialize() public method

public Deserialize ( Stream input ) : void
input Stream
return void
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x666D726D && // fmrm
                magic.Swap() != 0x666D726D)
            {
                throw new FormatException();
            }
            var endian = magic == 0x666D726D ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 1)
            {
                throw new FormatException();
            }
            this.Version = version;

            /*var maxKeyLength =*/ input.ReadValueS32(endian);
            var maxValueLength = input.ReadValueS32(endian);

            var stringTableSize = input.ReadValueU32(endian);
            var huffmanSize = input.ReadValueU32(endian);
            var indexSize = input.ReadValueU32(endian);
            var dataSize = input.ReadValueU32(endian);

            var strings = new List<KeyValuePair<uint, string>>();
            using (var data = input.ReadToMemoryStream(stringTableSize))
            {
                var localStringTableSize = data.ReadValueU32(endian);
                if (localStringTableSize != stringTableSize)
                {
                    throw new FormatException();
                }

                var count = data.ReadValueU32(endian);

                var offsets = new List<KeyValuePair<uint, uint>>();
                for (uint i = 0; i < count; i++)
                {
                    var hash = data.ReadValueU32(endian);
                    var offset = data.ReadValueU32(endian);
                    offsets.Add(new KeyValuePair<uint, uint>(hash, offset));
                }

                foreach (var kv in offsets)
                {
                    var hash = kv.Key;
                    var offset = kv.Value;

                    data.Seek(8 + offset, SeekOrigin.Begin);
                    var length = data.ReadValueU16(endian);
                    var text = data.ReadString(length, Encoding.UTF8);

                    if (text.HashCrc32() != hash)
                    {
                        throw new InvalidOperationException();
                    }

                    strings.Add(new KeyValuePair<uint, string>(hash, text));
                }
            }

            Huffman.Pair[] huffmanTree;
            using (var data = input.ReadToMemoryStream(huffmanSize))
            {
                var count = data.ReadValueU16(endian);
                huffmanTree = new Huffman.Pair[count];
                for (ushort i = 0; i < count; i++)
                {
                    var left = data.ReadValueS32(endian);
                    var right = data.ReadValueS32(endian);
                    huffmanTree[i] = new Huffman.Pair(left, right);
                }
            }

            using (var index = input.ReadToMemoryStream(indexSize))
            {
                var totalBits = input.ReadValueS32(endian);
                var data = input.ReadBytes(dataSize);
                var bitArray = new BitArray(data) { Length = totalBits };

                var files = new List<KeyValuePair<string, uint>>();
                var fileCount = index.ReadValueU16(endian);
                for (ushort i = 0; i < fileCount; i++)
                {
                    var nameIndex = index.ReadValueU16(endian);
                    var name = strings[nameIndex].Value;
                    var offset = index.ReadValueU32(endian);
                    files.Add(new KeyValuePair<string, uint>(name, offset));
                }

                foreach (var fileInfo in files.OrderBy(f => f.Key))
                {
                    var file = new Coalesced.File() { Name = fileInfo.Key };

                    index.Seek(fileInfo.Value, SeekOrigin.Begin);
                    var sectionCount = index.ReadValueU16(endian);
                    var sections = new List<KeyValuePair<string, uint>>();
                    for (ushort i = 0; i < sectionCount; i++)
                    {
                        var nameIndex = index.ReadValueU16(endian);
                        var name = strings[nameIndex].Value;
                        var offset = index.ReadValueU32(endian);
                        sections.Add(new KeyValuePair<string, uint>(name, offset));
                    }

                    foreach (var sectionInfo in sections.OrderBy(s => s.Key))
                    {
                        var section = new Dictionary<string, List<Coalesced.Entry>>();

                        index.Seek(fileInfo.Value + sectionInfo.Value, SeekOrigin.Begin);
                        var valueCount = index.ReadValueU16(endian);
                        var values = new List<KeyValuePair<string, uint>>();
                        for (ushort i = 0; i < valueCount; i++)
                        {
                            var nameIndex = index.ReadValueU16(endian);
                            var name = strings[nameIndex].Value;
                            var offset = index.ReadValueU32(endian);
                            values.Add(new KeyValuePair<string, uint>(name, offset));
                        }

                        foreach (var valueInfo in values.OrderBy(v => v.Key))
                        {
                            var value = new List<Coalesced.Entry>();

                            index.Seek(fileInfo.Value + sectionInfo.Value + valueInfo.Value, SeekOrigin.Begin);
                            var itemCount = index.ReadValueU16(endian);

                            for (ushort i = 0; i < itemCount; i++)
                            {
                                var offset = index.ReadValueS32(endian);

                                var type = (offset & 0xE0000000) >> 29;
                                if (type == 1)
                                {
                                    value.Add(new Coalesced.Entry(1, null));
                                }
                                else if (type == 0 || type == 2 || type == 3 || type == 4)
                                {
                                    offset &= 0x1FFFFFFF;
                                    var text = Huffman.Decoder.Decode(
                                        huffmanTree, bitArray, offset, maxValueLength);
                                    value.Add(new Coalesced.Entry(2, text));
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }

                            section.Add(valueInfo.Key, value);
                        }

                        file.Sections.Add(sectionInfo.Key, section);
                    }

                    this.Files.Add(file);
                }
            }

            this.Endian = endian;
        }
    }

Usage Example

Esempio n. 1
0
        public void LoadBIN(string path,string temp)
        {
            var mode = Mode.ToJson;
            if (mode == Mode.ToJson)
            {
                var inputPath = path;
                var outputPath = temp;

                using (var input = System.IO.File.OpenRead(inputPath))
                {
                    var coal = new CoalescedFile();
                    coal.Deserialize(input);

                    var padding = coal.Files.Count.ToString().Length;

                    var setup = new Setup
                    {
                        Endian = coal.Endian,
                        Version = coal.Version,
                    };

                    var counter = 0;
                    foreach (var file in coal.Files)
                    {
                        var iniPath = string.Format("{1}_{0}",
                            Path.GetFileNameWithoutExtension(file.Name),
                            counter.ToString().PadLeft(padding, '0'));
                        iniPath = Path.Combine(outputPath, Path.ChangeExtension(iniPath, ".json"));
                        counter++;

                        setup.Files.Add(Path.GetFileName(iniPath));

                        Directory.CreateDirectory(Path.GetDirectoryName(iniPath));
                        using (var output = System.IO.File.Create(iniPath))
                        {
                            var writer = new StreamWriter(output);
                            writer.Write(JsonConvert.SerializeObject(
                                new FileWrapper()
                                {
                                    Name = file.Name,
                                    Sections = file.Sections,
                                }, Formatting.Indented));
                            writer.Flush();
                        }
                    }

                    Directory.CreateDirectory(outputPath);
                    using (var output = System.IO.File.Create(Path.Combine(outputPath, "@coalesced.json")))
                    {
                        var writer = new StreamWriter(output);
                        writer.Write(JsonConvert.SerializeObject(
                            setup, Formatting.Indented));
                        writer.Flush();
                    }
                }
            }
        }
All Usage Examples Of Gibbed.MassEffect3.FileFormats.CoalescedFile::Deserialize