From 177da650dde785abbee7ed446e71115839082517 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 13 Aug 2011 18:06:09 +1000 Subject: CGE: Fix loading of vol.cat file to be endian safe --- engines/cge/btfile.cpp | 41 +++++++++++++++++++++++++++++++++++------ engines/cge/btfile.h | 16 ++++++++-------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/engines/cge/btfile.cpp b/engines/cge/btfile.cpp index 1f987340b7..7ecfa94e9b 100644 --- a/engines/cge/btfile.cpp +++ b/engines/cge/btfile.cpp @@ -31,6 +31,7 @@ #include "cge/cge.h" #include "common/debug.h" #include "common/debug-channels.h" +#include "common/memstream.h" namespace CGE { @@ -61,8 +62,8 @@ void BtFile::putPage(int lev, bool hard) { debugC(1, kCGEDebugFile, "BtFile::putPage(%d, %s)", lev, hard ? "true" : "false"); if (hard || _buff[lev]._updt) { - seek(_buff[lev]._pgNo * sizeof(BtPage)); - write((uint8 *) _buff[lev]._page, sizeof(BtPage)); + seek(_buff[lev]._pgNo * kBtSize); + write((uint8 *) _buff[lev]._page, kBtSize); _buff[lev]._updt = false; } } @@ -72,17 +73,25 @@ BtPage *BtFile::getPage(int lev, uint16 pgn) { debugC(1, kCGEDebugFile, "BtFile::getPage(%d, %d)", lev, pgn); if (_buff[lev]._pgNo != pgn) { - int32 pos = pgn * sizeof(BtPage); + int32 pos = pgn * kBtSize; putPage(lev, false); _buff[lev]._pgNo = pgn; if (size() > pos) { - seek((uint32) pgn * sizeof(BtPage)); - read((uint8 *) _buff[lev]._page, sizeof(BtPage)); + seek((uint32) pgn * kBtSize); + + // Read in the page + byte buffer[kBtSize]; + int bytesRead = read(buffer, kBtSize); + + // Unpack it into the page structure + Common::MemoryReadStream stream(buffer, bytesRead, DisposeAfterUse::NO); + _buff[lev]._page->read(stream); + _buff[lev]._updt = false; } else { + memset(&_buff[lev]._page, 0, kBtSize); _buff[lev]._page->_hea._count = 0; _buff[lev]._page->_hea._down = kBtValNone; - memset(_buff[lev]._page->_data, '\0', sizeof(_buff[lev]._page->_data)); _buff[lev]._updt = true; } _buff[lev]._indx = -1; @@ -152,4 +161,24 @@ void BtFile::make(BtKeypack *keypack, uint16 count) { } } +void BtPage::read(Common::ReadStream &s) { + _hea._count = s.readUint16LE(); + _hea._down = s.readUint16LE(); + + if (_hea._down == kBtValNone) { + // Leaf list + for (int i = 0; i < kBtLeafCount; ++i) { + s.read(_lea[i]._key, kBtKeySize); + _lea[i]._mark = s.readUint32LE(); + _lea[i]._size = s.readUint16LE(); + } + } else { + // Root index + for (int i = 0; i < kBtInnerCount; ++i) { + s.read(_inn[i]._key, kBtKeySize); + _inn[i]._down = s.readUint16LE(); + } + } +} + } // End of namespace CGE diff --git a/engines/cge/btfile.h b/engines/cge/btfile.h index 6b7155d43d..26b008bea6 100644 --- a/engines/cge/btfile.h +++ b/engines/cge/btfile.h @@ -29,18 +29,19 @@ #define __CGE_BTFILE__ #include "cge/general.h" +#include "common/stream.h" namespace CGE { #define kBtSize 1024 #define kBtKeySize 13 #define kBtLevel 2 +#define kBtInnerCount ((kBtSize - 4 /*sizeof(Hea) */) / (kBtKeySize + 2 /*sizeof(Inner) */)) +#define kBtLeafCount ((kBtSize - 4 /*sizeof(Hea) */) / (kBtKeySize + 4 + 2 /*sizeof(BtKeypack) */)) #define kBtValNone 0xFFFF #define kBtValRoot 0 -#include "common/pack-start.h" // START STRUCT PACKING - struct BtKeypack { char _key[kBtKeySize]; uint32 _mark; @@ -61,16 +62,15 @@ struct BtPage { Hea _hea; union { // dummy filler to make proper size of union - uint8 _data[kBtSize - sizeof(Hea)]; + uint8 _data[kBtSize - 4 /*sizeof(Hea) */]; // inner version of data: key + word-sized page link - Inner _inn[(kBtSize - sizeof(Hea)) / sizeof(Inner)]; + Inner _inn[kBtInnerCount]; // leaf version of data: key + all user data - BtKeypack _lea[(kBtSize - sizeof(Hea)) / sizeof(BtKeypack)]; + BtKeypack _lea[kBtLeafCount]; }; -}; - -#include "common/pack-end.h" // END STRUCT PACKING + void read(Common::ReadStream &s); +}; class BtFile : public IoHand { struct { -- cgit v1.2.3