public static RpDbTableEntry ReadEntry(Stream s, RpDbTable table) { //Create object. RpDbTableEntry entry = new RpDbTableEntry(table, null); entry.offset = (UInt32)s.Position; //First, read in the UUID. UInt32 uuid = ReaderTools.ReadUInt32(s); entry.uuid = uuid; //Read in the lengths. UInt16[] lengths = new UInt16[table.typeOrder.Length]; for (int i = 0; i < table.typeOrder.Length; i++) { lengths[i] = ReaderTools.ReadUInt16(s); } //Now, read in the data object obj = Activator.CreateInstance(table.type); for (int i = 0; i < table.typeOrder.Length; i++) { Writer.PropIdPair pair = table.typeOrder[i]; //Skip this if the length is zero. (it's null) UInt16 length = lengths[i]; if (length != 0) { //Read in the data. byte[] buf = new byte[length]; s.Read(buf, 0, length); //Todo: Actually get the data from it. //For now, just read it in as a string object d = Encoding.UTF8.GetString(buf); //Now, set it inside the object. pair.prop.SetValue(obj, d, null); } } //Set the entry's object to this. entry.data = obj; //Return the entry. return(entry); }
public static RpDbDatabase ReadDatabase(Stream s, Type[] types) { //Read "RpDb" at the beginning char[] intro = ReaderTools.ReadChars(s, 4); //Read the version. UInt16 version = ReaderTools.ReadUInt16(s); //Skip 32 bytes of reserved space. s.Position += 32; //Read table count. UInt16 tableCount = ReaderTools.ReadUInt16(s); //Create the database object. RpDbDatabase db = new RpDbDatabase(s); //Create the tables array in the database. db.tables = new RpDbTable[tableCount]; //Read the table offsets. UInt32[] tableOffsets = new UInt32[tableCount]; string[] tableNames = new string[tableCount]; //Read each of the offsets and table names. for (int i = 0; i < tableCount; i++) { tableOffsets[i] = ReaderTools.ReadUInt32(s); //Read the name for verification. tableNames[i] = ReaderTools.ReadString(s); } //Read each of the tables, starting at the offsets. UInt32 startingOffset = (UInt32)s.Position; for (int tableId = 0; tableId < tableCount; tableId++) { //Jump to the position offered. s.Position = startingOffset + tableOffsets[tableId]; db.tables[tableId] = TableReader.ReadTable(s, types, db); } //Return the database. return(db); }
public static RpDbTable ReadTable(Stream s, Type[] types, RpDbDatabase database) { //Read the table name. string name = ReaderTools.ReadString(s); //Read the type string typeName = ReaderTools.ReadString(s); //Determine the type. Type t = null; //Loop through types and find match. foreach (Type tt in types) { if (tt.ToString() == typeName) { t = tt; } } //Check if it was found. if (t == null) { throw new Exception("Failed to find type '" + typeName + "'."); } //Create the object. RpDbTable table = new RpDbTable(name, t, database); //Read the number of entries. UInt32 entryCount = ReaderTools.ReadUInt32(s); //Read number of types. UInt16 typeCount = ReaderTools.ReadUInt16(s); //Read the type table in. This'll give us the order. Writer.PropIdPair[] order = new Writer.PropIdPair[typeCount]; for (int i = 0; i < typeCount; i++) { //Read in. UInt16 typeId = ReaderTools.ReadUInt16(s); ClassAttrib attr = null; System.Reflection.PropertyInfo chosenProp = null; //Find this in the object. foreach (var prop in table.type.GetProperties()) { //Check the UUID. ClassAttrib propAttr = Writer.TableWriter.GetUuidFromProperty(prop); //If there is no UUID, skip this. if (propAttr == null) { continue; } //Add this to the order if it matches if (propAttr.uuid == typeId) { attr = propAttr; chosenProp = prop; } } if (attr != null && chosenProp != null) { order[i] = new Writer.PropIdPair(chosenProp, typeId); } else { Console.WriteLine("No attr found for ID " + typeId.ToString() + "."); } } table.typeOrder = order; //Now that we know the order of the types, we can read it in. //Skip 32 bytes of reserved data. s.Position += 32; //Read each of the offsets in. Add them to the dict as we go. for (int i = 0; i < entryCount; i++) { //Read offset UInt32 offset = ReaderTools.ReadUInt32(s); //Read UUID UInt32 uuid = ReaderTools.ReadUInt32(s); //Insert. table.uuidLookup.Add(uuid, offset); } //Now, the data begins. Add the flag. table.tableDataOffset = s.Position; //We can now continue to the next table. return(table); }