Fixed a couple of obscure bugs that cropped up when trying to recompress

a GSHK-added zero-byte file with a "fake" thread.
This commit is contained in:
Andy McFadden 2004-08-22 23:59:47 +00:00
parent 804ca87a19
commit 3ccb2c16f1
3 changed files with 34 additions and 11 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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;
}