From 3ccb2c16f1527ecab90c196d4cb7b195bd3754d0 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sun, 22 Aug 2004 23:59:47 +0000 Subject: [PATCH] Fixed a couple of obscure bugs that cropped up when trying to recompress a GSHK-added zero-byte file with a "fake" thread. --- nufxlib-0/Deferred.c | 17 +++++++++++++++-- nufxlib-0/Record.c | 12 +++++------- nufxlib-0/Thread.c | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/nufxlib-0/Deferred.c b/nufxlib-0/Deferred.c index 37a595a..6e6b9f2 100644 --- a/nufxlib-0/Deferred.c +++ b/nufxlib-0/Deferred.c @@ -36,6 +36,7 @@ Nu_ThreadModAdd_New(NuArchive* pArchive, NuThreadID threadID, return kNuErrMalloc; (*ppThreadMod)->entry.kind = kNuThreadModAdd; + (*ppThreadMod)->entry.add.used = false; (*ppThreadMod)->entry.add.threadIdx = Nu_GetNextThreadIdx(pArchive); (*ppThreadMod)->entry.add.threadID = threadID; (*ppThreadMod)->entry.add.threadFormat = threadFormat; @@ -64,6 +65,7 @@ Nu_ThreadModUpdate_New(NuArchive* pArchive, NuThreadIdx threadIdx, return kNuErrMalloc; (*ppThreadMod)->entry.kind = kNuThreadModUpdate; + (*ppThreadMod)->entry.update.used = false; (*ppThreadMod)->entry.update.threadIdx = threadIdx; (*ppThreadMod)->entry.update.pDataSource = Nu_DataSourceCopy(pDataSource); @@ -87,6 +89,7 @@ Nu_ThreadModDelete_New(NuArchive* pArchive, NuThreadIdx threadIdx, return kNuErrMalloc; (*ppThreadMod)->entry.kind = kNuThreadModDelete; + (*ppThreadMod)->entry.delete.used = false; (*ppThreadMod)->entry.delete.threadIdx = threadIdx; (*ppThreadMod)->entry.delete.threadID = threadID; @@ -506,6 +509,8 @@ Nu_VerifyAllTouched(NuArchive* pArchive, const NuRecord* pRecord) pThreadMod = pRecord->pThreadMods; while (pThreadMod != nil) { + Assert(pThreadMod->entry.generic.used == false || + pThreadMod->entry.generic.used == true); if (!pThreadMod->entry.generic.used) return false; pThreadMod = pThreadMod->pNext; @@ -515,6 +520,7 @@ Nu_VerifyAllTouched(NuArchive* pArchive, const NuRecord* pRecord) pThread = Nu_GetThread(pRecord, idx); Assert(pThread != nil); + Assert(pThread->used == false || pThread->used == true); if (!pThread->used) return false; } @@ -943,7 +949,7 @@ Nu_ConstructArchiveThreads(NuArchive* pArchive, NuRecord* pRecord, * The thread has a related ThreadMod. Deal with it. */ - pThreadMod->entry.generic.used = true; /* for assert, later */ + pThreadMod->entry.generic.used = true; /* for Assert, later */ if (pThreadMod->entry.kind == kNuThreadModDelete) { /* this is a delete, ignore this thread */ @@ -1111,7 +1117,12 @@ Nu_ConstructArchiveRecord(NuArchive* pArchive, NuRecord* pRecord) if (pRecord->filename == nil) pRecord->filename = kNuDefaultRecordName; - /* make a hole, including the header filename if we're not dropping it */ + /* + * Make a hole, including the header filename if we're not dropping it. + * + * This ignores fake vs. non-fake threads, because once we're done + * writing they're all "real". + */ newHeaderSize = pRecord->recAttribCount + numThreads * kNuThreadHeaderSize; if (!pRecord->dropRecFilename) newHeaderSize += pRecord->recFilenameLength; @@ -1207,6 +1218,8 @@ Nu_ConstructArchiveRecord(NuArchive* pArchive, NuRecord* pRecord) err = Nu_WriteRecordHeader(pArchive, pRecord, pArchive->tmpFp); BailError(err); + Assert(newHeaderSize == pRecord->recHeaderLength); + /* * Seek forward once again, so we are positioned at the correct * place to write the next record. diff --git a/nufxlib-0/Record.c b/nufxlib-0/Record.c index 10d3b14..5a5c7bd 100644 --- a/nufxlib-0/Record.c +++ b/nufxlib-0/Record.c @@ -1259,7 +1259,7 @@ Nu_WriteRecordHeader(NuArchive* pArchive, NuRecord* pRecord, FILE* fp) goto bail; } - /* write the thread headers */ + /* write the thread headers, and zero out "fake" thread count */ err = Nu_WriteThreadHeaders(pArchive, pRecord, fp, &crc); BailError(err); @@ -1283,12 +1283,8 @@ Nu_WriteRecordHeader(NuArchive* pArchive, NuRecord* pRecord, FILE* fp) /* * Update values for misc record fields. - * - * Note that, despite having written the record header, we can still - * have "fake" threads. This is because WriteThreadHeaders only saves - * the real ones. This is in line with our policy of not altering - * anything we don't have to. */ + Assert(pRecord->fakeThreads == 0); pRecord->recHeaderLength = bytesWritten + pRecord->recTotalThreads * kNuThreadHeaderSize; pRecord->recHeaderLength -= pRecord->fakeThreads * kNuThreadHeaderSize; @@ -1525,9 +1521,11 @@ Nu_FakeZeroExtract(NuArchive* pArchive, NuRecord* pRecord, int threadKind) fakeThread.thThreadCRC = kNuInitialThreadCRC; fakeThread.thThreadEOF = 0; fakeThread.thCompThreadEOF = 0; - fakeThread.actualThreadEOF = 0; + fakeThread.threadIdx = (NuThreadIdx)-1; /* shouldn't matter */ + fakeThread.actualThreadEOF = 0; fakeThread.fileOffset = 0; /* shouldn't matter */ + fakeThread.used = false; err = Nu_ExtractThreadBulk(pArchive, pRecord, &fakeThread); if (err == kNuErrSkipped) diff --git a/nufxlib-0/Thread.c b/nufxlib-0/Thread.c index 0fc9115..0aa895a 100644 --- a/nufxlib-0/Thread.c +++ b/nufxlib-0/Thread.c @@ -172,6 +172,7 @@ Nu_ReadThreadHeader(NuArchive* pArchive, NuThread* pThread, ushort* pCrc) pThread->threadIdx = Nu_GetNextThreadIdx(pArchive); pThread->actualThreadEOF = 0; /* fix me later */ pThread->fileOffset = -1; /* mark as invalid */ + pThread->used = 0xcfcf; /* init to invalid value */ return Nu_HeaderIOFailed(pArchive, fp); } @@ -277,9 +278,10 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc) pThread->thThreadCRC = kNuInitialThreadCRC; pThread->thThreadEOF = 0; pThread->thCompThreadEOF = 0; - pThread->actualThreadEOF = 0; pThread->threadIdx = Nu_GetNextThreadIdx(pArchive); + pThread->actualThreadEOF = 0; pThread->fileOffset = -99999999; + pThread->used = false; if (needRsrc) { pThread++; @@ -289,9 +291,10 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc) pThread->thThreadCRC = kNuInitialThreadCRC; pThread->thThreadEOF = 0; pThread->thCompThreadEOF = 0; - pThread->actualThreadEOF = 0; pThread->threadIdx = Nu_GetNextThreadIdx(pArchive); + pThread->actualThreadEOF = 0; pThread->fileOffset = -99999999; + pThread->used = false; } } @@ -324,6 +327,10 @@ Nu_WriteThreadHeader(NuArchive* pArchive, const NuThread* pThread, FILE* fp, /* * Write the thread headers for the record at the current file position. + * + * Note this doesn't care whether a thread was "fake" or not. In + * effect, we promote all threads to "real" status. We update the + * "fake" count in pRecord accordingly. */ NuError Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp, @@ -341,6 +348,11 @@ Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp, BailError(err); } + if (pRecord->fakeThreads != 0) { + DBUG(("+++ promoting %ld fake threads to real\n",pRecord->fakeThreads)); + pRecord->fakeThreads = 0; + } + bail: return err; }