private static CpkColumnInfo ReadColumn(BinaryReaderX tableBr, BinaryReaderX stringBr, BinaryReaderX dataBr) { // Read column info var flags = tableBr.ReadByte(); var nameOffset = tableBr.ReadInt32(); // Resolve final information var name = CpkSupport.ReadString(stringBr, nameOffset); var storage = (CpkColumnStorage)(flags >> 4); var type = (CpkDataType)(flags & 0xF); switch (storage) { case CpkColumnStorage.Const: return(CpkColumnInfo.CreateConst(name, CpkValue.Read(type, tableBr, stringBr, dataBr))); case CpkColumnStorage.Default: return(CpkColumnInfo.CreateZero(name, type)); case CpkColumnStorage.Row: return(CpkColumnInfo.CreateRow(name, type)); default: throw new InvalidOperationException($"Unknown storage type '{storage}'."); } }
public static CpkTable Create(Stream utfStream, string tableMagic) { // Read table info using var utfBr = new BinaryReaderX(utfStream, ByteOrder.BigEndian); var tableInfo = utfBr.ReadType <CpkTableInfo>(); // Create readers var tableStream = new SubStream(utfStream, 0x8, tableInfo.tableSize); var stringStream = new SubStream(tableStream, tableInfo.stringsOffset, tableInfo.binaryOffset - tableInfo.stringsOffset); var dataStream = new SubStream(tableStream, tableInfo.binaryOffset, tableInfo.tableSize - tableInfo.binaryOffset); using var tableBr = new BinaryReaderX(tableStream, ByteOrder.BigEndian); using var stringBr = new BinaryReaderX(stringStream, ByteOrder.BigEndian); using var dataBr = new BinaryReaderX(dataStream, ByteOrder.BigEndian); // Read table name var name = CpkSupport.ReadString(stringBr, tableInfo.nameOffset); // Read columns tableStream.Position = 0x18; var columns = new CpkColumnInfo[tableInfo.columnCount]; for (var i = 0; i < tableInfo.columnCount; i++) { columns[i] = ReadColumn(tableBr, stringBr, dataBr); } // Read rows tableStream.Position = tableInfo.valuesOffset; var rows = new CpkRow[tableInfo.rowCount]; for (var i = 0; i < tableInfo.rowCount; i++) { rows[i] = ReadRow(tableBr, stringBr, dataBr, columns); } return(new CpkTable(tableMagic, name, rows)); }