public void LoadBinary(string filename) { using (var stream = new BinaryStream(filename)) { Debug.WriteLine(">> Reading infos header..."); var infosOffset = stream.ReadInt32(); var infosCount = stream.ReadInt32(); Use32Bit = ((stream.Length - (infosCount * 0xC)) == infosOffset); Debug.WriteLine(">> Reading FCB header..."); var magic = stream.ReadInt32(); if (magic != Magic) { throw new InvalidOperationException("Bad magic, no FCB data to parse!"); } var type = stream.ReadInt16(); if (type != Type) { throw new InvalidOperationException("FCB library reported the incorrect type?!"); } stream.Position += 2; // ;) var totalCount = stream.ReadInt32(); // * 3 var nodesCount = stream.ReadInt32(); // * 4 var dataOffset = (int)stream.Position; var memSize = ((totalCount * 3) + nodesCount) * 4; var memSizeAlign = Memory.Align(memSize, 16); #if DEBUG Console.WriteLine("[Library.Header]"); Console.WriteLine($" Total: {totalCount}"); Console.WriteLine($" Nodes: {nodesCount}"); Console.WriteLine($" MemSize: {memSize:X8}"); #endif // read the infos first! Debug.WriteLine(">> Reading infos..."); stream.Position = infosOffset; var nInfosTotal = 0; var nInfosNodes = 0; var refDatas = new Dictionary <int, EntityReferenceData>(infosCount); for (int i = 0; i < infosCount; i++) { var refData = new EntityReferenceData(stream, Use32Bit); nInfosTotal += refData.TotalCount; nInfosNodes += refData.NodesCount; refDatas.Add(refData.Offset, refData); } var count1Diff = (totalCount - nInfosTotal); var count2Diff = (nodesCount - nInfosNodes); #if DEBUG Console.WriteLine("[Library.Infos]"); Console.WriteLine($" Total: {nInfosTotal}"); Console.WriteLine($" Nodes: {nInfosNodes}"); Console.WriteLine("[Library.Logging]"); Console.WriteLine($" TotalDiff: {count1Diff}"); Console.WriteLine($" NodesDiff: {count2Diff}"); #endif // read fcb data Debug.WriteLine(">> Reading libraries..."); stream.Position = dataOffset; var root = new NodeClass(stream); Libraries = new List <EntityLibrary>(root.Children.Count); foreach (var library in root.Children) { // deserialize from the class var lib = new EntityLibrary() { Use32Bit = Use32Bit, }; lib.Deserialize(library); // update UIDs foreach (var entry in lib.Entries) { var node = entry.GroupNode; var offset = node.Offset; if (refDatas.ContainsKey(offset)) { var entRef = refDatas[offset]; entry.UID = entRef.UID; } } Libraries.Add(lib); } Console.WriteLine($"Finished reading {Libraries.Count} libraries. Collected {Utils.GetTotalNumberOfNodes(root)} nodes in total."); } }
public void SaveBinary(string filename) { var root = GetNodeClass(); byte[] buffer; Debug.WriteLine(">> Generating binary data..."); using (var stream = new BinaryStream(BufferSize)) { // list of references sorted by their UID var references = GetEntityReferences(true); // we need to write the offset to our infos here Debug.WriteLine(">> Writing infos header..."); var ptr = stream.Position; stream.Position += 4; stream.Write(references.Count); Debug.WriteLine(">> Writing FCB header..."); stream.Write((int)Magic); stream.Write((short)Type); stream.Write((short)MagicNumber.FB); // ;) var nodesCount = Utils.GetTotalNumberOfNodes(root); var attrCount = root.Attributes.Count; if (attrCount == 0) { attrCount = 1; } var totalCount = (nodesCount + attrCount); stream.Write(totalCount); stream.Write(nodesCount); root.Serialize(stream); //Debug.WriteLine(">> Optimizing data..."); //using (var bs = new BinaryStream(BufferSize)) //{ // root.Serialize(bs); // // var dataLen = bs.Position; // bs.SetLength(dataLen); // // var data = OptimizedData.Create(nodesCount, bs.ToArray()); // data.WriteTo(stream); //} var refsOffset = (int)(Memory.Align(stream.Position, 8) - ptr); Debug.WriteLine(">> Writing infos offset..."); stream.Position = ptr; stream.Write(refsOffset); Debug.WriteLine(">> Writing infos..."); stream.Position = refsOffset; foreach (var reference in references) { var refData = new EntityReferenceData(reference) { Use32Bit = Use32Bit, }; refData.Serialize(stream); } var size = (int)stream.Position; buffer = new byte[size]; Debug.WriteLine(">> Copying to buffer..."); stream.Position = 0; stream.Read(buffer, 0, size); } Debug.WriteLine(">> Writing to file..."); File.WriteAllBytes(filename, buffer); }