public bool ReadUTF(EndianReader br) { long offset = br.BaseStream.Position; if (tools.ReadCString(br, 4) != "@UTF") { return(false); } table_size = br.ReadInt32(); rows_offset = br.ReadInt32(); strings_offset = br.ReadInt32(); data_offset = br.ReadInt32(); // CPK Header & UTF Header are ignored, so add 8 to each offset rows_offset += (offset + 8); strings_offset += (offset + 8); data_offset += (offset + 8); table_name = br.ReadInt32(); num_columns = br.ReadInt16(); row_length = br.ReadInt16(); num_rows = br.ReadInt32(); //read Columns columns = new List <COLUMN>(); COLUMN column; for (int i = 0; i < num_columns; i++) { column = new COLUMN(); column.flags = br.ReadByte(); if (column.flags == 0) { br.BaseStream.Seek(3, SeekOrigin.Current); column.flags = br.ReadByte(); } column.name = tools.ReadCString(br, -1, (long)(br.ReadInt32() + strings_offset)); columns.Add(column); } //read Rows rows = new List <ROWS>(); ROWS current_entry; ROW current_row; int storage_flag; for (int j = 0; j < num_rows; j++) { br.BaseStream.Seek(rows_offset + (j * row_length), SeekOrigin.Begin); current_entry = new ROWS(); for (int i = 0; i < num_columns; i++) { current_row = new ROW(); storage_flag = (columns[i].flags & (int)COLUMN_FLAGS.STORAGE_MASK); if (storage_flag == (int)COLUMN_FLAGS.STORAGE_NONE) // 0x00 { current_entry.rows.Add(current_row); continue; } if (storage_flag == (int)COLUMN_FLAGS.STORAGE_ZERO) // 0x10 { current_entry.rows.Add(current_row); continue; } if (storage_flag == (int)COLUMN_FLAGS.STORAGE_CONSTANT) // 0x30 { current_entry.rows.Add(current_row); continue; } // 0x50 current_row.type = columns[i].flags & (int)COLUMN_FLAGS.TYPE_MASK; current_row.position = br.BaseStream.Position; switch (current_row.type) { case 0: case 1: current_row.uint8 = br.ReadByte(); break; case 2: case 3: current_row.uint16 = br.ReadUInt16(); break; case 4: case 5: current_row.uint32 = br.ReadUInt32(); break; case 6: case 7: current_row.uint64 = br.ReadUInt64(); break; case 8: current_row.ufloat = br.ReadSingle(); break; case 0xA: current_row.str = tools.ReadCString(br, -1, br.ReadInt32() + strings_offset); break; case 0xB: long position = br.ReadInt32() + data_offset; current_row.position = position; current_row.data = tools.GetData(br, position, br.ReadInt32()); break; default: throw new NotImplementedException(); } current_entry.rows.Add(current_row); } rows.Add(current_entry); } return(true); }
/// <summary> /// </summary> /// <param name="reader"></param> /// <returns></returns> public bool ReadUtf(EndianReader reader) { var offset = reader.BaseStream.Position + 8; if (Tools.ReadCString(reader, 4) != "@UTF") { return(false); } Columns = new List <Column>(); TableSize = reader.ReadInt32(); RowsOffset = reader.ReadInt32(); StringsOffset = reader.ReadInt32(); DataOffset = reader.ReadInt32(); DataOffset += offset; RowsOffset += offset; StringsOffset += offset; TableName = reader.ReadInt32(); ColumnCount = reader.ReadInt16(); RowLength = reader.ReadInt16(); RowCount = reader.ReadInt32(); for (var position = 0; position < ColumnCount; position++) { var column = new Column { Flags = reader.ReadByte() }; if (column.Flags == 0) { reader.BaseStream.Seek(3, SeekOrigin.Current); column.Flags = reader.ReadByte(); } column.Name = Tools.ReadCString(reader, -1, reader.ReadInt32() + StringsOffset); Columns.Add(column); } Rows = new List <List <Row> >(); for (var rowIndex = 0; rowIndex < RowCount; rowIndex++) { reader.BaseStream.Seek(RowsOffset + rowIndex * RowLength, SeekOrigin.Begin); var entries = new List <Row>(); for (var columnIndex = 0; columnIndex < ColumnCount; columnIndex++) { var row = new Row(); switch ((ColumnFlags)Columns[columnIndex].Flags & ColumnFlags.StorageMask) { case ColumnFlags.StorageNone: entries.Add(row); continue; case ColumnFlags.StorageZero: entries.Add(row); continue; case ColumnFlags.StorageConstant: entries.Add(row); continue; } row.Position = reader.BaseStream.Position; row.Type = Columns[columnIndex].Flags & (int)ColumnFlags.TypeMask; switch (row.Type) { case 0x00: case 0x01: row.Uint8 = reader.ReadByte(); break; case 0x02: case 0x03: row.Uint16 = reader.ReadUInt16(); break; case 0x04: case 0x05: row.Uint32 = reader.ReadUInt32(); break; case 0x06: case 0x07: row.Uint64 = reader.ReadUInt64(); break; case 0x08: row.Ufloat = reader.ReadSingle(); break; case 0x0A: row.Str = Tools.ReadCString(reader, -1, reader.ReadInt32() + StringsOffset); break; case 0x0B: row.Position = reader.ReadInt32() + DataOffset; row.Data = Tools.GetData(reader, row.Position, reader.ReadInt32()); break; default: continue; } entries.Add(row); } Rows.Add(entries); } return(true); }