mirror of
https://github.com/fadden/nulib2.git
synced 2024-10-05 21:54:24 +00:00
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:
parent
804ca87a19
commit
3ccb2c16f1
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user