public static DTBFile FromFile(string path, DTBEncoding encoding) { using (FileStream fs = File.OpenRead(path)) { using (AwesomeReader ar = new AwesomeReader(fs)) { return(FromStream(ar, encoding)); } } }
public static DTBFile FromStream(AwesomeReader ar, DTBEncoding encoding) { byte firstByte = ar.ReadByte(); if (firstByte != 1) { throw new Exception("Invalid first DTB byte. Expected 1."); } short itemCount; int version; DTBFile dtb = new DTBFile(); dtb.Encoding = encoding; if (encoding == DTBEncoding.FME) { ar.ReadInt32(); // Always 0 } if (encoding != DTBEncoding.RBVR) { itemCount = ar.ReadInt16(); version = ar.ReadInt32(); // Reads version. Should be either 0 or 1 } else { version = ar.ReadInt32(); // Reads version. Should be either 0 or 1 itemCount = ar.ReadInt16(); ar.ReadInt16(); // Unknown, always 1? } if (version == 0) { dtb.Embedded = true; } else if (version == 1) { dtb.Embedded = false; // Much more common } //else throw new Exception("Invalid DTB version. Expected 0 or 1."); for (int i = 0; i < itemCount; i++) { ParseItem(ar, dtb.Items, encoding); } return(dtb); }
private static void ParseItem(AwesomeReader ar, ParentItem parent, DTBEncoding encoding) { int itemID = ar.ReadInt32(); DTBItem item; switch (itemID) { // Integer case 0x00: item = new IntegerItem(ar.ReadInt32()); break; // Float case 0x01: item = new FloatItem(ar.ReadSingle()); break; // String case 0x02: // Variable case 0x04: // MiloEmbedded case 0x05: // Keyword case 0x06: // KDataUnhandled case 0x07: // IfNDef case 0x08: // Else case 0x09: // EndIf case 0x12: // Default case 0x20: // Define case 0x21: // Include case 0x22: // Merge case 0x23: // IfNDef case 0x24: // Mysterious24 item = new StringItem((StringType)itemID, ar.ReadString()); break; case 0x10: // Default case 0x11: // Script case 0x13: // Property item = new ParentItem((ParentType)itemID); short itemCount; if (encoding == DTBEncoding.Classic) { itemCount = ar.ReadInt16(); ar.ReadInt32(); // Reads line number } else // Fantasia / RBVR { ar.ReadInt32(); // Unknown (RBVR - Always 1) itemCount = (encoding == DTBEncoding.RBVR) ? ar.ReadInt16() : (short)ar.ReadInt32(); ar.ReadInt16(); } for (int i = 0; i < itemCount; i++) { // Recursion: Like a boss ParseItem(ar, item as ParentItem, encoding); } break; default: throw new Exception(string.Format("Unknown chunk: {0} at {1}", itemID, ar.BaseStream.Position)); } parent.Add(item); }