Saveload: Tidy up logging of chunk IDs

Add helper to dump chunk IDs as strings
Avoid duplicate logging of load steps for upstream load paths
pull/661/head
Jonathan G Rennison 3 months ago
parent ba1fa3ad29
commit bd2358f6cc

@ -405,7 +405,7 @@ static void SlNullPointers()
}
if (ch.ptrs_proc != nullptr) {
DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
DEBUG(sl, 3, "Nulling pointers for %s", ChunkIDDumper()(ch.id));
ch.ptrs_proc();
}
}
@ -2270,7 +2270,7 @@ void SlLoadTableOrRiffFiltered(const SaveLoadTable &slt)
SlObjectLoadFiltered(nullptr, slt);
if (SlIsTableChunk() && SlIterateArray() != -1) {
uint32_t id = _sl.current_chunk_id;
SlErrorCorruptFmt("Too many %c%c%c%c entries", id >> 24, id >> 16, id >> 8, id);
SlErrorCorruptFmt("Too many %s entries", ChunkIDDumper()(id));
}
}
@ -2409,6 +2409,8 @@ static void SlLoadChunk(const ChunkHandler &ch)
if (ch.special_proc(ch.id, CSLSO_PRE_LOAD) == CSLSOR_LOAD_CHUNK_CONSUMED) return;
}
DEBUG(sl, 2, "Loading chunk %s", ChunkIDDumper()(ch.id));
byte m = SlReadByte();
size_t len;
size_t endoffs;
@ -2438,12 +2440,12 @@ static void SlLoadChunk(const ChunkHandler &ch)
case CH_TABLE:
_sl.array_index = 0;
ch.load_proc();
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
if (_next_offs != 0) SlErrorCorruptFmt("Invalid array length in %s", ChunkIDDumper()(ch.id));
break;
case CH_SPARSE_ARRAY:
case CH_SPARSE_TABLE:
ch.load_proc();
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
if (_next_offs != 0) SlErrorCorruptFmt("Invalid array length in %s", ChunkIDDumper()(ch.id));
break;
default:
if ((m & 0xF) == CH_RIFF) {
@ -2453,7 +2455,7 @@ static void SlLoadChunk(const ChunkHandler &ch)
SlRIFFSpringPPCheck(len);
if (SlXvIsFeaturePresent(XSLFI_RIFF_HEADER_60_BIT)) {
if (len != 0) {
SlErrorCorrupt("RIFF chunk too large");
SlErrorCorruptFmt("RIFF chunk too large: %s", ChunkIDDumper()(ch.id));
}
len = SlReadUint32();
}
@ -2465,17 +2467,17 @@ static void SlLoadChunk(const ChunkHandler &ch)
endoffs = _sl.reader->GetSize() + len;
ch.load_proc();
if (_sl.reader->GetSize() != endoffs) {
DEBUG(sl, 1, "Invalid chunk size: " PRINTF_SIZE " != " PRINTF_SIZE ", (" PRINTF_SIZE ")", _sl.reader->GetSize(), endoffs, len);
SlErrorCorruptFmt("Invalid chunk size - expected to be at position " PRINTF_SIZE ", actually at " PRINTF_SIZE ", length: " PRINTF_SIZE,
endoffs, _sl.reader->GetSize(), len);
DEBUG(sl, 1, "Invalid chunk size: " PRINTF_SIZE " != " PRINTF_SIZE ", (" PRINTF_SIZE ") for %s", _sl.reader->GetSize(), endoffs, len, ChunkIDDumper()(ch.id));
SlErrorCorruptFmt("Invalid chunk size - expected to be at position " PRINTF_SIZE ", actually at " PRINTF_SIZE ", length: " PRINTF_SIZE " for %s",
endoffs, _sl.reader->GetSize(), len, ChunkIDDumper()(ch.id));
}
} else {
SlErrorCorrupt("Invalid chunk type");
SlErrorCorruptFmt("Invalid chunk type for %s", ChunkIDDumper()(ch.id));
}
break;
}
if (_sl.expect_table_header) SlErrorCorruptFmt("Table chunk without header: %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
if (_sl.expect_table_header) SlErrorCorruptFmt("Table chunk without header: %s", ChunkIDDumper()(ch.id));
}
/**
@ -2483,12 +2485,18 @@ static void SlLoadChunk(const ChunkHandler &ch)
* If the chunkhandler is nullptr, the chunk is skipped.
* @param ch The chunkhandler that will be used for the operation, this may be nullptr
*/
static void SlLoadCheckChunk(const ChunkHandler *ch)
static void SlLoadCheckChunk(const ChunkHandler *ch, uint32_t chunk_id)
{
if (ch && ch->special_proc != nullptr) {
if (ch != nullptr && ch->special_proc != nullptr) {
if (ch->special_proc(ch->id, CSLSO_PRE_LOADCHECK) == CSLSOR_LOAD_CHUNK_CONSUMED) return;
}
if (ch == nullptr) {
DEBUG(sl, 1, "Discarding chunk %s", ChunkIDDumper()(chunk_id));
} else {
DEBUG(sl, 2, "Loading chunk %s", ChunkIDDumper()(chunk_id));
}
byte m = SlReadByte();
size_t len;
size_t endoffs;
@ -2518,7 +2526,7 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
case CH_TABLE:
_sl.array_index = 0;
if (ext_flags) {
SlErrorCorruptFmt("CH_ARRAY does not take chunk header extension flags: 0x%X", ext_flags);
SlErrorCorruptFmt("CH_ARRAY does not take chunk header extension flags: 0x%X in %s", ext_flags, ChunkIDDumper()(chunk_id));
}
if (ch && ch->load_check_proc) {
ch->load_check_proc();
@ -2530,7 +2538,7 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
case CH_SPARSE_ARRAY:
case CH_SPARSE_TABLE:
if (ext_flags) {
SlErrorCorruptFmt("CH_SPARSE_ARRAY does not take chunk header extension flags: 0x%X", ext_flags);
SlErrorCorruptFmt("CH_SPARSE_ARRAY does not take chunk header extension flags: 0x%X in %s", ext_flags, ChunkIDDumper()(chunk_id));
}
if (ch && ch->load_check_proc) {
ch->load_check_proc();
@ -2542,7 +2550,7 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
default:
if ((m & 0xF) == CH_RIFF) {
if (ext_flags != (ext_flags & SLCEHF_BIG_RIFF)) {
SlErrorCorruptFmt("Unknown chunk header extension flags for CH_RIFF: 0x%X", ext_flags);
SlErrorCorruptFmt("Unknown chunk header extension flags for CH_RIFF: 0x%X in %s", ext_flags, ChunkIDDumper()(chunk_id));
}
/* Read length */
len = (SlReadByte() << 16) | ((m >> 4) << 24);
@ -2553,12 +2561,12 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
SlErrorCorrupt("RIFF chunk too large");
}
len = SlReadUint32();
if (ext_flags & SLCEHF_BIG_RIFF) SlErrorCorrupt("XSLFI_RIFF_HEADER_60_BIT and SLCEHF_BIG_RIFF both present");
if (ext_flags & SLCEHF_BIG_RIFF) SlErrorCorruptFmt("XSLFI_RIFF_HEADER_60_BIT and SLCEHF_BIG_RIFF both present in %s", ChunkIDDumper()(chunk_id));
}
if (ext_flags & SLCEHF_BIG_RIFF) {
uint64_t full_len = len | (static_cast<uint64_t>(SlReadUint32()) << 28);
if (full_len >= (1LL << 32)) {
SlErrorCorruptFmt("Chunk size too large: " OTTD_PRINTFHEX64, full_len);
SlErrorCorruptFmt("Chunk size too large: " OTTD_PRINTFHEX64 " in %s", full_len, ChunkIDDumper()(chunk_id));
}
len = static_cast<size_t>(full_len);
}
@ -2570,17 +2578,17 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
SlSkipBytes(len);
}
if (_sl.reader->GetSize() != endoffs) {
DEBUG(sl, 1, "Invalid chunk size: " PRINTF_SIZE " != " PRINTF_SIZE ", (" PRINTF_SIZE ")", _sl.reader->GetSize(), endoffs, len);
SlErrorCorruptFmt("Invalid chunk size - expected to be at position " PRINTF_SIZE ", actually at " PRINTF_SIZE ", length: " PRINTF_SIZE,
endoffs, _sl.reader->GetSize(), len);
DEBUG(sl, 1, "Invalid chunk size: " PRINTF_SIZE " != " PRINTF_SIZE ", (" PRINTF_SIZE ") for %s", _sl.reader->GetSize(), endoffs, len, ChunkIDDumper()(chunk_id));
SlErrorCorruptFmt("Invalid chunk size - expected to be at position " PRINTF_SIZE ", actually at " PRINTF_SIZE ", length: " PRINTF_SIZE " for %s",
endoffs, _sl.reader->GetSize(), len, ChunkIDDumper()(chunk_id));
}
} else {
SlErrorCorrupt("Invalid chunk type");
SlErrorCorruptFmt("Invalid chunk type for: %s", ChunkIDDumper()(chunk_id));
}
break;
}
if (_sl.expect_table_header) SlErrorCorrupt("Table chunk without header");
if (_sl.expect_table_header) SlErrorCorruptFmt("Table chunk without header: %s", ChunkIDDumper()(chunk_id));
}
/**
@ -2611,7 +2619,7 @@ static void SlSaveChunk(const ChunkHandler &ch)
_sl.current_chunk_id = ch.id;
SlWriteUint32(ch.id);
DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
DEBUG(sl, 2, "Saving chunk %s", ChunkIDDumper()(ch.id));
size_t written = 0;
if (_debug_sl_level >= 3) written = SlGetBytesWritten();
@ -2640,9 +2648,9 @@ static void SlSaveChunk(const ChunkHandler &ch)
default: NOT_REACHED();
}
if (_sl.expect_table_header) SlErrorCorruptFmt("Table chunk without header: %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
if (_sl.expect_table_header) SlErrorCorruptFmt("Table chunk without header: %s", ChunkIDDumper()(ch.id));
DEBUG(sl, 3, "Saved chunk %c%c%c%c (" PRINTF_SIZE " bytes)", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id, SlGetBytesWritten() - written);
DEBUG(sl, 3, "Saved chunk %s (" PRINTF_SIZE " bytes)", ChunkIDDumper()(ch.id), SlGetBytesWritten() - written);
}
/** Save all chunks */
@ -2678,22 +2686,20 @@ static void SlLoadChunks()
for (uint32_t id = SlReadUint32(); id != 0; id = SlReadUint32()) {
_sl.current_chunk_id = id;
DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
size_t read = 0;
if (_debug_sl_level >= 3) read = SlGetBytesRead();
if (SlXvIsChunkDiscardable(id)) {
DEBUG(sl, 1, "Discarding chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
SlLoadCheckChunk(nullptr);
SlLoadCheckChunk(nullptr, id);
} else {
const ChunkHandler *ch = SlFindChunkHandler(id);
if (ch == nullptr) {
SlErrorCorrupt("Unknown chunk type");
SlErrorCorruptFmt("Unknown chunk type: %s", ChunkIDDumper()(id));
} else {
SlLoadChunk(*ch);
}
}
DEBUG(sl, 3, "Loaded chunk %c%c%c%c (" PRINTF_SIZE " bytes)", id >> 24, id >> 16, id >> 8, id, SlGetBytesRead() - read);
DEBUG(sl, 3, "Loaded chunk %s (" PRINTF_SIZE " bytes)", ChunkIDDumper()(id), SlGetBytesRead() - read);
}
}
@ -2710,7 +2716,6 @@ static void SlLoadCheckChunks()
for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
_sl.current_chunk_id = id;
DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
size_t read = 0;
if (_debug_sl_level >= 3) read = SlGetBytesRead();
@ -2718,10 +2723,10 @@ static void SlLoadCheckChunks()
ch = nullptr;
} else {
ch = SlFindChunkHandler(id);
if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
if (ch == nullptr) SlErrorCorruptFmt("Unknown chunk type: %s", ChunkIDDumper()(id));
}
SlLoadCheckChunk(ch);
DEBUG(sl, 3, "Loaded chunk %c%c%c%c (" PRINTF_SIZE " bytes)", id >> 24, id >> 16, id >> 8, id, SlGetBytesRead() - read);
SlLoadCheckChunk(ch, id);
DEBUG(sl, 3, "Loaded chunk %s (" PRINTF_SIZE " bytes)", ChunkIDDumper()(id), SlGetBytesRead() - read);
}
}
@ -2740,7 +2745,7 @@ static void SlFixPointers()
if (ch.special_proc(ch.id, CSLSO_PRE_PTRS) == CSLSOR_LOAD_CHUNK_CONSUMED) continue;
}
if (ch.ptrs_proc != nullptr) {
DEBUG(sl, 3, "Fixing pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
DEBUG(sl, 3, "Fixing pointers for %s", ChunkIDDumper()(ch.id));
ch.ptrs_proc();
}
}
@ -4198,3 +4203,9 @@ void SlUnreachablePlaceholder()
{
NOT_REACHED();
}
const char *ChunkIDDumper::operator()(uint32_t id)
{
seprintf(this->buffer, lastof(this->buffer), "%c%c%c%c", id >> 24, id >> 16, id >> 8, id);
return this->buffer;
}

@ -125,6 +125,13 @@ struct ChunkHandler {
ChunkSaveLoadSpecialProc *special_proc = nullptr;
};
struct ChunkIDDumper {
const char *operator()(uint32_t id);
private:
char buffer[5];
};
template <typename F>
void SlExecWithSlVersion(SaveLoadVersion use_version, F proc)
{

Loading…
Cancel
Save