mirror of
https://github.com/fadden/nulib2.git
synced 2024-06-16 23:29:29 +00:00
Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
811ebe9ba3 | ||
|
6eb33543cb | ||
|
0f957f9e83 | ||
|
918f318ca4 | ||
|
ca8605c403 | ||
|
2a5e5bc299 | ||
|
ae66fba7bc | ||
|
0619ef3fe7 | ||
|
7ec4eb46c7 | ||
|
21a10ad266 | ||
|
f6ff60420b | ||
|
ea89644bfa | ||
|
9fdc77a108 | ||
|
137cafa05b | ||
|
20fe7efb4d | ||
|
51af83986c | ||
|
bbeb9eaf90 | ||
|
7f158dd206 | ||
|
eb40d65f1d | ||
|
f37b387cc6 | ||
|
bc96aa420b | ||
|
508531fb54 | ||
|
ae8eec5d1b | ||
|
8d2f1a5479 | ||
|
506e278e34 | ||
|
5a5d8993d3 | ||
|
6ba112fdfe | ||
|
137f209a3f | ||
|
e5b74c28f2 | ||
|
0137d4ef38 | ||
|
3ee3c9451e | ||
|
cf4ab2ee2f | ||
|
76ee85b6ec | ||
|
24a49dfece | ||
|
132a8338b9 | ||
|
1286c3518e | ||
|
c6c7133d43 | ||
|
ad2ec98e8b | ||
|
e7bf743afd | ||
|
e2088e64d3 | ||
|
f4dea8b251 | ||
|
5d5dd3900f | ||
|
dbbbe6a858 | ||
|
524e0926e7 | ||
|
9666ebd97a | ||
|
20c9ac1195 | ||
|
ce1b57e2ad | ||
|
cf433eeae0 | ||
|
281813a8ea |
|
@ -7,9 +7,8 @@ operate on ShrinkIt and Binary II files (.shk, .sdk, .bxy, .bse, .bny, .bqy).
|
|||
NufxLib is a library of code that supports ShrinkIt archives. It's
|
||||
used by NuLib2 and CiderPress.
|
||||
|
||||
A pre-built NuLib2 binary is available for x86 Windows. For Linux systems,
|
||||
you can download the source code and build it.
|
||||
A pre-built NuLib2 binary is available for x86 Windows. For Linux and
|
||||
Mac OS X systems, you can download the source code and build it.
|
||||
|
||||
More information, including full documentation for NuLib2 and NufxLib,
|
||||
can be found on http://www.nulib.com/.
|
||||
|
||||
can be found on https://nulib.com/ (or https://fadden.github.io/nulib2).
|
||||
|
|
21
nufxlib/.gitignore
vendored
21
nufxlib/.gitignore
vendored
|
@ -1,12 +1,17 @@
|
|||
# config-generated sources
|
||||
Makefile
|
||||
Version.c
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
exerciser
|
||||
imgconv
|
||||
launder
|
||||
test-basic
|
||||
test-extract
|
||||
test-simple
|
||||
test-twirl
|
||||
nufxlib.pc
|
||||
|
||||
# generated binaries
|
||||
libnufx.a
|
||||
samples/exerciser
|
||||
samples/imgconv
|
||||
samples/launder
|
||||
samples/test-basic
|
||||
samples/test-extract
|
||||
samples/test-names
|
||||
samples/test-simple
|
||||
samples/test-twirl
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
#endif
|
||||
|
||||
/* master header identification */
|
||||
static const uchar kNuMasterID[kNufileIDLen] =
|
||||
static const uint8_t kNuMasterID[kNufileIDLen] =
|
||||
{ 0x4e, 0xf5, 0x46, 0xe9, 0x6c, 0xe5 };
|
||||
|
||||
/* other identification; can be no longer than kNufileIDLen */
|
||||
static const uchar kNuBinary2ID[] =
|
||||
static const uint8_t kNuBinary2ID[] =
|
||||
{ 0x0a, 0x47, 0x4c };
|
||||
static const uchar kNuSHKSEAID[] =
|
||||
static const uint8_t kNuSHKSEAID[] =
|
||||
{ 0xa2, 0x2e, 0x00 };
|
||||
|
||||
/*
|
||||
|
@ -53,19 +53,16 @@ static void Nu_CloseAndFree(NuArchive* pArchive);
|
|||
/*
|
||||
* Allocate and initialize a new NuArchive structure.
|
||||
*/
|
||||
static NuError
|
||||
Nu_NuArchiveNew(NuArchive** ppArchive)
|
||||
static NuError Nu_NuArchiveNew(NuArchive** ppArchive)
|
||||
{
|
||||
Assert(ppArchive != nil);
|
||||
Assert(ppArchive != NULL);
|
||||
|
||||
/* validate some assumptions we make throughout the code */
|
||||
Assert(sizeof(int) >= 2);
|
||||
Assert(sizeof(ushort) >= 2);
|
||||
Assert(sizeof(ulong) >= 4);
|
||||
Assert(sizeof(void*) >= sizeof(NuArchive*));
|
||||
|
||||
*ppArchive = Nu_Calloc(nil, sizeof(**ppArchive));
|
||||
if (*ppArchive == nil)
|
||||
*ppArchive = Nu_Calloc(NULL, sizeof(**ppArchive));
|
||||
if (*ppArchive == NULL)
|
||||
return kNuErrMalloc;
|
||||
|
||||
(*ppArchive)->structMagic = kNuArchiveStructMagic;
|
||||
|
@ -107,10 +104,9 @@ Nu_NuArchiveNew(NuArchive** ppArchive)
|
|||
/*
|
||||
* Free up a NuArchive structure and its contents.
|
||||
*/
|
||||
static NuError
|
||||
Nu_NuArchiveFree(NuArchive* pArchive)
|
||||
static NuError Nu_NuArchiveFree(NuArchive* pArchive)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pArchive->structMagic == kNuArchiveStructMagic);
|
||||
|
||||
(void) Nu_RecordSet_FreeAllRecords(pArchive, &pArchive->origRecordSet);
|
||||
|
@ -118,15 +114,15 @@ Nu_NuArchiveFree(NuArchive* pArchive)
|
|||
(void) Nu_RecordSet_FreeAllRecords(pArchive, &pArchive->copyRecordSet);
|
||||
(void) Nu_RecordSet_FreeAllRecords(pArchive, &pArchive->newRecordSet);
|
||||
|
||||
Nu_Free(nil, pArchive->archivePathname);
|
||||
Nu_Free(nil, pArchive->tmpPathname);
|
||||
Nu_Free(nil, pArchive->compBuf);
|
||||
Nu_Free(nil, pArchive->lzwCompressState);
|
||||
Nu_Free(nil, pArchive->lzwExpandState);
|
||||
Nu_Free(NULL, pArchive->archivePathnameUNI);
|
||||
Nu_Free(NULL, pArchive->tmpPathnameUNI);
|
||||
Nu_Free(NULL, pArchive->compBuf);
|
||||
Nu_Free(NULL, pArchive->lzwCompressState);
|
||||
Nu_Free(NULL, pArchive->lzwExpandState);
|
||||
|
||||
/* mark it as deceased to prevent further use, then free it */
|
||||
pArchive->structMagic = kNuArchiveStructMagic ^ 0xffffffff;
|
||||
Nu_Free(nil, pArchive);
|
||||
Nu_Free(NULL, pArchive);
|
||||
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
@ -135,13 +131,12 @@ Nu_NuArchiveFree(NuArchive* pArchive)
|
|||
/*
|
||||
* Copy a NuMasterHeader struct.
|
||||
*/
|
||||
void
|
||||
Nu_MasterHeaderCopy(NuArchive* pArchive, NuMasterHeader* pDstHeader,
|
||||
void Nu_MasterHeaderCopy(NuArchive* pArchive, NuMasterHeader* pDstHeader,
|
||||
const NuMasterHeader* pSrcHeader)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pDstHeader != nil);
|
||||
Assert(pSrcHeader != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pDstHeader != NULL);
|
||||
Assert(pSrcHeader != NULL);
|
||||
|
||||
*pDstHeader = *pSrcHeader;
|
||||
}
|
||||
|
@ -149,10 +144,10 @@ Nu_MasterHeaderCopy(NuArchive* pArchive, NuMasterHeader* pDstHeader,
|
|||
/*
|
||||
* Get a pointer to the archive master header (this is an API call).
|
||||
*/
|
||||
NuError
|
||||
Nu_GetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
|
||||
NuError Nu_GetMasterHeader(NuArchive* pArchive,
|
||||
const NuMasterHeader** ppMasterHeader)
|
||||
{
|
||||
if (ppMasterHeader == nil)
|
||||
if (ppMasterHeader == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
*ppMasterHeader = &pArchive->masterHeader;
|
||||
|
@ -164,16 +159,15 @@ Nu_GetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
|
|||
/*
|
||||
* Allocate the general-purpose compression buffer, if needed.
|
||||
*/
|
||||
NuError
|
||||
Nu_AllocCompressionBufferIFN(NuArchive* pArchive)
|
||||
NuError Nu_AllocCompressionBufferIFN(NuArchive* pArchive)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
if (pArchive->compBuf != nil)
|
||||
if (pArchive->compBuf != NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
pArchive->compBuf = Nu_Malloc(pArchive, kNuGenCompBufSize);
|
||||
if (pArchive->compBuf == nil)
|
||||
if (pArchive->compBuf == NULL)
|
||||
return kNuErrMalloc;
|
||||
|
||||
return kNuErrNone;
|
||||
|
@ -183,8 +177,7 @@ Nu_AllocCompressionBufferIFN(NuArchive* pArchive)
|
|||
/*
|
||||
* Return a unique value.
|
||||
*/
|
||||
NuRecordIdx
|
||||
Nu_GetNextRecordIdx(NuArchive* pArchive)
|
||||
NuRecordIdx Nu_GetNextRecordIdx(NuArchive* pArchive)
|
||||
{
|
||||
return pArchive->nextRecordIdx++;
|
||||
}
|
||||
|
@ -192,8 +185,7 @@ Nu_GetNextRecordIdx(NuArchive* pArchive)
|
|||
/*
|
||||
* Return a unique value.
|
||||
*/
|
||||
NuThreadIdx
|
||||
Nu_GetNextThreadIdx(NuArchive* pArchive)
|
||||
NuThreadIdx Nu_GetNextThreadIdx(NuArchive* pArchive)
|
||||
{
|
||||
return pArchive->nextRecordIdx++; /* just use the record counter */
|
||||
}
|
||||
|
@ -208,8 +200,7 @@ Nu_GetNextThreadIdx(NuArchive* pArchive)
|
|||
/*
|
||||
* Copy the wrapper from the archive file to the temp file.
|
||||
*/
|
||||
NuError
|
||||
Nu_CopyWrapperToTemp(NuArchive* pArchive)
|
||||
NuError Nu_CopyWrapperToTemp(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -247,13 +238,12 @@ bail:
|
|||
* guess some of the SEA weirdness stems from some far-sighted support
|
||||
* for multiple archives within a single SEA wrapper.
|
||||
*/
|
||||
NuError
|
||||
Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
|
||||
NuError Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Boolean hasBinary2, hasSea;
|
||||
uchar identBuf[kNufileIDLen];
|
||||
ulong archiveLen, archiveLen512;
|
||||
uint8_t identBuf[kNufileIDLen];
|
||||
uint32_t archiveLen, archiveLen512;
|
||||
|
||||
Assert(pArchive->newMasterHeader.isValid); /* need new crc and len */
|
||||
|
||||
|
@ -306,20 +296,20 @@ Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
|
|||
|
||||
err = Nu_FSeek(fp, kNuBNYFileSizeLo - kNufileIDLen, SEEK_CUR);
|
||||
BailError(err);
|
||||
Nu_WriteTwo(pArchive, fp, (ushort)(archiveLen512 & 0xffff));
|
||||
Nu_WriteTwo(pArchive, fp, (uint16_t)(archiveLen512 & 0xffff));
|
||||
|
||||
err = Nu_FSeek(fp, kNuBNYFileSizeHi - (kNuBNYFileSizeLo+2), SEEK_CUR);
|
||||
BailError(err);
|
||||
Nu_WriteTwo(pArchive, fp, (ushort)(archiveLen512 >> 16));
|
||||
Nu_WriteTwo(pArchive, fp, (uint16_t)(archiveLen512 >> 16));
|
||||
|
||||
err = Nu_FSeek(fp, kNuBNYEOFLo - (kNuBNYFileSizeHi+2), SEEK_CUR);
|
||||
BailError(err);
|
||||
Nu_WriteTwo(pArchive, fp, (ushort)(archiveLen & 0xffff));
|
||||
Nu_WriteOne(pArchive, fp, (uchar)((archiveLen >> 16) & 0xff));
|
||||
Nu_WriteTwo(pArchive, fp, (uint16_t)(archiveLen & 0xffff));
|
||||
Nu_WriteOne(pArchive, fp, (uint8_t)((archiveLen >> 16) & 0xff));
|
||||
|
||||
err = Nu_FSeek(fp, kNuBNYEOFHi - (kNuBNYEOFLo+3), SEEK_CUR);
|
||||
BailError(err);
|
||||
Nu_WriteOne(pArchive, fp, (uchar)(archiveLen >> 24));
|
||||
Nu_WriteOne(pArchive, fp, (uint8_t)(archiveLen >> 24));
|
||||
|
||||
err = Nu_FSeek(fp, kNuBNYDiskSpace - (kNuBNYEOFHi+1), SEEK_CUR);
|
||||
BailError(err);
|
||||
|
@ -358,11 +348,11 @@ Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
|
|||
|
||||
err = Nu_FSeek(fp, kNuSEALength1 - (kNuSEAFunkySize+4), SEEK_CUR);
|
||||
BailError(err);
|
||||
Nu_WriteTwo(pArchive, fp, (ushort)archiveLen);
|
||||
Nu_WriteTwo(pArchive, fp, (uint16_t)archiveLen);
|
||||
|
||||
err = Nu_FSeek(fp, kNuSEALength2 - (kNuSEALength1+2), SEEK_CUR);
|
||||
BailError(err);
|
||||
Nu_WriteTwo(pArchive, fp, (ushort)archiveLen);
|
||||
Nu_WriteTwo(pArchive, fp, (uint16_t)archiveLen);
|
||||
|
||||
/* seek past end of SEA wrapper */
|
||||
err = Nu_FSeek(fp, kNuSEAOffset - (kNuSEALength2+2), SEEK_CUR);
|
||||
|
@ -399,8 +389,7 @@ bail:
|
|||
* require additional disk space to be used, assuming a filesystem block
|
||||
* size of at least 128 bytes.
|
||||
*/
|
||||
NuError
|
||||
Nu_AdjustWrapperPadding(NuArchive* pArchive, FILE* fp)
|
||||
NuError Nu_AdjustWrapperPadding(NuArchive* pArchive, FILE* fp)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Boolean hasBinary2, hasSea;
|
||||
|
@ -495,17 +484,16 @@ bail:
|
|||
*
|
||||
* On exit, the stream will be positioned just past the master header.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ReadMasterHeader(NuArchive* pArchive)
|
||||
static NuError Nu_ReadMasterHeader(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
ushort crc;
|
||||
uint16_t crc;
|
||||
FILE* fp;
|
||||
NuMasterHeader* pHeader;
|
||||
Boolean isBinary2 = false;
|
||||
Boolean isSea = false;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
fp = pArchive->archiveFp; /* saves typing */
|
||||
pHeader = &pArchive->masterHeader;
|
||||
|
@ -640,7 +628,7 @@ retry:
|
|||
|
||||
/* compare the CRC */
|
||||
if (!pArchive->valIgnoreCRC && crc != pHeader->mhMasterCRC) {
|
||||
if (!Nu_ShouldIgnoreBadCRC(pArchive, nil, kNuErrBadMHCRC)) {
|
||||
if (!Nu_ShouldIgnoreBadCRC(pArchive, NULL, kNuErrBadMHCRC)) {
|
||||
err = kNuErrBadMHCRC;
|
||||
Nu_ReportError(NU_BLOB, err, "Stored MH CRC=0x%04x, calc=0x%04x",
|
||||
pHeader->mhMasterCRC, crc);
|
||||
|
@ -669,7 +657,7 @@ retry:
|
|||
if (pHeader->mhMasterEOF == kNuMasterHeaderSize) {
|
||||
err = kNuErrNoRecords;
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Master EOF is %ld, archive is probably truncated",
|
||||
"Master EOF is %u, archive is probably truncated",
|
||||
pHeader->mhMasterEOF);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -712,12 +700,11 @@ bail:
|
|||
* Prepare the NuArchive and NuMasterHeader structures for use with a
|
||||
* newly-created archive.
|
||||
*/
|
||||
static void
|
||||
Nu_InitNewArchive(NuArchive* pArchive)
|
||||
static void Nu_InitNewArchive(NuArchive* pArchive)
|
||||
{
|
||||
NuMasterHeader* pHeader;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
pHeader = &pArchive->masterHeader;
|
||||
|
||||
|
@ -741,14 +728,13 @@ Nu_InitNewArchive(NuArchive* pArchive)
|
|||
/*
|
||||
* Open an archive in streaming read-only mode.
|
||||
*/
|
||||
NuError
|
||||
Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive)
|
||||
NuError Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
Assert(infp != nil);
|
||||
Assert(ppArchive != nil);
|
||||
Assert(infp != NULL);
|
||||
Assert(ppArchive != NULL);
|
||||
|
||||
err = Nu_NuArchiveNew(ppArchive);
|
||||
if (err != kNuErrNone)
|
||||
|
@ -757,16 +743,16 @@ Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive)
|
|||
|
||||
pArchive->openMode = kNuOpenStreamingRO;
|
||||
pArchive->archiveFp = infp;
|
||||
pArchive->archivePathname = strdup("(stream)");
|
||||
pArchive->archivePathnameUNI = strdup("(stream)");
|
||||
|
||||
err = Nu_ReadMasterHeader(pArchive);
|
||||
BailError(err);
|
||||
|
||||
bail:
|
||||
if (err != kNuErrNone) {
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
(void) Nu_NuArchiveFree(pArchive);
|
||||
*ppArchive = nil;
|
||||
*ppArchive = NULL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -775,21 +761,24 @@ bail:
|
|||
/*
|
||||
* Open an archive in non-streaming read-only mode.
|
||||
*/
|
||||
NuError
|
||||
Nu_OpenRO(const char* archivePathname, NuArchive** ppArchive)
|
||||
NuError Nu_OpenRO(const UNICHAR* archivePathnameUNI, NuArchive** ppArchive)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
FILE* fp = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
FILE* fp = NULL;
|
||||
|
||||
if (archivePathname == nil || !strlen(archivePathname) || ppArchive == nil)
|
||||
if (archivePathnameUNI == NULL || !strlen(archivePathnameUNI) ||
|
||||
ppArchive == NULL)
|
||||
{
|
||||
return kNuErrInvalidArg;
|
||||
}
|
||||
|
||||
*ppArchive = nil;
|
||||
*ppArchive = NULL;
|
||||
|
||||
fp = fopen(archivePathname, kNuFileOpenReadOnly);
|
||||
if (fp == nil) {
|
||||
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'", archivePathname);
|
||||
fp = fopen(archivePathnameUNI, kNuFileOpenReadOnly);
|
||||
if (fp == NULL) {
|
||||
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'",
|
||||
archivePathnameUNI);
|
||||
err = kNuErrFileOpen;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -801,19 +790,19 @@ Nu_OpenRO(const char* archivePathname, NuArchive** ppArchive)
|
|||
|
||||
pArchive->openMode = kNuOpenRO;
|
||||
pArchive->archiveFp = fp;
|
||||
fp = nil;
|
||||
pArchive->archivePathname = strdup(archivePathname);
|
||||
fp = NULL;
|
||||
pArchive->archivePathnameUNI = strdup(archivePathnameUNI);
|
||||
|
||||
err = Nu_ReadMasterHeader(pArchive);
|
||||
BailError(err);
|
||||
|
||||
bail:
|
||||
if (err != kNuErrNone) {
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
(void) Nu_CloseAndFree(pArchive);
|
||||
*ppArchive = nil;
|
||||
*ppArchive = NULL;
|
||||
}
|
||||
if (fp != nil)
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
}
|
||||
return err;
|
||||
|
@ -822,15 +811,15 @@ bail:
|
|||
|
||||
/*
|
||||
* Open a temp file. If "fileName" contains six Xs ("XXXXXX"), it will
|
||||
* be treated as a mktemp-style template, and modified before use.
|
||||
* be treated as a mktemp-style template, and modified before use (so
|
||||
* pass a copy of the string in).
|
||||
*
|
||||
* Thought for the day: consider using Win32 SetFileAttributes() to make
|
||||
* temp files hidden. We will need to un-hide it before rolling it over.
|
||||
*/
|
||||
static NuError
|
||||
Nu_OpenTempFile(char* fileName, FILE** pFp)
|
||||
static NuError Nu_OpenTempFile(UNICHAR* fileNameUNI, FILE** pFp)
|
||||
{
|
||||
NuArchive* pArchive = nil; /* dummy for NU_BLOB */
|
||||
NuArchive* pArchive = NULL; /* dummy for NU_BLOB */
|
||||
NuError err = kNuErrNone;
|
||||
int len;
|
||||
|
||||
|
@ -843,25 +832,25 @@ Nu_OpenTempFile(char* fileName, FILE** pFp)
|
|||
* to complain about mktemp, since it's generally a bad way to do
|
||||
* things.
|
||||
*/
|
||||
len = strlen(fileName);
|
||||
if (len > 6 && strcmp(fileName + len - 6, "XXXXXX") == 0) {
|
||||
len = strlen(fileNameUNI);
|
||||
if (len > 6 && strcmp(fileNameUNI + len - 6, "XXXXXX") == 0) {
|
||||
#if defined(HAVE_MKSTEMP) && defined(HAVE_FDOPEN)
|
||||
int fd;
|
||||
|
||||
DBUG(("+++ Using mkstemp\n"));
|
||||
|
||||
/* this modifies the template *and* opens the file */
|
||||
fd = mkstemp(fileName);
|
||||
fd = mkstemp(fileNameUNI);
|
||||
if (fd < 0) {
|
||||
err = errno ? errno : kNuErrFileOpen;
|
||||
Nu_ReportError(NU_BLOB, kNuErrNone, "mkstemp failed on '%s'",
|
||||
fileName);
|
||||
fileNameUNI);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
DBUG(("--- Fd-opening temp file '%s'\n", fileName));
|
||||
DBUG(("--- Fd-opening temp file '%s'\n", fileNameUNI));
|
||||
*pFp = fdopen(fd, kNuFileOpenReadWriteCreat);
|
||||
if (*pFp == nil) {
|
||||
if (*pFp == NULL) {
|
||||
close(fd);
|
||||
err = errno ? errno : kNuErrFileOpen;
|
||||
goto bail;
|
||||
|
@ -874,10 +863,10 @@ Nu_OpenTempFile(char* fileName, FILE** pFp)
|
|||
char* result;
|
||||
|
||||
DBUG(("+++ Using mktemp\n"));
|
||||
result = mktemp(fileName);
|
||||
if (result == nil) {
|
||||
result = mktemp(fileNameUNI);
|
||||
if (result == NULL) {
|
||||
Nu_ReportError(NU_BLOB, kNuErrNone, "mktemp failed on '%s'",
|
||||
fileName);
|
||||
fileNameUNI);
|
||||
err = kNuErrInternal;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -886,34 +875,33 @@ Nu_OpenTempFile(char* fileName, FILE** pFp)
|
|||
#endif
|
||||
}
|
||||
|
||||
DBUG(("--- Opening temp file '%s'\n", fileName));
|
||||
DBUG(("--- Opening temp file '%s'\n", fileNameUNI));
|
||||
|
||||
#if defined(HAVE_FDOPEN)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(fileName, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
|
||||
fd = open(fileNameUNI, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
|
||||
if (fd < 0) {
|
||||
err = errno ? errno : kNuErrFileOpen;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
*pFp = fdopen(fd, kNuFileOpenReadWriteCreat);
|
||||
if (*pFp == nil) {
|
||||
if (*pFp == NULL) {
|
||||
close(fd);
|
||||
err = errno ? errno : kNuErrFileOpen;
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* (not sure how portable "access" is... I think it's POSIX) */
|
||||
if (access(fileName, F_OK) == 0) {
|
||||
if (access(fileNameUNI, F_OK) == 0) {
|
||||
err = kNuErrFileExists;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
*pFp = fopen(fileName, kNuFileOpenReadWriteCreat);
|
||||
if (*pFp == nil) {
|
||||
*pFp = fopen(fileNameUNI, kNuFileOpenReadWriteCreat);
|
||||
if (*pFp == NULL) {
|
||||
err = errno ? errno : kNuErrFileOpen;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -928,26 +916,25 @@ bail:
|
|||
* Open an archive in read-write mode, optionally creating it if it doesn't
|
||||
* exist.
|
||||
*/
|
||||
NuError
|
||||
Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
|
||||
NuArchive** ppArchive)
|
||||
NuError Nu_OpenRW(const UNICHAR* archivePathnameUNI,
|
||||
const UNICHAR* tmpPathnameUNI, uint32_t flags, NuArchive** ppArchive)
|
||||
{
|
||||
NuError err;
|
||||
FILE* fp = nil;
|
||||
FILE* tmpFp = nil;
|
||||
NuArchive* pArchive = nil;
|
||||
char* tmpPathDup = nil;
|
||||
FILE* fp = NULL;
|
||||
FILE* tmpFp = NULL;
|
||||
NuArchive* pArchive = NULL;
|
||||
char* tmpPathDup = NULL;
|
||||
Boolean archiveExists;
|
||||
Boolean newlyCreated;
|
||||
|
||||
if (archivePathname == nil || !strlen(archivePathname) ||
|
||||
tmpPathname == nil || !strlen(tmpPathname) || ppArchive == nil ||
|
||||
(flags & ~(kNuOpenCreat|kNuOpenExcl)) != 0)
|
||||
if (archivePathnameUNI == NULL || !strlen(archivePathnameUNI) ||
|
||||
tmpPathnameUNI == NULL || !strlen(tmpPathnameUNI) ||
|
||||
ppArchive == NULL || (flags & ~(kNuOpenCreat|kNuOpenExcl)) != 0)
|
||||
{
|
||||
return kNuErrInvalidArg;
|
||||
}
|
||||
|
||||
archiveExists = (access(archivePathname, F_OK) == 0);
|
||||
archiveExists = (access(archivePathnameUNI, F_OK) == 0);
|
||||
|
||||
/*
|
||||
* Open or create archive file.
|
||||
|
@ -955,27 +942,30 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
|
|||
if (archiveExists) {
|
||||
if ((flags & kNuOpenCreat) && (flags & kNuOpenExcl)) {
|
||||
err = kNuErrFileExists;
|
||||
Nu_ReportError(NU_BLOB, err, "File '%s' exists", archivePathname);
|
||||
Nu_ReportError(NU_BLOB, err, "File '%s' exists",
|
||||
archivePathnameUNI);
|
||||
goto bail;
|
||||
}
|
||||
fp = fopen(archivePathname, kNuFileOpenReadWrite);
|
||||
fp = fopen(archivePathnameUNI, kNuFileOpenReadWrite);
|
||||
newlyCreated = false;
|
||||
} else {
|
||||
if (!(flags & kNuOpenCreat)) {
|
||||
err = kNuErrFileNotFound;
|
||||
Nu_ReportError(NU_BLOB, err, "File '%s' not found",archivePathname);
|
||||
Nu_ReportError(NU_BLOB, err, "File '%s' not found",
|
||||
archivePathnameUNI);
|
||||
goto bail;
|
||||
}
|
||||
fp = fopen(archivePathname, kNuFileOpenReadWriteCreat);
|
||||
fp = fopen(archivePathnameUNI, kNuFileOpenReadWriteCreat);
|
||||
newlyCreated = true;
|
||||
}
|
||||
|
||||
if (fp == nil) {
|
||||
if (fp == NULL) {
|
||||
if (errno == EACCES)
|
||||
err = kNuErrFileAccessDenied;
|
||||
else
|
||||
err = kNuErrFileOpen;
|
||||
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'", archivePathname);
|
||||
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'",
|
||||
archivePathnameUNI);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
@ -985,7 +975,7 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
|
|||
if (archiveExists && !newlyCreated) {
|
||||
long length;
|
||||
|
||||
err = Nu_GetFileLength(nil, fp, &length);
|
||||
err = Nu_GetFileLength(NULL, fp, &length);
|
||||
BailError(err);
|
||||
|
||||
if (!length) {
|
||||
|
@ -1003,12 +993,12 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
|
|||
* So, create a temp file whether we think we need one or not. Won't
|
||||
* do any harm, and might save us some troubles later.
|
||||
*/
|
||||
tmpPathDup = strdup(tmpPathname);
|
||||
tmpPathDup = strdup(tmpPathnameUNI);
|
||||
BailNil(tmpPathDup);
|
||||
err = Nu_OpenTempFile(tmpPathDup, &tmpFp);
|
||||
if (err != kNuErrNone) {
|
||||
Nu_ReportError(NU_BLOB, err, "Failed opening temp file '%s'",
|
||||
tmpPathname);
|
||||
tmpPathnameUNI);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
@ -1019,13 +1009,13 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
|
|||
|
||||
pArchive->openMode = kNuOpenRW;
|
||||
pArchive->newlyCreated = newlyCreated;
|
||||
pArchive->archivePathname = strdup(archivePathname);
|
||||
pArchive->archivePathnameUNI = strdup(archivePathnameUNI);
|
||||
pArchive->archiveFp = fp;
|
||||
fp = nil;
|
||||
fp = NULL;
|
||||
pArchive->tmpFp = tmpFp;
|
||||
tmpFp = nil;
|
||||
pArchive->tmpPathname = tmpPathDup;
|
||||
tmpPathDup = nil;
|
||||
tmpFp = NULL;
|
||||
pArchive->tmpPathnameUNI = tmpPathDup;
|
||||
tmpPathDup = NULL;
|
||||
|
||||
if (archiveExists && !newlyCreated) {
|
||||
err = Nu_ReadMasterHeader(pArchive);
|
||||
|
@ -1036,15 +1026,15 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
|
|||
|
||||
bail:
|
||||
if (err != kNuErrNone) {
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
(void) Nu_CloseAndFree(pArchive);
|
||||
*ppArchive = nil;
|
||||
*ppArchive = NULL;
|
||||
}
|
||||
if (fp != nil)
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
if (tmpFp != nil)
|
||||
if (tmpFp != NULL)
|
||||
fclose(tmpFp);
|
||||
if (tmpPathDup != nil)
|
||||
if (tmpPathDup != NULL)
|
||||
Nu_Free(pArchive, tmpPathDup);
|
||||
}
|
||||
return err;
|
||||
|
@ -1060,17 +1050,16 @@ bail:
|
|||
/*
|
||||
* Write the NuFX master header at the current offset.
|
||||
*/
|
||||
NuError
|
||||
Nu_WriteMasterHeader(NuArchive* pArchive, FILE* fp,
|
||||
NuError Nu_WriteMasterHeader(NuArchive* pArchive, FILE* fp,
|
||||
NuMasterHeader* pHeader)
|
||||
{
|
||||
NuError err;
|
||||
long crcOffset;
|
||||
ushort crc;
|
||||
uint16_t crc;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pHeader != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pHeader != NULL);
|
||||
Assert(pHeader->isValid);
|
||||
Assert(pHeader->mhMasterVersion == kNuOurMHVersion);
|
||||
|
||||
|
@ -1122,23 +1111,22 @@ bail:
|
|||
* If it's a brand-new archive, and we didn't add anything to it, then we
|
||||
* want to remove the stub archive file.
|
||||
*/
|
||||
static void
|
||||
Nu_CloseAndFree(NuArchive* pArchive)
|
||||
static void Nu_CloseAndFree(NuArchive* pArchive)
|
||||
{
|
||||
if (pArchive->archiveFp != nil) {
|
||||
if (pArchive->archiveFp != NULL) {
|
||||
DBUG(("--- Closing archive\n"));
|
||||
fclose(pArchive->archiveFp);
|
||||
pArchive->archiveFp = nil;
|
||||
pArchive->archiveFp = NULL;
|
||||
}
|
||||
|
||||
if (pArchive->tmpFp != nil) {
|
||||
if (pArchive->tmpFp != NULL) {
|
||||
DBUG(("--- Closing and removing temp file\n"));
|
||||
fclose(pArchive->tmpFp);
|
||||
pArchive->tmpFp = nil;
|
||||
Assert(pArchive->tmpPathname != nil);
|
||||
if (remove(pArchive->tmpPathname) != 0) {
|
||||
pArchive->tmpFp = NULL;
|
||||
Assert(pArchive->tmpPathnameUNI != NULL);
|
||||
if (remove(pArchive->tmpPathnameUNI) != 0) {
|
||||
Nu_ReportError(NU_BLOB, errno, "Unable to remove temp file '%s'",
|
||||
pArchive->tmpPathname);
|
||||
pArchive->tmpPathnameUNI);
|
||||
/* keep going */
|
||||
}
|
||||
}
|
||||
|
@ -1146,9 +1134,9 @@ Nu_CloseAndFree(NuArchive* pArchive)
|
|||
if (pArchive->newlyCreated && Nu_RecordSet_IsEmpty(&pArchive->origRecordSet))
|
||||
{
|
||||
DBUG(("--- Newly-created archive unmodified; removing it\n"));
|
||||
if (remove(pArchive->archivePathname) != 0) {
|
||||
if (remove(pArchive->archivePathnameUNI) != 0) {
|
||||
Nu_ReportError(NU_BLOB, errno, "Unable to remove archive file '%s'",
|
||||
pArchive->archivePathname);
|
||||
pArchive->archivePathnameUNI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1158,13 +1146,12 @@ Nu_CloseAndFree(NuArchive* pArchive)
|
|||
/*
|
||||
* Flush pending changes to the archive, then close it.
|
||||
*/
|
||||
NuError
|
||||
Nu_Close(NuArchive* pArchive)
|
||||
NuError Nu_Close(NuArchive* pArchive)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
long flushStatus;
|
||||
uint32_t flushStatus;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
if (!Nu_IsReadOnly(pArchive))
|
||||
err = Nu_Flush(pArchive, &flushStatus);
|
||||
|
@ -1190,29 +1177,28 @@ Nu_Close(NuArchive* pArchive)
|
|||
/*
|
||||
* Delete the archive file, which should already have been closed.
|
||||
*/
|
||||
NuError
|
||||
Nu_DeleteArchiveFile(NuArchive* pArchive)
|
||||
NuError Nu_DeleteArchiveFile(NuArchive* pArchive)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive->archiveFp == nil);
|
||||
Assert(pArchive->archivePathname != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pArchive->archiveFp == NULL);
|
||||
Assert(pArchive->archivePathnameUNI != NULL);
|
||||
|
||||
return Nu_DeleteFile(pArchive->archivePathname);
|
||||
return Nu_DeleteFile(pArchive->archivePathnameUNI);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rename the temp file on top of the original archive. The temp file
|
||||
* should be closed, and the archive file should be deleted.
|
||||
*/
|
||||
NuError
|
||||
Nu_RenameTempToArchive(NuArchive* pArchive)
|
||||
NuError Nu_RenameTempToArchive(NuArchive* pArchive)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive->archiveFp == nil);
|
||||
Assert(pArchive->tmpFp == nil);
|
||||
Assert(pArchive->archivePathname != nil);
|
||||
Assert(pArchive->tmpPathname != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pArchive->archiveFp == NULL);
|
||||
Assert(pArchive->tmpFp == NULL);
|
||||
Assert(pArchive->archivePathnameUNI != NULL);
|
||||
Assert(pArchive->tmpPathnameUNI != NULL);
|
||||
|
||||
return Nu_RenameFile(pArchive->tmpPathname, pArchive->archivePathname);
|
||||
return Nu_RenameFile(pArchive->tmpPathnameUNI,
|
||||
pArchive->archivePathnameUNI);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,45 +26,41 @@
|
|||
/*
|
||||
* Read one byte, optionally computing a CRC.
|
||||
*/
|
||||
uchar
|
||||
Nu_ReadOneC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
|
||||
uint8_t Nu_ReadOneC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
|
||||
{
|
||||
int ic;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
|
||||
return (uchar) ic;
|
||||
return (uint8_t) ic;
|
||||
}
|
||||
|
||||
uchar
|
||||
Nu_ReadOne(NuArchive* pArchive, FILE* fp)
|
||||
uint8_t Nu_ReadOne(NuArchive* pArchive, FILE* fp)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
return Nu_ReadOneC(pArchive, fp, &dummyCrc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one byte, optionally computing a CRC.
|
||||
*/
|
||||
void
|
||||
Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uchar val, ushort* pCrc)
|
||||
void Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uint8_t val, uint16_t* pCrc)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
putc(val, fp);
|
||||
}
|
||||
|
||||
void
|
||||
Nu_WriteOne(NuArchive* pArchive, FILE* fp, uchar val)
|
||||
void Nu_WriteOne(NuArchive* pArchive, FILE* fp, uint8_t val)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
Nu_WriteOneC(pArchive, fp, val, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -72,27 +68,25 @@ Nu_WriteOne(NuArchive* pArchive, FILE* fp, uchar val)
|
|||
/*
|
||||
* Read two little-endian bytes, optionally computing a CRC.
|
||||
*/
|
||||
ushort
|
||||
Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
|
||||
uint16_t Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
|
||||
{
|
||||
int ic1, ic2;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
ic1 = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
|
||||
ic2 = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
|
||||
|
||||
return ic1 | ic2 << 8;
|
||||
}
|
||||
|
||||
ushort
|
||||
Nu_ReadTwo(NuArchive* pArchive, FILE* fp)
|
||||
uint16_t Nu_ReadTwo(NuArchive* pArchive, FILE* fp)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
return Nu_ReadTwoC(pArchive, fp, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -100,28 +94,26 @@ Nu_ReadTwo(NuArchive* pArchive, FILE* fp)
|
|||
/*
|
||||
* Write two little-endian bytes, optionally computing a CRC.
|
||||
*/
|
||||
void
|
||||
Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, ushort val, ushort* pCrc)
|
||||
void Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, uint16_t val, uint16_t* pCrc)
|
||||
{
|
||||
int ic1, ic2;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
ic1 = val & 0xff;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
|
||||
ic2 = val >> 8;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
|
||||
|
||||
putc(ic1, fp);
|
||||
putc(ic2, fp);
|
||||
}
|
||||
|
||||
void
|
||||
Nu_WriteTwo(NuArchive* pArchive, FILE* fp, ushort val)
|
||||
void Nu_WriteTwo(NuArchive* pArchive, FILE* fp, uint16_t val)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
Nu_WriteTwoC(pArchive, fp, val, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -129,31 +121,29 @@ Nu_WriteTwo(NuArchive* pArchive, FILE* fp, ushort val)
|
|||
/*
|
||||
* Read four little-endian bytes, optionally computing a CRC.
|
||||
*/
|
||||
ulong
|
||||
Nu_ReadFourC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
|
||||
uint32_t Nu_ReadFourC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
|
||||
{
|
||||
int ic1, ic2, ic3, ic4;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
ic1 = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
|
||||
ic2 = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
|
||||
ic3 = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic3, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic3, *pCrc);
|
||||
ic4 = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic4, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic4, *pCrc);
|
||||
|
||||
return ic1 | ic2 << 8 | (ulong)ic3 << 16 | (ulong)ic4 << 24;
|
||||
return ic1 | ic2 << 8 | (uint32_t)ic3 << 16 | (uint32_t)ic4 << 24;
|
||||
}
|
||||
|
||||
ulong
|
||||
Nu_ReadFour(NuArchive* pArchive, FILE* fp)
|
||||
uint32_t Nu_ReadFour(NuArchive* pArchive, FILE* fp)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
return Nu_ReadFourC(pArchive, fp, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -161,23 +151,22 @@ Nu_ReadFour(NuArchive* pArchive, FILE* fp)
|
|||
/*
|
||||
* Write four little-endian bytes, optionally computing a CRC.
|
||||
*/
|
||||
void
|
||||
Nu_WriteFourC(NuArchive* pArchive, FILE* fp, ulong val, ushort* pCrc)
|
||||
void Nu_WriteFourC(NuArchive* pArchive, FILE* fp, uint32_t val, uint16_t* pCrc)
|
||||
{
|
||||
int ic1, ic2, ic3, ic4;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
ic1 = val & 0xff;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
|
||||
ic2 = (val >> 8) & 0xff;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
|
||||
ic3 = (val >> 16) & 0xff;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic3, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic3, *pCrc);
|
||||
ic4 = val >> 24;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic4, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic4, *pCrc);
|
||||
|
||||
putc(ic1, fp);
|
||||
putc(ic2, fp);
|
||||
|
@ -185,10 +174,9 @@ Nu_WriteFourC(NuArchive* pArchive, FILE* fp, ulong val, ushort* pCrc)
|
|||
putc(ic4, fp);
|
||||
}
|
||||
|
||||
void
|
||||
Nu_WriteFour(NuArchive* pArchive, FILE* fp, ulong val)
|
||||
void Nu_WriteFour(NuArchive* pArchive, FILE* fp, uint32_t val)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
Nu_WriteFourC(pArchive, fp, val, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -200,48 +188,46 @@ Nu_WriteFour(NuArchive* pArchive, FILE* fp, ulong val)
|
|||
* and GS/ShrinkIt. It's easy enough to deal with, and I figure the less
|
||||
* messing-with, the better.
|
||||
*/
|
||||
NuDateTime
|
||||
Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
|
||||
NuDateTime Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
|
||||
{
|
||||
NuDateTime temp;
|
||||
int ic;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.second = ic;
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.minute = ic;
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.hour = ic;
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.year = ic;
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.day = ic;
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.month = ic;
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.extra = ic;
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
temp.weekDay = ic;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
NuDateTime
|
||||
Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, ushort* pCrc)
|
||||
NuDateTime Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
return Nu_ReadDateTimeC(pArchive, fp, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -249,46 +235,44 @@ Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, ushort* pCrc)
|
|||
/*
|
||||
* Write an 8-byte NuFX Date/Time structure.
|
||||
*/
|
||||
void
|
||||
Nu_WriteDateTimeC(NuArchive* pArchive, FILE* fp, NuDateTime dateTime,
|
||||
ushort* pCrc)
|
||||
void Nu_WriteDateTimeC(NuArchive* pArchive, FILE* fp, NuDateTime dateTime,
|
||||
uint16_t* pCrc)
|
||||
{
|
||||
int ic;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
ic = dateTime.second;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
ic = dateTime.minute;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
ic = dateTime.hour;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
ic = dateTime.year;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
ic = dateTime.day;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
ic = dateTime.month;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
ic = dateTime.extra;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
ic = dateTime.weekDay;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
}
|
||||
|
||||
void
|
||||
Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime)
|
||||
void Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
Nu_WriteDateTimeC(pArchive, fp, dateTime, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -296,30 +280,28 @@ Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime)
|
|||
/*
|
||||
* Read N bytes from the stream, optionally computing a CRC.
|
||||
*/
|
||||
void
|
||||
Nu_ReadBytesC(NuArchive* pArchive, FILE* fp, void* vbuffer, long count,
|
||||
ushort* pCrc)
|
||||
void Nu_ReadBytesC(NuArchive* pArchive, FILE* fp, void* vbuffer, long count,
|
||||
uint16_t* pCrc)
|
||||
{
|
||||
uchar* buffer = vbuffer;
|
||||
uint8_t* buffer = vbuffer;
|
||||
int ic;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(buffer != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
Assert(buffer != NULL);
|
||||
Assert(count > 0);
|
||||
|
||||
while (count--) {
|
||||
ic = getc(fp);
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
*buffer++ = ic;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count)
|
||||
void Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
Nu_ReadBytesC(pArchive, fp, vbuffer, count, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -327,30 +309,29 @@ Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count)
|
|||
/*
|
||||
* Write N bytes to the stream, optionally computing a CRC.
|
||||
*/
|
||||
void
|
||||
Nu_WriteBytesC(NuArchive* pArchive, FILE* fp, const void* vbuffer, long count,
|
||||
ushort* pCrc)
|
||||
void Nu_WriteBytesC(NuArchive* pArchive, FILE* fp, const void* vbuffer,
|
||||
long count, uint16_t* pCrc)
|
||||
{
|
||||
const uchar* buffer = vbuffer;
|
||||
const uint8_t* buffer = vbuffer;
|
||||
int ic;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(buffer != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
Assert(buffer != NULL);
|
||||
Assert(count > 0);
|
||||
|
||||
while (count--) {
|
||||
ic = *buffer++;
|
||||
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
|
||||
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
|
||||
putc(ic, fp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer, long count)
|
||||
void Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer,
|
||||
long count)
|
||||
{
|
||||
ushort dummyCrc CLEAN_INIT;
|
||||
uint16_t dummyCrc CLEAN_INIT;
|
||||
Nu_WriteBytesC(pArchive, fp, vbuffer, count, &dummyCrc);
|
||||
}
|
||||
|
||||
|
@ -365,8 +346,7 @@ Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer, long count)
|
|||
* Determine whether the stream completed the last set of operations
|
||||
* successfully.
|
||||
*/
|
||||
NuError
|
||||
Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp)
|
||||
NuError Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp)
|
||||
{
|
||||
if (feof(fp) || ferror(fp))
|
||||
return kNuErrFile;
|
||||
|
@ -381,8 +361,7 @@ Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp)
|
|||
*
|
||||
* The values for "ptrname" are the same as for fseek().
|
||||
*/
|
||||
NuError
|
||||
Nu_SeekArchive(NuArchive* pArchive, FILE* fp, long offset, int ptrname)
|
||||
NuError Nu_SeekArchive(NuArchive* pArchive, FILE* fp, long offset, int ptrname)
|
||||
{
|
||||
if (Nu_IsStreaming(pArchive)) {
|
||||
Assert(ptrname == SEEK_CUR);
|
||||
|
@ -408,10 +387,9 @@ Nu_SeekArchive(NuArchive* pArchive, FILE* fp, long offset, int ptrname)
|
|||
*
|
||||
* Note that rewind(3S) resets the error indication, but this doesn't.
|
||||
*/
|
||||
NuError
|
||||
Nu_RewindArchive(NuArchive* pArchive)
|
||||
NuError Nu_RewindArchive(NuArchive* pArchive)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(!Nu_IsStreaming(pArchive));
|
||||
|
||||
if (Nu_SeekArchive(pArchive, pArchive->archiveFp,
|
||||
|
|
|
@ -25,13 +25,11 @@
|
|||
/*
|
||||
* Alloc and free functions provided to libbz2.
|
||||
*/
|
||||
static void*
|
||||
Nu_bzalloc(void* opaque, int items, int size)
|
||||
static void* Nu_bzalloc(void* opaque, int items, int size)
|
||||
{
|
||||
return Nu_Malloc(opaque, items * size);
|
||||
}
|
||||
static void
|
||||
Nu_bzfree(void* opaque, void* address)
|
||||
static void Nu_bzfree(void* opaque, void* address)
|
||||
{
|
||||
Nu_Free(opaque, address);
|
||||
}
|
||||
|
@ -46,21 +44,20 @@ Nu_bzfree(void* opaque, void* address)
|
|||
/*
|
||||
* Compress "srcLen" bytes from "pStraw" to "fp".
|
||||
*/
|
||||
NuError
|
||||
Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc)
|
||||
NuError Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
bz_stream bzstream;
|
||||
int bzerr;
|
||||
uchar* outbuf = nil;
|
||||
uint8_t* outbuf = NULL;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pStraw != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(srcLen > 0);
|
||||
Assert(pDstLen != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pDstLen != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
if (err != kNuErrNone)
|
||||
|
@ -76,7 +73,7 @@ Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
bzstream.bzalloc = Nu_bzalloc;
|
||||
bzstream.bzfree = Nu_bzfree;
|
||||
bzstream.opaque = pArchive;
|
||||
bzstream.next_in = nil;
|
||||
bzstream.next_in = NULL;
|
||||
bzstream.avail_in = 0;
|
||||
bzstream.next_out = outbuf;
|
||||
bzstream.avail_out = kNuGenCompBufSize;
|
||||
|
@ -98,7 +95,7 @@ Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
* Loop while we have data.
|
||||
*/
|
||||
do {
|
||||
ulong getSize;
|
||||
uint32_t getSize;
|
||||
int action;
|
||||
|
||||
/* should be able to read a full buffer every time */
|
||||
|
@ -139,8 +136,8 @@ Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
(bzerr == BZ_STREAM_END && bzstream.avail_out != kNuGenCompBufSize))
|
||||
{
|
||||
DBUG(("+++ writing %d bytes\n",
|
||||
(uchar*)bzstream.next_out - outbuf));
|
||||
err = Nu_FWrite(fp, outbuf, (uchar*)bzstream.next_out - outbuf);
|
||||
(uint8_t*)bzstream.next_out - outbuf));
|
||||
err = Nu_FWrite(fp, outbuf, (uint8_t*)bzstream.next_out - outbuf);
|
||||
if (err != kNuErrNone) {
|
||||
Nu_ReportError(NU_BLOB, err, "fwrite failed in bzip2");
|
||||
goto bz_bail;
|
||||
|
@ -158,8 +155,8 @@ bz_bail:
|
|||
BZ2_bzCompressEnd(&bzstream); /* free up any allocated structures */
|
||||
|
||||
bail:
|
||||
if (outbuf != nil)
|
||||
free(outbuf);
|
||||
if (outbuf != NULL)
|
||||
Nu_Free(NULL, outbuf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -173,20 +170,19 @@ bail:
|
|||
/*
|
||||
* Expand from "infp" to "pFunnel".
|
||||
*/
|
||||
NuError
|
||||
Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
|
||||
NuError Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
bz_stream bzstream;
|
||||
int bzerr;
|
||||
ulong compRemaining;
|
||||
uchar* outbuf;
|
||||
uint32_t compRemaining;
|
||||
uint8_t* outbuf;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(infp != nil);
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(infp != NULL);
|
||||
Assert(pFunnel != NULL);
|
||||
|
||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
if (err != kNuErrNone)
|
||||
|
@ -204,7 +200,7 @@ Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
bzstream.bzalloc = Nu_bzalloc;
|
||||
bzstream.bzfree = Nu_bzfree;
|
||||
bzstream.opaque = pArchive;
|
||||
bzstream.next_in = nil;
|
||||
bzstream.next_in = NULL;
|
||||
bzstream.avail_in = 0;
|
||||
bzstream.next_out = outbuf;
|
||||
bzstream.avail_out = kNuGenCompBufSize;
|
||||
|
@ -226,7 +222,7 @@ Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* Loop while we have data.
|
||||
*/
|
||||
do {
|
||||
ulong getSize;
|
||||
uint32_t getSize;
|
||||
|
||||
/* read as much as we can */
|
||||
if (bzstream.avail_in == 0) {
|
||||
|
@ -258,17 +254,18 @@ Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
|
||||
/* write every time there's anything (buffer will usually be full) */
|
||||
if (bzstream.avail_out != kNuGenCompBufSize) {
|
||||
DBUG(("+++ writing %d bytes\n",(uchar*)bzstream.next_out - outbuf));
|
||||
DBUG(("+++ writing %d bytes\n",
|
||||
(uint8_t*) bzstream.next_out - outbuf));
|
||||
err = Nu_FunnelWrite(pArchive, pFunnel, outbuf,
|
||||
(uchar*)bzstream.next_out - outbuf);
|
||||
(uint8_t*)bzstream.next_out - outbuf);
|
||||
if (err != kNuErrNone) {
|
||||
Nu_ReportError(NU_BLOB, err, "write failed in bzip2");
|
||||
goto bz_bail;
|
||||
}
|
||||
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, outbuf,
|
||||
(uchar*) bzstream.next_out - outbuf);
|
||||
(uint8_t*) bzstream.next_out - outbuf);
|
||||
|
||||
bzstream.next_out = outbuf;
|
||||
bzstream.avail_out = kNuGenCompBufSize;
|
||||
|
@ -291,8 +288,8 @@ bz_bail:
|
|||
BZ2_bzDecompressEnd(&bzstream); /* free up any allocated structures */
|
||||
|
||||
bail:
|
||||
if (outbuf != nil)
|
||||
free(outbuf);
|
||||
if (outbuf != NULL)
|
||||
Nu_Free(NULL, outbuf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
2017/09/21 ***** v3.1.0 shipped *****
|
||||
|
||||
2016/01/11 fadden
|
||||
- Fix handling of disk images (broken by previous change).
|
||||
|
||||
2015/12/26 fadden
|
||||
- Fix handling of entries with missing threads.
|
||||
- Improve handling of Mac OS X file type attributes.
|
||||
|
||||
2015/01/09 ***** v3.0.0 shipped *****
|
||||
|
||||
2015/01/03 fadden
|
||||
- Mac OS X: replace Carbon FinderInfo calls with BSD xattr.
|
||||
- Mac OS X: fix resource fork naming.
|
||||
- Mac OS X: disable use of native resource forks.
|
||||
|
||||
2015/01/02 fadden
|
||||
- Distinguish Unicode and Mac OS Roman strings.
|
||||
|
||||
2014/12/22 fadden
|
||||
- Source code cleanup.
|
||||
|
||||
2014/10/30 ***** v2.2.2 shipped *****
|
||||
|
||||
2014/10/28 fadden
|
||||
|
|
553
nufxlib/Charset.c
Normal file
553
nufxlib/Charset.c
Normal file
|
@ -0,0 +1,553 @@
|
|||
/*
|
||||
* NuFX archive manipulation library
|
||||
* Copyright (C) 2014 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING-LIB.
|
||||
*
|
||||
* Miscellaneous NufxLib utility functions.
|
||||
*/
|
||||
#include "NufxLibPriv.h"
|
||||
|
||||
/*
|
||||
* Convert Mac OS Roman to Unicode. Mapping comes from:
|
||||
*
|
||||
* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT
|
||||
*
|
||||
* We use the "Control Pictures" block for the control characters
|
||||
* (0x00-0x1f, 0x7f --> 0x2400-0x241f, 0x2421). This is a bit nicer
|
||||
* than embedding control characters in filenames.
|
||||
*/
|
||||
static const uint16_t gMORToUnicode[256] = {
|
||||
/*0x00*/ 0x2400, // [control] NULL
|
||||
/*0x01*/ 0x2401, // [control] START OF HEADING
|
||||
/*0x02*/ 0x2402, // [control] START OF TEXT
|
||||
/*0x03*/ 0x2403, // [control] END OF TEXT
|
||||
/*0x04*/ 0x2404, // [control] END OF TRANSMISSION
|
||||
/*0x05*/ 0x2405, // [control] ENQUIRY
|
||||
/*0x06*/ 0x2406, // [control] ACKNOWLEDGE
|
||||
/*0x07*/ 0x2407, // [control] BELL
|
||||
/*0x08*/ 0x2408, // [control] BACKSPACE
|
||||
/*0x09*/ 0x2409, // [control] HORIZONTAL TABULATION
|
||||
/*0x0a*/ 0x240a, // [control] LINE FEED
|
||||
/*0x0b*/ 0x240b, // [control] VERTICAL TABULATION
|
||||
/*0x0c*/ 0x240c, // [control] FORM FEED
|
||||
/*0x0d*/ 0x240d, // [control] CARRIAGE RETURN
|
||||
/*0x0e*/ 0x240e, // [control] SHIFT OUT
|
||||
/*0x0f*/ 0x240f, // [control] SHIFT IN
|
||||
/*0x10*/ 0x2410, // [control] DATA LINK ESCAPE
|
||||
/*0x11*/ 0x2411, // [control] DEVICE CONTROL ONE
|
||||
/*0x12*/ 0x2412, // [control] DEVICE CONTROL TWO
|
||||
/*0x13*/ 0x2413, // [control] DEVICE CONTROL THREE
|
||||
/*0x14*/ 0x2414, // [control] DEVICE CONTROL FOUR
|
||||
/*0x15*/ 0x2415, // [control] NEGATIVE ACKNOWLEDGE
|
||||
/*0x16*/ 0x2416, // [control] SYNCHRONOUS IDLE
|
||||
/*0x17*/ 0x2417, // [control] END OF TRANSMISSION BLOCK
|
||||
/*0x18*/ 0x2418, // [control] CANCEL
|
||||
/*0x19*/ 0x2419, // [control] END OF MEDIUM
|
||||
/*0x1a*/ 0x241a, // [control] SUBSTITUTE
|
||||
/*0x1b*/ 0x241b, // [control] ESCAPE
|
||||
/*0x1c*/ 0x241c, // [control] FILE SEPARATOR
|
||||
/*0x1d*/ 0x241d, // [control] GROUP SEPARATOR
|
||||
/*0x1e*/ 0x241e, // [control] RECORD SEPARATOR
|
||||
/*0x1f*/ 0x241f, // [control] UNIT SEPARATOR
|
||||
/*0x20*/ 0x0020, // SPACE
|
||||
/*0x21*/ 0x0021, // EXCLAMATION MARK
|
||||
/*0x22*/ 0x0022, // QUOTATION MARK
|
||||
/*0x23*/ 0x0023, // NUMBER SIGN
|
||||
/*0x24*/ 0x0024, // DOLLAR SIGN
|
||||
/*0x25*/ 0x0025, // PERCENT SIGN
|
||||
/*0x26*/ 0x0026, // AMPERSAND
|
||||
/*0x27*/ 0x0027, // APOSTROPHE
|
||||
/*0x28*/ 0x0028, // LEFT PARENTHESIS
|
||||
/*0x29*/ 0x0029, // RIGHT PARENTHESIS
|
||||
/*0x2A*/ 0x002A, // ASTERISK
|
||||
/*0x2B*/ 0x002B, // PLUS SIGN
|
||||
/*0x2C*/ 0x002C, // COMMA
|
||||
/*0x2D*/ 0x002D, // HYPHEN-MINUS
|
||||
/*0x2E*/ 0x002E, // FULL STOP
|
||||
/*0x2F*/ 0x002F, // SOLIDUS
|
||||
/*0x30*/ 0x0030, // DIGIT ZERO
|
||||
/*0x31*/ 0x0031, // DIGIT ONE
|
||||
/*0x32*/ 0x0032, // DIGIT TWO
|
||||
/*0x33*/ 0x0033, // DIGIT THREE
|
||||
/*0x34*/ 0x0034, // DIGIT FOUR
|
||||
/*0x35*/ 0x0035, // DIGIT FIVE
|
||||
/*0x36*/ 0x0036, // DIGIT SIX
|
||||
/*0x37*/ 0x0037, // DIGIT SEVEN
|
||||
/*0x38*/ 0x0038, // DIGIT EIGHT
|
||||
/*0x39*/ 0x0039, // DIGIT NINE
|
||||
/*0x3A*/ 0x003A, // COLON
|
||||
/*0x3B*/ 0x003B, // SEMICOLON
|
||||
/*0x3C*/ 0x003C, // LESS-THAN SIGN
|
||||
/*0x3D*/ 0x003D, // EQUALS SIGN
|
||||
/*0x3E*/ 0x003E, // GREATER-THAN SIGN
|
||||
/*0x3F*/ 0x003F, // QUESTION MARK
|
||||
/*0x40*/ 0x0040, // COMMERCIAL AT
|
||||
/*0x41*/ 0x0041, // LATIN CAPITAL LETTER A
|
||||
/*0x42*/ 0x0042, // LATIN CAPITAL LETTER B
|
||||
/*0x43*/ 0x0043, // LATIN CAPITAL LETTER C
|
||||
/*0x44*/ 0x0044, // LATIN CAPITAL LETTER D
|
||||
/*0x45*/ 0x0045, // LATIN CAPITAL LETTER E
|
||||
/*0x46*/ 0x0046, // LATIN CAPITAL LETTER F
|
||||
/*0x47*/ 0x0047, // LATIN CAPITAL LETTER G
|
||||
/*0x48*/ 0x0048, // LATIN CAPITAL LETTER H
|
||||
/*0x49*/ 0x0049, // LATIN CAPITAL LETTER I
|
||||
/*0x4A*/ 0x004A, // LATIN CAPITAL LETTER J
|
||||
/*0x4B*/ 0x004B, // LATIN CAPITAL LETTER K
|
||||
/*0x4C*/ 0x004C, // LATIN CAPITAL LETTER L
|
||||
/*0x4D*/ 0x004D, // LATIN CAPITAL LETTER M
|
||||
/*0x4E*/ 0x004E, // LATIN CAPITAL LETTER N
|
||||
/*0x4F*/ 0x004F, // LATIN CAPITAL LETTER O
|
||||
/*0x50*/ 0x0050, // LATIN CAPITAL LETTER P
|
||||
/*0x51*/ 0x0051, // LATIN CAPITAL LETTER Q
|
||||
/*0x52*/ 0x0052, // LATIN CAPITAL LETTER R
|
||||
/*0x53*/ 0x0053, // LATIN CAPITAL LETTER S
|
||||
/*0x54*/ 0x0054, // LATIN CAPITAL LETTER T
|
||||
/*0x55*/ 0x0055, // LATIN CAPITAL LETTER U
|
||||
/*0x56*/ 0x0056, // LATIN CAPITAL LETTER V
|
||||
/*0x57*/ 0x0057, // LATIN CAPITAL LETTER W
|
||||
/*0x58*/ 0x0058, // LATIN CAPITAL LETTER X
|
||||
/*0x59*/ 0x0059, // LATIN CAPITAL LETTER Y
|
||||
/*0x5A*/ 0x005A, // LATIN CAPITAL LETTER Z
|
||||
/*0x5B*/ 0x005B, // LEFT SQUARE BRACKET
|
||||
/*0x5C*/ 0x005C, // REVERSE SOLIDUS
|
||||
/*0x5D*/ 0x005D, // RIGHT SQUARE BRACKET
|
||||
/*0x5E*/ 0x005E, // CIRCUMFLEX ACCENT
|
||||
/*0x5F*/ 0x005F, // LOW LINE
|
||||
/*0x60*/ 0x0060, // GRAVE ACCENT
|
||||
/*0x61*/ 0x0061, // LATIN SMALL LETTER A
|
||||
/*0x62*/ 0x0062, // LATIN SMALL LETTER B
|
||||
/*0x63*/ 0x0063, // LATIN SMALL LETTER C
|
||||
/*0x64*/ 0x0064, // LATIN SMALL LETTER D
|
||||
/*0x65*/ 0x0065, // LATIN SMALL LETTER E
|
||||
/*0x66*/ 0x0066, // LATIN SMALL LETTER F
|
||||
/*0x67*/ 0x0067, // LATIN SMALL LETTER G
|
||||
/*0x68*/ 0x0068, // LATIN SMALL LETTER H
|
||||
/*0x69*/ 0x0069, // LATIN SMALL LETTER I
|
||||
/*0x6A*/ 0x006A, // LATIN SMALL LETTER J
|
||||
/*0x6B*/ 0x006B, // LATIN SMALL LETTER K
|
||||
/*0x6C*/ 0x006C, // LATIN SMALL LETTER L
|
||||
/*0x6D*/ 0x006D, // LATIN SMALL LETTER M
|
||||
/*0x6E*/ 0x006E, // LATIN SMALL LETTER N
|
||||
/*0x6F*/ 0x006F, // LATIN SMALL LETTER O
|
||||
/*0x70*/ 0x0070, // LATIN SMALL LETTER P
|
||||
/*0x71*/ 0x0071, // LATIN SMALL LETTER Q
|
||||
/*0x72*/ 0x0072, // LATIN SMALL LETTER R
|
||||
/*0x73*/ 0x0073, // LATIN SMALL LETTER S
|
||||
/*0x74*/ 0x0074, // LATIN SMALL LETTER T
|
||||
/*0x75*/ 0x0075, // LATIN SMALL LETTER U
|
||||
/*0x76*/ 0x0076, // LATIN SMALL LETTER V
|
||||
/*0x77*/ 0x0077, // LATIN SMALL LETTER W
|
||||
/*0x78*/ 0x0078, // LATIN SMALL LETTER X
|
||||
/*0x79*/ 0x0079, // LATIN SMALL LETTER Y
|
||||
/*0x7A*/ 0x007A, // LATIN SMALL LETTER Z
|
||||
/*0x7B*/ 0x007B, // LEFT CURLY BRACKET
|
||||
/*0x7C*/ 0x007C, // VERTICAL LINE
|
||||
/*0x7D*/ 0x007D, // RIGHT CURLY BRACKET
|
||||
/*0x7E*/ 0x007E, // TILDE
|
||||
/*0x7f*/ 0x2421, // [control] DELETE
|
||||
/*0x80*/ 0x00C4, // LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||
/*0x81*/ 0x00C5, // LATIN CAPITAL LETTER A WITH RING ABOVE
|
||||
/*0x82*/ 0x00C7, // LATIN CAPITAL LETTER C WITH CEDILLA
|
||||
/*0x83*/ 0x00C9, // LATIN CAPITAL LETTER E WITH ACUTE
|
||||
/*0x84*/ 0x00D1, // LATIN CAPITAL LETTER N WITH TILDE
|
||||
/*0x85*/ 0x00D6, // LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
/*0x86*/ 0x00DC, // LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||
/*0x87*/ 0x00E1, // LATIN SMALL LETTER A WITH ACUTE
|
||||
/*0x88*/ 0x00E0, // LATIN SMALL LETTER A WITH GRAVE
|
||||
/*0x89*/ 0x00E2, // LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||
/*0x8A*/ 0x00E4, // LATIN SMALL LETTER A WITH DIAERESIS
|
||||
/*0x8B*/ 0x00E3, // LATIN SMALL LETTER A WITH TILDE
|
||||
/*0x8C*/ 0x00E5, // LATIN SMALL LETTER A WITH RING ABOVE
|
||||
/*0x8D*/ 0x00E7, // LATIN SMALL LETTER C WITH CEDILLA
|
||||
/*0x8E*/ 0x00E9, // LATIN SMALL LETTER E WITH ACUTE
|
||||
/*0x8F*/ 0x00E8, // LATIN SMALL LETTER E WITH GRAVE
|
||||
/*0x90*/ 0x00EA, // LATIN SMALL LETTER E WITH CIRCUMFLEX
|
||||
/*0x91*/ 0x00EB, // LATIN SMALL LETTER E WITH DIAERESIS
|
||||
/*0x92*/ 0x00ED, // LATIN SMALL LETTER I WITH ACUTE
|
||||
/*0x93*/ 0x00EC, // LATIN SMALL LETTER I WITH GRAVE
|
||||
/*0x94*/ 0x00EE, // LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||
/*0x95*/ 0x00EF, // LATIN SMALL LETTER I WITH DIAERESIS
|
||||
/*0x96*/ 0x00F1, // LATIN SMALL LETTER N WITH TILDE
|
||||
/*0x97*/ 0x00F3, // LATIN SMALL LETTER O WITH ACUTE
|
||||
/*0x98*/ 0x00F2, // LATIN SMALL LETTER O WITH GRAVE
|
||||
/*0x99*/ 0x00F4, // LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||
/*0x9A*/ 0x00F6, // LATIN SMALL LETTER O WITH DIAERESIS
|
||||
/*0x9B*/ 0x00F5, // LATIN SMALL LETTER O WITH TILDE
|
||||
/*0x9C*/ 0x00FA, // LATIN SMALL LETTER U WITH ACUTE
|
||||
/*0x9D*/ 0x00F9, // LATIN SMALL LETTER U WITH GRAVE
|
||||
/*0x9E*/ 0x00FB, // LATIN SMALL LETTER U WITH CIRCUMFLEX
|
||||
/*0x9F*/ 0x00FC, // LATIN SMALL LETTER U WITH DIAERESIS
|
||||
/*0xA0*/ 0x2020, // DAGGER
|
||||
/*0xA1*/ 0x00B0, // DEGREE SIGN
|
||||
/*0xA2*/ 0x00A2, // CENT SIGN
|
||||
/*0xA3*/ 0x00A3, // POUND SIGN
|
||||
/*0xA4*/ 0x00A7, // SECTION SIGN
|
||||
/*0xA5*/ 0x2022, // BULLET
|
||||
/*0xA6*/ 0x00B6, // PILCROW SIGN
|
||||
/*0xA7*/ 0x00DF, // LATIN SMALL LETTER SHARP S
|
||||
/*0xA8*/ 0x00AE, // REGISTERED SIGN
|
||||
/*0xA9*/ 0x00A9, // COPYRIGHT SIGN
|
||||
/*0xAA*/ 0x2122, // TRADE MARK SIGN
|
||||
/*0xAB*/ 0x00B4, // ACUTE ACCENT
|
||||
/*0xAC*/ 0x00A8, // DIAERESIS
|
||||
/*0xAD*/ 0x2260, // NOT EQUAL TO
|
||||
/*0xAE*/ 0x00C6, // LATIN CAPITAL LETTER AE
|
||||
/*0xAF*/ 0x00D8, // LATIN CAPITAL LETTER O WITH STROKE
|
||||
/*0xB0*/ 0x221E, // INFINITY
|
||||
/*0xB1*/ 0x00B1, // PLUS-MINUS SIGN
|
||||
/*0xB2*/ 0x2264, // LESS-THAN OR EQUAL TO
|
||||
/*0xB3*/ 0x2265, // GREATER-THAN OR EQUAL TO
|
||||
/*0xB4*/ 0x00A5, // YEN SIGN
|
||||
/*0xB5*/ 0x00B5, // MICRO SIGN
|
||||
/*0xB6*/ 0x2202, // PARTIAL DIFFERENTIAL
|
||||
/*0xB7*/ 0x2211, // N-ARY SUMMATION
|
||||
/*0xB8*/ 0x220F, // N-ARY PRODUCT
|
||||
/*0xB9*/ 0x03C0, // GREEK SMALL LETTER PI
|
||||
/*0xBA*/ 0x222B, // INTEGRAL
|
||||
/*0xBB*/ 0x00AA, // FEMININE ORDINAL INDICATOR
|
||||
/*0xBC*/ 0x00BA, // MASCULINE ORDINAL INDICATOR
|
||||
/*0xBD*/ 0x03A9, // GREEK CAPITAL LETTER OMEGA
|
||||
/*0xBE*/ 0x00E6, // LATIN SMALL LETTER AE
|
||||
/*0xBF*/ 0x00F8, // LATIN SMALL LETTER O WITH STROKE
|
||||
/*0xC0*/ 0x00BF, // INVERTED QUESTION MARK
|
||||
/*0xC1*/ 0x00A1, // INVERTED EXCLAMATION MARK
|
||||
/*0xC2*/ 0x00AC, // NOT SIGN
|
||||
/*0xC3*/ 0x221A, // SQUARE ROOT
|
||||
/*0xC4*/ 0x0192, // LATIN SMALL LETTER F WITH HOOK
|
||||
/*0xC5*/ 0x2248, // ALMOST EQUAL TO
|
||||
/*0xC6*/ 0x2206, // INCREMENT
|
||||
/*0xC7*/ 0x00AB, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
/*0xC8*/ 0x00BB, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
/*0xC9*/ 0x2026, // HORIZONTAL ELLIPSIS
|
||||
/*0xCA*/ 0x00A0, // NO-BREAK SPACE
|
||||
/*0xCB*/ 0x00C0, // LATIN CAPITAL LETTER A WITH GRAVE
|
||||
/*0xCC*/ 0x00C3, // LATIN CAPITAL LETTER A WITH TILDE
|
||||
/*0xCD*/ 0x00D5, // LATIN CAPITAL LETTER O WITH TILDE
|
||||
/*0xCE*/ 0x0152, // LATIN CAPITAL LIGATURE OE
|
||||
/*0xCF*/ 0x0153, // LATIN SMALL LIGATURE OE
|
||||
/*0xD0*/ 0x2013, // EN DASH
|
||||
/*0xD1*/ 0x2014, // EM DASH
|
||||
/*0xD2*/ 0x201C, // LEFT DOUBLE QUOTATION MARK
|
||||
/*0xD3*/ 0x201D, // RIGHT DOUBLE QUOTATION MARK
|
||||
/*0xD4*/ 0x2018, // LEFT SINGLE QUOTATION MARK
|
||||
/*0xD5*/ 0x2019, // RIGHT SINGLE QUOTATION MARK
|
||||
/*0xD6*/ 0x00F7, // DIVISION SIGN
|
||||
/*0xD7*/ 0x25CA, // LOZENGE
|
||||
/*0xD8*/ 0x00FF, // LATIN SMALL LETTER Y WITH DIAERESIS
|
||||
/*0xD9*/ 0x0178, // LATIN CAPITAL LETTER Y WITH DIAERESIS
|
||||
/*0xDA*/ 0x2044, // FRACTION SLASH
|
||||
/*0xDB*/ 0x00A4, // CURRENCY SIGN (was EURO SIGN)
|
||||
/*0xDC*/ 0x2039, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
||||
/*0xDD*/ 0x203A, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
/*0xDE*/ 0xFB01, // LATIN SMALL LIGATURE FI
|
||||
/*0xDF*/ 0xFB02, // LATIN SMALL LIGATURE FL
|
||||
/*0xE0*/ 0x2021, // DOUBLE DAGGER
|
||||
/*0xE1*/ 0x00B7, // MIDDLE DOT
|
||||
/*0xE2*/ 0x201A, // SINGLE LOW-9 QUOTATION MARK
|
||||
/*0xE3*/ 0x201E, // DOUBLE LOW-9 QUOTATION MARK
|
||||
/*0xE4*/ 0x2030, // PER MILLE SIGN
|
||||
/*0xE5*/ 0x00C2, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||
/*0xE6*/ 0x00CA, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
||||
/*0xE7*/ 0x00C1, // LATIN CAPITAL LETTER A WITH ACUTE
|
||||
/*0xE8*/ 0x00CB, // LATIN CAPITAL LETTER E WITH DIAERESIS
|
||||
/*0xE9*/ 0x00C8, // LATIN CAPITAL LETTER E WITH GRAVE
|
||||
/*0xEA*/ 0x00CD, // LATIN CAPITAL LETTER I WITH ACUTE
|
||||
/*0xEB*/ 0x00CE, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||
/*0xEC*/ 0x00CF, // LATIN CAPITAL LETTER I WITH DIAERESIS
|
||||
/*0xED*/ 0x00CC, // LATIN CAPITAL LETTER I WITH GRAVE
|
||||
/*0xEE*/ 0x00D3, // LATIN CAPITAL LETTER O WITH ACUTE
|
||||
/*0xEF*/ 0x00D4, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||
/*0xF0*/ 0xF8FF, // Apple logo
|
||||
/*0xF1*/ 0x00D2, // LATIN CAPITAL LETTER O WITH GRAVE
|
||||
/*0xF2*/ 0x00DA, // LATIN CAPITAL LETTER U WITH ACUTE
|
||||
/*0xF3*/ 0x00DB, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
||||
/*0xF4*/ 0x00D9, // LATIN CAPITAL LETTER U WITH GRAVE
|
||||
/*0xF5*/ 0x0131, // LATIN SMALL LETTER DOTLESS I
|
||||
/*0xF6*/ 0x02C6, // MODIFIER LETTER CIRCUMFLEX ACCENT
|
||||
/*0xF7*/ 0x02DC, // SMALL TILDE
|
||||
/*0xF8*/ 0x00AF, // MACRON
|
||||
/*0xF9*/ 0x02D8, // BREVE
|
||||
/*0xFA*/ 0x02D9, // DOT ABOVE
|
||||
/*0xFB*/ 0x02DA, // RING ABOVE
|
||||
/*0xFC*/ 0x00B8, // CEDILLA
|
||||
/*0xFD*/ 0x02DD, // DOUBLE ACUTE ACCENT
|
||||
/*0xFE*/ 0x02DB, // OGONEK
|
||||
/*0xFF*/ 0x02C7 // CARON
|
||||
};
|
||||
|
||||
/*
|
||||
* Static table, populated on first use. Provides the inverse map.
|
||||
*
|
||||
* An entry with 0x00 indicates no conversion. That's incorrect for
|
||||
* the entry for '\0', but since we're operating on null-terminated
|
||||
* strings that's never valid anyway. (It's possible for a filename
|
||||
* to contain 0x2400, but that would translate to 0x00, which we don't
|
||||
* allow; so it makes more sense to treat it as illegal.)
|
||||
*/
|
||||
static uint8_t gUnicodeToMOR[65536] = { 0xff /*indicates not initialized*/ };
|
||||
|
||||
static void Nu_GenerateUnicodeToMOR(void)
|
||||
{
|
||||
memset(gUnicodeToMOR, 0, sizeof(gUnicodeToMOR));
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
int codePoint = gMORToUnicode[i];
|
||||
Assert(codePoint >= 0 && codePoint < 65536);
|
||||
gUnicodeToMOR[codePoint] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Converts stringMOR to Unicode, storing the output in bufUNI until it's
|
||||
* full. Null termination is guaranteed. If the buffer size is zero or
|
||||
* bufUNI is NULL, no string data is returned.
|
||||
*
|
||||
* Returns the number of bytes required to represent stringMOR in Unicode.
|
||||
*/
|
||||
size_t Nu_ConvertMORToUNI(const char* stringMOR, UNICHAR* bufUNI,
|
||||
size_t bufSize)
|
||||
{
|
||||
Assert(stringMOR != 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* place-holder if we're not using UTF-16 yet */
|
||||
Assert(sizeof(UNICHAR) == 1);
|
||||
size_t morLen = strlen(stringMOR) + 1;
|
||||
if (bufUNI != NULL && bufSize != 0) {
|
||||
size_t copyLen = morLen < bufSize ? morLen : bufSize;
|
||||
memcpy(bufUNI, stringMOR, copyLen);
|
||||
bufUNI[bufSize-1] = '\0';
|
||||
}
|
||||
return morLen;
|
||||
#else
|
||||
/*
|
||||
* Convert Mac OS Roman to UTF-8. We only output full code points,
|
||||
* so if only the first byte of a UTF-8 sequence will fit we just
|
||||
* stop early.
|
||||
*/
|
||||
size_t uniLen = 0;
|
||||
Boolean doOutput = (bufUNI != NULL);
|
||||
|
||||
while (*stringMOR != '\0') {
|
||||
// ASCII values just "convert" to themselves in this table
|
||||
uint16_t us = gMORToUnicode[(uint8_t)*stringMOR];
|
||||
if (us < 0x80) {
|
||||
// single byte, no conversion
|
||||
if (uniLen+1 >= bufSize) {
|
||||
doOutput = false;
|
||||
}
|
||||
if (doOutput) {
|
||||
bufUNI[uniLen] = (char) us;
|
||||
}
|
||||
uniLen++;
|
||||
} else if (us < 0x7ff) {
|
||||
// two bytes
|
||||
if (uniLen+2 >= bufSize) {
|
||||
doOutput = false;
|
||||
}
|
||||
if (doOutput) {
|
||||
bufUNI[uniLen] = (us >> 6) | 0xc0;
|
||||
bufUNI[uniLen+1] = (us & 0x3f) | 0x80;
|
||||
}
|
||||
uniLen += 2;
|
||||
} else {
|
||||
// three bytes
|
||||
if (uniLen+3 >= bufSize) {
|
||||
doOutput = false;
|
||||
}
|
||||
if (doOutput) {
|
||||
bufUNI[uniLen] = (us >> 12) | 0xe0;
|
||||
bufUNI[uniLen+1] = ((us >> 6) & 0x3f) | 0x80;
|
||||
bufUNI[uniLen+2] = (us & 0x3f) | 0x80;
|
||||
}
|
||||
uniLen += 3;
|
||||
}
|
||||
|
||||
stringMOR++;
|
||||
}
|
||||
|
||||
// null-terminate
|
||||
if (doOutput && uniLen < bufSize) {
|
||||
bufUNI[uniLen] = '\0';
|
||||
}
|
||||
uniLen++;
|
||||
|
||||
return uniLen;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a single Unicode code point from a UTF-8 string. This will
|
||||
* consume 1 to 4 bytes. If an error is detected, only one byte is
|
||||
* consumed, and the code point value will be 0xDCnn (invalid).
|
||||
*
|
||||
* cf. http://en.wikipedia.org/wiki/UTF-8#Sample_code
|
||||
*/
|
||||
static uint32_t Nu_DecodeUTF8(const char** pStr)
|
||||
{
|
||||
const uint8_t* str = (const uint8_t*) *pStr;
|
||||
uint32_t codePoint;
|
||||
uint32_t uc1, uc2, uc3, uc4;
|
||||
uc1 = *str++;
|
||||
|
||||
if (uc1 < 0x80) {
|
||||
// single byte
|
||||
codePoint = uc1;
|
||||
} else if (uc1 < 0xc2) {
|
||||
// illegal: continuation or overlong 2-byte sequence
|
||||
goto fail;
|
||||
} else if (uc1 < 0xe0) {
|
||||
// 2-byte sequence
|
||||
uc2 = *str++;
|
||||
if ((uc2 & 0xc0) != 0x80) {
|
||||
goto fail; // not a continuation
|
||||
}
|
||||
codePoint = (uc1 << 6) + uc2 - 0x3080;
|
||||
} else if (uc1 < 0xf0) {
|
||||
// 3-byte sequence */
|
||||
uc2 = *str++;
|
||||
if ((uc2 & 0xc0) != 0x80) {
|
||||
goto fail; // not a continuation
|
||||
}
|
||||
if (uc1 == 0xe0 && uc2 < 0xa0) {
|
||||
goto fail; // overlong
|
||||
}
|
||||
uc3 = *str++;
|
||||
if ((uc3 & 0xc0) != 0x80) {
|
||||
goto fail; // not a continuation
|
||||
}
|
||||
codePoint = (uc1 << 12) + (uc2 << 6) + uc3 - 0xE2080;
|
||||
} else if (uc1 < 0xf5) {
|
||||
uc2 = *str++;
|
||||
if ((uc2 & 0xc0) != 0x80) {
|
||||
goto fail; // not a continuation
|
||||
}
|
||||
if (uc1 == 0xf0 && uc2 < 0x90) {
|
||||
goto fail; // overlong
|
||||
}
|
||||
if (uc1 == 0xf4 && uc2 >= 0x90) {
|
||||
goto fail; // U+10FFFF
|
||||
}
|
||||
uc3 = *str++;
|
||||
if ((uc3 & 0xc0) != 0x80) {
|
||||
goto fail; // not a continuation
|
||||
}
|
||||
uc4 = *str++;
|
||||
if ((uc4 & 0xc0) != 0x80) {
|
||||
goto fail; // not a continuation
|
||||
}
|
||||
codePoint = (uc1 << 18) + (uc2 << 12) + (uc3 << 6) + uc4 - 0x3C82080;
|
||||
} else {
|
||||
// illegal: > U+10FFFF
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*pStr = (const UNICHAR*) str;
|
||||
return codePoint;
|
||||
|
||||
fail:
|
||||
(*pStr)++; // advance one char only
|
||||
return 0xdc00 | uc1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts stringUNI to Mac OS Roman, storing the output in bufMOR
|
||||
* until it's full. Null termination is guaranteed. If the buffer
|
||||
* size is zero or bufMOR is NULL, no string data is returned.
|
||||
*
|
||||
* Returns the number of bytes required to represent stringUNI in MOR.
|
||||
*/
|
||||
size_t Nu_ConvertUNIToMOR(const UNICHAR* stringUNI, char* bufMOR,
|
||||
size_t bufSize)
|
||||
{
|
||||
Assert(stringUNI != 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Place-holder if we're not using UTF-16 yet. This doesn't pass
|
||||
* tests that check for behavior with non-MOR Unicode values.
|
||||
*/
|
||||
Assert(sizeof(UNICHAR) == 1);
|
||||
size_t uniLen = strlen(stringUNI) + 1;
|
||||
if (bufMOR != NULL && bufSize != 0) {
|
||||
size_t copyLen = uniLen < bufSize ? uniLen : bufSize;
|
||||
memcpy(bufMOR, stringUNI, copyLen);
|
||||
bufMOR[bufSize-1] = '\0';
|
||||
}
|
||||
return uniLen;
|
||||
#else
|
||||
/*
|
||||
* Convert UTF-8 to Mac OS Roman. If the code point doesn't have
|
||||
* a valid conversion (either because it's not in the table, or the
|
||||
* UTF-8 code is damaged) we just insert an ASCII '?'.
|
||||
*/
|
||||
if (gUnicodeToMOR[0] == 0xff) {
|
||||
Nu_GenerateUnicodeToMOR();
|
||||
Assert(gUnicodeToMOR[0] != 0xff);
|
||||
}
|
||||
|
||||
uint32_t codePoint;
|
||||
size_t morLen = 0;
|
||||
Boolean doOutput = (bufMOR != NULL);
|
||||
|
||||
while (*stringUNI != '\0') {
|
||||
codePoint = Nu_DecodeUTF8(&stringUNI);
|
||||
char mc;
|
||||
|
||||
if (codePoint < 0x80) {
|
||||
mc = (char) codePoint;
|
||||
} else if (codePoint < 0xffff) {
|
||||
// UTF-8 errors come back as 0xDCnn, which has no mapping in table
|
||||
mc = gUnicodeToMOR[codePoint];
|
||||
if (mc == 0x00) {
|
||||
mc = '?';
|
||||
}
|
||||
} else {
|
||||
// non-BMP code point
|
||||
mc = '?';
|
||||
}
|
||||
if (morLen+1 >= bufSize) {
|
||||
doOutput = false;
|
||||
}
|
||||
if (doOutput) {
|
||||
bufMOR[morLen] = mc;
|
||||
}
|
||||
morLen++;
|
||||
}
|
||||
|
||||
// null-terminate
|
||||
if (doOutput && morLen < bufSize) {
|
||||
bufMOR[morLen] = '\0';
|
||||
}
|
||||
morLen++;
|
||||
|
||||
return morLen;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function that wraps NuConvertMORToUTF8, allocating a new
|
||||
* buffer to hold the converted string. The caller must free the result.
|
||||
*
|
||||
* Returns NULL if stringMOR is NULL or the conversion fails.
|
||||
*/
|
||||
UNICHAR* Nu_CopyMORToUNI(const char* stringMOR)
|
||||
{
|
||||
size_t uniLen;
|
||||
UNICHAR* uniBuf;
|
||||
|
||||
if (stringMOR == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uniLen = Nu_ConvertMORToUNI(stringMOR, NULL, 0);
|
||||
if (uniLen == (size_t) -1) {
|
||||
return NULL;
|
||||
}
|
||||
uniBuf = (UNICHAR*) Nu_Malloc(NULL, uniLen);
|
||||
Nu_ConvertMORToUNI(stringMOR, uniBuf, uniLen);
|
||||
return uniBuf;
|
||||
}
|
|
@ -15,17 +15,16 @@
|
|||
/*
|
||||
* "Compress" an uncompressed thread.
|
||||
*/
|
||||
static NuError
|
||||
Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
|
||||
FILE* fp, ulong srcLen, ulong* pDstLen, ushort *pCrc)
|
||||
static NuError Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
|
||||
FILE* fp, uint32_t srcLen, uint32_t* pDstLen, uint16_t *pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
/*uchar* buffer = nil;*/
|
||||
ulong count, getsize;
|
||||
/*uint8_t* buffer = NULL;*/
|
||||
uint32_t count, getsize;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pStraw != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(srcLen > 0);
|
||||
|
||||
*pDstLen = srcLen; /* get this over with */
|
||||
|
@ -33,7 +32,7 @@ Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
|
|||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
BailError(err);
|
||||
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = kNuInitialThreadCRC;
|
||||
count = srcLen;
|
||||
|
||||
|
@ -42,7 +41,7 @@ Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
|
|||
|
||||
err = Nu_StrawRead(pArchive, pStraw, pArchive->compBuf, getsize);
|
||||
BailError(err);
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, pArchive->compBuf, getsize);
|
||||
err = Nu_FWrite(fp, pArchive->compBuf, getsize);
|
||||
BailError(err);
|
||||
|
@ -87,24 +86,23 @@ bail:
|
|||
* On exit, the output file will be positioned after the last byte of the
|
||||
* output. (For a pre-sized buffer, this may not be the desired result.)
|
||||
*/
|
||||
NuError
|
||||
Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||
NuError Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||
NuThreadID threadID, NuThreadFormat sourceFormat,
|
||||
NuThreadFormat targetFormat, NuProgressData* pProgressData, FILE* dstFp,
|
||||
NuThread* pThread)
|
||||
{
|
||||
NuError err;
|
||||
long origOffset;
|
||||
NuStraw* pStraw = nil;
|
||||
NuDataSink* pDataSink = nil;
|
||||
ulong srcLen = 0, dstLen = 0;
|
||||
ushort threadCrc;
|
||||
NuStraw* pStraw = NULL;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
uint32_t srcLen = 0, dstLen = 0;
|
||||
uint16_t threadCrc;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pDataSource != nil);
|
||||
/* okay if pProgressData is nil */
|
||||
Assert(dstFp != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pDataSource != NULL);
|
||||
/* okay if pProgressData is NULL */
|
||||
Assert(dstFp != NULL);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
/* remember file offset, so we can back up if compression fails */
|
||||
err = Nu_FTell(dstFp, &origOffset);
|
||||
|
@ -116,7 +114,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
|
||||
pThread->thThreadClass = NuThreadIDGetClass(threadID);
|
||||
pThread->thThreadKind = NuThreadIDGetKind(threadID);
|
||||
pThread->actualThreadEOF = (ulong)-1;
|
||||
pThread->actualThreadEOF = (uint32_t)-1;
|
||||
/* nuThreadIdx and fileOffset should already be set */
|
||||
|
||||
/*
|
||||
|
@ -168,7 +166,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
if (pArchive->valMimicSHK && srcLen < kNuSHKLZWThreshold)
|
||||
targetFormat = kNuThreadFormatUncompressed;
|
||||
|
||||
if (pProgressData != nil) {
|
||||
if (pProgressData != NULL) {
|
||||
if (targetFormat != kNuThreadFormatUncompressed)
|
||||
Nu_StrawSetProgressState(pStraw, kNuProgressCompressing);
|
||||
else
|
||||
|
@ -245,7 +243,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
BailError(err);
|
||||
err = Nu_StrawRewind(pArchive, pStraw);
|
||||
BailError(err);
|
||||
if (pProgressData != nil)
|
||||
if (pProgressData != NULL)
|
||||
Nu_StrawSetProgressState(pStraw, kNuProgressStoring);
|
||||
err = Nu_ProgressDataCompressPrep(pArchive, pStraw,
|
||||
kNuThreadFormatUncompressed, srcLen);
|
||||
|
@ -262,7 +260,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
* computed a CRC on the entire file (i.e. didn't stop early
|
||||
* when it noticed the output was larger than the input). If
|
||||
* this is always the case, then we can change "&threadCrc"
|
||||
* a few lines back to "nil" and avoid re-computing the CRC.
|
||||
* a few lines back to "NULL" and avoid re-computing the CRC.
|
||||
* If this is not always the case, remove this assert.
|
||||
*/
|
||||
Assert(threadCrc == pThread->thThreadCRC);
|
||||
|
@ -276,14 +274,14 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
/*
|
||||
* Copy the already-compressed input.
|
||||
*/
|
||||
if (pProgressData != nil)
|
||||
if (pProgressData != NULL)
|
||||
Nu_StrawSetProgressState(pStraw, kNuProgressCopying);
|
||||
err = Nu_ProgressDataCompressPrep(pArchive, pStraw,
|
||||
kNuThreadFormatUncompressed, srcLen);
|
||||
BailError(err);
|
||||
|
||||
err = Nu_CompressUncompressed(pArchive, pStraw, dstFp, srcLen,
|
||||
&dstLen, nil);
|
||||
&dstLen, NULL);
|
||||
BailError(err);
|
||||
|
||||
pThread->thThreadEOF = Nu_DataSourceGetOtherLen(pDataSource);
|
||||
|
@ -298,7 +296,7 @@ done:
|
|||
srcLen, dstLen, pThread->actualThreadEOF));
|
||||
|
||||
/* make sure we send a final "success" progress message at 100% */
|
||||
if (pProgressData != nil) {
|
||||
if (pProgressData != NULL) {
|
||||
(void) Nu_StrawSetProgressState(pStraw, kNuProgressDone);
|
||||
err = Nu_StrawSendProgressUpdate(pArchive, pStraw);
|
||||
BailError(err);
|
||||
|
@ -322,14 +320,13 @@ bail:
|
|||
* will copy the data, and then continue writing zeros to fill out the rest
|
||||
* of the pre-sized buffer.
|
||||
*/
|
||||
NuError
|
||||
Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||
NuError Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||
NuThreadID threadID, FILE* dstFp, NuThread* pThread, char** ppSavedCopy)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuStraw* pStraw = nil;
|
||||
ulong srcLen, bufferLen;
|
||||
ulong count, getsize;
|
||||
NuStraw* pStraw = NULL;
|
||||
uint32_t srcLen, bufferLen;
|
||||
uint32_t count, getsize;
|
||||
|
||||
srcLen = Nu_DataSourceGetDataLen(pDataSource);
|
||||
bufferLen = Nu_DataSourceGetOtherLen(pDataSource);
|
||||
|
@ -355,7 +352,7 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
* is a convenient way to deal with the dataSource, even though we
|
||||
* don't have a progress updater.
|
||||
*/
|
||||
err = Nu_StrawNew(pArchive, pDataSource, nil, &pStraw);
|
||||
err = Nu_StrawNew(pArchive, pDataSource, NULL, &pStraw);
|
||||
BailError(err);
|
||||
|
||||
count = srcLen;
|
||||
|
@ -370,7 +367,7 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
err = Nu_FWrite(dstFp, pArchive->compBuf, getsize);
|
||||
BailError(err);
|
||||
|
||||
if (ppSavedCopy != nil && *ppSavedCopy == nil) {
|
||||
if (ppSavedCopy != NULL && *ppSavedCopy == NULL) {
|
||||
/*
|
||||
* Grab a copy of the filename for our own use. This assumes
|
||||
* that the filename fits in kNuGenCompBufSize, which is a
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
* Compute 16-bit CRCs. Depending on the hardware, the table version
|
||||
* might be slower than the loop computation.
|
||||
*/
|
||||
#define __Crc16_c__ 1
|
||||
#include "NufxLibPriv.h"
|
||||
|
||||
#define CRC_TAB
|
||||
|
@ -30,7 +29,7 @@
|
|||
|
||||
|
||||
/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
|
||||
const ushort gNuCrc16Table[256] = {
|
||||
const uint16_t gNuCrc16Table[256] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
|
@ -83,13 +82,11 @@ const ushort gNuCrc16Table[256] = {
|
|||
* Depending on CPU architecture, one may be dramatically faster than
|
||||
* the other.
|
||||
*/
|
||||
ushort
|
||||
Nu_CalcCRC16(ushort seed, const uchar* ptr, int count)
|
||||
uint16_t Nu_CalcCRC16(uint16_t seed, const uint8_t* ptr, int count)
|
||||
{
|
||||
ushort CRC = seed;
|
||||
uint16_t CRC = seed;
|
||||
#ifndef CRC_TAB
|
||||
int x;
|
||||
Assert(sizeof(ushort) == 2); /* I think this is assumed */
|
||||
#endif
|
||||
|
||||
do {
|
||||
|
|
|
@ -65,8 +65,7 @@ static const char* gFileSysIDs[] = {
|
|||
*
|
||||
* Returns "buffer" for the benefit of printf() calls.
|
||||
*/
|
||||
static char*
|
||||
Nu_DebugDumpDate(const NuDateTime* pDateTime, char* buffer)
|
||||
static char* Nu_DebugDumpDate(const NuDateTime* pDateTime, char* buffer)
|
||||
{
|
||||
char* cp;
|
||||
|
||||
|
@ -118,8 +117,7 @@ bail:
|
|||
*
|
||||
* The result will be 2x the size of the original, +1 for a null byte.
|
||||
*/
|
||||
static void
|
||||
ConvertToHexStr(const uchar* inBuf, int inLen, char* outBuf)
|
||||
static void ConvertToHexStr(const uint8_t* inBuf, int inLen, char* outBuf)
|
||||
{
|
||||
while (inLen--) {
|
||||
*outBuf++ = HexConv((*inBuf >> 4) & 0x0f);
|
||||
|
@ -133,14 +131,13 @@ ConvertToHexStr(const uchar* inBuf, int inLen, char* outBuf)
|
|||
/*
|
||||
* Dump everything we know about pThread.
|
||||
*/
|
||||
void
|
||||
Nu_DebugDumpThread(const NuThread* pThread)
|
||||
void Nu_DebugDumpThread(const NuThread* pThread)
|
||||
{
|
||||
static const char* kInd = " ";
|
||||
NuThreadID threadID;
|
||||
const char* descr;
|
||||
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
printf("%sThreadClass: 0x%04x (%s)\n", kInd,
|
||||
pThread->thThreadClass,
|
||||
|
@ -164,9 +161,9 @@ Nu_DebugDumpThread(const NuThread* pThread)
|
|||
printf("%sThreadKind: 0x%04x (%s)\n", kInd,
|
||||
pThread->thThreadKind, descr);
|
||||
|
||||
printf("%sThreadCRC: 0x%04x ThreadEOF: %lu CompThreadEOF: %lu\n", kInd,
|
||||
printf("%sThreadCRC: 0x%04x ThreadEOF: %u CompThreadEOF: %u\n", kInd,
|
||||
pThread->thThreadCRC, pThread->thThreadEOF, pThread->thCompThreadEOF);
|
||||
printf("%s*File data offset: %ld actualThreadEOF: %ld\n", kInd,
|
||||
printf("%s*File data offset: %ld actualThreadEOF: %d\n", kInd,
|
||||
pThread->fileOffset, pThread->actualThreadEOF);
|
||||
}
|
||||
|
||||
|
@ -177,8 +174,7 @@ Nu_DebugDumpThread(const NuThread* pThread)
|
|||
* set. Pass in the "orig" copy in "pRecord", and optionally pass in the
|
||||
* "copy" set in "pXrefRecord" to glean data from both.
|
||||
*/
|
||||
static void
|
||||
Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
static void Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuRecord* pXrefRecord, Boolean isDeleted)
|
||||
{
|
||||
NuError err; /* dummy */
|
||||
|
@ -186,22 +182,24 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
char dateBuf[kNuDateOutputLen];
|
||||
const NuThreadMod* pThreadMod;
|
||||
const NuThread* pThread;
|
||||
ulong idx;
|
||||
uint32_t idx;
|
||||
|
||||
Assert(pRecord != nil);
|
||||
Assert(pRecord != NULL);
|
||||
|
||||
/*printf("PTR: pRecord=0x%08lx pXrefRecord=0x%08lx\n", (long) pRecord,
|
||||
(long) pXrefRecord);*/
|
||||
|
||||
printf("%s%s%sFilename: '%s' (idx=%lu)\n", kInd,
|
||||
UNICHAR* filenameUNI = Nu_CopyMORToUNI(pRecord->filenameMOR);
|
||||
printf("%s%s%sFilename: '%s' (idx=%u)\n", kInd,
|
||||
isDeleted ? "[DEL] " : "",
|
||||
pXrefRecord != nil && pXrefRecord->pThreadMods != nil ? "[MOD] " : "",
|
||||
pRecord->filename == nil ? "<not specified>" : pRecord->filename,
|
||||
pXrefRecord != NULL && pXrefRecord->pThreadMods != NULL ? "[MOD] " : "",
|
||||
filenameUNI == NULL ? "<not specified>" : filenameUNI,
|
||||
pRecord->recordIdx);
|
||||
free(filenameUNI);
|
||||
printf("%sHeaderID: '%.4s' VersionNumber: 0x%04x HeaderCRC: 0x%04x\n",
|
||||
kInd,
|
||||
pRecord->recNufxID, pRecord->recVersionNumber, pRecord->recHeaderCRC);
|
||||
printf("%sAttribCount: %u TotalThreads: %lu\n", kInd,
|
||||
printf("%sAttribCount: %u TotalThreads: %u\n", kInd,
|
||||
pRecord->recAttribCount, pRecord->recTotalThreads);
|
||||
printf("%sFileSysID: %u (%s) FileSysInfo: 0x%04x ('%c')\n", kInd,
|
||||
pRecord->recFileSysID,
|
||||
|
@ -209,7 +207,7 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
pRecord->recFileSysInfo,
|
||||
NuGetSepFromSysInfo(pRecord->recFileSysInfo));
|
||||
/* do something fancy for ProDOS? */
|
||||
printf("%sFileType: 0x%08lx ExtraType: 0x%08lx Access: 0x%08lx\n", kInd,
|
||||
printf("%sFileType: 0x%08x ExtraType: 0x%08x Access: 0x%08x\n", kInd,
|
||||
pRecord->recFileType, pRecord->recExtraType, pRecord->recAccess);
|
||||
printf("%sCreateWhen: %s\n", kInd,
|
||||
Nu_DebugDumpDate(&pRecord->recCreateWhen, dateBuf));
|
||||
|
@ -223,13 +221,13 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
if (pRecord->recOptionSize) {
|
||||
char* outBuf = Nu_Malloc(pArchive, pRecord->recOptionSize * 2 +1);
|
||||
BailAlloc(outBuf);
|
||||
Assert(pRecord->recOptionList != nil);
|
||||
Assert(pRecord->recOptionList != NULL);
|
||||
ConvertToHexStr(pRecord->recOptionList, pRecord->recOptionSize, outBuf);
|
||||
printf("%sOptionList: [%s]\n", kInd, outBuf);
|
||||
Nu_Free(pArchive, outBuf);
|
||||
}
|
||||
|
||||
printf("%s*ExtraCount: %ld RecFileOffset: %ld RecHeaderLength: %ld\n",
|
||||
printf("%s*ExtraCount: %d RecFileOffset: %ld RecHeaderLength: %d\n",
|
||||
kInd,
|
||||
pRecord->extraCount, pRecord->fileOffset, pRecord->recHeaderLength);
|
||||
|
||||
|
@ -238,34 +236,34 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
|
||||
isFake = (idx >= pRecord->recTotalThreads - pRecord->fakeThreads);
|
||||
pThread = Nu_GetThread(pRecord, idx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
printf("%s--Thread #%lu (idx=%lu)%s\n", kInd, idx, pThread->threadIdx,
|
||||
printf("%s--Thread #%u (idx=%u)%s\n", kInd, idx, pThread->threadIdx,
|
||||
isFake ? " [FAKE]" : "");
|
||||
Nu_DebugDumpThread(pThread);
|
||||
}
|
||||
|
||||
if (pXrefRecord != nil)
|
||||
if (pXrefRecord != NULL)
|
||||
pThreadMod = pXrefRecord->pThreadMods;
|
||||
else
|
||||
pThreadMod = pRecord->pThreadMods; /* probably empty */
|
||||
|
||||
if (pThreadMod != nil)
|
||||
if (pThreadMod != NULL)
|
||||
printf("%s*ThreadMods -----\n", kInd);
|
||||
while (pThreadMod != nil) {
|
||||
while (pThreadMod != NULL) {
|
||||
switch (pThreadMod->entry.kind) {
|
||||
case kNuThreadModAdd:
|
||||
printf("%s *-ThreadMod ADD 0x%08lx 0x%04x (sourceType=%d)\n", kInd,
|
||||
printf("%s *-ThreadMod ADD 0x%08x 0x%04x (sourceType=%d)\n", kInd,
|
||||
pThreadMod->entry.add.threadID,
|
||||
pThreadMod->entry.add.threadFormat,
|
||||
Nu_DataSourceGetType(pThreadMod->entry.add.pDataSource));
|
||||
break;
|
||||
case kNuThreadModUpdate:
|
||||
printf("%s *-ThreadMod UPDATE %6ld\n", kInd,
|
||||
printf("%s *-ThreadMod UPDATE %6d\n", kInd,
|
||||
pThreadMod->entry.update.threadIdx);
|
||||
break;
|
||||
case kNuThreadModDelete:
|
||||
printf("%s *-ThreadMod DELETE %6ld\n", kInd,
|
||||
printf("%s *-ThreadMod DELETE %6d\n", kInd,
|
||||
pThreadMod->entry.delete.threadIdx);
|
||||
break;
|
||||
case kNuThreadModUnknown:
|
||||
|
@ -280,7 +278,7 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
|
||||
/*printf("%s*TotalLength: %ld TotalCompLength: %ld\n",
|
||||
kInd, pRecord->totalLength, pRecord->totalCompLength);*/
|
||||
printf("%s*TotalCompLength: %ld\n", kInd, pRecord->totalCompLength);
|
||||
printf("%s*TotalCompLength: %u\n", kInd, pRecord->totalCompLength);
|
||||
printf("\n");
|
||||
|
||||
bail:
|
||||
|
@ -290,9 +288,8 @@ bail:
|
|||
/*
|
||||
* Dump the records in a RecordSet.
|
||||
*/
|
||||
static void
|
||||
Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
|
||||
const NuRecordSet* pXrefSet)
|
||||
static void Nu_DebugDumpRecordSet(NuArchive* pArchive,
|
||||
const NuRecordSet* pRecordSet, const NuRecordSet* pXrefSet)
|
||||
{
|
||||
const NuRecord* pRecord;
|
||||
const NuRecord* pXrefRecord;
|
||||
|
@ -300,8 +297,8 @@ Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
|
|||
long count;
|
||||
|
||||
doXref = false;
|
||||
pXrefRecord = nil;
|
||||
if (pXrefSet != nil && Nu_RecordSet_GetLoaded(pXrefSet)) {
|
||||
pXrefRecord = NULL;
|
||||
if (pXrefSet != NULL && Nu_RecordSet_GetLoaded(pXrefSet)) {
|
||||
pXrefRecord = Nu_RecordSet_GetListHead(pXrefSet);
|
||||
doXref = true;
|
||||
}
|
||||
|
@ -309,18 +306,18 @@ Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
|
|||
/* dump every record, if we've loaded them */
|
||||
count = Nu_RecordSet_GetNumRecords(pRecordSet);
|
||||
pRecord = Nu_RecordSet_GetListHead(pRecordSet);
|
||||
if (pRecord != nil) {
|
||||
if (pRecord != NULL) {
|
||||
Assert(count != 0);
|
||||
while (count--) {
|
||||
Assert(pRecord != nil);
|
||||
Assert(pRecord != NULL);
|
||||
|
||||
if (pXrefRecord != nil &&
|
||||
if (pXrefRecord != NULL &&
|
||||
pRecord->recordIdx == pXrefRecord->recordIdx)
|
||||
{
|
||||
Nu_DebugDumpRecord(pArchive, pRecord, pXrefRecord, false);
|
||||
pXrefRecord = pXrefRecord->pNext;
|
||||
} else {
|
||||
Nu_DebugDumpRecord(pArchive, pRecord, nil, doXref);
|
||||
Nu_DebugDumpRecord(pArchive, pRecord, NULL, doXref);
|
||||
}
|
||||
pRecord = pRecord->pNext;
|
||||
}
|
||||
|
@ -332,22 +329,21 @@ Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
|
|||
/*
|
||||
* Dump the master header block.
|
||||
*/
|
||||
static void
|
||||
Nu_DebugDumpMH(const NuMasterHeader* pMasterHeader)
|
||||
static void Nu_DebugDumpMH(const NuMasterHeader* pMasterHeader)
|
||||
{
|
||||
static const char* kInd = " ";
|
||||
char dateBuf1[kNuDateOutputLen];
|
||||
|
||||
Assert(pMasterHeader != nil);
|
||||
Assert(pMasterHeader != NULL);
|
||||
|
||||
printf("%sNufileID: '%.6s' MasterCRC: 0x%04x TotalRecords: %lu\n", kInd,
|
||||
printf("%sNufileID: '%.6s' MasterCRC: 0x%04x TotalRecords: %u\n", kInd,
|
||||
pMasterHeader->mhNufileID, pMasterHeader->mhMasterCRC,
|
||||
pMasterHeader->mhTotalRecords);
|
||||
printf("%sArchiveCreateWhen: %s\n", kInd,
|
||||
Nu_DebugDumpDate(&pMasterHeader->mhArchiveCreateWhen, dateBuf1));
|
||||
printf("%sArchiveModWhen: %s\n", kInd,
|
||||
Nu_DebugDumpDate(&pMasterHeader->mhArchiveModWhen, dateBuf1));
|
||||
printf("%sMasterVersion: %u MasterEOF: %lu\n", kInd,
|
||||
printf("%sMasterVersion: %u MasterEOF: %u\n", kInd,
|
||||
pMasterHeader->mhMasterVersion, pMasterHeader->mhMasterEOF);
|
||||
}
|
||||
|
||||
|
@ -359,20 +355,19 @@ Nu_DebugDumpMH(const NuMasterHeader* pMasterHeader)
|
|||
* the archive, then this won't be very interesting. This will never
|
||||
* show any records for streaming-mode archives.
|
||||
*/
|
||||
void
|
||||
Nu_DebugDumpAll(NuArchive* pArchive)
|
||||
void Nu_DebugDumpAll(NuArchive* pArchive)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
printf("*Archive pathname: '%s'\n", pArchive->archivePathname);
|
||||
printf("*Archive pathname: '%s'\n", pArchive->archivePathnameUNI);
|
||||
printf("*Archive type: %d\n", pArchive->archiveType);
|
||||
printf("*Header offset: %ld (junk offset=%ld)\n",
|
||||
pArchive->headerOffset, pArchive->junkOffset);
|
||||
printf("*Num records: %ld orig, %ld copy, %ld new\n",
|
||||
printf("*Num records: %u orig, %u copy, %u new\n",
|
||||
Nu_RecordSet_GetNumRecords(&pArchive->origRecordSet),
|
||||
Nu_RecordSet_GetNumRecords(&pArchive->copyRecordSet),
|
||||
Nu_RecordSet_GetNumRecords(&pArchive->newRecordSet));
|
||||
printf("*NuRecordIdx seed: %lu NuRecordIdx next: %lu\n",
|
||||
printf("*NuRecordIdx seed: %u NuRecordIdx next: %u\n",
|
||||
pArchive->recordIdxSeed, pArchive->nextRecordIdx);
|
||||
|
||||
/* master header */
|
||||
|
@ -382,7 +377,7 @@ Nu_DebugDumpAll(NuArchive* pArchive)
|
|||
Nu_DebugDumpRecordSet(pArchive, &pArchive->origRecordSet,
|
||||
&pArchive->copyRecordSet);
|
||||
printf(" *NEW record set:\n");
|
||||
Nu_DebugDumpRecordSet(pArchive, &pArchive->newRecordSet, nil);
|
||||
Nu_DebugDumpRecordSet(pArchive, &pArchive->newRecordSet, NULL);
|
||||
|
||||
if (!Nu_RecordSet_GetLoaded(&pArchive->origRecordSet) &&
|
||||
!Nu_RecordSet_GetLoaded(&pArchive->newRecordSet))
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,13 +25,11 @@
|
|||
/*
|
||||
* Alloc and free functions provided to zlib.
|
||||
*/
|
||||
static voidpf
|
||||
Nu_zalloc(voidpf opaque, uInt items, uInt size)
|
||||
static voidpf Nu_zalloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
return Nu_Malloc(opaque, items * size);
|
||||
}
|
||||
static void
|
||||
Nu_zfree(voidpf opaque, voidpf address)
|
||||
static void Nu_zfree(voidpf opaque, voidpf address)
|
||||
{
|
||||
Nu_Free(opaque, address);
|
||||
}
|
||||
|
@ -46,21 +44,20 @@ Nu_zfree(voidpf opaque, voidpf address)
|
|||
/*
|
||||
* Compress "srcLen" bytes from "pStraw" to "fp".
|
||||
*/
|
||||
NuError
|
||||
Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc)
|
||||
NuError Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
z_stream zstream;
|
||||
int zerr;
|
||||
Bytef* outbuf = nil;
|
||||
Bytef* outbuf = NULL;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pStraw != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(srcLen > 0);
|
||||
Assert(pDstLen != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pDstLen != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
if (err != kNuErrNone)
|
||||
|
@ -76,7 +73,7 @@ Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
zstream.zalloc = Nu_zalloc;
|
||||
zstream.zfree = Nu_zfree;
|
||||
zstream.opaque = pArchive;
|
||||
zstream.next_in = nil;
|
||||
zstream.next_in = NULL;
|
||||
zstream.avail_in = 0;
|
||||
zstream.next_out = outbuf;
|
||||
zstream.avail_out = kNuGenCompBufSize;
|
||||
|
@ -100,7 +97,7 @@ Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
* Loop while we have data.
|
||||
*/
|
||||
do {
|
||||
ulong getSize;
|
||||
uint32_t getSize;
|
||||
int flush;
|
||||
|
||||
/* should be able to read a full buffer every time */
|
||||
|
@ -159,7 +156,7 @@ z_bail:
|
|||
deflateEnd(&zstream); /* free up any allocated structures */
|
||||
|
||||
bail:
|
||||
if (outbuf != nil)
|
||||
if (outbuf != NULL)
|
||||
free(outbuf);
|
||||
return err;
|
||||
}
|
||||
|
@ -174,20 +171,19 @@ bail:
|
|||
/*
|
||||
* Expand from "infp" to "pFunnel".
|
||||
*/
|
||||
NuError
|
||||
Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
|
||||
NuError Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
z_stream zstream;
|
||||
int zerr;
|
||||
ulong compRemaining;
|
||||
uint32_t compRemaining;
|
||||
Bytef* outbuf;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(infp != nil);
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(infp != NULL);
|
||||
Assert(pFunnel != NULL);
|
||||
|
||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
if (err != kNuErrNone)
|
||||
|
@ -205,7 +201,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
zstream.zalloc = Nu_zalloc;
|
||||
zstream.zfree = Nu_zfree;
|
||||
zstream.opaque = pArchive;
|
||||
zstream.next_in = nil;
|
||||
zstream.next_in = NULL;
|
||||
zstream.avail_in = 0;
|
||||
zstream.next_out = outbuf;
|
||||
zstream.avail_out = kNuGenCompBufSize;
|
||||
|
@ -229,7 +225,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* Loop while we have data.
|
||||
*/
|
||||
do {
|
||||
ulong getSize;
|
||||
uint32_t getSize;
|
||||
|
||||
/* read as much as we can */
|
||||
if (zstream.avail_in == 0) {
|
||||
|
@ -269,7 +265,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
goto z_bail;
|
||||
}
|
||||
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, outbuf, zstream.next_out - outbuf);
|
||||
|
||||
zstream.next_out = outbuf;
|
||||
|
@ -282,7 +278,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
if (zstream.total_out != pThread->actualThreadEOF) {
|
||||
err = kNuErrBadData;
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"size mismatch on inflated file (%ld vs %ld)",
|
||||
"size mismatch on inflated file (%ld vs %u)",
|
||||
zstream.total_out, pThread->actualThreadEOF);
|
||||
goto z_bail;
|
||||
}
|
||||
|
@ -291,7 +287,7 @@ z_bail:
|
|||
inflateEnd(&zstream); /* free up any allocated structures */
|
||||
|
||||
bail:
|
||||
if (outbuf != nil)
|
||||
if (outbuf != NULL)
|
||||
free(outbuf);
|
||||
return err;
|
||||
}
|
||||
|
|
298
nufxlib/Entry.c
298
nufxlib/Entry.c
|
@ -24,8 +24,7 @@
|
|||
* it does not follow all sorts of crazy semaphore semantics. If you
|
||||
* have the need, go ahead and fix it.
|
||||
*/
|
||||
static inline void
|
||||
Nu_SetBusy(NuArchive* pArchive)
|
||||
static inline void Nu_SetBusy(NuArchive* pArchive)
|
||||
{
|
||||
pArchive->busy = true;
|
||||
}
|
||||
|
@ -33,8 +32,7 @@ Nu_SetBusy(NuArchive* pArchive)
|
|||
/*
|
||||
* Clear the busy flag.
|
||||
*/
|
||||
static inline void
|
||||
Nu_ClearBusy(NuArchive* pArchive)
|
||||
static inline void Nu_ClearBusy(NuArchive* pArchive)
|
||||
{
|
||||
pArchive->busy = false;
|
||||
}
|
||||
|
@ -45,13 +43,11 @@ Nu_ClearBusy(NuArchive* pArchive)
|
|||
* can be made during callback functions when the archive isn't fully
|
||||
* consistent.
|
||||
*/
|
||||
static NuError
|
||||
Nu_PartiallyValidateNuArchive(const NuArchive* pArchive)
|
||||
static NuError Nu_PartiallyValidateNuArchive(const NuArchive* pArchive)
|
||||
{
|
||||
if (pArchive == nil)
|
||||
if (pArchive == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
pArchive = pArchive;
|
||||
if (pArchive->structMagic != kNuArchiveStructMagic)
|
||||
return kNuErrBadStruct;
|
||||
|
||||
|
@ -61,8 +57,7 @@ Nu_PartiallyValidateNuArchive(const NuArchive* pArchive)
|
|||
/*
|
||||
* Validate the NuArchive* argument passed in to us.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ValidateNuArchive(const NuArchive* pArchive)
|
||||
static NuError Nu_ValidateNuArchive(const NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -77,19 +72,19 @@ Nu_ValidateNuArchive(const NuArchive* pArchive)
|
|||
/* make sure the TOC state is consistent */
|
||||
if (pArchive->haveToc) {
|
||||
if (pArchive->masterHeader.mhTotalRecords != 0)
|
||||
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) != nil);
|
||||
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) != NULL);
|
||||
Assert(Nu_RecordSet_GetNumRecords(&pArchive->origRecordSet) ==
|
||||
pArchive->masterHeader.mhTotalRecords);
|
||||
} else {
|
||||
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) == nil);
|
||||
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) == NULL);
|
||||
}
|
||||
|
||||
/* make sure we have open files to work with */
|
||||
Assert(pArchive->archivePathname == nil || pArchive->archiveFp != nil);
|
||||
if (pArchive->archivePathname != nil && pArchive->archiveFp == nil)
|
||||
Assert(pArchive->archivePathnameUNI == NULL || pArchive->archiveFp != NULL);
|
||||
if (pArchive->archivePathnameUNI != NULL && pArchive->archiveFp == NULL)
|
||||
return kNuErrInternal;
|
||||
Assert(pArchive->tmpPathname == nil || pArchive->tmpFp != nil);
|
||||
if (pArchive->tmpPathname != nil && pArchive->tmpFp == nil)
|
||||
Assert(pArchive->tmpPathnameUNI == NULL || pArchive->tmpFp != NULL);
|
||||
if (pArchive->tmpPathnameUNI != NULL && pArchive->tmpFp == NULL)
|
||||
return kNuErrInternal;
|
||||
|
||||
/* further validations */
|
||||
|
@ -104,12 +99,11 @@ Nu_ValidateNuArchive(const NuArchive* pArchive)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuStreamOpenRO(FILE* infp, NuArchive** ppArchive)
|
||||
NUFXLIB_API NuError NuStreamOpenRO(FILE* infp, NuArchive** ppArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if (infp == nil || ppArchive == nil)
|
||||
if (infp == NULL || ppArchive == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
err = Nu_StreamOpenRO(infp, (NuArchive**) ppArchive);
|
||||
|
@ -117,8 +111,7 @@ NuStreamOpenRO(FILE* infp, NuArchive** ppArchive)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuContents(NuArchive* pArchive, NuCallback contentFunc)
|
||||
NUFXLIB_API NuError NuContents(NuArchive* pArchive, NuCallback contentFunc)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -134,8 +127,7 @@ NuContents(NuArchive* pArchive, NuCallback contentFunc)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuExtract(NuArchive* pArchive)
|
||||
NUFXLIB_API NuError NuExtract(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -151,8 +143,7 @@ NuExtract(NuArchive* pArchive)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuTest(NuArchive* pArchive)
|
||||
NUFXLIB_API NuError NuTest(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -168,8 +159,7 @@ NuTest(NuArchive* pArchive)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
||||
NUFXLIB_API NuError NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -189,18 +179,17 @@ NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuOpenRO(const char* filename, NuArchive** ppArchive)
|
||||
NUFXLIB_API NuError NuOpenRO(const UNICHAR* archivePathnameUNI,
|
||||
NuArchive** ppArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
err = Nu_OpenRO(filename, (NuArchive**) ppArchive);
|
||||
err = Nu_OpenRO(archivePathnameUNI, (NuArchive**) ppArchive);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
||||
NUFXLIB_API NuError NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -213,8 +202,7 @@ NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NUFXLIB_API NuError NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuDataSink* pDataSink)
|
||||
{
|
||||
NuError err;
|
||||
|
@ -228,8 +216,7 @@ NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
NUFXLIB_API NuError NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const NuRecord** ppRecord)
|
||||
{
|
||||
NuError err;
|
||||
|
@ -243,23 +230,21 @@ NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetRecordIdxByName(NuArchive* pArchive, const char* name,
|
||||
NuRecordIdx* pRecordIdx)
|
||||
NUFXLIB_API NuError NuGetRecordIdxByName(NuArchive* pArchive,
|
||||
const char* nameMOR, NuRecordIdx* pRecordIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
Nu_SetBusy(pArchive);
|
||||
err = Nu_GetRecordIdxByName(pArchive, name, pRecordIdx);
|
||||
err = Nu_GetRecordIdxByName(pArchive, nameMOR, pRecordIdx);
|
||||
Nu_ClearBusy(pArchive);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetRecordIdxByPosition(NuArchive* pArchive, unsigned long position,
|
||||
NUFXLIB_API NuError NuGetRecordIdxByPosition(NuArchive* pArchive, uint32_t position,
|
||||
NuRecordIdx* pRecordIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
@ -280,20 +265,18 @@ NuGetRecordIdxByPosition(NuArchive* pArchive, unsigned long position,
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuOpenRW(const char* archivePathname, const char* tmpPathname,
|
||||
unsigned long flags, NuArchive** ppArchive)
|
||||
NUFXLIB_API NuError NuOpenRW(const UNICHAR* archivePathnameUNI,
|
||||
const UNICHAR* tmpPathnameUNI, uint32_t flags, NuArchive** ppArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
err = Nu_OpenRW(archivePathname, tmpPathname, flags,
|
||||
err = Nu_OpenRW(archivePathnameUNI, tmpPathnameUNI, flags,
|
||||
(NuArchive**) ppArchive);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuFlush(NuArchive* pArchive, long* pStatusFlags)
|
||||
NUFXLIB_API NuError NuFlush(NuArchive* pArchive, uint32_t* pStatusFlags)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -306,8 +289,7 @@ NuFlush(NuArchive* pArchive, long* pStatusFlags)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuAbort(NuArchive* pArchive)
|
||||
NUFXLIB_API NuError NuAbort(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -320,24 +302,22 @@ NuAbort(NuArchive* pArchive)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuAddRecord(NuArchive* pArchive, const NuFileDetails* pFileDetails,
|
||||
NuRecordIdx* pRecordIdx)
|
||||
NUFXLIB_API NuError NuAddRecord(NuArchive* pArchive,
|
||||
const NuFileDetails* pFileDetails, NuRecordIdx* pRecordIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
Nu_SetBusy(pArchive);
|
||||
err = Nu_AddRecord(pArchive, pFileDetails, pRecordIdx, nil);
|
||||
err = Nu_AddRecord(pArchive, pFileDetails, pRecordIdx, NULL);
|
||||
Nu_ClearBusy(pArchive);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx, NuThreadID threadID,
|
||||
NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
|
||||
NUFXLIB_API NuError NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
NuThreadID threadID, NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -351,8 +331,7 @@ NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx, NuThreadID threadID,
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuAddFile(NuArchive* pArchive, const char* pathname,
|
||||
NUFXLIB_API NuError NuAddFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
|
||||
const NuFileDetails* pFileDetails, short isFromRsrcFork,
|
||||
NuRecordIdx* pRecordIdx)
|
||||
{
|
||||
|
@ -360,7 +339,7 @@ NuAddFile(NuArchive* pArchive, const char* pathname,
|
|||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
Nu_SetBusy(pArchive);
|
||||
err = Nu_AddFile(pArchive, pathname, pFileDetails,
|
||||
err = Nu_AddFile(pArchive, pathnameUNI, pFileDetails,
|
||||
(Boolean)(isFromRsrcFork != 0), pRecordIdx);
|
||||
Nu_ClearBusy(pArchive);
|
||||
}
|
||||
|
@ -368,15 +347,14 @@ NuAddFile(NuArchive* pArchive, const char* pathname,
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuRename(NuArchive* pArchive, NuRecordIdx recordIdx, const char* pathname,
|
||||
char fssep)
|
||||
NUFXLIB_API NuError NuRename(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const char* pathnameMOR, char fssep)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
Nu_SetBusy(pArchive);
|
||||
err = Nu_Rename(pArchive, recordIdx, pathname, fssep);
|
||||
err = Nu_Rename(pArchive, recordIdx, pathnameMOR, fssep);
|
||||
Nu_ClearBusy(pArchive);
|
||||
}
|
||||
|
||||
|
@ -384,8 +362,7 @@ NuRename(NuArchive* pArchive, NuRecordIdx recordIdx, const char* pathname,
|
|||
}
|
||||
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
NUFXLIB_API NuError NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const NuRecordAttr* pRecordAttr)
|
||||
{
|
||||
NuError err;
|
||||
|
@ -399,9 +376,8 @@ NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuUpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuDataSource* pDataSource, long* pMaxLen)
|
||||
NUFXLIB_API NuError NuUpdatePresizedThread(NuArchive* pArchive,
|
||||
NuThreadIdx threadIdx, NuDataSource* pDataSource, int32_t* pMaxLen)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -415,8 +391,7 @@ NuUpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuDelete(NuArchive* pArchive)
|
||||
NUFXLIB_API NuError NuDelete(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -429,8 +404,7 @@ NuDelete(NuArchive* pArchive)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
||||
NUFXLIB_API NuError NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -443,8 +417,7 @@ NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
|
||||
NUFXLIB_API NuError NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -464,8 +437,7 @@ NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuClose(NuArchive* pArchive)
|
||||
NUFXLIB_API NuError NuClose(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -480,8 +452,8 @@ NuClose(NuArchive* pArchive)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
|
||||
NUFXLIB_API NuError NuGetMasterHeader(NuArchive* pArchive,
|
||||
const NuMasterHeader** ppMasterHeader)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -491,12 +463,11 @@ NuGetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetExtraData(NuArchive* pArchive, void** ppData)
|
||||
NUFXLIB_API NuError NuGetExtraData(NuArchive* pArchive, void** ppData)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if (ppData == nil)
|
||||
if (ppData == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
if ((err = Nu_PartiallyValidateNuArchive(pArchive)) == kNuErrNone)
|
||||
*ppData = pArchive->extraData;
|
||||
|
@ -504,8 +475,7 @@ NuGetExtraData(NuArchive* pArchive, void** ppData)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuSetExtraData(NuArchive* pArchive, void* pData)
|
||||
NUFXLIB_API NuError NuSetExtraData(NuArchive* pArchive, void* pData)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -515,8 +485,8 @@ NuSetExtraData(NuArchive* pArchive, void* pData)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
|
||||
NUFXLIB_API NuError NuGetValue(NuArchive* pArchive, NuValueID ident,
|
||||
NuValue* pValue)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -526,8 +496,8 @@ NuGetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuSetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
||||
NUFXLIB_API NuError NuSetValue(NuArchive* pArchive, NuValueID ident,
|
||||
NuValue value)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -537,8 +507,8 @@ NuSetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
|
||||
NUFXLIB_API NuError NuGetAttr(NuArchive* pArchive, NuAttrID ident,
|
||||
NuAttr* pAttr)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -548,8 +518,7 @@ NuGetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuDebugDumpArchive(NuArchive* pArchive)
|
||||
NUFXLIB_API NuError NuDebugDumpArchive(NuArchive* pArchive)
|
||||
{
|
||||
#if defined(DEBUG_MSGS)
|
||||
/* skip validation checks for this one */
|
||||
|
@ -568,82 +537,75 @@ NuDebugDumpArchive(NuArchive* pArchive)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuCreateDataSourceForFile(NuThreadFormat threadFormat,
|
||||
unsigned long otherLen, const char* pathname, short isFromRsrcFork,
|
||||
NUFXLIB_API NuError NuCreateDataSourceForFile(NuThreadFormat threadFormat,
|
||||
uint32_t otherLen, const UNICHAR* pathnameUNI, short isFromRsrcFork,
|
||||
NuDataSource** ppDataSource)
|
||||
{
|
||||
return Nu_DataSourceFile_New(threadFormat, otherLen,
|
||||
pathname, (Boolean)(isFromRsrcFork != 0), ppDataSource);
|
||||
pathnameUNI, (Boolean)(isFromRsrcFork != 0), ppDataSource);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuCreateDataSourceForFP(NuThreadFormat threadFormat,
|
||||
unsigned long otherLen, FILE* fp, long offset, long length,
|
||||
NUFXLIB_API NuError NuCreateDataSourceForFP(NuThreadFormat threadFormat,
|
||||
uint32_t otherLen, FILE* fp, long offset, long length,
|
||||
NuCallback fcloseFunc, NuDataSource** ppDataSource)
|
||||
{
|
||||
return Nu_DataSourceFP_New(threadFormat, otherLen,
|
||||
fp, offset, length, fcloseFunc, ppDataSource);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuCreateDataSourceForBuffer(NuThreadFormat threadFormat,
|
||||
unsigned long otherLen, const unsigned char* buffer, long offset,
|
||||
NUFXLIB_API NuError NuCreateDataSourceForBuffer(NuThreadFormat threadFormat,
|
||||
uint32_t otherLen, const uint8_t* buffer, long offset,
|
||||
long length, NuCallback freeFunc, NuDataSource** ppDataSource)
|
||||
{
|
||||
return Nu_DataSourceBuffer_New(threadFormat, otherLen,
|
||||
buffer, offset, length, freeFunc, ppDataSource);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuFreeDataSource(NuDataSource* pDataSource)
|
||||
NUFXLIB_API NuError NuFreeDataSource(NuDataSource* pDataSource)
|
||||
{
|
||||
return Nu_DataSourceFree(pDataSource);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuDataSourceSetRawCrc(NuDataSource* pDataSource, unsigned short crc)
|
||||
NUFXLIB_API NuError NuDataSourceSetRawCrc(NuDataSource* pDataSource,
|
||||
uint16_t crc)
|
||||
{
|
||||
if (pDataSource == nil)
|
||||
if (pDataSource == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
Nu_DataSourceSetRawCrc(pDataSource, crc);
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuCreateDataSinkForFile(short doExpand, NuValue convertEOL,
|
||||
const char* pathname, char fssep, NuDataSink** ppDataSink)
|
||||
NUFXLIB_API NuError NuCreateDataSinkForFile(short doExpand, NuValue convertEOL,
|
||||
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink)
|
||||
{
|
||||
return Nu_DataSinkFile_New((Boolean)(doExpand != 0), convertEOL, pathname,
|
||||
fssep, ppDataSink);
|
||||
return Nu_DataSinkFile_New((Boolean)(doExpand != 0), convertEOL,
|
||||
pathnameUNI, fssep, ppDataSink);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuCreateDataSinkForFP(short doExpand, NuValue convertEOL, FILE* fp,
|
||||
NuDataSink** ppDataSink)
|
||||
NUFXLIB_API NuError NuCreateDataSinkForFP(short doExpand, NuValue convertEOL,
|
||||
FILE* fp, NuDataSink** ppDataSink)
|
||||
{
|
||||
return Nu_DataSinkFP_New((Boolean)(doExpand != 0), convertEOL, fp,
|
||||
ppDataSink);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuCreateDataSinkForBuffer(short doExpand, NuValue convertEOL,
|
||||
unsigned char* buffer, unsigned long bufLen, NuDataSink** ppDataSink)
|
||||
NUFXLIB_API NuError NuCreateDataSinkForBuffer(short doExpand,
|
||||
NuValue convertEOL, uint8_t* buffer, uint32_t bufLen,
|
||||
NuDataSink** ppDataSink)
|
||||
{
|
||||
return Nu_DataSinkBuffer_New((Boolean)(doExpand != 0), convertEOL, buffer,
|
||||
bufLen, ppDataSink);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuFreeDataSink(NuDataSink* pDataSink)
|
||||
NUFXLIB_API NuError NuFreeDataSink(NuDataSink* pDataSink)
|
||||
{
|
||||
return Nu_DataSinkFree(pDataSink);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuDataSinkGetOutCount(NuDataSink* pDataSink, ulong* pOutCount)
|
||||
NUFXLIB_API NuError NuDataSinkGetOutCount(NuDataSink* pDataSink,
|
||||
uint32_t* pOutCount)
|
||||
{
|
||||
if (pDataSink == nil || pOutCount == nil)
|
||||
if (pDataSink == NULL || pOutCount == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
*pOutCount = Nu_DataSinkGetOutCount(pDataSink);
|
||||
|
@ -657,22 +619,19 @@ NuDataSinkGetOutCount(NuDataSink* pDataSink, ulong* pOutCount)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NUFXLIB_API const char*
|
||||
NuStrError(NuError err)
|
||||
NUFXLIB_API const char* NuStrError(NuError err)
|
||||
{
|
||||
return Nu_StrError(err);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuGetVersion(long* pMajorVersion, long* pMinorVersion, long* pBugVersion,
|
||||
const char** ppBuildDate, const char** ppBuildFlags)
|
||||
NUFXLIB_API NuError NuGetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
|
||||
int32_t* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags)
|
||||
{
|
||||
return Nu_GetVersion(pMajorVersion, pMinorVersion, pBugVersion,
|
||||
ppBuildDate, ppBuildFlags);
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuTestFeature(NuFeature feature)
|
||||
NUFXLIB_API NuError NuTestFeature(NuFeature feature)
|
||||
{
|
||||
NuError err = kNuErrUnsupFeature;
|
||||
|
||||
|
@ -710,8 +669,8 @@ NuTestFeature(NuFeature feature)
|
|||
return err;
|
||||
}
|
||||
|
||||
NUFXLIB_API void
|
||||
NuRecordCopyAttr(NuRecordAttr* pRecordAttr, const NuRecord* pRecord)
|
||||
NUFXLIB_API void NuRecordCopyAttr(NuRecordAttr* pRecordAttr,
|
||||
const NuRecord* pRecord)
|
||||
{
|
||||
pRecordAttr->fileSysID = pRecord->recFileSysID;
|
||||
/*pRecordAttr->fileSysInfo = pRecord->recFileSysInfo;*/
|
||||
|
@ -723,16 +682,16 @@ NuRecordCopyAttr(NuRecordAttr* pRecordAttr, const NuRecord* pRecord)
|
|||
pRecordAttr->archiveWhen = pRecord->recArchiveWhen;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuError
|
||||
NuRecordCopyThreads(const NuRecord* pNuRecord, NuThread** ppThreads)
|
||||
NUFXLIB_API NuError NuRecordCopyThreads(const NuRecord* pNuRecord,
|
||||
NuThread** ppThreads)
|
||||
{
|
||||
if (pNuRecord == nil || ppThreads == nil)
|
||||
if (pNuRecord == NULL || ppThreads == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
Assert(pNuRecord->pThreads != nil);
|
||||
Assert(pNuRecord->pThreads != NULL);
|
||||
|
||||
*ppThreads = Nu_Malloc(nil, pNuRecord->recTotalThreads * sizeof(NuThread));
|
||||
if (*ppThreads == nil)
|
||||
*ppThreads = Nu_Malloc(NULL, pNuRecord->recTotalThreads * sizeof(NuThread));
|
||||
if (*ppThreads == NULL)
|
||||
return kNuErrMalloc;
|
||||
|
||||
memcpy(*ppThreads, pNuRecord->pThreads,
|
||||
|
@ -741,29 +700,39 @@ NuRecordCopyThreads(const NuRecord* pNuRecord, NuThread** ppThreads)
|
|||
return kNuErrNone;
|
||||
}
|
||||
|
||||
NUFXLIB_API unsigned long
|
||||
NuRecordGetNumThreads(const NuRecord* pNuRecord)
|
||||
NUFXLIB_API uint32_t NuRecordGetNumThreads(const NuRecord* pNuRecord)
|
||||
{
|
||||
if (pNuRecord == nil)
|
||||
if (pNuRecord == NULL)
|
||||
return -1;
|
||||
|
||||
return pNuRecord->recTotalThreads;
|
||||
}
|
||||
|
||||
NUFXLIB_API const NuThread*
|
||||
NuThreadGetByIdx(const NuThread* pNuThread, long idx)
|
||||
NUFXLIB_API const NuThread* NuThreadGetByIdx(const NuThread* pNuThread,
|
||||
int32_t idx)
|
||||
{
|
||||
if (pNuThread == nil)
|
||||
return nil;
|
||||
if (pNuThread == NULL)
|
||||
return NULL;
|
||||
return &pNuThread[idx]; /* can't range-check here */
|
||||
}
|
||||
|
||||
NUFXLIB_API short
|
||||
NuIsPresizedThreadID(NuThreadID threadID)
|
||||
NUFXLIB_API short NuIsPresizedThreadID(NuThreadID threadID)
|
||||
{
|
||||
return Nu_IsPresizedThreadID(threadID);
|
||||
}
|
||||
|
||||
NUFXLIB_API size_t NuConvertMORToUNI(const char* stringMOR,
|
||||
UNICHAR* bufUNI, size_t bufSize)
|
||||
{
|
||||
return Nu_ConvertMORToUNI(stringMOR, bufUNI, bufSize);
|
||||
}
|
||||
|
||||
NUFXLIB_API size_t NuConvertUNIToMOR(const UNICHAR* stringUNI,
|
||||
char* bufMOR, size_t bufSize)
|
||||
{
|
||||
return Nu_ConvertUNIToMOR(stringUNI, bufMOR, bufSize);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
|
@ -771,13 +740,13 @@ NuIsPresizedThreadID(NuThreadID threadID)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NUFXLIB_API NuCallback
|
||||
NuSetSelectionFilter(NuArchive* pArchive, NuCallback filterFunc)
|
||||
NUFXLIB_API NuCallback NuSetSelectionFilter(NuArchive* pArchive,
|
||||
NuCallback filterFunc)
|
||||
{
|
||||
NuError err;
|
||||
NuCallback oldFunc = kNuInvalidCallback;
|
||||
|
||||
/*Assert(!((ulong)filterFunc % 4));*/
|
||||
/*Assert(!((uint32_t)filterFunc % 4));*/
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
oldFunc = pArchive->selectionFilterFunc;
|
||||
|
@ -787,13 +756,13 @@ NuSetSelectionFilter(NuArchive* pArchive, NuCallback filterFunc)
|
|||
return oldFunc;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuCallback
|
||||
NuSetOutputPathnameFilter(NuArchive* pArchive, NuCallback filterFunc)
|
||||
NUFXLIB_API NuCallback NuSetOutputPathnameFilter(NuArchive* pArchive,
|
||||
NuCallback filterFunc)
|
||||
{
|
||||
NuError err;
|
||||
NuCallback oldFunc = kNuInvalidCallback;
|
||||
|
||||
/*Assert(!((ulong)filterFunc % 4));*/
|
||||
/*Assert(!((uint32_t)filterFunc % 4));*/
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
oldFunc = pArchive->outputPathnameFunc;
|
||||
|
@ -803,13 +772,13 @@ NuSetOutputPathnameFilter(NuArchive* pArchive, NuCallback filterFunc)
|
|||
return oldFunc;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuCallback
|
||||
NuSetProgressUpdater(NuArchive* pArchive, NuCallback updateFunc)
|
||||
NUFXLIB_API NuCallback NuSetProgressUpdater(NuArchive* pArchive,
|
||||
NuCallback updateFunc)
|
||||
{
|
||||
NuError err;
|
||||
NuCallback oldFunc = kNuInvalidCallback;
|
||||
|
||||
/*Assert(!((ulong)updateFunc % 4));*/
|
||||
/*Assert(!((uint32_t)updateFunc % 4));*/
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
oldFunc = pArchive->progressUpdaterFunc;
|
||||
|
@ -819,13 +788,13 @@ NuSetProgressUpdater(NuArchive* pArchive, NuCallback updateFunc)
|
|||
return oldFunc;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuCallback
|
||||
NuSetErrorHandler(NuArchive* pArchive, NuCallback errorFunc)
|
||||
NUFXLIB_API NuCallback NuSetErrorHandler(NuArchive* pArchive,
|
||||
NuCallback errorFunc)
|
||||
{
|
||||
NuError err;
|
||||
NuCallback oldFunc = kNuInvalidCallback;
|
||||
|
||||
/*Assert(!((ulong)errorFunc % 4));*/
|
||||
/*Assert(!((uint32_t)errorFunc % 4));*/
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
oldFunc = pArchive->errorHandlerFunc;
|
||||
|
@ -835,13 +804,13 @@ NuSetErrorHandler(NuArchive* pArchive, NuCallback errorFunc)
|
|||
return oldFunc;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuCallback
|
||||
NuSetErrorMessageHandler(NuArchive* pArchive, NuCallback messageHandlerFunc)
|
||||
NUFXLIB_API NuCallback NuSetErrorMessageHandler(NuArchive* pArchive,
|
||||
NuCallback messageHandlerFunc)
|
||||
{
|
||||
NuError err;
|
||||
NuCallback oldFunc = kNuInvalidCallback;
|
||||
|
||||
/*Assert(!((ulong)messageHandlerFunc % 4));*/
|
||||
/*Assert(!((uint32_t)messageHandlerFunc % 4));*/
|
||||
|
||||
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
|
||||
oldFunc = pArchive->messageHandlerFunc;
|
||||
|
@ -851,11 +820,10 @@ NuSetErrorMessageHandler(NuArchive* pArchive, NuCallback messageHandlerFunc)
|
|||
return oldFunc;
|
||||
}
|
||||
|
||||
NUFXLIB_API NuCallback
|
||||
NuSetGlobalErrorMessageHandler(NuCallback messageHandlerFunc)
|
||||
NUFXLIB_API NuCallback NuSetGlobalErrorMessageHandler(NuCallback messageHandlerFunc)
|
||||
{
|
||||
NuCallback oldFunc = kNuInvalidCallback;
|
||||
/*Assert(!((ulong)messageHandlerFunc % 4));*/
|
||||
/*Assert(!((uint32_t)messageHandlerFunc % 4));*/
|
||||
|
||||
oldFunc = gNuGlobalErrorMessageHandler;
|
||||
gNuGlobalErrorMessageHandler = messageHandlerFunc;
|
||||
|
|
|
@ -12,18 +12,18 @@
|
|||
/*
|
||||
* "Expand" an uncompressed thread.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ExpandUncompressed(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
|
||||
static NuError Nu_ExpandUncompressed(NuArchive* pArchive,
|
||||
const NuRecord* pRecord, const NuThread* pThread, FILE* infp,
|
||||
NuFunnel* pFunnel, uint16_t* pCrc)
|
||||
{
|
||||
NuError err;
|
||||
/*uchar* buffer = nil;*/
|
||||
ulong count, getsize;
|
||||
/*uint8_t* buffer = NULL;*/
|
||||
uint32_t count, getsize;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(infp != nil);
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(infp != NULL);
|
||||
Assert(pFunnel != NULL);
|
||||
|
||||
/* doesn't have to be same size as funnel, but it's not a bad idea */
|
||||
/*buffer = Nu_Malloc(pArchive, kNuFunnelBufSize);*/
|
||||
|
@ -43,7 +43,7 @@ Nu_ExpandUncompressed(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
|
||||
err = Nu_FRead(infp, pArchive->compBuf, getsize);
|
||||
BailError(err);
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, pArchive->compBuf, getsize);
|
||||
err = Nu_FunnelWrite(pArchive, pFunnel, pArchive->compBuf, getsize);
|
||||
BailError(err);
|
||||
|
@ -63,18 +63,17 @@ bail:
|
|||
* Copy the "raw" data out of the thread. Unlike the preceeding function,
|
||||
* this reads up to "thCompThreadEOF", and doesn't even try to compute a CRC.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ExpandRaw(NuArchive* pArchive, const NuThread* pThread, FILE* infp,
|
||||
NuFunnel* pFunnel)
|
||||
static NuError Nu_ExpandRaw(NuArchive* pArchive, const NuThread* pThread,
|
||||
FILE* infp, NuFunnel* pFunnel)
|
||||
{
|
||||
NuError err;
|
||||
/*uchar* buffer = nil;*/
|
||||
ulong count, getsize;
|
||||
/*uint8_t* buffer = NULL;*/
|
||||
uint32_t count, getsize;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(infp != nil);
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(infp != NULL);
|
||||
Assert(pFunnel != NULL);
|
||||
|
||||
/* doesn't have to be same size as funnel, but it's not a bad idea */
|
||||
/*buffer = Nu_Malloc(pArchive, kNuFunnelBufSize);*/
|
||||
|
@ -108,13 +107,12 @@ bail:
|
|||
* Expand a thread from "infp" to "pFunnel", using the compression
|
||||
* and stream length specified by "pThread".
|
||||
*/
|
||||
NuError
|
||||
Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
NuError Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
ushort calcCrc;
|
||||
ushort* pCalcCrc;
|
||||
uint16_t calcCrc;
|
||||
uint16_t* pCalcCrc;
|
||||
|
||||
if (!pThread->thThreadEOF && !pThread->thCompThreadEOF) {
|
||||
/* somebody stored an empty file! */
|
||||
|
@ -134,7 +132,7 @@ Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* unfortunately, unprotected before v3.
|
||||
*/
|
||||
calcCrc = kNuInitialThreadCRC;
|
||||
pCalcCrc = nil;
|
||||
pCalcCrc = NULL;
|
||||
if (Nu_ThreadHasCRC(pRecord->recVersionNumber, NuGetThreadID(pThread)) &&
|
||||
!pArchive->valIgnoreCRC)
|
||||
{
|
||||
|
@ -205,7 +203,7 @@ Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
/*
|
||||
* If we have a CRC to check, check it.
|
||||
*/
|
||||
if (pCalcCrc != nil) {
|
||||
if (pCalcCrc != NULL) {
|
||||
if (calcCrc != pThread->thThreadCRC) {
|
||||
if (!Nu_ShouldIgnoreBadCRC(pArchive, pRecord, kNuErrBadThreadCRC)) {
|
||||
err = kNuErrBadDataCRC;
|
||||
|
|
671
nufxlib/FileIO.c
671
nufxlib/FileIO.c
File diff suppressed because it is too large
Load Diff
251
nufxlib/Funnel.c
251
nufxlib/Funnel.c
|
@ -22,38 +22,36 @@
|
|||
* The same structure will be used when expanding all threads in a given
|
||||
* record.
|
||||
*/
|
||||
NuError
|
||||
Nu_ProgressDataInit_Compress(NuArchive* pArchive, NuProgressData* pProgressData,
|
||||
const NuRecord* pRecord, const char* origPathname)
|
||||
NuError Nu_ProgressDataInit_Compress(NuArchive* pArchive,
|
||||
NuProgressData* pProgressData, const NuRecord* pRecord,
|
||||
const UNICHAR* origPathnameUNI, const UNICHAR* pathnameUNI)
|
||||
{
|
||||
const char* cp;
|
||||
|
||||
Assert(pProgressData != nil);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pRecord != nil);
|
||||
Assert(origPathname != nil);
|
||||
Assert(pProgressData != NULL);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pRecord != NULL);
|
||||
Assert(origPathnameUNI != NULL);
|
||||
Assert(pathnameUNI != NULL);
|
||||
|
||||
pProgressData->pRecord = pRecord;
|
||||
|
||||
pProgressData->origPathname = origPathname;
|
||||
pProgressData->pathname = pRecord->filename;
|
||||
cp = strrchr(pRecord->filename,
|
||||
NuGetSepFromSysInfo(pRecord->recFileSysInfo));
|
||||
if (cp == nil || *(cp+1) == '\0')
|
||||
pProgressData->filename = pProgressData->pathname;
|
||||
pProgressData->origPathnameUNI = origPathnameUNI;
|
||||
pProgressData->pathnameUNI = pathnameUNI;
|
||||
cp = strrchr(pathnameUNI, NuGetSepFromSysInfo(pRecord->recFileSysInfo));
|
||||
if (cp == NULL || *(cp+1) == '\0')
|
||||
pProgressData->filenameUNI = pProgressData->pathnameUNI;
|
||||
else
|
||||
pProgressData->filename = cp+1;
|
||||
pProgressData->filenameUNI = cp+1;
|
||||
|
||||
pProgressData->operation = kNuOpAdd;
|
||||
pProgressData->state = kNuProgressPreparing;
|
||||
/*pProgressData->compressedLength = 0;*/
|
||||
/*pProgressData->compressedProgress = 0;*/
|
||||
pProgressData->uncompressedLength = 0;
|
||||
pProgressData->uncompressedProgress = 0;
|
||||
|
||||
pProgressData->compress.threadFormat = (NuThreadFormat)-1;
|
||||
|
||||
/* ya know... if this is nil, none of the above matters much */
|
||||
/* ya know... if this is NULL, none of the above matters much */
|
||||
pProgressData->progressFunc = pArchive->progressUpdaterFunc;
|
||||
|
||||
return kNuErrNone;
|
||||
|
@ -67,31 +65,32 @@ Nu_ProgressDataInit_Compress(NuArchive* pArchive, NuProgressData* pProgressData,
|
|||
* The same structure will be used when expanding all threads in a given
|
||||
* record.
|
||||
*/
|
||||
NuError
|
||||
Nu_ProgressDataInit_Expand(NuArchive* pArchive, NuProgressData* pProgressData,
|
||||
const NuRecord* pRecord, const char* newPathname, char newFssep,
|
||||
NuValue convertEOL)
|
||||
NuError Nu_ProgressDataInit_Expand(NuArchive* pArchive,
|
||||
NuProgressData* pProgressData, const NuRecord* pRecord,
|
||||
const UNICHAR* newPathnameUNI, UNICHAR newFssep,
|
||||
const UNICHAR* origPathnameUNI, NuValue convertEOL)
|
||||
{
|
||||
const NuThread* pThreadIter;
|
||||
const char* cp;
|
||||
int i;
|
||||
|
||||
Assert(pProgressData != nil);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pRecord != nil);
|
||||
Assert(newPathname != nil);
|
||||
Assert(pProgressData != NULL);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pRecord != NULL);
|
||||
Assert(newPathnameUNI != NULL);
|
||||
Assert(origPathnameUNI != NULL);
|
||||
Assert(newFssep != 0);
|
||||
|
||||
pProgressData->pRecord = pRecord;
|
||||
pProgressData->expand.pThread = nil;
|
||||
pProgressData->expand.pThread = NULL;
|
||||
|
||||
pProgressData->origPathname = pRecord->filename;
|
||||
pProgressData->pathname = newPathname;
|
||||
cp = strrchr(newPathname, newFssep);
|
||||
if (cp == nil || *(cp+1) == '\0')
|
||||
pProgressData->filename = newPathname;
|
||||
pProgressData->origPathnameUNI = origPathnameUNI;
|
||||
pProgressData->pathnameUNI = newPathnameUNI;
|
||||
cp = strrchr(newPathnameUNI, newFssep);
|
||||
if (cp == NULL || *(cp+1) == '\0')
|
||||
pProgressData->filenameUNI = newPathnameUNI;
|
||||
else
|
||||
pProgressData->filename = cp+1;
|
||||
pProgressData->filenameUNI = cp+1;
|
||||
|
||||
pProgressData->expand.convertEOL = convertEOL;
|
||||
|
||||
|
@ -111,12 +110,10 @@ Nu_ProgressDataInit_Expand(NuArchive* pArchive, NuProgressData* pProgressData,
|
|||
if (pArchive->testMode)
|
||||
pProgressData->operation = kNuOpTest;
|
||||
pProgressData->state = kNuProgressPreparing;
|
||||
/*pProgressData->expand.compressedLength = 0;*/
|
||||
/*pProgressData->expand.compressedProgress = 0;*/
|
||||
pProgressData->uncompressedLength = 0;
|
||||
pProgressData->uncompressedProgress = 0;
|
||||
|
||||
/* ya know... if this is nil, none of the above matters much */
|
||||
/* ya know... if this is NULL, none of the above matters much */
|
||||
pProgressData->progressFunc = pArchive->progressUpdaterFunc;
|
||||
|
||||
return kNuErrNone;
|
||||
|
@ -126,18 +123,17 @@ Nu_ProgressDataInit_Expand(NuArchive* pArchive, NuProgressData* pProgressData,
|
|||
/*
|
||||
* Do the setup on a ProgressData prior to compressing a thread.
|
||||
*/
|
||||
NuError
|
||||
Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
|
||||
NuThreadFormat threadFormat, ulong sourceLen)
|
||||
NuError Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
|
||||
NuThreadFormat threadFormat, uint32_t sourceLen)
|
||||
{
|
||||
NuProgressData* pProgressData;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pStraw != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(sourceLen < 32767*65536);
|
||||
|
||||
pProgressData = pStraw->pProgress;
|
||||
if (pProgressData == nil)
|
||||
if (pProgressData == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
pProgressData->uncompressedLength = sourceLen;
|
||||
|
@ -151,18 +147,17 @@ Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
|
|||
*
|
||||
* "pThread" is the thread being expanded.
|
||||
*/
|
||||
NuError
|
||||
Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
|
||||
NuError Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
|
||||
const NuThread* pThread)
|
||||
{
|
||||
NuProgressData* pProgressData;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pFunnel != NULL);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
pProgressData = pFunnel->pProgress;
|
||||
if (pProgressData == nil)
|
||||
if (pProgressData == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
/*pProgressData->compressedLength = pThread->thCompThreadEOF;*/
|
||||
|
@ -175,10 +170,9 @@ Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
|
|||
/*
|
||||
* Compute a completion percentage.
|
||||
*/
|
||||
static int
|
||||
Nu_ComputePercent(ulong total, ulong progress)
|
||||
static int Nu_ComputePercent(uint32_t total, uint32_t progress)
|
||||
{
|
||||
ulong perc;
|
||||
uint32_t perc;
|
||||
|
||||
if (!total)
|
||||
return 0;
|
||||
|
@ -200,15 +194,14 @@ Nu_ComputePercent(ulong total, ulong progress)
|
|||
* Send the initial progress message, before the output file is opened
|
||||
* (when extracting) or the input file is opened (when adding).
|
||||
*/
|
||||
NuError
|
||||
Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress)
|
||||
NuError Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress)
|
||||
{
|
||||
NuResult result;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pProgress != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pProgress != NULL);
|
||||
|
||||
if (pProgress->progressFunc == nil)
|
||||
if (pProgress->progressFunc == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
pProgress->percentComplete = Nu_ComputePercent(
|
||||
|
@ -234,15 +227,15 @@ Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress)
|
|||
/*
|
||||
* Allocate and initialize a Funnel.
|
||||
*/
|
||||
NuError
|
||||
Nu_FunnelNew(NuArchive* pArchive, NuDataSink* pDataSink, NuValue convertEOL,
|
||||
NuValue convertEOLTo, NuProgressData* pProgress, NuFunnel** ppFunnel)
|
||||
NuError Nu_FunnelNew(NuArchive* pArchive, NuDataSink* pDataSink,
|
||||
NuValue convertEOL, NuValue convertEOLTo, NuProgressData* pProgress,
|
||||
NuFunnel** ppFunnel)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuFunnel* pFunnel = nil;
|
||||
NuFunnel* pFunnel = NULL;
|
||||
|
||||
Assert(ppFunnel != nil);
|
||||
Assert(pDataSink != nil);
|
||||
Assert(ppFunnel != NULL);
|
||||
Assert(pDataSink != NULL);
|
||||
Assert(convertEOL == kNuConvertOff ||
|
||||
convertEOL == kNuConvertOn ||
|
||||
convertEOL == kNuConvertAuto);
|
||||
|
@ -278,10 +271,9 @@ bail:
|
|||
* The data should already have been written; it's not the duty of a
|
||||
* "free" function to flush data out.
|
||||
*/
|
||||
NuError
|
||||
Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel)
|
||||
NuError Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel)
|
||||
{
|
||||
if (pFunnel == nil)
|
||||
if (pFunnel == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
#ifdef DEBUG_MSGS
|
||||
|
@ -304,10 +296,9 @@ Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel)
|
|||
* allows us to bail out as soon as it's apparent that compression is
|
||||
* failing and is actually resulting in a larger file.
|
||||
*/
|
||||
void
|
||||
Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, ulong maxBytes)
|
||||
void Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, uint32_t maxBytes)
|
||||
{
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pFunnel != NULL);
|
||||
Assert(maxBytes > 0);
|
||||
|
||||
pFunnel->outMax = maxBytes;
|
||||
|
@ -324,13 +315,12 @@ Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, ulong maxBytes)
|
|||
* character must have its high bit set, except for spaces (0x20).
|
||||
* (The exception is courtesy Glen Bredon's "Merlin".)
|
||||
*/
|
||||
static Boolean
|
||||
Nu_CheckHighASCII(const NuFunnel* pFunnel, const unsigned char* buffer,
|
||||
unsigned long count)
|
||||
static Boolean Nu_CheckHighASCII(const NuFunnel* pFunnel, const uint8_t* buffer,
|
||||
uint32_t count)
|
||||
{
|
||||
Boolean isHighASCII;
|
||||
|
||||
Assert(buffer != nil);
|
||||
Assert(buffer != NULL);
|
||||
Assert(count != 0);
|
||||
Assert(pFunnel->checkStripHighASCII);
|
||||
|
||||
|
@ -405,12 +395,12 @@ static const char gNuIsBinary[256] = {
|
|||
* Returns kConvEOLOff or kConvEOLOn, and sets pFunnel->doStripHighASCII
|
||||
* if pFunnel->CheckStripHighASCII is set.
|
||||
*/
|
||||
static NuValue
|
||||
Nu_DetermineConversion(NuFunnel* pFunnel, const uchar* buffer, ulong count)
|
||||
static NuValue Nu_DetermineConversion(NuFunnel* pFunnel, const uint8_t* buffer,
|
||||
uint32_t count)
|
||||
{
|
||||
ulong bufCount, numBinary, numLF, numCR;
|
||||
uint32_t bufCount, numBinary, numLF, numCR;
|
||||
Boolean isHighASCII;
|
||||
uchar val;
|
||||
uint8_t val;
|
||||
|
||||
if (count < kNuMinConvThreshold)
|
||||
return kNuConvertOff;
|
||||
|
@ -484,12 +474,12 @@ Nu_DetermineConversion(NuFunnel* pFunnel, const uchar* buffer, ulong count)
|
|||
* This is either a Funnel function or a DataSink function, depending on
|
||||
* your perspective.
|
||||
*/
|
||||
static inline void
|
||||
Nu_FunnelPutBlock(NuFunnel* pFunnel, const uchar* buf, ulong len)
|
||||
static inline void Nu_FunnelPutBlock(NuFunnel* pFunnel, const uint8_t* buf,
|
||||
uint32_t len)
|
||||
{
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pFunnel->pDataSink != nil);
|
||||
Assert(buf != nil);
|
||||
Assert(pFunnel != NULL);
|
||||
Assert(pFunnel->pDataSink != NULL);
|
||||
Assert(buf != NULL);
|
||||
Assert(len > 0);
|
||||
|
||||
#if 0
|
||||
|
@ -511,10 +501,9 @@ Nu_FunnelPutBlock(NuFunnel* pFunnel, const uchar* buf, ulong len)
|
|||
/*
|
||||
* Output the EOL marker requested for this system.
|
||||
*/
|
||||
static inline void
|
||||
Nu_PutEOL(NuFunnel* pFunnel)
|
||||
static inline void Nu_PutEOL(NuFunnel* pFunnel)
|
||||
{
|
||||
uchar ch;
|
||||
uint8_t ch;
|
||||
|
||||
if (pFunnel->convertEOLTo == kNuEOLCR) {
|
||||
ch = kNuCharCR;
|
||||
|
@ -540,11 +529,11 @@ Nu_PutEOL(NuFunnel* pFunnel)
|
|||
* that looks like an EOL mark and convert it. Doesn't matter if it's
|
||||
* CR, LF, or CRLF; all three get converted to whatever the system uses.
|
||||
*/
|
||||
static NuError
|
||||
Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
|
||||
static NuError Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uint8_t* buffer,
|
||||
uint32_t count)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
ulong progressCount = count;
|
||||
uint32_t progressCount = count;
|
||||
|
||||
/*if (pFunnel->outMaxExceeded)
|
||||
return kNuErrOutMax;*/
|
||||
|
@ -566,7 +555,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
|
|||
pFunnel->convertEOL = kNuConvertOff;
|
||||
}
|
||||
/* put it where the progress meter can see it */
|
||||
if (pFunnel->pProgress != nil)
|
||||
if (pFunnel->pProgress != NULL)
|
||||
pFunnel->pProgress->expand.convertEOL = pFunnel->convertEOL;
|
||||
} else if (pFunnel->convertEOL == kNuConvertOn) {
|
||||
if (pFunnel->checkStripHighASCII) {
|
||||
|
@ -589,7 +578,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
|
|||
} else {
|
||||
/* do the EOL conversion and optional high-bit stripping */
|
||||
Boolean lastCR = pFunnel->lastCR; /* make local copy */
|
||||
uchar uch;
|
||||
uint8_t uch;
|
||||
int mask;
|
||||
|
||||
if (pFunnel->doStripHighASCII)
|
||||
|
@ -627,7 +616,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
|
|||
err = Nu_DataSinkGetError(pFunnel->pDataSink);
|
||||
|
||||
/* update progress counter with pre-LFCR count */
|
||||
if (err == kNuErrNone && pFunnel->pProgress != nil)
|
||||
if (err == kNuErrNone && pFunnel->pProgress != NULL)
|
||||
pFunnel->pProgress->uncompressedProgress += progressCount;
|
||||
|
||||
return err;
|
||||
|
@ -637,8 +626,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
|
|||
/*
|
||||
* Flush any data currently in the funnel.
|
||||
*/
|
||||
NuError
|
||||
Nu_FunnelFlush(NuArchive* pArchive, NuFunnel* pFunnel)
|
||||
NuError Nu_FunnelFlush(NuArchive* pArchive, NuFunnel* pFunnel)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
|
@ -661,9 +649,8 @@ bail:
|
|||
* Write a bunch of bytes into a funnel. They will be held in the buffer
|
||||
* if they fit, or flushed out the bottom if not.
|
||||
*/
|
||||
NuError
|
||||
Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel, const uchar* buffer,
|
||||
ulong count)
|
||||
NuError Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel,
|
||||
const uint8_t* buffer, uint32_t count)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
|
@ -714,12 +701,11 @@ bail:
|
|||
/*
|
||||
* Set the Funnel's progress state.
|
||||
*/
|
||||
NuError
|
||||
Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state)
|
||||
NuError Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state)
|
||||
{
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pFunnel != NULL);
|
||||
|
||||
if (pFunnel->pProgress == nil)
|
||||
if (pFunnel->pProgress == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
pFunnel->pProgress->state = state;
|
||||
|
@ -731,20 +717,19 @@ Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state)
|
|||
/*
|
||||
* Send a progress update to the application, if they're interested.
|
||||
*/
|
||||
NuError
|
||||
Nu_FunnelSendProgressUpdate(NuArchive* pArchive, NuFunnel* pFunnel)
|
||||
NuError Nu_FunnelSendProgressUpdate(NuArchive* pArchive, NuFunnel* pFunnel)
|
||||
{
|
||||
NuProgressData* pProgress;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pFunnel != NULL);
|
||||
|
||||
pProgress = pFunnel->pProgress;
|
||||
if (pProgress == nil)
|
||||
if (pProgress == NULL)
|
||||
return kNuErrNone; /* no progress meter attached */
|
||||
|
||||
/* don't continue if they're not accepting progress messages */
|
||||
if (pProgress->progressFunc == nil)
|
||||
if (pProgress->progressFunc == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
/* other than the choice of arguments, it's pretty much the same story */
|
||||
|
@ -755,11 +740,10 @@ Nu_FunnelSendProgressUpdate(NuArchive* pArchive, NuFunnel* pFunnel)
|
|||
/*
|
||||
* Pull the "doExpand" parameter out of the data source.
|
||||
*/
|
||||
Boolean
|
||||
Nu_FunnelGetDoExpand(NuFunnel* pFunnel)
|
||||
Boolean Nu_FunnelGetDoExpand(NuFunnel* pFunnel)
|
||||
{
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pFunnel->pDataSink != nil);
|
||||
Assert(pFunnel != NULL);
|
||||
Assert(pFunnel->pDataSink != NULL);
|
||||
|
||||
return Nu_DataSinkGetDoExpand(pFunnel->pDataSink);
|
||||
}
|
||||
|
@ -774,15 +758,14 @@ Nu_FunnelGetDoExpand(NuFunnel* pFunnel)
|
|||
/*
|
||||
* Allocate and initialize a Straw.
|
||||
*/
|
||||
NuError
|
||||
Nu_StrawNew(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||
NuError Nu_StrawNew(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||
NuProgressData* pProgress, NuStraw** ppStraw)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuStraw* pStraw = nil;
|
||||
NuStraw* pStraw = NULL;
|
||||
|
||||
Assert(ppStraw != nil);
|
||||
Assert(pDataSource != nil);
|
||||
Assert(ppStraw != NULL);
|
||||
Assert(pDataSource != NULL);
|
||||
|
||||
pStraw = Nu_Calloc(pArchive, sizeof(*pStraw));
|
||||
BailAlloc(pStraw);
|
||||
|
@ -802,10 +785,9 @@ bail:
|
|||
/*
|
||||
* Free a Straw.
|
||||
*/
|
||||
NuError
|
||||
Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw)
|
||||
NuError Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw)
|
||||
{
|
||||
if (pStraw == nil)
|
||||
if (pStraw == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
/* we don't own the data source or progress meter */
|
||||
|
@ -818,11 +800,10 @@ Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw)
|
|||
/*
|
||||
* Set the Straw's progress state.
|
||||
*/
|
||||
NuError
|
||||
Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state)
|
||||
NuError Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state)
|
||||
{
|
||||
Assert(pStraw != nil);
|
||||
Assert(pStraw->pProgress != nil);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(pStraw->pProgress != NULL);
|
||||
|
||||
pStraw->pProgress->state = state;
|
||||
|
||||
|
@ -832,20 +813,19 @@ Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state)
|
|||
/*
|
||||
* Send a progress update to the application, if they're interested.
|
||||
*/
|
||||
NuError
|
||||
Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw)
|
||||
NuError Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw)
|
||||
{
|
||||
NuProgressData* pProgress;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pStraw != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pStraw != NULL);
|
||||
|
||||
pProgress = pStraw->pProgress;
|
||||
if (pProgress == nil)
|
||||
if (pProgress == NULL)
|
||||
return kNuErrNone; /* no progress meter attached */
|
||||
|
||||
/* don't continue if they're not accepting progress messages */
|
||||
if (pProgress->progressFunc == nil)
|
||||
if (pProgress->progressFunc == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
/* other than the choice of arguments, it's pretty much the same story */
|
||||
|
@ -856,14 +836,14 @@ Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw)
|
|||
/*
|
||||
* Read data from a straw.
|
||||
*/
|
||||
NuError
|
||||
Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uchar* buffer, long len)
|
||||
NuError Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uint8_t* buffer,
|
||||
long len)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pStraw != nil);
|
||||
Assert(buffer != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(buffer != NULL);
|
||||
Assert(len > 0);
|
||||
|
||||
/*
|
||||
|
@ -887,7 +867,7 @@ Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uchar* buffer, long len)
|
|||
* on the previous call. (This assumes that whatever they asked for
|
||||
* last time has already been fully processed.)
|
||||
*/
|
||||
if (pStraw->pProgress != nil) {
|
||||
if (pStraw->pProgress != NULL) {
|
||||
pStraw->pProgress->uncompressedProgress = pStraw->lastProgress;
|
||||
pStraw->lastProgress += len;
|
||||
|
||||
|
@ -911,11 +891,10 @@ bail:
|
|||
* Rewind a straw. This rewinds the underlying data source, and resets
|
||||
* some progress counters.
|
||||
*/
|
||||
NuError
|
||||
Nu_StrawRewind(NuArchive* pArchive, NuStraw* pStraw)
|
||||
NuError Nu_StrawRewind(NuArchive* pArchive, NuStraw* pStraw)
|
||||
{
|
||||
Assert(pStraw != nil);
|
||||
Assert(pStraw->pDataSource != nil);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(pStraw->pDataSource != NULL);
|
||||
|
||||
pStraw->lastProgress = 0;
|
||||
pStraw->lastDisplayed = 0;
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
/*
|
||||
* Selected definitions from compress.h.
|
||||
*/
|
||||
typedef unsigned short CODE;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned int INTCODE;
|
||||
typedef unsigned int HASH;
|
||||
typedef uint16_t CODE;
|
||||
typedef uint8_t UCHAR;
|
||||
typedef uint32_t INTCODE;
|
||||
typedef uint32_t HASH;
|
||||
typedef int FLAG;
|
||||
|
||||
#ifndef FALSE /* let's get some sense to this */
|
||||
|
@ -80,7 +80,7 @@ static UCHAR gNu_magic_header[] = { 0x1F,0x9D };
|
|||
* Normally in COMPUSI.UNI.
|
||||
*/
|
||||
static inline ALLOCTYPE FAR *
|
||||
Nu_LZC_emalloc(NuArchive* pArchive, unsigned int x, int y)
|
||||
Nu_LZC_emalloc(NuArchive* pArchive, uint32_t x, int y)
|
||||
{
|
||||
return Nu_Malloc(pArchive, x*y);
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ Nu_LZC_efree(NuArchive* pArchive, ALLOCTYPE FAR * ptr)
|
|||
typedef struct LZCState {
|
||||
NuArchive* pArchive;
|
||||
int doCalcCRC;
|
||||
ushort crc;
|
||||
uint16_t crc;
|
||||
|
||||
/* compression */
|
||||
NuStraw* pStraw;
|
||||
|
@ -163,7 +163,7 @@ typedef struct LZCState {
|
|||
/* expansion */
|
||||
FILE* infp;
|
||||
NuFunnel* pFunnel;
|
||||
ushort* pCrc;
|
||||
uint16_t* pCrc;
|
||||
long compRemaining;
|
||||
|
||||
|
||||
|
@ -251,18 +251,18 @@ static CONST INTCODE gNu_mc[] = {
|
|||
#ifdef __STDC__
|
||||
#ifdef DEBUG_LZC
|
||||
#define allocx(type, ptr, size) \
|
||||
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (unsigned int)(size),sizeof(type))) == NULLPTR(type) \
|
||||
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (uint32_t)(size),sizeof(type))) == NULLPTR(type) \
|
||||
? (DBUG(("%s: "#ptr" -- ", "LZC")), NOMEM) : OK \
|
||||
)
|
||||
#else
|
||||
#define allocx(type,ptr,size) \
|
||||
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (unsigned int)(size),sizeof(type))) == NULLPTR(type) \
|
||||
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (uint32_t)(size),sizeof(type))) == NULLPTR(type) \
|
||||
? NOMEM : OK \
|
||||
)
|
||||
#endif
|
||||
#else
|
||||
#define allocx(type,ptr,size) \
|
||||
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (unsigned int)(size),sizeof(type))) == NULLPTR(type) \
|
||||
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (uint32_t)(size),sizeof(type))) == NULLPTR(type) \
|
||||
? NOMEM : OK \
|
||||
)
|
||||
#endif
|
||||
|
@ -300,8 +300,8 @@ static CONST INTCODE gNu_mc[] = {
|
|||
#endif
|
||||
|
||||
|
||||
static int
|
||||
Nu_LZC_alloc_tables(LZCState* pLzcState, INTCODE newmaxcode, HASH newhashsize)
|
||||
static int Nu_LZC_alloc_tables(LZCState* pLzcState, INTCODE newmaxcode,
|
||||
HASH newhashsize)
|
||||
{
|
||||
NuArchive* pArchive = pLzcState->pArchive;
|
||||
/*static INTCODE oldmaxcode = 0;*/
|
||||
|
@ -421,8 +421,7 @@ Nu_LZC_alloc_tables(LZCState* pLzcState, INTCODE newmaxcode, HASH newhashsize)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
static void
|
||||
Nu_prratio(long int num, long int den)
|
||||
static void Nu_prratio(long int num, long int den)
|
||||
{
|
||||
register int q; /* Doesn't need to be long */
|
||||
|
||||
|
@ -443,8 +442,7 @@ Nu_prratio(long int num, long int den)
|
|||
/* table clear for block compress */
|
||||
/* this is for adaptive reset present in version 4.0 joe release */
|
||||
/* DjG, sets it up and returns TRUE to compress and FALSE to not compress */
|
||||
static int
|
||||
Nu_LZC_cl_block(LZCState* pLzcState)
|
||||
static int Nu_LZC_cl_block(LZCState* pLzcState)
|
||||
{
|
||||
register long int rat;
|
||||
|
||||
|
@ -486,8 +484,7 @@ Nu_LZC_cl_block(LZCState* pLzcState)
|
|||
|
||||
static CONST UCHAR gNu_rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
|
||||
|
||||
static void
|
||||
Nu_LZC_putcode(LZCState* pLzcState, INTCODE code, register int bits)
|
||||
static void Nu_LZC_putcode(LZCState* pLzcState, INTCODE code, register int bits)
|
||||
{
|
||||
/*static int oldbits = 0;*/
|
||||
/*static UCHAR outbuf[MAXBITS];*/
|
||||
|
@ -554,11 +551,10 @@ Nu_LZC_putcode(LZCState* pLzcState, INTCODE code, register int bits)
|
|||
*
|
||||
* Returns kNuLZCEOF as the value when we're out of data.
|
||||
*/
|
||||
static NuError
|
||||
Nu_LZCGetcCRC(LZCState* pLzcState, int* pSym)
|
||||
static NuError Nu_LZCGetcCRC(LZCState* pLzcState, int* pSym)
|
||||
{
|
||||
NuError err;
|
||||
uchar c;
|
||||
uint8_t c;
|
||||
|
||||
if (!pLzcState->uncompRemaining) {
|
||||
*pSym = kNuLZCEOF;
|
||||
|
@ -579,15 +575,14 @@ Nu_LZCGetcCRC(LZCState* pLzcState, int* pSym)
|
|||
/*
|
||||
* compress stdin to stdout
|
||||
*/
|
||||
static void
|
||||
Nu_LZC_compress(LZCState* pLzcState, ulong* pDstLen)
|
||||
static void Nu_LZC_compress(LZCState* pLzcState, uint32_t* pDstLen)
|
||||
{
|
||||
int c,adjbits;
|
||||
register HASH hash;
|
||||
register INTCODE code;
|
||||
HASH hashf[256];
|
||||
|
||||
Assert(pLzcState->outfp != nil);
|
||||
Assert(pLzcState->outfp != NULL);
|
||||
|
||||
pLzcState->maxcode = Maxcode(pLzcState->maxbits);
|
||||
pLzcState->hashsize = Hashsize(pLzcState->maxbits);
|
||||
|
@ -758,9 +753,8 @@ Nu_LZC_compress(LZCState* pLzcState, ulong* pDstLen)
|
|||
/*
|
||||
* NufxLib interface to LZC compression.
|
||||
*/
|
||||
static NuError
|
||||
Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc, int maxbits)
|
||||
static NuError Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc, int maxbits)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
LZCState lzcState;
|
||||
|
@ -771,7 +765,7 @@ Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
lzcState.outfp = fp;
|
||||
lzcState.uncompRemaining = srcLen;
|
||||
|
||||
if (pCrc == nil) {
|
||||
if (pCrc == NULL) {
|
||||
lzcState.doCalcCRC = false;
|
||||
} else {
|
||||
lzcState.doCalcCRC = true;
|
||||
|
@ -800,22 +794,20 @@ Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
#endif
|
||||
free_array(char,lzcState.sfx, 256);
|
||||
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = lzcState.crc;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
NuError
|
||||
Nu_CompressLZC12(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc)
|
||||
NuError Nu_CompressLZC12(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
|
||||
{
|
||||
return Nu_CompressLZC(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, 12);
|
||||
}
|
||||
|
||||
NuError
|
||||
Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc)
|
||||
NuError Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
|
||||
{
|
||||
return Nu_CompressLZC(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, 16);
|
||||
}
|
||||
|
@ -833,22 +825,20 @@ Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
*
|
||||
* Returns kNuLZCEOF as the value when we're out of data.
|
||||
*/
|
||||
static NuError
|
||||
Nu_LZCPutcCRC(LZCState* pLzcState, char c)
|
||||
static NuError Nu_LZCPutcCRC(LZCState* pLzcState, char c)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
err = Nu_FunnelWrite(pLzcState->pArchive, pLzcState->pFunnel,
|
||||
(uchar*) &c, 1);
|
||||
(uint8_t*) &c, 1);
|
||||
if (pLzcState->doCalcCRC)
|
||||
pLzcState->crc = Nu_CalcCRC16(pLzcState->crc, (uchar*) &c, 1);
|
||||
pLzcState->crc = Nu_CalcCRC16(pLzcState->crc, (uint8_t*) &c, 1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
Nu_LZC_nextcode(LZCState* pLzcState, INTCODE* codeptr)
|
||||
static int Nu_LZC_nextcode(LZCState* pLzcState, INTCODE* codeptr)
|
||||
/* Get the next code from input and put it in *codeptr.
|
||||
* Return (TRUE) on success, or return (FALSE) on end-of-file.
|
||||
* Adapted from COMPRESS V4.0.
|
||||
|
@ -898,8 +888,7 @@ Nu_LZC_nextcode(LZCState* pLzcState, INTCODE* codeptr)
|
|||
return (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
Nu_LZC_decompress(LZCState* pLzcState, ulong compressedLen)
|
||||
static void Nu_LZC_decompress(LZCState* pLzcState, uint32_t compressedLen)
|
||||
{
|
||||
NuArchive* pArchive = pLzcState->pArchive;
|
||||
register int i;
|
||||
|
@ -911,7 +900,7 @@ Nu_LZC_decompress(LZCState* pLzcState, ulong compressedLen)
|
|||
/*static*/ int maxtoklen = MAXTOKLEN;
|
||||
int flags;
|
||||
|
||||
Assert(pLzcState->infp != nil);
|
||||
Assert(pLzcState->infp != NULL);
|
||||
|
||||
pLzcState->exit_stat = OK;
|
||||
|
||||
|
@ -1060,9 +1049,8 @@ Nu_LZC_decompress(LZCState* pLzcState, ulong compressedLen)
|
|||
/*
|
||||
* NufxLib interface to LZC expansion.
|
||||
*/
|
||||
NuError
|
||||
Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
|
||||
NuError Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
LZCState lzcState;
|
||||
|
@ -1072,7 +1060,7 @@ Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
lzcState.infp = infp;
|
||||
lzcState.pFunnel = pFunnel;
|
||||
|
||||
if (pCrc == nil) {
|
||||
if (pCrc == NULL) {
|
||||
lzcState.doCalcCRC = false;
|
||||
} else {
|
||||
lzcState.doCalcCRC = true;
|
||||
|
@ -1098,7 +1086,7 @@ Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
#endif
|
||||
free_array(char,lzcState.sfx, 256);
|
||||
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = lzcState.crc;
|
||||
return err;
|
||||
}
|
||||
|
|
291
nufxlib/Lzw.c
291
nufxlib/Lzw.c
|
@ -119,17 +119,17 @@ static const int gNuBitMask[] = {
|
|||
typedef struct LZWCompressState {
|
||||
NuArchive* pArchive;
|
||||
|
||||
ushort entry[kNuLZWHashSize]; /* uint or ushort */
|
||||
ushort prefix[kNuLZWMaxCode+1]; /* uint or ushort */
|
||||
uchar suffix[kNuLZWMaxCode+1];
|
||||
uint16_t entry[kNuLZWHashSize]; /* uint or ushort */
|
||||
uint16_t prefix[kNuLZWMaxCode+1]; /* uint or ushort */
|
||||
uint8_t suffix[kNuLZWMaxCode+1];
|
||||
|
||||
ushort hashFunc[kNuLZWHashFuncTblSize]; /* uint or ushort */
|
||||
uint16_t hashFunc[kNuLZWHashFuncTblSize]; /* uint or ushort */
|
||||
|
||||
uchar inputBuf[kNuLZWBlockSize]; /* 4K of raw input */
|
||||
uchar rleBuf[kNuLZWBlockSize*2 + kNuSafetyPadding];
|
||||
uchar lzwBuf[(kNuLZWBlockSize * 3) / 2 + kNuSafetyPadding];
|
||||
uint8_t inputBuf[kNuLZWBlockSize]; /* 4K of raw input */
|
||||
uint8_t rleBuf[kNuLZWBlockSize*2 + kNuSafetyPadding];
|
||||
uint8_t lzwBuf[(kNuLZWBlockSize * 3) / 2 + kNuSafetyPadding];
|
||||
|
||||
ushort chunkCrc; /* CRC for LZW/1 */
|
||||
uint16_t chunkCrc; /* CRC for LZW/1 */
|
||||
|
||||
/* LZW/2 state variables */
|
||||
int nextFree;
|
||||
|
@ -146,15 +146,14 @@ typedef struct LZWCompressState {
|
|||
* the hash function. This way we don't have to re-create it for
|
||||
* every file, or store it statically in the binary.
|
||||
*/
|
||||
static NuError
|
||||
Nu_AllocLZWCompressState(NuArchive* pArchive)
|
||||
static NuError Nu_AllocLZWCompressState(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
LZWCompressState* lzwState;
|
||||
int ic;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive->lzwCompressState == nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pArchive->lzwCompressState == NULL);
|
||||
|
||||
/* allocate the general-purpose compression buffer, if needed */
|
||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
|
@ -162,7 +161,7 @@ Nu_AllocLZWCompressState(NuArchive* pArchive)
|
|||
return err;
|
||||
|
||||
pArchive->lzwCompressState = Nu_Malloc(pArchive, sizeof(LZWCompressState));
|
||||
if (pArchive->lzwCompressState == nil)
|
||||
if (pArchive->lzwCompressState == NULL)
|
||||
return kNuErrMalloc;
|
||||
|
||||
/*
|
||||
|
@ -191,13 +190,12 @@ Nu_AllocLZWCompressState(NuArchive* pArchive)
|
|||
* The RLE format is "<delim> <char> <count>", where count is zero-based
|
||||
* (i.e. for three bytes we encode "2", allowing us to express 1-256).
|
||||
*/
|
||||
static NuError
|
||||
Nu_CompressBlockRLE(LZWCompressState* lzwState, int* pRLESize)
|
||||
static NuError Nu_CompressBlockRLE(LZWCompressState* lzwState, int* pRLESize)
|
||||
{
|
||||
const uchar* inPtr = lzwState->inputBuf;
|
||||
const uchar* endPtr = inPtr + kNuLZWBlockSize;
|
||||
uchar* outPtr = lzwState->rleBuf;
|
||||
uchar matchChar;
|
||||
const uint8_t* inPtr = lzwState->inputBuf;
|
||||
const uint8_t* endPtr = inPtr + kNuLZWBlockSize;
|
||||
uint8_t* outPtr = lzwState->rleBuf;
|
||||
uint8_t matchChar;
|
||||
int matchCount;
|
||||
|
||||
while (inPtr < endPtr) {
|
||||
|
@ -258,10 +256,9 @@ Nu_CompressBlockRLE(LZWCompressState* lzwState, int* pRLESize)
|
|||
/*
|
||||
* Clear the LZW table. Also resets the LZW/2 state.
|
||||
*/
|
||||
static void
|
||||
Nu_ClearLZWTable(LZWCompressState* lzwState)
|
||||
static void Nu_ClearLZWTable(LZWCompressState* lzwState)
|
||||
{
|
||||
Assert(lzwState != nil);
|
||||
Assert(lzwState != NULL);
|
||||
|
||||
/*DBUG_LZW(("### clear table\n"));*/
|
||||
|
||||
|
@ -296,11 +293,11 @@ Nu_ClearLZWTable(LZWCompressState* lzwState)
|
|||
*
|
||||
* (Turning this into a macro might speed things up.)
|
||||
*/
|
||||
static inline void
|
||||
Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
|
||||
static inline void Nu_LZWPutCode(uint8_t** pOutBuf, uint32_t prefixCode,
|
||||
int codeBits, int* pAtBit)
|
||||
{
|
||||
int atBit = *pAtBit;
|
||||
uchar* outBuf = *pOutBuf;
|
||||
uint8_t* outBuf = *pOutBuf;
|
||||
|
||||
/*DBUG_LZW(("### PUT: prefixCode=0x%04lx, codeBits=%d, atBit=%d\n",
|
||||
prefixCode, codeBits, atBit));*/
|
||||
|
@ -313,20 +310,20 @@ Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
|
|||
|
||||
/* merge it with the buffer contents (if necessary) and write lo bits */
|
||||
outBuf--;
|
||||
*outBuf = (uchar)((*outBuf & gNuBitMask[atBit]) | prefixCode);
|
||||
*outBuf = (uint8_t)((*outBuf & gNuBitMask[atBit]) | prefixCode);
|
||||
outBuf++;
|
||||
} else {
|
||||
/* nothing to merge with; write lo byte at next posn and advance */
|
||||
*outBuf++ = (uchar)prefixCode;
|
||||
*outBuf++ = (uint8_t)prefixCode;
|
||||
}
|
||||
|
||||
/* codes are at least 9 bits, so we know we have to write one more */
|
||||
*outBuf++ = (uchar)(prefixCode >> 8);
|
||||
*outBuf++ = (uint8_t)(prefixCode >> 8);
|
||||
|
||||
/* in some cases, we may have to write yet another */
|
||||
atBit += codeBits;
|
||||
if (atBit > 16)
|
||||
*outBuf++ = (uchar)(prefixCode >> 16);
|
||||
*outBuf++ = (uint8_t)(prefixCode >> 16);
|
||||
|
||||
*pAtBit = atBit & 0x07;
|
||||
*pOutBuf = outBuf;
|
||||
|
@ -353,23 +350,22 @@ Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
|
|||
* "resetFix" logic in the expansion functions. Code 0x0101 is essentially
|
||||
* lost in this situation.
|
||||
*/
|
||||
static NuError
|
||||
Nu_CompressLZWBlock(LZWCompressState* lzwState, const uchar* inputBuf,
|
||||
int inputCount, int* pOutputCount)
|
||||
static NuError Nu_CompressLZWBlock(LZWCompressState* lzwState,
|
||||
const uint8_t* inputBuf, int inputCount, int* pOutputCount)
|
||||
{
|
||||
int nextFree, ic, atBit, codeBits;
|
||||
int hash, hashDelta;
|
||||
int prefixCode, code, highCode;
|
||||
const uchar* inputEnd = inputBuf + inputCount;
|
||||
const uint8_t* inputEnd = inputBuf + inputCount;
|
||||
/* local copies of lzwState members, for speed */
|
||||
const ushort* pHashFunc = lzwState->hashFunc;
|
||||
ushort* pEntry = lzwState->entry;
|
||||
ushort* pPrefix = lzwState->prefix;
|
||||
uchar* pSuffix = lzwState->suffix;
|
||||
uchar* outBuf = lzwState->lzwBuf;
|
||||
const uint16_t* pHashFunc = lzwState->hashFunc;
|
||||
uint16_t* pEntry = lzwState->entry;
|
||||
uint16_t* pPrefix = lzwState->prefix;
|
||||
uint8_t* pSuffix = lzwState->suffix;
|
||||
uint8_t* outBuf = lzwState->lzwBuf;
|
||||
|
||||
Assert(lzwState != nil);
|
||||
Assert(inputBuf != nil);
|
||||
Assert(lzwState != NULL);
|
||||
Assert(inputBuf != NULL);
|
||||
Assert(inputCount > 0 && inputCount <= kNuLZWBlockSize);
|
||||
/* make sure nobody has been messing with the types */
|
||||
Assert(sizeof(pHashFunc[0]) == sizeof(lzwState->hashFunc[0]));
|
||||
|
@ -555,35 +551,34 @@ Nu_CompressLZWBlock(LZWCompressState* lzwState, const uchar* inputBuf,
|
|||
*
|
||||
* On exit, the output file will be positioned past the last byte written.
|
||||
*/
|
||||
static NuError
|
||||
Nu_CompressLZW(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pThreadCrc, Boolean isType2)
|
||||
static NuError Nu_CompressLZW(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pThreadCrc, Boolean isType2)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
LZWCompressState* lzwState;
|
||||
long initialOffset;
|
||||
const uchar* lzwInputBuf;
|
||||
uint blockSize, rleSize, lzwSize;
|
||||
const uint8_t* lzwInputBuf;
|
||||
uint32_t blockSize, rleSize, lzwSize;
|
||||
long compressedLen;
|
||||
Boolean keepLzw;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pStraw != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pStraw != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(srcLen > 0);
|
||||
Assert(pDstLen != nil);
|
||||
Assert(pThreadCrc != nil);
|
||||
Assert(pDstLen != NULL);
|
||||
Assert(pThreadCrc != NULL);
|
||||
Assert(isType2 == true || isType2 == false);
|
||||
|
||||
/*
|
||||
* Do some initialization and set-up.
|
||||
*/
|
||||
if (pArchive->lzwCompressState == nil) {
|
||||
if (pArchive->lzwCompressState == NULL) {
|
||||
err = Nu_AllocLZWCompressState(pArchive);
|
||||
BailError(err);
|
||||
}
|
||||
Assert(pArchive->lzwCompressState != nil);
|
||||
Assert(pArchive->compBuf != nil);
|
||||
Assert(pArchive->lzwCompressState != NULL);
|
||||
Assert(pArchive->compBuf != NULL);
|
||||
|
||||
lzwState = pArchive->lzwCompressState;
|
||||
lzwState->pArchive = pArchive;
|
||||
|
@ -782,9 +777,8 @@ bail:
|
|||
/*
|
||||
* Compress ShrinkIt-style "LZW/1".
|
||||
*/
|
||||
NuError
|
||||
Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc)
|
||||
NuError Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
|
||||
{
|
||||
return Nu_CompressLZW(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, false);
|
||||
}
|
||||
|
@ -792,9 +786,8 @@ Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
/*
|
||||
* Compress ShrinkIt-style "LZW/2".
|
||||
*/
|
||||
NuError
|
||||
Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc)
|
||||
NuError Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
|
||||
{
|
||||
return Nu_CompressLZW(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, true);
|
||||
}
|
||||
|
@ -813,21 +806,21 @@ Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
/*
|
||||
* Static tables useful for bit manipulation.
|
||||
*/
|
||||
static const uint gNuMaskTable[17] = {
|
||||
static const uint32_t gNuMaskTable[17] = {
|
||||
0x0000, 0x01ff, 0x03ff, 0x03ff, 0x07ff, 0x07ff, 0x07ff, 0x07ff,
|
||||
0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
|
||||
0x0fff
|
||||
};
|
||||
/* convert high byte of "entry" into a bit width */
|
||||
static const uint gNuBitWidth[17] = {
|
||||
static const uint32_t gNuBitWidth[17] = {
|
||||
8,9,10,10,11,11,11,11,12,12,12,12,12,12,12,12,12
|
||||
};
|
||||
|
||||
|
||||
/* entry in the trie */
|
||||
typedef struct TableEntry {
|
||||
uchar ch;
|
||||
uint prefix;
|
||||
uint8_t ch;
|
||||
uint32_t prefix;
|
||||
} TableEntry;
|
||||
|
||||
/*
|
||||
|
@ -839,38 +832,38 @@ typedef struct LZWExpandState {
|
|||
NuArchive* pArchive;
|
||||
|
||||
TableEntry trie[4096-256]; /* holds from 9 bits to 12 bits */
|
||||
uchar stack[kNuLZWBlockSize];
|
||||
uint8_t stack[kNuLZWBlockSize];
|
||||
|
||||
uint entry; /* 16-bit index into table */
|
||||
uint oldcode; /* carryover state for LZW/2 */
|
||||
uint incode; /* carryover state for LZW/2 */
|
||||
uint finalc; /* carryover state for LZW/2 */
|
||||
// some of these don't need to be 32 bits; they were "uint" before
|
||||
uint32_t entry; /* 16-bit index into table */
|
||||
uint32_t oldcode; /* carryover state for LZW/2 */
|
||||
uint32_t incode; /* carryover state for LZW/2 */
|
||||
uint32_t finalc; /* carryover state for LZW/2 */
|
||||
Boolean resetFix; /* work around an LZW/2 bug */
|
||||
|
||||
ushort chunkCrc; /* CRC we calculate for LZW/1 */
|
||||
ushort fileCrc; /* CRC stored with file */
|
||||
uint16_t chunkCrc; /* CRC we calculate for LZW/1 */
|
||||
uint16_t fileCrc; /* CRC stored with file */
|
||||
|
||||
uchar diskVol; /* disk volume # */
|
||||
uchar rleEscape; /* RLE escape char, usually 0xdb */
|
||||
uint8_t diskVol; /* disk volume # */
|
||||
uint8_t rleEscape; /* RLE escape char, usually 0xdb */
|
||||
|
||||
ulong dataInBuffer; /* #of bytes in compBuf */
|
||||
uchar* dataPtr; /* current data offset */
|
||||
uint32_t dataInBuffer; /* #of bytes in compBuf */
|
||||
uint8_t* dataPtr; /* current data offset */
|
||||
|
||||
uchar lzwOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
|
||||
uchar rleOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
|
||||
uint8_t lzwOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
|
||||
uint8_t rleOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
|
||||
} LZWExpandState;
|
||||
|
||||
|
||||
/*
|
||||
* Allocate some "reusable" state for LZW expansion.
|
||||
*/
|
||||
static NuError
|
||||
Nu_AllocLZWExpandState(NuArchive* pArchive)
|
||||
static NuError Nu_AllocLZWExpandState(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive->lzwExpandState == nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pArchive->lzwExpandState == NULL);
|
||||
|
||||
/* allocate the general-purpose compression buffer, if needed */
|
||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
|
@ -878,7 +871,7 @@ Nu_AllocLZWExpandState(NuArchive* pArchive)
|
|||
return err;
|
||||
|
||||
pArchive->lzwExpandState = Nu_Malloc(pArchive, sizeof(LZWExpandState));
|
||||
if (pArchive->lzwExpandState == nil)
|
||||
if (pArchive->lzwExpandState == NULL)
|
||||
return kNuErrMalloc;
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
@ -896,8 +889,8 @@ Nu_AllocLZWExpandState(NuArchive* pArchive)
|
|||
( Nu_LZWPopCheck(lzwState, stackPtr), *(--stackPtr) )
|
||||
# define Nu_LZWStackEmpty() ( stackPtr == lzwState->stack )
|
||||
|
||||
static inline void
|
||||
Nu_LZWPushCheck(uchar uch, const LZWExpandState* lzwState,const uchar* stackPtr)
|
||||
static inline void Nu_LZWPushCheck(uint8_t uch, const LZWExpandState* lzwState,
|
||||
const uint8_t* stackPtr)
|
||||
{
|
||||
if (stackPtr >= lzwState->stack + sizeof(lzwState->stack)) {
|
||||
Nu_ReportError(lzwState->NU_BLOB, kNuErrBadData, "stack overflow");
|
||||
|
@ -905,8 +898,8 @@ Nu_LZWPushCheck(uchar uch, const LZWExpandState* lzwState,const uchar* stackPtr)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
Nu_LZWPopCheck(const LZWExpandState* lzwState, const uchar* stackPtr)
|
||||
static inline void Nu_LZWPopCheck(const LZWExpandState* lzwState,
|
||||
const uint8_t* stackPtr)
|
||||
{
|
||||
if (stackPtr == lzwState->stack) {
|
||||
Nu_ReportError(lzwState->NU_BLOB, kNuErrBadData, "stack underflow");
|
||||
|
@ -927,13 +920,11 @@ Nu_LZWPopCheck(const LZWExpandState* lzwState, const uchar* stackPtr)
|
|||
*
|
||||
* (Turning this into a macro might speed things up.)
|
||||
*/
|
||||
static inline uint
|
||||
Nu_LZWGetCode(const uchar** pInBuf, uint entry, int* pAtBit, uint* pLastByte)
|
||||
static inline uint32_t Nu_LZWGetCode(const uint8_t** pInBuf, uint32_t entry,
|
||||
int* pAtBit, uint32_t* pLastByte)
|
||||
{
|
||||
uint numBits, startBit, lastBit;
|
||||
ulong value;
|
||||
|
||||
Assert(sizeof(uint) >= 2);
|
||||
uint32_t numBits, startBit, lastBit;
|
||||
uint32_t value;
|
||||
|
||||
numBits = (entry +1) >> 8; /* bit-width of next code */
|
||||
startBit = *pAtBit;
|
||||
|
@ -952,7 +943,7 @@ Nu_LZWGetCode(const uchar** pInBuf, uint entry, int* pAtBit, uint* pLastByte)
|
|||
/* need two more bytes */
|
||||
value |= *(*pInBuf)++ << 8;
|
||||
*pLastByte = *(*pInBuf)++;
|
||||
value |= (ulong) *pLastByte << 16;
|
||||
value |= (uint32_t) *pLastByte << 16;
|
||||
} else {
|
||||
/* only need one more byte */
|
||||
*pLastByte = *(*pInBuf)++;
|
||||
|
@ -977,20 +968,19 @@ Nu_LZWGetCode(const uchar** pInBuf, uint entry, int* pAtBit, uint* pLastByte)
|
|||
*
|
||||
* Reads from lzwState->dataPtr, writes to lzwState->lzwOutBuf.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ExpandLZW1(LZWExpandState* lzwState, uint expectedLen)
|
||||
static NuError Nu_ExpandLZW1(LZWExpandState* lzwState, uint32_t expectedLen)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
TableEntry* tablePtr;
|
||||
int atBit;
|
||||
uint entry, oldcode, incode, ptr;
|
||||
uint lastByte, finalc;
|
||||
const uchar* inbuf;
|
||||
uchar* outbuf;
|
||||
uchar* outbufend;
|
||||
uchar* stackPtr;
|
||||
uint32_t entry, oldcode, incode, ptr;
|
||||
uint32_t lastByte, finalc;
|
||||
const uint8_t* inbuf;
|
||||
uint8_t* outbuf;
|
||||
uint8_t* outbufend;
|
||||
uint8_t* stackPtr;
|
||||
|
||||
Assert(lzwState != nil);
|
||||
Assert(lzwState != NULL);
|
||||
Assert(expectedLen > 0 && expectedLen <= kNuLZWBlockSize);
|
||||
|
||||
inbuf = lzwState->dataPtr;
|
||||
|
@ -1024,7 +1014,7 @@ Nu_ExpandLZW1(LZWExpandState* lzwState, uint expectedLen)
|
|||
err = kNuErrBadData;
|
||||
return err;
|
||||
}
|
||||
Nu_LZWPush((uchar)finalc);
|
||||
Nu_LZWPush((uint8_t)finalc);
|
||||
ptr = oldcode;
|
||||
}
|
||||
|
||||
|
@ -1062,7 +1052,7 @@ bail:
|
|||
/* adjust input buffer */
|
||||
lzwState->dataInBuffer -= (inbuf - lzwState->dataPtr);
|
||||
Assert(lzwState->dataInBuffer < 32767*65536);
|
||||
lzwState->dataPtr = (uchar*)inbuf;
|
||||
lzwState->dataPtr = (uint8_t*)inbuf;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1077,24 +1067,23 @@ bail:
|
|||
* In some cases, "expectedInputUsed" will be -1 to indicate that the
|
||||
* value is not known.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ExpandLZW2(LZWExpandState* lzwState, uint expectedLen,
|
||||
uint expectedInputUsed)
|
||||
static NuError Nu_ExpandLZW2(LZWExpandState* lzwState, uint32_t expectedLen,
|
||||
uint32_t expectedInputUsed)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
TableEntry* tablePtr;
|
||||
int atBit;
|
||||
uint entry, oldcode, incode, ptr;
|
||||
uint lastByte, finalc;
|
||||
const uchar* inbuf;
|
||||
const uchar* inbufend;
|
||||
uchar* outbuf;
|
||||
uchar* outbufend;
|
||||
uchar* stackPtr;
|
||||
uint32_t entry, oldcode, incode, ptr;
|
||||
uint32_t lastByte, finalc;
|
||||
const uint8_t* inbuf;
|
||||
const uint8_t* inbufend;
|
||||
uint8_t* outbuf;
|
||||
uint8_t* outbufend;
|
||||
uint8_t* stackPtr;
|
||||
|
||||
/*DBUG_LZW(("### LZW/2 block start (compIn=%d, rleOut=%d, entry=0x%04x)\n",
|
||||
expectedInputUsed, expectedLen, lzwState->entry));*/
|
||||
Assert(lzwState != nil);
|
||||
Assert(lzwState != NULL);
|
||||
Assert(expectedLen > 0 && expectedLen <= kNuLZWBlockSize);
|
||||
|
||||
inbuf = lzwState->dataPtr;
|
||||
|
@ -1171,7 +1160,7 @@ main_loop:
|
|||
err = kNuErrBadData;
|
||||
return err;
|
||||
}
|
||||
Nu_LZWPush((uchar)finalc);
|
||||
Nu_LZWPush((uint8_t)finalc);
|
||||
ptr = oldcode;
|
||||
}
|
||||
|
||||
|
@ -1203,7 +1192,7 @@ main_loop:
|
|||
|
||||
bail:
|
||||
/*DBUG_LZW(("### end of block\n"));*/
|
||||
if (expectedInputUsed != (unsigned int) -1 && inbuf != inbufend) {
|
||||
if (expectedInputUsed != (uint32_t) -1 && inbuf != inbufend) {
|
||||
/* data was corrupted; if we keep going this will get worse */
|
||||
DBUG(("--- inbuf != inbufend in ExpandLZW2 (diff=%d)\n",
|
||||
inbufend - inbuf));
|
||||
|
@ -1215,7 +1204,7 @@ bail:
|
|||
/* adjust input buffer */
|
||||
lzwState->dataInBuffer -= (inbuf - lzwState->dataPtr);
|
||||
Assert(lzwState->dataInBuffer < 32767*65536);
|
||||
lzwState->dataPtr = (uchar*)inbuf;
|
||||
lzwState->dataPtr = (uint8_t*)inbuf;
|
||||
|
||||
/* save off local copies of stuff */
|
||||
lzwState->entry = entry;
|
||||
|
@ -1230,15 +1219,14 @@ bail:
|
|||
/*
|
||||
* Expands a chunk of RLEd data into 4K of output.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ExpandRLE(LZWExpandState* lzwState, const uchar* inbuf,
|
||||
uint expectedInputUsed)
|
||||
static NuError Nu_ExpandRLE(LZWExpandState* lzwState, const uint8_t* inbuf,
|
||||
uint32_t expectedInputUsed)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
uchar *outbuf;
|
||||
uchar *outbufend;
|
||||
const uchar *inbufend;
|
||||
uchar uch, rleEscape;
|
||||
uint8_t *outbuf;
|
||||
uint8_t *outbufend;
|
||||
const uint8_t *inbufend;
|
||||
uint8_t uch, rleEscape;
|
||||
int count;
|
||||
|
||||
outbuf = lzwState->rleOutBuf;
|
||||
|
@ -1284,8 +1272,7 @@ bail:
|
|||
/*
|
||||
* Utility function to get a byte from the input buffer.
|
||||
*/
|
||||
static inline uchar
|
||||
Nu_GetHeaderByte(LZWExpandState* lzwState)
|
||||
static inline uint8_t Nu_GetHeaderByte(LZWExpandState* lzwState)
|
||||
{
|
||||
lzwState->dataInBuffer--;
|
||||
Assert(lzwState->dataInBuffer > 0);
|
||||
|
@ -1298,33 +1285,33 @@ Nu_GetHeaderByte(LZWExpandState* lzwState)
|
|||
* This manages the input data buffer, passing chunks of compressed data
|
||||
* into the appropriate expansion function.
|
||||
*
|
||||
* Pass in nil for "pThreadCrc" if no thread CRC is desired. Otherwise,
|
||||
* Pass in NULL for "pThreadCrc" if no thread CRC is desired. Otherwise,
|
||||
* "*pThreadCrc" should already be set to its initial value. On exit it
|
||||
* will contain the CRC of the uncompressed data.
|
||||
*/
|
||||
NuError
|
||||
Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pThreadCrc)
|
||||
NuError Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel,
|
||||
uint16_t* pThreadCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Boolean isType2;
|
||||
LZWExpandState* lzwState;
|
||||
ulong compRemaining, uncompRemaining, minSize;
|
||||
uint32_t compRemaining, uncompRemaining, minSize;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(infp != nil);
|
||||
Assert(pFunnel != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(infp != NULL);
|
||||
Assert(pFunnel != NULL);
|
||||
|
||||
/*
|
||||
* Do some initialization and set-up.
|
||||
*/
|
||||
if (pArchive->lzwExpandState == nil) {
|
||||
if (pArchive->lzwExpandState == NULL) {
|
||||
err = Nu_AllocLZWExpandState(pArchive);
|
||||
BailError(err);
|
||||
}
|
||||
Assert(pArchive->lzwExpandState != nil);
|
||||
Assert(pArchive->compBuf != nil);
|
||||
Assert(pArchive->lzwExpandState != NULL);
|
||||
Assert(pArchive->compBuf != NULL);
|
||||
|
||||
lzwState = pArchive->lzwExpandState;
|
||||
lzwState->pArchive = pArchive;
|
||||
|
@ -1368,7 +1355,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
compRemaining -= 2;
|
||||
|
||||
lzwState->dataInBuffer = 0;
|
||||
lzwState->dataPtr = nil;
|
||||
lzwState->dataPtr = NULL;
|
||||
|
||||
/* reset pointers */
|
||||
lzwState->entry = kNuLZWFirstCode; /* 0x0101 */
|
||||
|
@ -1396,11 +1383,11 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
while (uncompRemaining) {
|
||||
Boolean rleUsed;
|
||||
Boolean lzwUsed;
|
||||
ulong getSize;
|
||||
uint rleLen; /* length after RLE; 4096 if no RLE */
|
||||
uint lzwLen = 0; /* type 2 only */
|
||||
uint writeLen, inCount;
|
||||
const uchar* writeBuf;
|
||||
uint32_t getSize;
|
||||
uint32_t rleLen; /* length after RLE; 4096 if no RLE */
|
||||
uint32_t lzwLen = 0; /* type 2 only */
|
||||
uint32_t writeLen, inCount;
|
||||
const uint8_t* writeBuf;
|
||||
|
||||
/* if we're low, and there's more data available, read more */
|
||||
if (lzwState->dataInBuffer < kNuLZWDesiredChunk && compRemaining) {
|
||||
|
@ -1409,7 +1396,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* the buffer.
|
||||
*/
|
||||
if (lzwState->dataInBuffer) {
|
||||
Assert(lzwState->dataPtr != nil);
|
||||
Assert(lzwState->dataPtr != NULL);
|
||||
Assert(pArchive->compBuf != lzwState->dataPtr);
|
||||
memmove(pArchive->compBuf, lzwState->dataPtr,
|
||||
lzwState->dataInBuffer);
|
||||
|
@ -1429,7 +1416,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
getSize);
|
||||
if (err != kNuErrNone) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"failed reading compressed data (%ld bytes)", getSize);
|
||||
"failed reading compressed data (%u bytes)", getSize);
|
||||
goto bail;
|
||||
}
|
||||
lzwState->dataInBuffer += getSize;
|
||||
|
@ -1476,7 +1463,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
writeLen = kNuLZWBlockSize;
|
||||
|
||||
#ifndef NDEBUG
|
||||
writeBuf = nil;
|
||||
writeBuf = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1491,7 +1478,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
} else {
|
||||
if (pRecord->isBadMac || pArchive->valIgnoreLZW2Len) {
|
||||
/* might be big-endian, might be okay; just ignore it */
|
||||
lzwLen = (unsigned int) -1;
|
||||
lzwLen = (uint32_t) -1;
|
||||
} else if (lzwState->dataInBuffer < lzwLen) {
|
||||
/* rare -- GSHK will do this if you don't let it finish */
|
||||
err = kNuErrBufferUnderrun;
|
||||
|
@ -1537,7 +1524,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
lzwState->resetFix = false;
|
||||
}
|
||||
|
||||
Assert(writeBuf != nil);
|
||||
Assert(writeBuf != NULL);
|
||||
|
||||
/*
|
||||
* Compute the CRC of the uncompressed data, and write it. For
|
||||
|
@ -1547,7 +1534,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* See commentary in the compression code for why we have to
|
||||
* compute two CRCs for LZW/1.
|
||||
*/
|
||||
if (pThreadCrc != nil) {
|
||||
if (pThreadCrc != NULL) {
|
||||
*pThreadCrc = Nu_CalcCRC16(*pThreadCrc, writeBuf, writeLen);
|
||||
}
|
||||
if (!isType2) {
|
||||
|
@ -1590,7 +1577,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
DBUG(("--- Found %ld bytes following compressed data (compRem=%ld)\n",
|
||||
lzwState->dataInBuffer, compRemaining));
|
||||
if (lzwState->dataInBuffer > 32) {
|
||||
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) lots of fluff (%ld)",
|
||||
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) lots of fluff (%u)",
|
||||
lzwState->dataInBuffer);
|
||||
}
|
||||
}
|
||||
|
@ -1602,7 +1589,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
if (compRemaining) {
|
||||
err = kNuErrBadData;
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"not all compressed data was used (%ld/%ld)",
|
||||
"not all compressed data was used (%u/%u)",
|
||||
compRemaining, lzwState->dataInBuffer);
|
||||
goto bail;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#
|
||||
# The shared library support currently leaves much to be desired.
|
||||
#
|
||||
# If you build with -DDEBUG_MSGS, nulib2 will be able to use the hidden
|
||||
# 'g' command, which generates a verbose archive dump for debugging.
|
||||
#
|
||||
|
||||
# NufxLib install location.
|
||||
prefix = @prefix@
|
||||
|
@ -31,14 +34,14 @@ OPT = @CFLAGS@
|
|||
#OPT = @CFLAGS@ -DDEBUG_MSGS
|
||||
#OPT = @CFLAGS@ -DDEBUG_VERBOSE
|
||||
GCC_FLAGS = -Wall -Wwrite-strings -Wstrict-prototypes -Wpointer-arith -Wshadow
|
||||
CFLAGS = @BUILD_FLAGS@ -I. @DEFS@ -DOPTFLAGSTR="\"$(OPT)\""
|
||||
CFLAGS = @BUILD_FLAGS@ -I. @DEFS@ -fPIC -DOPTFLAGSTR="\"$(OPT)\""
|
||||
|
||||
SRCS = Archive.c ArchiveIO.c Bzip2.c Compress.c Crc16.c Debug.c \
|
||||
Deferred.c Deflate.c Entry.c Expand.c FileIO.c Funnel.c \
|
||||
SRCS = Archive.c ArchiveIO.c Bzip2.c Charset.c Compress.c Crc16.c \
|
||||
Debug.c Deferred.c Deflate.c Entry.c Expand.c FileIO.c Funnel.c \
|
||||
Lzc.c Lzw.c MiscStuff.c MiscUtils.c Record.c SourceSink.c \
|
||||
Squeeze.c Thread.c Value.c Version.c
|
||||
OBJS = Archive.o ArchiveIO.o Bzip2.o Compress.o Crc16.o Debug.o \
|
||||
Deferred.o Deflate.o Entry.o Expand.o FileIO.o Funnel.o \
|
||||
OBJS = Archive.o ArchiveIO.o Bzip2.o Charset.o Compress.o Crc16.o \
|
||||
Debug.o Deferred.o Deflate.o Entry.o Expand.o FileIO.o Funnel.o \
|
||||
Lzc.o Lzw.o MiscStuff.o MiscUtils.o Record.o SourceSink.o \
|
||||
Squeeze.o Thread.o Value.o Version.o
|
||||
|
||||
|
@ -57,16 +60,18 @@ all: $(PRODUCT) samples
|
|||
install: $(STATIC_PRODUCT)
|
||||
$(srcdir)/mkinstalldirs $(libdir)
|
||||
$(INSTALL_DATA) $(STATIC_PRODUCT) $(libdir)
|
||||
$(srcdir)/mkinstalldirs $(includedir)
|
||||
$(srcdir)/mkinstalldirs $(includedir) $(libdir)/pkgconfig
|
||||
$(INSTALL_DATA) NufxLib.h $(includedir)
|
||||
$(INSTALL_DATA) nufxlib.pc $(libdir)/pkgconfig
|
||||
|
||||
install-shared: $(SHARED_PRODUCT)
|
||||
$(srcdir)/mkinstalldirs $(libdir)
|
||||
$(INSTALL_DATA) $(SHARED_PRODUCT) $(libdir)
|
||||
$(srcdir)/mkinstalldirs $(includedir)
|
||||
$(srcdir)/mkinstalldirs $(includedir) $(libdir)/pkgconfig
|
||||
$(INSTALL_DATA) NufxLib.h $(includedir)
|
||||
$(INSTALL_DATA) nufxlib.pc $(libdir)/pkgconfig
|
||||
|
||||
samples::
|
||||
samples:: $(STATIC_PRODUCT)
|
||||
@echo "Building samples..."
|
||||
@(cd samples; set +e; unset CFLAGS OBJS; set -e; \
|
||||
@SET_MAKE@ LIB_PRODUCT="../$(PRODUCT)" $(MAKE))
|
||||
|
@ -79,7 +84,7 @@ $(STATIC_PRODUCT): $(OBJS)
|
|||
$(AR) $@ $(OBJS)
|
||||
@RANLIB@ $@
|
||||
|
||||
# BUG: we probably want -fPIC -D_REENTRANT on the compile lines for this.
|
||||
# BUG: we need -fPIC, maybe -D_REENTRANT when compiling for this.
|
||||
# BUG: for Linux we may want -Wl,-soname,libnufx.so.1 on the link line.
|
||||
$(SHARED_PRODUCT): $(OBJS)
|
||||
-rm -f $(STATIC_PRODUCT) $(SHARED_PRODUCT)
|
||||
|
@ -97,7 +102,6 @@ tags::
|
|||
|
||||
distclean: clean
|
||||
(cd samples; make distclean)
|
||||
-rm -f Version.c
|
||||
-rm -f Makefile Makefile.bak
|
||||
-rm -f config.log config.cache config.status config.h
|
||||
-rm -f tags
|
||||
|
@ -111,12 +115,29 @@ baktar:
|
|||
@gzip -9 nufxlib.tar
|
||||
@mv -i nufxlib.tar.gz /home/fadden/BAK/
|
||||
|
||||
depend:
|
||||
makedepend -- $(CFLAGS) -I/usr/local/include -- $(SRCS)
|
||||
@(cd samples; unset CFLAGS OBJS; @SET_MAKE@ $(MAKE) depend)
|
||||
|
||||
# catch OPTFLAGSTR updates
|
||||
Version.o: Makefile
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
# dependency info
|
||||
COMMON_HDRS = NufxLibPriv.h NufxLib.h MiscStuff.h SysDefs.h
|
||||
Archive.o: Archive.c $(COMMON_HDRS)
|
||||
ArchiveIO.o: ArchiveIO.c $(COMMON_HDRS)
|
||||
Bzip2.o: Bzip2.c $(COMMON_HDRS)
|
||||
Charset.o: Charset.c $(COMMON_HDRS)
|
||||
Compress.o: Compress.c $(COMMON_HDRS)
|
||||
Crc16.o: Crc16.c $(COMMON_HDRS)
|
||||
Debug.o: Debug.c $(COMMON_HDRS)
|
||||
Deferred.o: Deferred.c $(COMMON_HDRS)
|
||||
Deflate.o: Deflate.c $(COMMON_HDRS)
|
||||
Entry.o: Entry.c $(COMMON_HDRS)
|
||||
Expand.o: Expand.c $(COMMON_HDRS)
|
||||
FileIO.o: FileIO.c $(COMMON_HDRS)
|
||||
Funnel.o: Funnel.c $(COMMON_HDRS)
|
||||
Lzc.o: Lzc.c $(COMMON_HDRS)
|
||||
Lzw.o: Lzw.c $(COMMON_HDRS)
|
||||
MiscStuff.o: MiscStuff.c $(COMMON_HDRS)
|
||||
MiscUtils.o: MiscUtils.c $(COMMON_HDRS)
|
||||
Record.o: Record.c $(COMMON_HDRS)
|
||||
SourceSink.o: SourceSink.c $(COMMON_HDRS)
|
||||
Squeeze.o: Squeeze.c $(COMMON_HDRS)
|
||||
Thread.o: Thread.c $(COMMON_HDRS)
|
||||
Value.o: Value.c $(COMMON_HDRS)
|
||||
Version.o: Version.c $(COMMON_HDRS) Makefile
|
||||
|
||||
|
|
|
@ -65,16 +65,16 @@ LDFLAGS = $(LDFLAGS) zlib.lib
|
|||
|
||||
|
||||
# object files
|
||||
OBJS = Archive.obj ArchiveIO.obj Bzip2.obj Compress.obj Crc16.obj Debug.obj \
|
||||
Deferred.obj Deflate.obj Entry.obj Expand.obj FileIO.obj Funnel.obj \
|
||||
Lzc.obj Lzw.obj MiscStuff.obj MiscUtils.obj Record.obj SourceSink.obj \
|
||||
Squeeze.obj Thread.obj Value.obj Version.obj
|
||||
OBJS = Archive.obj ArchiveIO.obj Bzip2.obj Charset.obj Compress.obj \
|
||||
Crc16.obj Debug.obj Deferred.obj Deflate.obj Entry.obj Expand.obj \
|
||||
FileIO.obj Funnel.obj Lzc.obj Lzw.obj MiscStuff.obj MiscUtils.obj \
|
||||
Record.obj SourceSink.obj Squeeze.obj Thread.obj Value.obj Version.obj
|
||||
|
||||
|
||||
# build targets -- static library, dynamic library, and test programs
|
||||
all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
|
||||
exerciser.exe imgconv.exe launder.exe test-basic.exe \
|
||||
test-basic-d.exe test-extract.exe test-simple.exe test-twirl.exe
|
||||
exerciser.exe imgconv.exe launder.exe test-basic.exe test-basic-d.exe \
|
||||
test-extract.exe test-names.exe test-simple.exe test-twirl.exe
|
||||
|
||||
clean:
|
||||
-del *.obj *.pdb *.exp
|
||||
|
@ -107,6 +107,9 @@ test-basic-d.exe: TestBasic.obj $(IMPLIB)
|
|||
test-extract.exe: TestExtract.obj $(STATICLIB)
|
||||
$(LD) $(LDFLAGS) -out:$@ TestExtract.obj $(STATICLIB)
|
||||
|
||||
test-names.exe: TestNames.obj $(STATICLIB)
|
||||
$(LD) $(LDFLAGS) -out:$@ TestNames.obj $(STATICLIB)
|
||||
|
||||
test-simple.exe: TestSimple.obj $(STATICLIB)
|
||||
$(LD) $(LDFLAGS) -out:$@ TestSimple.obj $(STATICLIB)
|
||||
|
||||
|
@ -125,6 +128,7 @@ COMMON_HDRS = NufxLibPriv.h NufxLib.h MiscStuff.h SysDefs.h
|
|||
Archive.obj: Archive.c $(COMMON_HDRS)
|
||||
ArchiveIO.obj: ArchiveIO.c $(COMMON_HDRS)
|
||||
Bzip2.obj: Bzip2.c $(COMMON_HDRS)
|
||||
Charset.obj: Charset.c $(COMMON_HDRS)
|
||||
Compress.obj: Compress.c $(COMMON_HDRS)
|
||||
Crc16.obj: Crc16.c $(COMMON_HDRS)
|
||||
Debug.obj: Debug.c $(COMMON_HDRS)
|
||||
|
@ -150,6 +154,7 @@ ImgConv.obj: samples/ImgConv.c $(COMMON_HDRS)
|
|||
Launder.obj: samples/Launder.c $(COMMON_HDRS)
|
||||
TestBasic.obj: samples/TestBasic.c $(COMMON_HDRS)
|
||||
TestExtract.obj: samples/TestExtract.c $(COMMON_HDRS)
|
||||
TestNames.obj: samples/TestNames.c $(COMMON_HDRS)
|
||||
TestSimple.obj: samples/TestSimple.c $(COMMON_HDRS)
|
||||
TestTwirl.obj: samples/TestTwirl.c $(COMMON_HDRS)
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
* Return a pointer to the appropriate string in the system table, or NULL
|
||||
* if the value is out of bounds.
|
||||
*/
|
||||
const char*
|
||||
Nu_strerror(int errnum)
|
||||
const char* Nu_strerror(int errnum)
|
||||
{
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
@ -38,8 +37,7 @@ Nu_strerror(int errnum)
|
|||
* from BSD, is available in the PGP 2.6.2 distribution, but this should
|
||||
* suffice for those few systems that don't have memmove.
|
||||
*/
|
||||
void*
|
||||
Nu_memmove(void* dst, const void* src, size_t n)
|
||||
void* Nu_memmove(void* dst, const void* src, size_t n)
|
||||
{
|
||||
void* retval = dst;
|
||||
char* srcp = (char*)src;
|
||||
|
@ -80,8 +78,7 @@ Nu_memmove(void* dst, const void* src, size_t n)
|
|||
* For our purposes here, strtol does all we need it to. Someday
|
||||
* we should replace this with a "real" version.
|
||||
*/
|
||||
unsigned long
|
||||
Nu_strtoul(const char *nptr, char **endptr, int base)
|
||||
unsigned long Nu_strtoul(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return strtol(nptr, endptr, base);
|
||||
}
|
||||
|
@ -91,8 +88,7 @@ Nu_strtoul(const char *nptr, char **endptr, int base)
|
|||
/*
|
||||
* Compare two strings, case-insensitive.
|
||||
*/
|
||||
int
|
||||
Nu_strcasecmp(const char *str1, const char *str2)
|
||||
int Nu_strcasecmp(const char *str1, const char *str2)
|
||||
{
|
||||
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
|
||||
str1++, str2++;
|
||||
|
@ -105,8 +101,7 @@ Nu_strcasecmp(const char *str1, const char *str2)
|
|||
/*
|
||||
* Compare two strings, case-insensitive, stopping after "n" chars.
|
||||
*/
|
||||
int
|
||||
Nu_strncasecmp(const char *str1, const char *str2, size_t n)
|
||||
int Nu_strncasecmp(const char *str1, const char *str2, size_t n)
|
||||
{
|
||||
while (n && *str1 && *str2 && toupper(*str1) == toupper(*str2))
|
||||
str1++, str2++, n--;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* Misc stuff (shared between nufxlib and nulib2). This is a collection
|
||||
* of miscellaneous types and macros that I find generally useful.
|
||||
*/
|
||||
#ifndef __MiscStuff__
|
||||
#define __MiscStuff__
|
||||
#ifndef NUFXLIB_MISCSTUFF_H
|
||||
#define NUFXLIB_MISCSTUFF_H
|
||||
|
||||
#define VALGRIND /* assume we're using it */
|
||||
|
||||
|
@ -42,11 +42,7 @@ int Nu_strncasecmp(const char *s1, const char *s2, size_t n);
|
|||
* Misc types.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define nil NULL /* I can't seem to stop typing 'nil' now */
|
||||
|
||||
typedef uchar Boolean;
|
||||
typedef unsigned char Boolean;
|
||||
#define false (0)
|
||||
#define true (!false)
|
||||
|
||||
|
@ -63,7 +59,7 @@ typedef uchar Boolean;
|
|||
(x) <= '9' ? (x) - '0' : toupper(x) +10 - 'A' )
|
||||
|
||||
/* convert number from 0-15 to hex digit */
|
||||
#define HexConv(x) ( ((uint)(x)) <= 15 ? \
|
||||
#define HexConv(x) ( ((unsigned int)(x)) <= 15 ? \
|
||||
( (x) <= 9 ? (x) + '0' : (x) -10 + 'A') : -1 )
|
||||
|
||||
|
||||
|
@ -106,4 +102,4 @@ typedef uchar Boolean;
|
|||
|
||||
#define kInvalidPtr ((void*)0xa3a3a3a3)
|
||||
|
||||
#endif /*__MiscStuff__*/
|
||||
#endif /*NUFXLIB_MISCSTUFF_H*/
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
*
|
||||
* Miscellaneous NufxLib utility functions.
|
||||
*/
|
||||
#define __MiscUtils_c__
|
||||
#include "NufxLibPriv.h"
|
||||
|
||||
/*
|
||||
* Big fat hairy global. Unfortunately this is unavoidable.
|
||||
*/
|
||||
NuCallback gNuGlobalErrorMessageHandler = nil;
|
||||
NuCallback gNuGlobalErrorMessageHandler = NULL;
|
||||
|
||||
|
||||
static const char* kNufxLibName = "nufxlib";
|
||||
|
@ -21,8 +20,7 @@ static const char* kNufxLibName = "nufxlib";
|
|||
/*
|
||||
* strerror() equivalent for NufxLib errors.
|
||||
*/
|
||||
const char*
|
||||
Nu_StrError(NuError err)
|
||||
const char* Nu_StrError(NuError err)
|
||||
{
|
||||
/*
|
||||
* BUG: this should be set up as per-thread storage in an MT environment.
|
||||
|
@ -32,7 +30,7 @@ Nu_StrError(NuError err)
|
|||
* to return this.
|
||||
*
|
||||
* An easier solution, should this present a problem for someone, would
|
||||
* be to have the function return nil or "unknown error" when the
|
||||
* be to have the function return NULL or "unknown error" when the
|
||||
* error value isn't recognized. I'd recommend leaving it as-is for
|
||||
* debug builds, though, as it's helpful to know *which* error is not
|
||||
* recognized.
|
||||
|
@ -200,15 +198,15 @@ Nu_StrError(NuError err)
|
|||
* Similar to perror(), but takes the error as an argument, and knows
|
||||
* about NufxLib errors as well as system errors.
|
||||
*
|
||||
* Depending on the compiler, "file", "line", and "function" may be nil/zero.
|
||||
* Depending on the compiler, "file", "line", and "function" may be NULL/zero.
|
||||
*
|
||||
* Calling here with "pArchive"==nil is allowed, but should only be done
|
||||
* Calling here with "pArchive"==NULL is allowed, but should only be done
|
||||
* if the archive is inaccessible (perhaps because it failed to open). We
|
||||
* can't invoke the error message callback if the pointer is nil.
|
||||
* can't invoke the error message callback if the pointer is NULL.
|
||||
*/
|
||||
void
|
||||
Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
||||
const char* function, Boolean isDebug, NuError err, const char* format, ...)
|
||||
void Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
||||
const char* function, Boolean isDebug, NuError err,
|
||||
const UNICHAR* format, ...)
|
||||
{
|
||||
NuErrorMessage errorMessage;
|
||||
const char* msg;
|
||||
|
@ -219,7 +217,7 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
|||
int cc;
|
||||
#endif
|
||||
|
||||
Assert(format != nil);
|
||||
Assert(format != NULL);
|
||||
|
||||
|
||||
va_start(args, format);
|
||||
|
@ -247,28 +245,28 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
|||
strcpy(buf+count, ": ");
|
||||
count += 2;
|
||||
|
||||
msg = nil;
|
||||
msg = NULL;
|
||||
if (err >= 0)
|
||||
msg = strerror(err);
|
||||
if (msg == nil)
|
||||
if (msg == NULL)
|
||||
msg = Nu_StrError(err);
|
||||
|
||||
#if defined(HAVE_SNPRINTF) && defined(SNPRINTF_DECLARED)
|
||||
if (msg == nil)
|
||||
if (msg == NULL)
|
||||
snprintf(buf+count, sizeof(buf) - count,
|
||||
"(unknown err=%d)", err);
|
||||
else
|
||||
snprintf(buf+count, sizeof(buf) - count, "%s", msg);
|
||||
#else
|
||||
#ifdef SPRINTF_RETURNS_INT
|
||||
if (msg == nil)
|
||||
if (msg == NULL)
|
||||
cc = sprintf(buf+count, "(unknown err=%d)", err);
|
||||
else
|
||||
cc = sprintf(buf+count, "%s", msg);
|
||||
Assert(cc > 0);
|
||||
count += cc;
|
||||
#else
|
||||
if (msg == nil)
|
||||
if (msg == NULL)
|
||||
sprintf(buf+count, "(unknown err=%d)", err);
|
||||
else
|
||||
sprintf(buf+count, "%s", msg);
|
||||
|
@ -284,8 +282,8 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
|||
Assert(count <= kNuHeftyBufSize);
|
||||
#endif
|
||||
|
||||
if ((pArchive != nil && pArchive->messageHandlerFunc == nil) ||
|
||||
(pArchive == nil && gNuGlobalErrorMessageHandler == nil))
|
||||
if ((pArchive != NULL && pArchive->messageHandlerFunc == NULL) ||
|
||||
(pArchive == NULL && gNuGlobalErrorMessageHandler == NULL))
|
||||
{
|
||||
if (isDebug) {
|
||||
fprintf(stderr, "%s: [%s:%d %s] %s\n", kNufxLibName,
|
||||
|
@ -301,7 +299,7 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
|||
errorMessage.line = line;
|
||||
errorMessage.function = function;
|
||||
|
||||
if (pArchive == nil)
|
||||
if (pArchive == NULL)
|
||||
(void) (*gNuGlobalErrorMessageHandler)(pArchive, &errorMessage);
|
||||
else
|
||||
(void) (*pArchive->messageHandlerFunc)(pArchive, &errorMessage);
|
||||
|
@ -322,48 +320,46 @@ bail:
|
|||
*/
|
||||
|
||||
#ifndef USE_DMALLOC
|
||||
void*
|
||||
Nu_Malloc(NuArchive* pArchive, size_t size)
|
||||
void* Nu_Malloc(NuArchive* pArchive, size_t size)
|
||||
{
|
||||
void* _result;
|
||||
|
||||
Assert(size > 0);
|
||||
_result = malloc(size);
|
||||
if (_result == nil) {
|
||||
Nu_ReportError(NU_BLOB, kNuErrMalloc, "malloc(%u) failed", (uint) size);
|
||||
if (_result == NULL) {
|
||||
Nu_ReportError(NU_BLOB, kNuErrMalloc,
|
||||
"malloc(%u) failed", (unsigned int) size);
|
||||
DebugAbort(); /* leave a core dump if we're built for it */
|
||||
}
|
||||
DebugFill(_result, size);
|
||||
return _result;
|
||||
}
|
||||
|
||||
void*
|
||||
Nu_Calloc(NuArchive* pArchive, size_t size)
|
||||
void* Nu_Calloc(NuArchive* pArchive, size_t size)
|
||||
{
|
||||
void* _cresult = Nu_Malloc(pArchive, size);
|
||||
memset(_cresult, 0, size);
|
||||
return _cresult;
|
||||
}
|
||||
|
||||
void*
|
||||
Nu_Realloc(NuArchive* pArchive, void* ptr, size_t size)
|
||||
void* Nu_Realloc(NuArchive* pArchive, void* ptr, size_t size)
|
||||
{
|
||||
void* _result;
|
||||
|
||||
Assert(ptr != nil); /* disallow this usage */
|
||||
Assert(ptr != NULL); /* disallow this usage */
|
||||
Assert(size > 0); /* disallow this usage */
|
||||
_result = realloc(ptr, size);
|
||||
if (_result == nil) {
|
||||
Nu_ReportError(NU_BLOB, kNuErrMalloc, "realloc(%u) failed",(uint) size);
|
||||
if (_result == NULL) {
|
||||
Nu_ReportError(NU_BLOB, kNuErrMalloc,
|
||||
"realloc(%u) failed", (unsigned int) size);
|
||||
DebugAbort(); /* leave a core dump if we're built for it */
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
|
||||
void
|
||||
Nu_Free(NuArchive* pArchive, void* ptr)
|
||||
void Nu_Free(NuArchive* pArchive, void* ptr)
|
||||
{
|
||||
if (ptr != nil)
|
||||
if (ptr != NULL)
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
@ -372,11 +368,10 @@ Nu_Free(NuArchive* pArchive, void* ptr)
|
|||
* If somebody internal wants to set doClose on a buffer DataSource
|
||||
* (looks like "Rename" does), we need to supply a "free" callback.
|
||||
*/
|
||||
NuResult
|
||||
Nu_InternalFreeCallback(NuArchive* pArchive, void* args)
|
||||
NuResult Nu_InternalFreeCallback(NuArchive* pArchive, void* args)
|
||||
{
|
||||
DBUG(("+++ internal free callback 0x%08lx\n", (long) args));
|
||||
Nu_Free(nil, args);
|
||||
Nu_Free(NULL, args);
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
NufxLib NOTES
|
||||
Last revised: 2000/01/23
|
||||
=============
|
||||
Last revised: 2015/01/04
|
||||
|
||||
|
||||
The interface is documented in "nufxlibapi.html", available from the
|
||||
www.nulib.com web site. This discusses some of the internal design that
|
||||
may be of interest.
|
||||
http://www.nulib.com/ web site. This discusses some of the internal
|
||||
design that may be of interest.
|
||||
|
||||
Some familiarity with the NuFX file format is assumed.
|
||||
|
||||
- - -
|
||||
|
||||
Read-Write Data Structures
|
||||
==========================
|
||||
### Read-Write Data Structures ###
|
||||
|
||||
For both read-only and read-write files (but not streaming read-only files),
|
||||
the archive is represented internally as a linked list of Records, each
|
||||
|
@ -64,15 +65,15 @@ threads are annotated in the "copy" list.)
|
|||
|
||||
One of the goals was to be able to execute a sequence of operations like:
|
||||
|
||||
- open original archive
|
||||
- read original archive
|
||||
- modify archive
|
||||
- flush (success)
|
||||
- modify archive
|
||||
- flush (failure, rollback)
|
||||
- modify archive
|
||||
- flush (success)
|
||||
- close archive
|
||||
open original archive
|
||||
read original archive
|
||||
modify archive
|
||||
flush (success)
|
||||
modify archive
|
||||
flush (failure, rollback)
|
||||
modify archive
|
||||
flush (success)
|
||||
close archive
|
||||
|
||||
The archive is opened at the start and held open across many operations.
|
||||
There is never a need to re-read the entire archive. We could avoid the
|
||||
|
@ -92,11 +93,11 @@ extraction are minimal.
|
|||
|
||||
In summary:
|
||||
|
||||
"orig" list has original set of records, and is not disturbed until
|
||||
- "orig" list has original set of records, and is not disturbed until
|
||||
the changes are committed.
|
||||
"copy" list is created on first add/update/delete operation, and
|
||||
- "copy" list is created on first add/update/delete operation, and
|
||||
initially contains a complete copy of "orig".
|
||||
"new" list contains all new additions to the archive, including
|
||||
- "new" list contains all new additions to the archive, including
|
||||
new additions that replace existing entries (the existing entry
|
||||
is deleted from "copy" and then added to "new").
|
||||
|
||||
|
@ -106,9 +107,9 @@ Any changes to the record header or additions to the thread mod list are
|
|||
made in the "copy" set; the "original" set remains untouched. The thread
|
||||
mod list can have the following items in it:
|
||||
|
||||
- delete thread (NuThreadIdx)
|
||||
- add thread (type, otherSize, format, +contents)
|
||||
- update pre-sized thread (NuThreadIdx, +contents)
|
||||
- delete thread (NuThreadIdx)
|
||||
- add thread (type, otherSize, format, +contents)
|
||||
- update pre-sized thread (NuThreadIdx, +contents)
|
||||
|
||||
Contents are specified with a NuDataSource, which allows the application
|
||||
to indicate that the data is already compressed. This is useful for
|
||||
|
@ -179,9 +180,9 @@ is possible that the archive could be unrecoverably damaged. NufxLib
|
|||
tries to identify such situations, and will leave the archive open in
|
||||
read-only mode after rolling back any new file additions.
|
||||
|
||||
- - -
|
||||
|
||||
Updating Filenames
|
||||
==================
|
||||
### Updating Filenames ###
|
||||
|
||||
Updating filenames is a small nightmare, because the filename can be
|
||||
either in the record header or in a filename thread. It's possible,
|
||||
|
@ -191,16 +192,148 @@ header and two or more filenames in threads.
|
|||
NufxLib will not automatically "fix" broken records, but it will prevent
|
||||
applications from creating situations that should not exist.
|
||||
|
||||
When reading an archive, NufxLib will use the filename from the
|
||||
- When reading an archive, NufxLib will use the filename from the
|
||||
first filename thread found. If no filename threads are found, the
|
||||
filename from the record header will be used.
|
||||
|
||||
If you add a filename thread to a record that has a filename in the
|
||||
- If you add a filename thread to a record that has a filename in the
|
||||
record header, the header name will be removed.
|
||||
|
||||
If you update a filename thread in a record that has a filename in
|
||||
- If you update a filename thread in a record that has a filename in
|
||||
the record header, the header name will be left untouched.
|
||||
|
||||
Adding a filename thread is only allowed if no filename thread exists,
|
||||
- Adding a filename thread is only allowed if no filename thread exists,
|
||||
or all existing filename threads have been deleted.
|
||||
|
||||
|
||||
- - -
|
||||
|
||||
### Unicode Filenames ###
|
||||
|
||||
Modern operating systems support filenames with a broader range of
|
||||
characters than the Apple II did. This presents problems and opportunities.
|
||||
|
||||
#### Background ####
|
||||
|
||||
The Apple IIgs and old Macintoshes use the Mac OS Roman ("MOR") character
|
||||
set. This defines a set of characters outside the ASCII range, i.e.
|
||||
byte values with the high bit set. In addition to the usual collection
|
||||
of vowels with accents and umlauts, MOR has some less-common characters,
|
||||
including the Apple logo.
|
||||
|
||||
On Windows, the high-ASCII values are generally interpreted according
|
||||
to Windows Code Page 1252 ("CP-1252"), which defines a similar set
|
||||
of vowels with accents and miscellaneous symbols. MOR and CP-1252
|
||||
have some overlap, but you can't really translate one into the other.
|
||||
The standards-approved equivalent of CP-1252 is ISO-8859-1, though
|
||||
according to [wikipedia](http://en.wikipedia.org/wiki/Windows-1252)
|
||||
there was some confusion between the two.
|
||||
|
||||
Modern operating systems support the Unicode Universal Character Set.
|
||||
This system allows for a very large number of characters (over a million),
|
||||
and includes definitions for all of the symbols in MOR and CP-1252.
|
||||
Each character is assigned a "code point", which is a numeric value between
|
||||
zero and 0x10FFFF. Most of the characters used in modern languages can
|
||||
be found in the Basic Multilingual Plane (BMP), which uses code points
|
||||
between zero and 0xFFFF (requiring only 16 bits).
|
||||
|
||||
There are different ways of encoding code points. Consider, for example,
|
||||
Unicode LATIN SMALL LETTER A WITH ACUTE:
|
||||
|
||||
MOR: 0x87
|
||||
CP-1252: 0xE1
|
||||
Unicode: U+00E1
|
||||
UTF-16: 0x00E1
|
||||
UTF-8: 0xC3 0xA1
|
||||
|
||||
Or the humble TRADE MARK SIGN:
|
||||
|
||||
MOR: 0xAA
|
||||
CP-1252: 0x99
|
||||
Unicode: U+2122
|
||||
UTF-16: 0x2122
|
||||
UTF-8: 0xE2 0x84 0xA2
|
||||
|
||||
Modern Linux and Mac OS X use UTF-8 encoding in filenames. Because it's a
|
||||
byte-oriented encoding, and 7-bit ASCII values are trivially represented
|
||||
as 7-bit ASCII values, all of the existing system and library calls work
|
||||
as they did before (i.e. if they took a `char*`, they still do).
|
||||
|
||||
Windows uses UTF-16, which requires at least 16 bits per code point.
|
||||
Filenames are now "wide" strings, based on `wchar_t*`. Windows includes
|
||||
an elaborate system of defines based around the `TCHAR` type, which can
|
||||
be either `char` or `wchar_t` depending on whether a program is compiled
|
||||
with `_MBCS` (Multi-Byte Character System) or `_UNICODE`. A set of
|
||||
preprocessor definitions is provided that will map I/O function names,
|
||||
so you can call `_tfopen(TCHAR* ...)`, and the compiler will turn it into
|
||||
either `fopen(char* ...)` or `_wfopen(wchar_t* ...)`. MBCS is deprecated
|
||||
in favor of Unicode, so any new code should be strictly UTF-16 based.
|
||||
|
||||
This means that, for code to work on both Linux and Windows, it has to
|
||||
work with incompatible filename string types and different I/O functions.
|
||||
|
||||
#### Opening Archive Files ####
|
||||
|
||||
On Linux and Mac OS X, NuLib2 can open any file named on the command line.
|
||||
On Windows, it's a bit trickier.
|
||||
|
||||
The problem is that NuLib2 provides a `main()` function that is passed a
|
||||
vector of "narrow" strings. The filenames provided on the command line
|
||||
will be converted from wide to narrow, so unless the filename is entirely
|
||||
composed of ASCII or CP-1252 characters, some information will be lost
|
||||
and it will be impossible to open the file.
|
||||
|
||||
NuLib2 must instead provide a `wmain()` function that takes wide strings.
|
||||
The strings must be stored and passed around as wide throughout the
|
||||
program, and passed into NufxLib this way (because NufxLib issues the
|
||||
actual _wopen call). This means that NufxLib API must take narrow strings
|
||||
when built for Linux, and wide strings when built for Windows.
|
||||
|
||||
#### Adding/Extracting Mac OS Roman Files ####
|
||||
|
||||
GS/ShrinkIt was designed to handle GS/OS files from HFS volumes, so NuFX
|
||||
archive filenames use the MOR character set. To preserve the encoding
|
||||
we could simply extract the values as-is and let them appear as whatever
|
||||
values happen to line up in CP-1252, which is what pre-3.0 NuLib2 did.
|
||||
It's much nicer to translate from MOR to Unicode when extracting, and
|
||||
convert back from Unicode to MOR when adding files to an archive.
|
||||
|
||||
The key consideration is that the character set associated with a
|
||||
filename must be tracked. The code can't simply extract a filename from
|
||||
the archive and pass it to a 'creat()` call. Character set conversions
|
||||
must take place at appropriate times.
|
||||
|
||||
With Windows it's a bit harder to confuse MOR and Unicode names, because
|
||||
one uses 8-bit characters and the other uses UTF-16, but the compiler
|
||||
doesn't catch everything.
|
||||
|
||||
#### Current State ####
|
||||
|
||||
NufxLib defines the UNICHAR type, which has a role very like TCHAR:
|
||||
it can be `char*` or `wchar_t*`, and can be accompanied by a set of
|
||||
preprocessor mappings that switch between I/O functions. The UNICHAR
|
||||
type will be determined based on a define provided from the compiler
|
||||
command line (perhaps `-DUSE_UTF16_FILENAMES`).
|
||||
|
||||
The current version of NufxLib (v3.0.0) takes the first step, defining
|
||||
all filename strings as either UNICHAR or MOR, and converting between them
|
||||
as necessary. This, plus a few minor tweaks to NuLib2, was enough to
|
||||
get Unicode filename support working on Linux and Mac OS X.
|
||||
|
||||
None of the work needed to make Windows work properly has been done.
|
||||
The string conversion functions are no-ops for Win32. As a result,
|
||||
NuLib2 for Windows treats filenames the same way in 3.x as it did in 2.x.
|
||||
|
||||
There are some situations where things can go awry even with UNICHAR,
|
||||
most notably printf-style arguments. These are checked by gcc, but
|
||||
not by Visual Studio unless you run the static analyzer. A simple
|
||||
`printf("filename=%s\n", filename)` would be correct for narrow strings
|
||||
but wrong for wide strings. It will likely be necessary to define a
|
||||
filename format string (similar to `PRI64d` for 64-bit values) and switch
|
||||
between "%s" and "%ls".
|
||||
|
||||
This is a fair bit of work and requires some amount of uglification to
|
||||
NuLib2 and NufxLib. Since Windows users can use CiderPress, and the
|
||||
vast majority of NuFX archives use ASCII-only ProDOS file names, it's
|
||||
not clear that the effort would be worthwhile.
|
||||
|
|
@ -6,10 +6,11 @@
|
|||
*
|
||||
* External interface (types, defines, and function prototypes).
|
||||
*/
|
||||
#ifndef __NufxLib__
|
||||
#define __NufxLib__
|
||||
#ifndef NUFXLIB_NUFXLIB_H
|
||||
#define NUFXLIB_NUFXLIB_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -31,9 +32,9 @@ extern "C" {
|
|||
* The "bug" version can usually be ignored, since it represents minor
|
||||
* fixes. Unless, of course, your code depends upon that fix.
|
||||
*/
|
||||
#define kNuVersionMajor 2
|
||||
#define kNuVersionMinor 2
|
||||
#define kNuVersionBug 2
|
||||
#define kNuVersionMajor 3
|
||||
#define kNuVersionMinor 1
|
||||
#define kNuVersionBug 0
|
||||
|
||||
|
||||
/*
|
||||
|
@ -42,6 +43,33 @@ extern "C" {
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unicode character type. For Linux and Mac OS X, filenames use "narrow"
|
||||
* characters and UTF-8 encoding, which allows them to use standard file I/O
|
||||
* functions like fopen(). Windows uses UTF-16, which requires a different
|
||||
* character type and an alternative set of I/O functions like _wfopen().
|
||||
*
|
||||
* The idea is that NufxLib API functions will operate on filenames with
|
||||
* the OS dominant method, so on Windows the API accepts UTF-16. This
|
||||
* definition is a bit like Windows TCHAR, but it's dependent on the OS, not
|
||||
* on whether _MBCS or _UNICODE is defined.
|
||||
*
|
||||
* The app can include "Unichar.h" to get definitions for functions that
|
||||
* switch between narrow and wide functions (e.g. "unistrlen()" becomes
|
||||
* strlen() or wcslen() as appropriate).
|
||||
*
|
||||
* We switch based on _WIN32, because we're not really switching on
|
||||
* filename-character size; the key issue is all the pesky wide I/O calls.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
// TODO: complete this
|
||||
//# include <wchar.h>
|
||||
//# define UNICHAR wchar_t
|
||||
# define UNICHAR char
|
||||
#else
|
||||
# define UNICHAR char
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Error values returned from functions.
|
||||
*
|
||||
|
@ -148,38 +176,41 @@ typedef enum NuResult {
|
|||
* NuRecordIdxs are assigned to records in an archive. You may assume that
|
||||
* the values are unique, but that is all.
|
||||
*/
|
||||
typedef unsigned long NuRecordIdx;
|
||||
typedef uint32_t NuRecordIdx;
|
||||
|
||||
/*
|
||||
* NuThreadIdxs are assigned to threads within a record. Again, you may
|
||||
* assume that the values are unique within a record, but that is all.
|
||||
*/
|
||||
typedef unsigned long NuThreadIdx;
|
||||
typedef uint32_t NuThreadIdx;
|
||||
|
||||
/*
|
||||
* Thread ID, a combination of thread_class and thread_kind. Standard
|
||||
* values have explicit identifiers.
|
||||
*/
|
||||
typedef unsigned long NuThreadID;
|
||||
typedef uint32_t NuThreadID;
|
||||
#define NuMakeThreadID(class, kind) /* construct a NuThreadID */ \
|
||||
((unsigned long)(class) << 16 | (unsigned long)(kind))
|
||||
((uint32_t)(class) << 16 | (uint32_t)(kind))
|
||||
#define NuGetThreadID(pThread) /* pull NuThreadID out of NuThread */ \
|
||||
(NuMakeThreadID((pThread)->thThreadClass, (pThread)->thThreadKind))
|
||||
#define NuThreadIDGetClass(threadID) /* get threadClass from NuThreadID */ \
|
||||
((unsigned short) ((unsigned long)(threadID) >> 16))
|
||||
((uint16_t) ((uint32_t)(threadID) >> 16))
|
||||
#define NuThreadIDGetKind(threadID) /* get threadKind from NuThreadID */ \
|
||||
((unsigned short) ((threadID) & 0xffff))
|
||||
((uint16_t) ((threadID) & 0xffff))
|
||||
#define kNuThreadClassMessage 0x0000
|
||||
#define kNuThreadClassControl 0x0001
|
||||
#define kNuThreadClassData 0x0002
|
||||
#define kNuThreadClassFilename 0x0003
|
||||
#define kNuThreadKindDataFork 0x0000 /* when class=data */
|
||||
#define kNuThreadKindDiskImage 0x0001 /* when class=data */
|
||||
#define kNuThreadKindRsrcFork 0x0002 /* when class=data */
|
||||
#define kNuThreadIDOldComment NuMakeThreadID(kNuThreadClassMessage, 0x0000)
|
||||
#define kNuThreadIDComment NuMakeThreadID(kNuThreadClassMessage, 0x0001)
|
||||
#define kNuThreadIDIcon NuMakeThreadID(kNuThreadClassMessage, 0x0002)
|
||||
#define kNuThreadIDMkdir NuMakeThreadID(kNuThreadClassControl, 0x0000)
|
||||
#define kNuThreadIDDataFork NuMakeThreadID(kNuThreadClassData, 0x0000)
|
||||
#define kNuThreadIDDiskImage NuMakeThreadID(kNuThreadClassData, 0x0001)
|
||||
#define kNuThreadIDRsrcFork NuMakeThreadID(kNuThreadClassData, 0x0002)
|
||||
#define kNuThreadIDDataFork NuMakeThreadID(kNuThreadClassData, kNuThreadKindDataFork)
|
||||
#define kNuThreadIDDiskImage NuMakeThreadID(kNuThreadClassData, kNuThreadKindDiskImage)
|
||||
#define kNuThreadIDRsrcFork NuMakeThreadID(kNuThreadClassData, kNuThreadKindRsrcFork)
|
||||
#define kNuThreadIDFilename NuMakeThreadID(kNuThreadClassFilename, 0x0000)
|
||||
#define kNuThreadIDWildcard NuMakeThreadID(0xffff, 0xffff)
|
||||
|
||||
|
@ -198,10 +229,10 @@ typedef enum NuThreadFormat {
|
|||
|
||||
/* extract the filesystem separator char from the "file_sys_info" field */
|
||||
#define NuGetSepFromSysInfo(sysInfo) \
|
||||
((char) ((sysInfo) & 0xff))
|
||||
((UNICHAR) ((sysInfo) & 0xff))
|
||||
/* return a file_sys_info with a replaced filesystem separator */
|
||||
#define NuSetSepInSysInfo(sysInfo, newSep) \
|
||||
((unsigned short) (((sysInfo) & 0xff00) | ((newSep) & 0xff)) )
|
||||
((uint16_t) (((sysInfo) & 0xff00) | ((newSep) & 0xff)) )
|
||||
|
||||
/* GS/OS-defined file system identifiers; sadly, UNIX is not among them */
|
||||
typedef enum NuFileSysID {
|
||||
|
@ -273,7 +304,7 @@ typedef enum NuValueID {
|
|||
kNuValueIgnoreLZW2Len = 14,
|
||||
kNuValueHandleBadMac = 15
|
||||
} NuValueID;
|
||||
typedef unsigned long NuValue;
|
||||
typedef uint32_t NuValue;
|
||||
|
||||
/*
|
||||
* Enumerated values for things you pass in a NuValue.
|
||||
|
@ -322,7 +353,7 @@ typedef enum NuAttrID {
|
|||
kNuAttrHeaderOffset = 3,
|
||||
kNuAttrJunkOffset = 4,
|
||||
} NuAttrID;
|
||||
typedef unsigned long NuAttr;
|
||||
typedef uint32_t NuAttr;
|
||||
|
||||
/*
|
||||
* Archive types.
|
||||
|
@ -381,14 +412,14 @@ typedef union NuDataSink NuDataSink; /* dummy def for internal struct */
|
|||
* NuFX Date/Time structure; same as TimeRec from IIgs "misctool.h".
|
||||
*/
|
||||
typedef struct NuDateTime {
|
||||
unsigned char second; /* 0-59 */
|
||||
unsigned char minute; /* 0-59 */
|
||||
unsigned char hour; /* 0-23 */
|
||||
unsigned char year; /* year - 1900 */
|
||||
unsigned char day; /* 0-30 */
|
||||
unsigned char month; /* 0-11 */
|
||||
unsigned char extra; /* (must be zero) */
|
||||
unsigned char weekDay; /* 1-7 (1=sunday) */
|
||||
uint8_t second; /* 0-59 */
|
||||
uint8_t minute; /* 0-59 */
|
||||
uint8_t hour; /* 0-23 */
|
||||
uint8_t year; /* year - 1900 */
|
||||
uint8_t day; /* 0-30 */
|
||||
uint8_t month; /* 0-11 */
|
||||
uint8_t extra; /* (must be zero) */
|
||||
uint8_t weekDay; /* 1-7 (1=sunday) */
|
||||
} NuDateTime;
|
||||
|
||||
/*
|
||||
|
@ -399,26 +430,30 @@ typedef struct NuDateTime {
|
|||
*/
|
||||
typedef struct NuThread {
|
||||
/* from the archive */
|
||||
unsigned short thThreadClass;
|
||||
NuThreadFormat thThreadFormat;
|
||||
unsigned short thThreadKind;
|
||||
unsigned short thThreadCRC; /* comp or uncomp data; see rec vers */
|
||||
unsigned long thThreadEOF;
|
||||
unsigned long thCompThreadEOF;
|
||||
uint16_t thThreadClass;
|
||||
NuThreadFormat thThreadFormat;
|
||||
uint16_t thThreadKind;
|
||||
uint16_t thThreadCRC; /* comp or uncomp data; see rec vers */
|
||||
uint32_t thThreadEOF;
|
||||
uint32_t thCompThreadEOF;
|
||||
|
||||
/* extra goodies */
|
||||
NuThreadIdx threadIdx;
|
||||
unsigned long actualThreadEOF; /* disk images might be off */
|
||||
long fileOffset; /* fseek offset to data in shk */
|
||||
NuThreadIdx threadIdx;
|
||||
uint32_t actualThreadEOF; /* disk images might be off */
|
||||
long fileOffset; /* fseek offset to data in shk */
|
||||
|
||||
/* internal use only */
|
||||
unsigned short used; /* mark as uninteresting */
|
||||
uint16_t used; /* mark as uninteresting */
|
||||
} NuThread;
|
||||
|
||||
/*
|
||||
* NuFX "record" definition.
|
||||
*
|
||||
* (Note to developers: update Nu_AddRecord if this changes.)
|
||||
*
|
||||
* The filenames are in Mac OS Roman format. It's arguable whether MOR
|
||||
* strings should be part of the interface at all. However, the API
|
||||
* pre-dates the inclusion of Unicode support, and I'm leaving it alone.
|
||||
*/
|
||||
#define kNufxIDLen 4 /* len of 'NuFX' with funky MSBs */
|
||||
#define kNuReasonableAttribCount 256
|
||||
|
@ -428,52 +463,52 @@ typedef struct NuThread {
|
|||
#define kNuOurRecordVersion 3 /* what we write */
|
||||
typedef struct NuRecord {
|
||||
/* version 0+ */
|
||||
unsigned char recNufxID[kNufxIDLen];
|
||||
unsigned short recHeaderCRC;
|
||||
unsigned short recAttribCount;
|
||||
unsigned short recVersionNumber;
|
||||
unsigned long recTotalThreads;
|
||||
NuFileSysID recFileSysID;
|
||||
unsigned short recFileSysInfo;
|
||||
unsigned long recAccess;
|
||||
unsigned long recFileType;
|
||||
unsigned long recExtraType;
|
||||
unsigned short recStorageType; /* NuStorage*,file_sys_block_size */
|
||||
NuDateTime recCreateWhen;
|
||||
NuDateTime recModWhen;
|
||||
NuDateTime recArchiveWhen;
|
||||
uint8_t recNufxID[kNufxIDLen];
|
||||
uint16_t recHeaderCRC;
|
||||
uint16_t recAttribCount;
|
||||
uint16_t recVersionNumber;
|
||||
uint32_t recTotalThreads;
|
||||
NuFileSysID recFileSysID;
|
||||
uint16_t recFileSysInfo;
|
||||
uint32_t recAccess;
|
||||
uint32_t recFileType;
|
||||
uint32_t recExtraType;
|
||||
uint16_t recStorageType; /* NuStorage*,file_sys_block_size */
|
||||
NuDateTime recCreateWhen;
|
||||
NuDateTime recModWhen;
|
||||
NuDateTime recArchiveWhen;
|
||||
|
||||
/* option lists only in version 1+ */
|
||||
unsigned short recOptionSize;
|
||||
unsigned char* recOptionList; /* NULL if v0 or recOptionSize==0 */
|
||||
uint16_t recOptionSize;
|
||||
uint8_t* recOptionList; /* NULL if v0 or recOptionSize==0 */
|
||||
|
||||
/* data specified by recAttribCount, not accounted for by option list */
|
||||
long extraCount;
|
||||
unsigned char* extraBytes;
|
||||
int32_t extraCount;
|
||||
uint8_t* extraBytes;
|
||||
|
||||
unsigned short recFilenameLength; /* usually zero */
|
||||
char* recFilename; /* doubles as disk volume_name */
|
||||
uint16_t recFilenameLength; /* usually zero */
|
||||
char* recFilenameMOR; /* doubles as disk volume_name */
|
||||
|
||||
/* extra goodies; "dirtyHeader" does not apply to anything below */
|
||||
NuRecordIdx recordIdx; /* session-unique record index */
|
||||
char* threadFilename; /* extracted from filename thread */
|
||||
char* newFilename; /* memorized during "add file" call */
|
||||
const char* filename; /* points at recFilen or threadFilen */
|
||||
unsigned long recHeaderLength; /* size of rec hdr, incl thread hdrs */
|
||||
unsigned long totalCompLength; /* total len of data in archive file */
|
||||
long fakeThreads; /* used by "MaskDataless" */
|
||||
int isBadMac; /* malformed "bad mac" header */
|
||||
NuRecordIdx recordIdx; /* session-unique record index */
|
||||
char* threadFilenameMOR; /* extracted from filename thread */
|
||||
char* newFilenameMOR; /* memorized during "add file" call */
|
||||
const char* filenameMOR; /* points at recFilen or threadFilen */
|
||||
uint32_t recHeaderLength; /* size of rec hdr, incl thread hdrs */
|
||||
uint32_t totalCompLength; /* total len of data in archive file */
|
||||
uint32_t fakeThreads; /* used by "MaskDataless" */
|
||||
int isBadMac; /* malformed "bad mac" header */
|
||||
|
||||
long fileOffset; /* file offset of record header */
|
||||
long fileOffset; /* file offset of record header */
|
||||
|
||||
/* use provided interface to access this */
|
||||
struct NuThread* pThreads; /* ptr to thread array */
|
||||
struct NuThread* pThreads; /* ptr to thread array */
|
||||
|
||||
/* private -- things the application shouldn't look at */
|
||||
struct NuRecord* pNext; /* used internally */
|
||||
NuThreadMod* pThreadMods; /* used internally */
|
||||
short dirtyHeader; /* set in "copy" when hdr fields uptd */
|
||||
short dropRecFilename; /* if set, we're dropping this name */
|
||||
struct NuRecord* pNext; /* used internally */
|
||||
NuThreadMod* pThreadMods; /* used internally */
|
||||
short dirtyHeader; /* set in "copy" when hdr fields uptd */
|
||||
short dropRecFilename; /* if set, we're dropping this name */
|
||||
} NuRecord;
|
||||
|
||||
/*
|
||||
|
@ -488,18 +523,18 @@ typedef struct NuRecord {
|
|||
#define kNuMaxMHVersion 2 /* max we can handle */
|
||||
#define kNuOurMHVersion 2 /* what we write */
|
||||
typedef struct NuMasterHeader {
|
||||
unsigned char mhNufileID[kNufileIDLen];
|
||||
unsigned short mhMasterCRC;
|
||||
unsigned long mhTotalRecords;
|
||||
NuDateTime mhArchiveCreateWhen;
|
||||
NuDateTime mhArchiveModWhen;
|
||||
unsigned short mhMasterVersion;
|
||||
unsigned char mhReserved1[kNufileMasterReserved1Len];
|
||||
unsigned long mhMasterEOF;
|
||||
unsigned char mhReserved2[kNufileMasterReserved2Len];
|
||||
uint8_t mhNufileID[kNufileIDLen];
|
||||
uint16_t mhMasterCRC;
|
||||
uint32_t mhTotalRecords;
|
||||
NuDateTime mhArchiveCreateWhen;
|
||||
NuDateTime mhArchiveModWhen;
|
||||
uint16_t mhMasterVersion;
|
||||
uint8_t mhReserved1[kNufileMasterReserved1Len];
|
||||
uint32_t mhMasterEOF;
|
||||
uint8_t mhReserved2[kNufileMasterReserved2Len];
|
||||
|
||||
/* private -- internal use only */
|
||||
short isValid;
|
||||
short isValid;
|
||||
} NuMasterHeader;
|
||||
|
||||
|
||||
|
@ -514,35 +549,40 @@ typedef struct NuMasterHeader {
|
|||
* a small subset of the full record.
|
||||
*/
|
||||
typedef struct NuRecordAttr {
|
||||
NuFileSysID fileSysID;
|
||||
/*unsigned short fileSysInfo;*/
|
||||
unsigned long access;
|
||||
unsigned long fileType;
|
||||
unsigned long extraType;
|
||||
NuDateTime createWhen;
|
||||
NuDateTime modWhen;
|
||||
NuDateTime archiveWhen;
|
||||
NuFileSysID fileSysID;
|
||||
/*uint16_t fileSysInfo;*/
|
||||
uint32_t access;
|
||||
uint32_t fileType;
|
||||
uint32_t extraType;
|
||||
NuDateTime createWhen;
|
||||
NuDateTime modWhen;
|
||||
NuDateTime archiveWhen;
|
||||
} NuRecordAttr;
|
||||
|
||||
/*
|
||||
* Some additional details about a file.
|
||||
*
|
||||
* Ideally (from an API cleanliness perspective) the storage name would
|
||||
* be passed around as UTF-8 and converted internally. Passing it as
|
||||
* MOR required fewer changes to the library, and allows us to avoid
|
||||
* having to deal with illegal characters.
|
||||
*/
|
||||
typedef struct NuFileDetails {
|
||||
/* used during AddFile call */
|
||||
NuThreadID threadID; /* data, rsrc, disk img? */
|
||||
const char* origName;
|
||||
NuThreadID threadID; /* data, rsrc, disk img? */
|
||||
const void* origName; /* arbitrary pointer, usually a string */
|
||||
|
||||
/* these go straight into the NuRecord */
|
||||
const char* storageName;
|
||||
NuFileSysID fileSysID;
|
||||
unsigned short fileSysInfo;
|
||||
unsigned long access;
|
||||
unsigned long fileType;
|
||||
unsigned long extraType;
|
||||
unsigned short storageType; /* use Unknown, or disk block size */
|
||||
NuDateTime createWhen;
|
||||
NuDateTime modWhen;
|
||||
NuDateTime archiveWhen;
|
||||
const char* storageNameMOR;
|
||||
NuFileSysID fileSysID;
|
||||
uint16_t fileSysInfo;
|
||||
uint32_t access;
|
||||
uint32_t fileType;
|
||||
uint32_t extraType;
|
||||
uint16_t storageType; /* use Unknown, or disk block size */
|
||||
NuDateTime createWhen;
|
||||
NuDateTime modWhen;
|
||||
NuDateTime archiveWhen;
|
||||
} NuFileDetails;
|
||||
|
||||
|
||||
|
@ -550,23 +590,23 @@ typedef struct NuFileDetails {
|
|||
* Passed into the SelectionFilter callback.
|
||||
*/
|
||||
typedef struct NuSelectionProposal {
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread;
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread;
|
||||
} NuSelectionProposal;
|
||||
|
||||
/*
|
||||
* Passed into the OutputPathnameFilter callback.
|
||||
*/
|
||||
typedef struct NuPathnameProposal {
|
||||
const char* pathname;
|
||||
char filenameSeparator;
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread;
|
||||
const UNICHAR* pathnameUNI;
|
||||
UNICHAR filenameSeparator;
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread;
|
||||
|
||||
const char* newPathname;
|
||||
unsigned char newFilenameSeparator;
|
||||
/*NuThreadID newStorage;*/
|
||||
NuDataSink* newDataSink;
|
||||
const UNICHAR* newPathnameUNI;
|
||||
UNICHAR newFilenameSeparator;
|
||||
/*NuThreadID newStorage;*/
|
||||
NuDataSink* newDataSink;
|
||||
} NuPathnameProposal;
|
||||
|
||||
|
||||
|
@ -598,7 +638,8 @@ typedef enum NuProgressState {
|
|||
} NuProgressState;
|
||||
|
||||
/*
|
||||
* Passed into the ProgressUpdater callback.
|
||||
* Passed into the ProgressUpdater callback. All pointers become
|
||||
* invalid when the callback returns.
|
||||
*
|
||||
* [ Thought for the day: add an optional flag that causes us to only
|
||||
* call the progressFunc when the "percentComplete" changes by more
|
||||
|
@ -606,36 +647,36 @@ typedef enum NuProgressState {
|
|||
*/
|
||||
typedef struct NuProgressData {
|
||||
/* what are we doing */
|
||||
NuOperation operation;
|
||||
NuOperation operation;
|
||||
/* what specifically are we doing */
|
||||
NuProgressState state;
|
||||
NuProgressState state;
|
||||
/* how far along are we */
|
||||
short percentComplete; /* 0-100 */
|
||||
short percentComplete; /* 0-100 */
|
||||
|
||||
/* original pathname (in archive for expand, on disk for compress) */
|
||||
const char* origPathname;
|
||||
const UNICHAR* origPathnameUNI;
|
||||
/* processed pathname (PathnameFilter for expand, in-record for compress) */
|
||||
const char* pathname;
|
||||
/* basename of "pathname" */
|
||||
const char* filename;
|
||||
const UNICHAR* pathnameUNI;
|
||||
/* basename of "pathname" (for convenience) */
|
||||
const UNICHAR* filenameUNI;
|
||||
/* pointer to the record we're expanding from */
|
||||
const NuRecord* pRecord;
|
||||
const NuRecord* pRecord;
|
||||
|
||||
unsigned long uncompressedLength; /* size of uncompressed data */
|
||||
unsigned long uncompressedProgress; /* #of bytes in/out */
|
||||
uint32_t uncompressedLength; /* size of uncompressed data */
|
||||
uint32_t uncompressedProgress; /* #of bytes in/out */
|
||||
|
||||
struct {
|
||||
NuThreadFormat threadFormat; /* compression being applied */
|
||||
NuThreadFormat threadFormat; /* compression being applied */
|
||||
} compress;
|
||||
|
||||
struct {
|
||||
unsigned long totalCompressedLength; /* all "data" threads */
|
||||
unsigned long totalUncompressedLength;
|
||||
uint32_t totalCompressedLength; /* all "data" threads */
|
||||
uint32_t totalUncompressedLength;
|
||||
|
||||
/*unsigned long compressedLength; * size of compressed data */
|
||||
/*unsigned long compressedProgress; * #of compressed bytes in/out*/
|
||||
const NuThread* pThread; /* thread we're working on */
|
||||
NuValue convertEOL; /* set if LF/CR conv is on */
|
||||
/*uint32_t compressedLength; * size of compressed data */
|
||||
/*uint32_t compressedProgress; * #of compressed bytes in/out*/
|
||||
const NuThread* pThread; /* thread we're working on */
|
||||
NuValue convertEOL; /* set if LF/CR conv is on */
|
||||
} expand;
|
||||
|
||||
/* pay no attention */
|
||||
|
@ -649,11 +690,11 @@ typedef struct NuErrorStatus {
|
|||
NuOperation operation; /* were we adding, extracting, ?? */
|
||||
NuError err; /* library error code */
|
||||
int sysErr; /* system error code, if applicable */
|
||||
const char* message; /* (optional) message to user */
|
||||
const UNICHAR* message; /* (optional) message to user */
|
||||
const NuRecord* pRecord; /* relevant record, if any */
|
||||
const char* pathname; /* problematic pathname, if any */
|
||||
const char* origPathname; /* original pathname, if any */
|
||||
char filenameSeparator; /* fssep for pathname, if any */
|
||||
const UNICHAR* pathnameUNI; /* problematic pathname, if any */
|
||||
const void* origPathname; /* original pathname ref, if any */
|
||||
UNICHAR filenameSeparator; /* fssep for pathname, if any */
|
||||
/*char origArchiveTouched;*/
|
||||
|
||||
char canAbort; /* give option to abort */
|
||||
|
@ -669,14 +710,14 @@ typedef struct NuErrorStatus {
|
|||
* Error message callback gets one of these.
|
||||
*/
|
||||
typedef struct NuErrorMessage {
|
||||
const char* message; /* the message itself */
|
||||
const char* message; /* the message itself (UTF-8) */
|
||||
NuError err; /* relevant error code (may be none) */
|
||||
short isDebug; /* set for debug-only messages */
|
||||
|
||||
/* these identify where the message originated if lib built w/debug set */
|
||||
const char* file; /* source file */
|
||||
const char* file; /* source file (UTF-8) */
|
||||
int line; /* line number */
|
||||
const char* function; /* function name (might be nil) */
|
||||
const char* function; /* function name (might be NULL) */
|
||||
} NuErrorMessage;
|
||||
|
||||
|
||||
|
@ -727,37 +768,38 @@ NUFXLIB_API NuError NuExtract(NuArchive* pArchive);
|
|||
NUFXLIB_API NuError NuTest(NuArchive* pArchive);
|
||||
|
||||
/* strictly non-streaming read-only interfaces */
|
||||
NUFXLIB_API NuError NuOpenRO(const char* archivePathname,NuArchive** ppArchive);
|
||||
NUFXLIB_API NuError NuOpenRO(const UNICHAR* archivePathnameUNI,
|
||||
NuArchive** ppArchive);
|
||||
NUFXLIB_API NuError NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx);
|
||||
NUFXLIB_API NuError NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuDataSink* pDataSink);
|
||||
NUFXLIB_API NuError NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx);
|
||||
NUFXLIB_API NuError NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const NuRecord** ppRecord);
|
||||
NUFXLIB_API NuError NuGetRecordIdxByName(NuArchive* pArchive, const char* name,
|
||||
NuRecordIdx* pRecordIdx);
|
||||
NUFXLIB_API NuError NuGetRecordIdxByName(NuArchive* pArchive,
|
||||
const char* nameMOR, NuRecordIdx* pRecordIdx);
|
||||
NUFXLIB_API NuError NuGetRecordIdxByPosition(NuArchive* pArchive,
|
||||
unsigned long position, NuRecordIdx* pRecordIdx);
|
||||
uint32_t position, NuRecordIdx* pRecordIdx);
|
||||
|
||||
/* read/write interfaces */
|
||||
NUFXLIB_API NuError NuOpenRW(const char* archivePathname,
|
||||
const char* tempPathname, unsigned long flags,
|
||||
NUFXLIB_API NuError NuOpenRW(const UNICHAR* archivePathnameUNI,
|
||||
const UNICHAR* tempPathnameUNI, uint32_t flags,
|
||||
NuArchive** ppArchive);
|
||||
NUFXLIB_API NuError NuFlush(NuArchive* pArchive, long* pStatusFlags);
|
||||
NUFXLIB_API NuError NuFlush(NuArchive* pArchive, uint32_t* pStatusFlags);
|
||||
NUFXLIB_API NuError NuAddRecord(NuArchive* pArchive,
|
||||
const NuFileDetails* pFileDetails, NuRecordIdx* pRecordIdx);
|
||||
NUFXLIB_API NuError NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
NuThreadID threadID, NuDataSource* pDataSource,
|
||||
NuThreadIdx* pThreadIdx);
|
||||
NUFXLIB_API NuError NuAddFile(NuArchive* pArchive, const char* pathname,
|
||||
NUFXLIB_API NuError NuAddFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
|
||||
const NuFileDetails* pFileDetails, short fromRsrcFork,
|
||||
NuRecordIdx* pRecordIdx);
|
||||
NUFXLIB_API NuError NuRename(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const char* pathname, char fssep);
|
||||
const char* pathnameMOR, char fssep);
|
||||
NUFXLIB_API NuError NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const NuRecordAttr* pRecordAttr);
|
||||
NUFXLIB_API NuError NuUpdatePresizedThread(NuArchive* pArchive,
|
||||
NuThreadIdx threadIdx, NuDataSource* pDataSource, long* pMaxLen);
|
||||
NuThreadIdx threadIdx, NuDataSource* pDataSource, int32_t* pMaxLen);
|
||||
NUFXLIB_API NuError NuDelete(NuArchive* pArchive);
|
||||
NUFXLIB_API NuError NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx);
|
||||
NUFXLIB_API NuError NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx);
|
||||
|
@ -779,31 +821,31 @@ NUFXLIB_API NuError NuDebugDumpArchive(NuArchive* pArchive);
|
|||
|
||||
/* sources and sinks */
|
||||
NUFXLIB_API NuError NuCreateDataSourceForFile(NuThreadFormat threadFormat,
|
||||
unsigned long otherLen, const char* pathname,
|
||||
uint32_t otherLen, const UNICHAR* pathnameUNI,
|
||||
short isFromRsrcFork, NuDataSource** ppDataSource);
|
||||
NUFXLIB_API NuError NuCreateDataSourceForFP(NuThreadFormat threadFormat,
|
||||
unsigned long otherLen, FILE* fp, long offset, long length,
|
||||
uint32_t otherLen, FILE* fp, long offset, long length,
|
||||
NuCallback closeFunc, NuDataSource** ppDataSource);
|
||||
NUFXLIB_API NuError NuCreateDataSourceForBuffer(NuThreadFormat threadFormat,
|
||||
unsigned long otherLen, const unsigned char* buffer, long offset,
|
||||
uint32_t otherLen, const uint8_t* buffer, long offset,
|
||||
long length, NuCallback freeFunc, NuDataSource** ppDataSource);
|
||||
NUFXLIB_API NuError NuFreeDataSource(NuDataSource* pDataSource);
|
||||
NUFXLIB_API NuError NuDataSourceSetRawCrc(NuDataSource* pDataSource,
|
||||
unsigned short crc);
|
||||
uint16_t crc);
|
||||
NUFXLIB_API NuError NuCreateDataSinkForFile(short doExpand, NuValue convertEOL,
|
||||
const char* pathname, char fssep, NuDataSink** ppDataSink);
|
||||
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink);
|
||||
NUFXLIB_API NuError NuCreateDataSinkForFP(short doExpand, NuValue convertEOL,
|
||||
FILE* fp, NuDataSink** ppDataSink);
|
||||
NUFXLIB_API NuError NuCreateDataSinkForBuffer(short doExpand,
|
||||
NuValue convertEOL, unsigned char* buffer, unsigned long bufLen,
|
||||
NuValue convertEOL, uint8_t* buffer, uint32_t bufLen,
|
||||
NuDataSink** ppDataSink);
|
||||
NUFXLIB_API NuError NuFreeDataSink(NuDataSink* pDataSink);
|
||||
NUFXLIB_API NuError NuDataSinkGetOutCount(NuDataSink* pDataSink,
|
||||
unsigned long* pOutCount);
|
||||
uint32_t* pOutCount);
|
||||
|
||||
/* miscellaneous non-archive operations */
|
||||
NUFXLIB_API NuError NuGetVersion(long* pMajorVersion, long* pMinorVersion,
|
||||
long* pBugVersion, const char** ppBuildDate,
|
||||
NUFXLIB_API NuError NuGetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
|
||||
int32_t* pBugVersion, const char** ppBuildDate,
|
||||
const char** ppBuildFlags);
|
||||
NUFXLIB_API const char* NuStrError(NuError err);
|
||||
NUFXLIB_API NuError NuTestFeature(NuFeature feature);
|
||||
|
@ -811,13 +853,18 @@ NUFXLIB_API void NuRecordCopyAttr(NuRecordAttr* pRecordAttr,
|
|||
const NuRecord* pRecord);
|
||||
NUFXLIB_API NuError NuRecordCopyThreads(const NuRecord* pRecord,
|
||||
NuThread** ppThreads);
|
||||
NUFXLIB_API unsigned long NuRecordGetNumThreads(const NuRecord* pRecord);
|
||||
NUFXLIB_API const NuThread* NuThreadGetByIdx(const NuThread* pThread, long idx);
|
||||
NUFXLIB_API uint32_t NuRecordGetNumThreads(const NuRecord* pRecord);
|
||||
NUFXLIB_API const NuThread* NuThreadGetByIdx(const NuThread* pThread,
|
||||
int32_t idx);
|
||||
NUFXLIB_API short NuIsPresizedThreadID(NuThreadID threadID);
|
||||
NUFXLIB_API size_t NuConvertMORToUNI(const char* stringMOR,
|
||||
UNICHAR* bufUNI, size_t bufSize);
|
||||
NUFXLIB_API size_t NuConvertUNIToMOR(const UNICHAR* stringUNI,
|
||||
char* bufMOR, size_t bufSize);
|
||||
|
||||
#define NuGetThread(pRecord, idx) ( (const NuThread*) \
|
||||
((unsigned long) (idx) < (unsigned long) (pRecord)->recTotalThreads ? \
|
||||
&(pRecord)->pThreads[(idx)] : NULL) \
|
||||
#define NuGetThread(pRecord, idx) ( (const NuThread*) \
|
||||
((uint32_t) (idx) < (pRecord)->recTotalThreads ? \
|
||||
&(pRecord)->pThreads[(idx)] : NULL) \
|
||||
)
|
||||
|
||||
|
||||
|
@ -840,4 +887,4 @@ NUFXLIB_API NuCallback NuSetGlobalErrorMessageHandler(NuCallback messageHandlerF
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /*__NufxLib__*/
|
||||
#endif /*NUFXLIB_NUFXLIB_H*/
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*
|
||||
* Global internal declarations and definitions.
|
||||
*/
|
||||
#ifndef __NufxLibPriv__
|
||||
#define __NufxLibPriv__
|
||||
#ifndef NUFXLIB_NUFXLIBPRIV_H
|
||||
#define NUFXLIB_NUFXLIBPRIV_H
|
||||
|
||||
/* include files that everybody needs */
|
||||
#include "SysDefs.h"
|
||||
|
@ -86,7 +86,7 @@ typedef enum NuOpenMode {
|
|||
*/
|
||||
typedef struct NuRecordSet {
|
||||
Boolean loaded;
|
||||
ulong numRecords;
|
||||
uint32_t numRecords;
|
||||
NuRecord* nuRecordHead;
|
||||
NuRecord* nuRecordTail;
|
||||
} NuRecordSet;
|
||||
|
@ -95,12 +95,12 @@ typedef struct NuRecordSet {
|
|||
* Archive state.
|
||||
*/
|
||||
struct NuArchive {
|
||||
ulong structMagic;
|
||||
uint32_t structMagic;
|
||||
Boolean busy;
|
||||
|
||||
NuOpenMode openMode;
|
||||
Boolean newlyCreated;
|
||||
char* archivePathname; /* pathname or "(stream)" */
|
||||
UNICHAR* archivePathnameUNI; /* pathname or "(stream)" */
|
||||
FILE* archiveFp;
|
||||
NuArchiveType archiveType;
|
||||
|
||||
|
@ -108,7 +108,7 @@ struct NuArchive {
|
|||
long junkOffset; /* skip past leading junk */
|
||||
long headerOffset; /* adjustment for BXY/SEA/BSE */
|
||||
|
||||
char* tmpPathname; /* temp file, for writes */
|
||||
UNICHAR* tmpPathnameUNI; /* temp file, for writes */
|
||||
FILE* tmpFp;
|
||||
|
||||
/* used during initial processing; helps avoid ftell() calls */
|
||||
|
@ -118,9 +118,9 @@ struct NuArchive {
|
|||
Boolean testMode;
|
||||
|
||||
/* clumsy way of remembering name used for other fork in forked file */
|
||||
const char* lastFileCreated;
|
||||
const UNICHAR* lastFileCreatedUNI;
|
||||
/* clumsy way to avoid trying to create the same subdir several times */
|
||||
const char* lastDirCreated;
|
||||
const UNICHAR* lastDirCreatedUNI;
|
||||
|
||||
/* master header from the archive */
|
||||
NuMasterHeader masterHeader; /* original */
|
||||
|
@ -135,7 +135,7 @@ struct NuArchive {
|
|||
NuRecordSet newRecordSet; /* newly-added records */
|
||||
|
||||
/* state for compression functions */
|
||||
uchar* compBuf; /* large general-purpose buffer */
|
||||
uint8_t* compBuf; /* large general-purpose buffer */
|
||||
void* lzwCompressState; /* state for LZW/1 and LZW/2 */
|
||||
void* lzwExpandState; /* state for LZW/1 and LZW/2 */
|
||||
|
||||
|
@ -169,7 +169,7 @@ struct NuArchive {
|
|||
|
||||
#define kNuArchiveStructMagic 0xc0edbabe
|
||||
|
||||
#define kNuDefaultRecordName "UNKNOWN"
|
||||
#define kNuDefaultRecordName "UNKNOWN" /* use ASCII charset */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -256,7 +256,7 @@ struct NuThreadMod {
|
|||
*/
|
||||
typedef struct NuFunnel {
|
||||
/* data storage */
|
||||
uchar* buffer; /* kNuFunnelBufSize worth of storage */
|
||||
uint8_t* buffer; /* kNuFunnelBufSize worth of storage */
|
||||
long bufCount; /* #of bytes in buffer */
|
||||
|
||||
/* text conversion; if "auto", on first flush we convert to "on" or "off" */
|
||||
|
@ -270,10 +270,10 @@ typedef struct NuFunnel {
|
|||
Boolean isFirstWrite; /* cleared on first write */
|
||||
|
||||
#if 0
|
||||
ulong inCount; /* total #of bytes in the top */
|
||||
ulong outCount; /* total #of bytes out the bottom */
|
||||
uint32_t inCount; /* total #of bytes in the top */
|
||||
uint32_t outCount; /* total #of bytes out the bottom */
|
||||
|
||||
ulong outMax; /* flag an err when outCount exceeds this */
|
||||
uint32_t outMax; /* flag an err when outCount exceeds this */
|
||||
Boolean outMaxExceeded; /* in fact, it's this flag */
|
||||
#endif
|
||||
|
||||
|
@ -302,11 +302,11 @@ typedef struct NuStraw {
|
|||
NuDataSource* pDataSource;
|
||||
|
||||
/* progress update fields */
|
||||
ulong lastProgress;
|
||||
ulong lastDisplayed;
|
||||
uint32_t lastProgress;
|
||||
uint32_t lastDisplayed;
|
||||
} NuStraw;
|
||||
|
||||
/*NuError Nu_CopyStreamToStream(FILE* outfp, FILE* infp, ulong count);*/
|
||||
/*NuError Nu_CopyStreamToStream(FILE* outfp, FILE* infp, uint32_t count);*/
|
||||
|
||||
|
||||
/*
|
||||
|
@ -329,10 +329,10 @@ typedef enum NuDataSourceType {
|
|||
typedef struct NuDataSourceCommon {
|
||||
NuDataSourceType sourceType;
|
||||
NuThreadFormat threadFormat; /* is it already compressed? */
|
||||
ushort rawCrc; /* crc for already-compressed data*/
|
||||
uint16_t rawCrc; /* crc for already-compressed data*/
|
||||
/*Boolean doClose; \* close on completion? */
|
||||
ulong dataLen; /* length of data (var for buf) */
|
||||
ulong otherLen; /* uncomp len or preset buf size */
|
||||
uint32_t dataLen; /* length of data (var for buf) */
|
||||
uint32_t otherLen; /* uncomp len or preset buf size */
|
||||
int refCount; /* so we can copy structs */
|
||||
} NuDataSourceCommon;
|
||||
|
||||
|
@ -343,7 +343,7 @@ union NuDataSource {
|
|||
|
||||
struct {
|
||||
NuDataSourceCommon common;
|
||||
char* pathname;
|
||||
UNICHAR* pathnameUNI;
|
||||
Boolean fromRsrcFork;
|
||||
|
||||
/* temp storage; only valid when processing in library */
|
||||
|
@ -360,7 +360,7 @@ union NuDataSource {
|
|||
|
||||
struct {
|
||||
NuDataSourceCommon common;
|
||||
const uchar* buffer; /* non-const if doClose=true */
|
||||
const uint8_t* buffer; /* non-const if doClose=true */
|
||||
long offset; /* starting offset */
|
||||
|
||||
long curOffset; /* current offset */
|
||||
|
@ -387,7 +387,7 @@ typedef struct NuDataSinkCommon {
|
|||
NuDataSinkType sinkType;
|
||||
Boolean doExpand; /* expand file? */
|
||||
NuValue convertEOL; /* convert EOL? (req "expand") */
|
||||
ulong outCount;
|
||||
uint32_t outCount;
|
||||
} NuDataSinkCommon;
|
||||
|
||||
union NuDataSink {
|
||||
|
@ -397,10 +397,10 @@ union NuDataSink {
|
|||
|
||||
struct {
|
||||
NuDataSinkCommon common;
|
||||
char* pathname; /* file to open */
|
||||
char fssep;
|
||||
UNICHAR* pathnameUNI; /* file to open */
|
||||
UNICHAR fssep;
|
||||
|
||||
/* temp storage; must be nil except when processing in library */
|
||||
/* temp storage; must be NULL except when processing in library */
|
||||
FILE* fp;
|
||||
} toFile;
|
||||
|
||||
|
@ -411,8 +411,8 @@ union NuDataSink {
|
|||
|
||||
struct {
|
||||
NuDataSinkCommon common;
|
||||
uchar* buffer;
|
||||
ulong bufLen; /* max amount of data "buffer" holds */
|
||||
uint8_t* buffer;
|
||||
uint32_t bufLen; /* max amount of data "buffer" holds */
|
||||
NuError stickyErr;
|
||||
} toBuffer;
|
||||
};
|
||||
|
@ -429,25 +429,25 @@ union NuDataSink {
|
|||
* the first arguments to Nu_ReportError, so we don't have to type them
|
||||
* in every time we use the function. It would've been much easier to
|
||||
* use a gcc-style varargs macro, but not everybody uses gcc.
|
||||
*
|
||||
* TODO: Visual C++ has vararg macros now; time to replace this.
|
||||
*/
|
||||
#ifdef DEBUG_MSGS
|
||||
#ifdef HAS__FUNCTION__
|
||||
#define _FUNCTION_ __FUNCTION__
|
||||
#else
|
||||
#define _FUNCTION_ ""
|
||||
#endif
|
||||
#ifdef HAS__FUNCTION__
|
||||
# define _FUNCTION_ __FUNCTION__
|
||||
#else
|
||||
# define _FUNCTION_ ""
|
||||
#endif
|
||||
|
||||
#define NU_BLOB pArchive, __FILE__, __LINE__, _FUNCTION_, false
|
||||
#define NU_BLOB_DEBUG pArchive, __FILE__, __LINE__, _FUNCTION_, true
|
||||
#define NU_NILBLOB NULL, __FILE__, __LINE__, _FUNCTION_, false
|
||||
#define DebugShowError(err) \
|
||||
#define NU_BLOB pArchive, __FILE__, __LINE__, _FUNCTION_, false
|
||||
#define NU_BLOB_DEBUG pArchive, __FILE__, __LINE__, _FUNCTION_, true
|
||||
#define NU_NILBLOB NULL, __FILE__, __LINE__, _FUNCTION_, false
|
||||
|
||||
#ifdef DEBUG_MSGS
|
||||
# define DebugShowError(err) \
|
||||
Nu_ReportError(pArchive, __FILE__, __LINE__, _FUNCTION_, \
|
||||
true, err, "(DEBUG)");
|
||||
#else
|
||||
#define NU_BLOB pArchive, "", 0, "", false
|
||||
#define NU_BLOB_DEBUG pArchive, "", 0, "", true
|
||||
#define NU_NILBLOB NULL, "", 0, "", false
|
||||
#define DebugShowError(err) ((void)0)
|
||||
# define DebugShowError(err) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -469,13 +469,13 @@ union NuDataSink {
|
|||
goto bail; \
|
||||
}
|
||||
#define BailNil(val) { \
|
||||
if ((val) == nil) { \
|
||||
if ((val) == NULL) { \
|
||||
err = kNuErrUnexpectedNil; \
|
||||
BailError(err); \
|
||||
} \
|
||||
}
|
||||
#define BailAlloc(val) { \
|
||||
if ((val) == nil) { \
|
||||
if ((val) == NULL) { \
|
||||
err = kNuErrMalloc; \
|
||||
BailError(err); \
|
||||
} \
|
||||
|
@ -498,9 +498,9 @@ NuError Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp);
|
|||
NuError Nu_AdjustWrapperPadding(NuArchive* pArchive, FILE* fp);
|
||||
NuError Nu_AllocCompressionBufferIFN(NuArchive* pArchive);
|
||||
NuError Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive);
|
||||
NuError Nu_OpenRO(const char* filename, NuArchive** ppArchive);
|
||||
NuError Nu_OpenRW(const char* archivePathname, const char* tempPathname,
|
||||
ulong flags, NuArchive** ppArchive);
|
||||
NuError Nu_OpenRO(const UNICHAR* archivePathnameUNI, NuArchive** ppArchive);
|
||||
NuError Nu_OpenRW(const UNICHAR* archivePathnameUNI,
|
||||
const UNICHAR* tempPathnameUNI, uint32_t flags, NuArchive** ppArchive);
|
||||
NuError Nu_WriteMasterHeader(NuArchive* pArchive, FILE* fp,
|
||||
NuMasterHeader* pMasterHeader);
|
||||
NuError Nu_Close(NuArchive* pArchive);
|
||||
|
@ -509,28 +509,28 @@ NuError Nu_RenameTempToArchive(NuArchive* pArchive);
|
|||
NuError Nu_DeleteArchiveFile(NuArchive* pArchive);
|
||||
|
||||
/* ArchiveIO.c */
|
||||
uchar Nu_ReadOneC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
|
||||
uchar Nu_ReadOne(NuArchive* pArchive, FILE* fp);
|
||||
void Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uchar val, ushort* pCrc);
|
||||
void Nu_WriteOne(NuArchive* pArchive, FILE* fp, uchar val);
|
||||
ushort Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
|
||||
ushort Nu_ReadTwo(NuArchive* pArchive, FILE* fp);
|
||||
void Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, ushort val, ushort* pCrc);
|
||||
void Nu_WriteTwo(NuArchive* pArchive, FILE* fp, ushort val);
|
||||
ulong Nu_ReadFourC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
|
||||
ulong Nu_ReadFour(NuArchive* pArchive, FILE* fp);
|
||||
void Nu_WriteFourC(NuArchive* pArchive, FILE* fp, ulong val, ushort* pCrc);
|
||||
void Nu_WriteFour(NuArchive* pArchive, FILE* fp, ulong val);
|
||||
NuDateTime Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
|
||||
NuDateTime Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, ushort* pCrc);
|
||||
uint8_t Nu_ReadOneC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
|
||||
uint8_t Nu_ReadOne(NuArchive* pArchive, FILE* fp);
|
||||
void Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uint8_t val, uint16_t* pCrc);
|
||||
void Nu_WriteOne(NuArchive* pArchive, FILE* fp, uint8_t val);
|
||||
uint16_t Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
|
||||
uint16_t Nu_ReadTwo(NuArchive* pArchive, FILE* fp);
|
||||
void Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, uint16_t val, uint16_t* pCrc);
|
||||
void Nu_WriteTwo(NuArchive* pArchive, FILE* fp, uint16_t val);
|
||||
uint32_t Nu_ReadFourC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
|
||||
uint32_t Nu_ReadFour(NuArchive* pArchive, FILE* fp);
|
||||
void Nu_WriteFourC(NuArchive* pArchive, FILE* fp, uint32_t val, uint16_t* pCrc);
|
||||
void Nu_WriteFour(NuArchive* pArchive, FILE* fp, uint32_t val);
|
||||
NuDateTime Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
|
||||
NuDateTime Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
|
||||
void Nu_WriteDateTimeC(NuArchive* pArchive, FILE* fp, NuDateTime dateTime,
|
||||
ushort* pCrc);
|
||||
uint16_t* pCrc);
|
||||
void Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime);
|
||||
void Nu_ReadBytesC(NuArchive* pArchive, FILE* fp, void* vbuffer, long count,
|
||||
ushort* pCrc);
|
||||
uint16_t* pCrc);
|
||||
void Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count);
|
||||
void Nu_WriteBytesC(NuArchive* pArchive, FILE* fp, const void* vbuffer,
|
||||
long count, ushort* pCrc);
|
||||
long count, uint16_t* pCrc);
|
||||
void Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer,
|
||||
long count);
|
||||
NuError Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp);
|
||||
|
@ -540,9 +540,16 @@ NuError Nu_RewindArchive(NuArchive* pArchive);
|
|||
|
||||
/* Bzip2.c */
|
||||
NuError Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
|
||||
NuError Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
|
||||
|
||||
/* Charset.c */
|
||||
size_t Nu_ConvertMORToUNI(const char* stringMOR, UNICHAR* bufUNI,
|
||||
size_t bufSize);
|
||||
UNICHAR* Nu_CopyMORToUNI(const char* stringMOR);
|
||||
size_t Nu_ConvertUNIToMOR(const UNICHAR* stringUNI, char* bufMOR,
|
||||
size_t bufSize);
|
||||
|
||||
/* Compress.c */
|
||||
NuError Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||
|
@ -554,22 +561,17 @@ NuError Nu_CopyPresizedToArchive(NuArchive* pArchive,
|
|||
NuThread* pThread, char** ppSavedCopy);
|
||||
|
||||
/* Crc16.c */
|
||||
extern const ushort gNuCrc16Table[256];
|
||||
ushort Nu_CalcCRC16(ushort seed, const uchar* ptr, int count);
|
||||
#ifdef __Crc16_c__ /* just doing "static inline" warns def-but-not-used */
|
||||
#define CRC_INLINE /**/
|
||||
#else
|
||||
#define CRC_INLINE extern inline
|
||||
#endif
|
||||
#if defined(inline) && !defined(__Crc16_c__) /* somebody ovrd inline def? */
|
||||
ushort Nu_UpdateCRC16(uchar val, ushort crc);
|
||||
#else
|
||||
CRC_INLINE ushort
|
||||
Nu_UpdateCRC16(uchar val, ushort crc)
|
||||
{
|
||||
return (gNuCrc16Table[((crc >> 8) & 0xFF) ^ val] ^ (crc << 8)) & 0xFFFF;
|
||||
}
|
||||
#endif
|
||||
extern const uint16_t gNuCrc16Table[256];
|
||||
uint16_t Nu_CalcCRC16(uint16_t seed, const uint8_t* ptr, int count);
|
||||
/*
|
||||
* Update the CRC-16.
|
||||
*
|
||||
* _val (uint8_t) is the byte to add to the CRC. It's evaluated once.
|
||||
* _crc (uint16_t) is the previous CRC. It's evaluated twice.
|
||||
* Returns the updated CRC as a uint16_t.
|
||||
*/
|
||||
#define Nu_UpdateCRC16(_val, _crc) \
|
||||
(gNuCrc16Table[(((_crc) >> 8) & 0xff) ^ (_val)] ^ ((_crc) << 8))
|
||||
|
||||
/* Debug.c */
|
||||
#if defined(DEBUG_MSGS) || !defined(NDEBUG)
|
||||
|
@ -591,13 +593,13 @@ NuError Nu_ThreadModAdd_FindByThreadID(const NuRecord* pRecord,
|
|||
void Nu_FreeThreadMods(NuArchive* pArchive, NuRecord* pRecord);
|
||||
NuThreadMod* Nu_ThreadMod_FindByThreadIdx(const NuRecord* pRecord,
|
||||
NuThreadIdx threadIdx);
|
||||
NuError Nu_Flush(NuArchive* pArchive, long* pStatusFlags);
|
||||
NuError Nu_Flush(NuArchive* pArchive, uint32_t* pStatusFlags);
|
||||
|
||||
/* Deflate.c */
|
||||
NuError Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
|
||||
NuError Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
|
||||
|
||||
/* Expand.c */
|
||||
NuError Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
|
@ -607,14 +609,14 @@ NuError Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
void Nu_SetCurrentDateTime(NuDateTime* pDateTime);
|
||||
Boolean Nu_IsOlder(const NuDateTime* pWhen1, const NuDateTime* pWhen2);
|
||||
NuError Nu_OpenOutputFile(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, const char* newPathname, char newFssep,
|
||||
const NuThread* pThread, const UNICHAR* newPathnameUNI, UNICHAR newFssep,
|
||||
FILE** pFp);
|
||||
NuError Nu_CloseOutputFile(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
FILE* fp, const char* pathname);
|
||||
NuError Nu_OpenInputFile(NuArchive* pArchive, const char* pathname,
|
||||
FILE* fp, const UNICHAR* pathnameUNI);
|
||||
NuError Nu_OpenInputFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
|
||||
Boolean openRsrc, FILE** pFp);
|
||||
NuError Nu_DeleteFile(const char* pathname);
|
||||
NuError Nu_RenameFile(const char* fromPath, const char* toPath);
|
||||
NuError Nu_DeleteFile(const UNICHAR* pathnameUNI);
|
||||
NuError Nu_RenameFile(const UNICHAR* fromPathUNI, const UNICHAR* toPathUNI);
|
||||
NuError Nu_FTell(FILE* fp, long* pOffset);
|
||||
NuError Nu_FSeek(FILE* fp, long offset, int ptrname);
|
||||
NuError Nu_FRead(FILE* fp, void* buf, size_t nbyte);
|
||||
|
@ -627,22 +629,23 @@ NuError Nu_TruncateOpenFile(FILE* fp, long length);
|
|||
/* Funnel.c */
|
||||
NuError Nu_ProgressDataInit_Compress(NuArchive* pArchive,
|
||||
NuProgressData* pProgressData, const NuRecord* pRecord,
|
||||
const char* origPathname);
|
||||
const UNICHAR* origPathnameUNI, const UNICHAR* pathnameUNI);
|
||||
NuError Nu_ProgressDataInit_Expand(NuArchive* pArchive,
|
||||
NuProgressData* pProgressData, const NuRecord* pRecord,
|
||||
const char* newPathname, char newFssep, NuValue convertEOL);
|
||||
const UNICHAR* newPathnameUNI, UNICHAR newFssep,
|
||||
const UNICHAR* origPathnameUNI, NuValue convertEOL);
|
||||
NuError Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress);
|
||||
|
||||
NuError Nu_FunnelNew(NuArchive* pArchive, NuDataSink* pDataSink,
|
||||
NuValue convertEOL, NuValue convertEOLTo, NuProgressData* pProgress,
|
||||
NuFunnel** ppFunnel);
|
||||
NuError Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel);
|
||||
/*void Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, ulong maxBytes);*/
|
||||
/*void Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, uint32_t maxBytes);*/
|
||||
NuError Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel,
|
||||
const uchar* buffer, ulong count);
|
||||
const uint8_t* buffer, uint32_t count);
|
||||
NuError Nu_FunnelFlush(NuArchive* pArchive, NuFunnel* pFunnel);
|
||||
NuError Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
|
||||
NuThreadFormat threadFormat, ulong sourceLen);
|
||||
NuThreadFormat threadFormat, uint32_t sourceLen);
|
||||
NuError Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
|
||||
const NuThread* pThread);
|
||||
NuError Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state);
|
||||
|
@ -654,32 +657,34 @@ NuError Nu_StrawNew(NuArchive* pArchive, NuDataSource* pDataSource,
|
|||
NuError Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw);
|
||||
NuError Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state);
|
||||
NuError Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw);
|
||||
NuError Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uchar* buffer,
|
||||
NuError Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uint8_t* buffer,
|
||||
long len);
|
||||
NuError Nu_StrawRewind(NuArchive* pArchive, NuStraw* pStraw);
|
||||
|
||||
/* Lzc.c */
|
||||
NuError Nu_CompressLZC12(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
|
||||
NuError Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
|
||||
NuError Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
|
||||
|
||||
/* Lzw.c */
|
||||
NuError Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
|
||||
NuError Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
|
||||
NuError Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pThreadCrc);
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel,
|
||||
uint16_t* pThreadCrc);
|
||||
|
||||
/* MiscUtils.c */
|
||||
/*extern const char* kNufxLibName;*/
|
||||
extern NuCallback gNuGlobalErrorMessageHandler;
|
||||
const char* Nu_StrError(NuError err);
|
||||
void Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
||||
const char* function, Boolean isDebug, NuError err, const char* format, ...)
|
||||
const char* function, Boolean isDebug, NuError err,
|
||||
const UNICHAR* format, ...)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((format(printf, 7, 8)))
|
||||
#endif
|
||||
|
@ -688,7 +693,7 @@ void Nu_ReportError(NuArchive* pArchive, const char* file, int line,
|
|||
# define Nu_Malloc(archive, size) malloc(size)
|
||||
# define Nu_Calloc(archive, size) calloc(1, size)
|
||||
# define Nu_Realloc(archive, ptr, size) realloc(ptr, size)
|
||||
# define Nu_Free(archive, ptr) (ptr != nil ? free(ptr) : (void)0)
|
||||
# define Nu_Free(archive, ptr) (ptr != NULL ? free(ptr) : (void)0)
|
||||
#else
|
||||
void* Nu_Malloc(NuArchive* pArchive, size_t size);
|
||||
void* Nu_Calloc(NuArchive* pArchive, size_t size);
|
||||
|
@ -701,8 +706,8 @@ NuResult Nu_InternalFreeCallback(NuArchive* pArchive, void* args);
|
|||
void Nu_RecordAddThreadMod(NuRecord* pRecord, NuThreadMod* pThreadMod);
|
||||
Boolean Nu_RecordIsEmpty(NuArchive* pArchive, const NuRecord* pRecord);
|
||||
Boolean Nu_RecordSet_GetLoaded(const NuRecordSet* pRecordSet);
|
||||
ulong Nu_RecordSet_GetNumRecords(const NuRecordSet* pRecordSet);
|
||||
void Nu_RecordSet_SetNumRecords(NuRecordSet* pRecordSet, ulong val);
|
||||
uint32_t Nu_RecordSet_GetNumRecords(const NuRecordSet* pRecordSet);
|
||||
void Nu_RecordSet_SetNumRecords(NuRecordSet* pRecordSet, uint32_t val);
|
||||
void Nu_RecordSet_IncNumRecords(NuRecordSet* pRecordSet);
|
||||
NuRecord* Nu_RecordSet_GetListHead(const NuRecordSet* pRecordSet);
|
||||
NuRecord** Nu_RecordSet_GetListHeadPtr(NuRecordSet* pRecordSet);
|
||||
|
@ -738,19 +743,19 @@ NuError Nu_Test(NuArchive* pArchive);
|
|||
NuError Nu_TestRecord(NuArchive* pArchive, NuRecordIdx recIdx);
|
||||
NuError Nu_GetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const NuRecord** ppRecord);
|
||||
NuError Nu_GetRecordIdxByName(NuArchive* pArchive, const char* name,
|
||||
NuError Nu_GetRecordIdxByName(NuArchive* pArchive, const char* nameMOR,
|
||||
NuRecordIdx* pRecordIdx);
|
||||
NuError Nu_GetRecordIdxByPosition(NuArchive* pArchive, ulong position,
|
||||
NuError Nu_GetRecordIdxByPosition(NuArchive* pArchive, uint32_t position,
|
||||
NuRecordIdx* pRecordIdx);
|
||||
NuError Nu_FindRecordForWriteByIdx(NuArchive* pArchive, NuRecordIdx recIdx,
|
||||
NuRecord** ppFoundRecord);
|
||||
NuError Nu_AddFile(NuArchive* pArchive, const char* pathname,
|
||||
NuError Nu_AddFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
|
||||
const NuFileDetails* pFileDetails, Boolean fromRsrcFork,
|
||||
NuRecordIdx* pRecordIdx);
|
||||
NuError Nu_AddRecord(NuArchive* pArchive, const NuFileDetails* pFileDetails,
|
||||
NuRecordIdx* pRecordIdx, NuRecord** ppRecord);
|
||||
NuError Nu_Rename(NuArchive* pArchive, NuRecordIdx recIdx,
|
||||
const char* pathname, char fssep);
|
||||
const char* pathnameMOR, char fssepMOR);
|
||||
NuError Nu_SetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
|
||||
const NuRecordAttr* pRecordAttr);
|
||||
NuError Nu_Delete(NuArchive* pArchive);
|
||||
|
@ -758,88 +763,74 @@ NuError Nu_DeleteRecord(NuArchive* pArchive, NuRecordIdx rec);
|
|||
|
||||
/* SourceSink.c */
|
||||
NuError Nu_DataSourceFile_New(NuThreadFormat threadFormat,
|
||||
ulong otherLen, const char* pathname, Boolean isFromRsrcFork,
|
||||
uint32_t otherLen, const UNICHAR* pathnameUNI, Boolean isFromRsrcFork,
|
||||
NuDataSource** ppDataSource);
|
||||
NuError Nu_DataSourceFP_New(NuThreadFormat threadFormat,
|
||||
ulong otherLen, FILE* fp, long offset, long length,
|
||||
uint32_t otherLen, FILE* fp, long offset, long length,
|
||||
NuCallback fcloseFunc, NuDataSource** ppDataSource);
|
||||
NuError Nu_DataSourceBuffer_New(NuThreadFormat threadFormat,
|
||||
ulong otherLen, const uchar* buffer, long offset, long length,
|
||||
uint32_t otherLen, const uint8_t* buffer, long offset, long length,
|
||||
NuCallback freeFunc, NuDataSource** ppDataSource);
|
||||
NuDataSource* Nu_DataSourceCopy(NuDataSource* pDataSource);
|
||||
NuError Nu_DataSourceFree(NuDataSource* pDataSource);
|
||||
NuDataSourceType Nu_DataSourceGetType(const NuDataSource* pDataSource);
|
||||
NuThreadFormat Nu_DataSourceGetThreadFormat(const NuDataSource* pDataSource);
|
||||
ulong Nu_DataSourceGetDataLen(const NuDataSource* pDataSource);
|
||||
ulong Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource);
|
||||
uint32_t Nu_DataSourceGetDataLen(const NuDataSource* pDataSource);
|
||||
uint32_t Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource);
|
||||
void Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen);
|
||||
ushort Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource);
|
||||
void Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, ushort crc);
|
||||
uint16_t Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource);
|
||||
void Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, uint16_t crc);
|
||||
NuError Nu_DataSourcePrepareInput(NuArchive* pArchive,
|
||||
NuDataSource* pDataSource);
|
||||
void Nu_DataSourceUnPrepareInput(NuArchive* pArchive,
|
||||
NuDataSource* pDataSource);
|
||||
const char* Nu_DataSourceFile_GetPathname(NuDataSource* pDataSource);
|
||||
NuError Nu_DataSourceGetBlock(NuDataSource* pDataSource, uchar* buf, ulong len);
|
||||
NuError Nu_DataSourceGetBlock(NuDataSource* pDataSource, uint8_t* buf,
|
||||
uint32_t len);
|
||||
NuError Nu_DataSourceRewind(NuDataSource* pDataSource);
|
||||
NuError Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL,
|
||||
const char* pathname, char fssep, NuDataSink** ppDataSink);
|
||||
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink);
|
||||
NuError Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
|
||||
NuDataSink** ppDataSink);
|
||||
NuError Nu_DataSinkBuffer_New(Boolean doExpand, NuValue convertEOL,
|
||||
uchar* buffer, ulong bufLen, NuDataSink** ppDataSink);
|
||||
uint8_t* buffer, uint32_t bufLen, NuDataSink** ppDataSink);
|
||||
NuError Nu_DataSinkVoid_New(Boolean doExpand, NuValue convertEOL,
|
||||
NuDataSink** ppDataSink);
|
||||
NuError Nu_DataSinkFree(NuDataSink* pDataSink);
|
||||
NuDataSinkType Nu_DataSinkGetType(const NuDataSink* pDataSink);
|
||||
Boolean Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink);
|
||||
NuValue Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink);
|
||||
ulong Nu_DataSinkGetOutCount(const NuDataSink* pDataSink);
|
||||
uint32_t Nu_DataSinkGetOutCount(const NuDataSink* pDataSink);
|
||||
const char* Nu_DataSinkFile_GetPathname(const NuDataSink* pDataSink);
|
||||
char Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink);
|
||||
UNICHAR Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink);
|
||||
FILE* Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink);
|
||||
void Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp);
|
||||
void Nu_DataSinkFile_Close(NuDataSink* pDataSink);
|
||||
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len);
|
||||
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uint8_t* buf,
|
||||
uint32_t len);
|
||||
NuError Nu_DataSinkGetError(NuDataSink* pDataSink);
|
||||
|
||||
/* Squeeze.c */
|
||||
NuError Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
|
||||
NuError Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
|
||||
|
||||
/* Thread.c */
|
||||
#ifdef __Thread_c__
|
||||
#define THREAD_INLINE /**/
|
||||
#else
|
||||
#define THREAD_INLINE extern inline
|
||||
#endif
|
||||
#if defined(inline) && !defined(__Thread_c__) /* somebody ovrd inline def? */
|
||||
NuThread* Nu_GetThread(const NuRecord* pRecord, int idx);
|
||||
#else
|
||||
THREAD_INLINE NuThread*
|
||||
Nu_GetThread(const NuRecord* pRecord, int idx)
|
||||
{
|
||||
if (idx >= (int)pRecord->recTotalThreads)
|
||||
return nil;
|
||||
else
|
||||
return &pRecord->pThreads[idx];
|
||||
}
|
||||
#endif
|
||||
void Nu_StripHiIfAllSet(char* str);
|
||||
Boolean Nu_IsPresizedThreadID(NuThreadID threadID);
|
||||
Boolean Nu_IsCompressibleThreadID(NuThreadID threadID);
|
||||
Boolean Nu_ThreadHasCRC(long recordVersion, NuThreadID threadID);
|
||||
Boolean Nu_ThreadHasCRC(uint16_t recordVersion, NuThreadID threadID);
|
||||
NuError Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
|
||||
NuThread** ppThread);
|
||||
NuError Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
|
||||
NuThread** ppThread);
|
||||
void Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread);
|
||||
NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
|
||||
ushort* pCrc);
|
||||
uint16_t* pCrc);
|
||||
NuError Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp,
|
||||
ushort* pCrc);
|
||||
uint16_t* pCrc);
|
||||
NuError Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord);
|
||||
NuError Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord,long numThreads);
|
||||
NuError Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
|
@ -853,7 +844,7 @@ NuError Nu_OkayToAddThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
NuError Nu_AddThread(NuArchive* pArchive, NuRecordIdx rec, NuThreadID threadID,
|
||||
NuDataSource* pDataSource, NuThreadIdx* pThreadIdx);
|
||||
NuError Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuDataSource* pDataSource, long* pMaxLen);
|
||||
NuDataSource* pDataSource, int32_t* pMaxLen);
|
||||
NuError Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx);
|
||||
|
||||
/* Value.c */
|
||||
|
@ -864,7 +855,7 @@ NuThreadFormat Nu_ConvertCompressValToFormat(NuArchive* pArchive,
|
|||
NuValue compValue);
|
||||
|
||||
/* Version.c */
|
||||
NuError Nu_GetVersion(long* pMajorVersion, long* pMinorVersion,
|
||||
long* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags);
|
||||
NuError Nu_GetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
|
||||
int32_t* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags);
|
||||
|
||||
#endif /*__NufxLibPriv__*/
|
||||
#endif /*NUFXLIB_NUFXLIBPRIV_H*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
NufxLib README, updated 2004/03/18
|
||||
NufxLib README, updated 2014/12/23
|
||||
http://www.nulib.com/
|
||||
|
||||
See "COPYING-LIB" for distribution restrictions.
|
||||
|
@ -42,11 +42,8 @@ for @CFLAGS@ is "-g -O2".
|
|||
(Implicitly sets DEBUG_MSGS.) Spray lots of debugging output.
|
||||
|
||||
If you want to do benchmarks, use "-O2 -DNDEBUG". The recommended
|
||||
configuration during testing is "-g -O2 -DDEBUG_MSGS", so that verbose
|
||||
debug output is available when errors occur.
|
||||
|
||||
The flags are stuffed into Version.c, so the application program can
|
||||
examine and display the flags that were used to build the library.
|
||||
configuration is "-g -O2 -DDEBUG_MSGS", so that verbose debug output is
|
||||
available when errors occur.
|
||||
|
||||
|
||||
BeOS
|
||||
|
@ -67,14 +64,10 @@ If you're using BeOS/PPC, it will also do:
|
|||
Mac OS X
|
||||
========
|
||||
|
||||
This works just like the UNIX version, with the exception that when you link
|
||||
against nufxlib, your project must also link against the Carbon framework.
|
||||
This can be done in ProjectBuilder by using the Add Framework option in the
|
||||
Project menu, or by adding "-framework Carbon" to the gcc command line.
|
||||
This works just like the UNIX version, but includes support for resource
|
||||
forks and Finder file/aux types.
|
||||
|
||||
You'll see some warnings due to some namespace collisions between nufxlib and
|
||||
Carbon, but everything will work fine. Carbon is used to provide support for
|
||||
file types and resource forks.
|
||||
Tested with Xcode v5.1.1 and Mac OS 10.8.5.
|
||||
|
||||
|
||||
Win32
|
||||
|
@ -83,29 +76,24 @@ Win32
|
|||
If you're using an environment that supports "configure" scripts, such as
|
||||
DJGPP, follow the UNIX instructions.
|
||||
|
||||
NufxLib has been tested with Microsoft Visual C++ 6.0. To build NufxLib,
|
||||
start up a DOS shell and run vcvars32.bat to set your environment. Run:
|
||||
NufxLib has been tested with Microsoft Visual C++ 12 (Visual Studio 2013).
|
||||
To build NufxLib, run the "Visual Studio 2013 x86 Native Tools Command
|
||||
Prompt" shortcut to get a shell. Change to the nufxlib directory, then:
|
||||
|
||||
nmake -f makefile.msc
|
||||
to build with debugging info, or
|
||||
nmake -f makefile.msc nodebug=1
|
||||
to build optimized.
|
||||
|
||||
See the makefile for comments about including zlib or libbz2. These
|
||||
need to be enabled at compile time and linked into the sample apps.
|
||||
When the build finishes, run "test-basic.exe" to confirm things are working.
|
||||
|
||||
Once the library has been built, "cd samples" and run the same command there.
|
||||
When it finishes, run "test-basic.exe".
|
||||
If you want to have zlib support enabled, you will need to have zlib.h,
|
||||
zconf.h, and zlib.lib copied into the directory. See "makefile.msc" for
|
||||
more details.
|
||||
|
||||
If you want to build NufxLib as a DLL, use "makefile.dll" instead.
|
||||
If you're using zlib or libbz2, these will need to be linked into the DLL.
|
||||
The makefile currently assumes that you will want to use zlib.dll.
|
||||
The makefile builds NufxLib as a static library and as a DLL.
|
||||
|
||||
|
||||
Other Notes
|
||||
===========
|
||||
|
||||
All of the source code is now formatted with spaces instead of tabs.
|
||||
|
||||
If you want to use the library in a multithreaded application, you should
|
||||
define "USE_REENTRANT_CALLS" to tell it to use reentrant versions of
|
||||
certain library calls. This defines _REENTRANT, which causes Solaris to
|
||||
|
@ -113,12 +101,19 @@ add the appropriate goodies. (Seems to me you'd always want this on, but
|
|||
for some reason Solaris makes you take an extra step, so I'm not going to
|
||||
define it by default.)
|
||||
|
||||
Originally, NufxLib / NuLib2 were intended to be usable natively on the
|
||||
Apple IIgs, so some of the design decisions were influenced by the need
|
||||
to minimize memory usage (e.g. being able to get a directory listing
|
||||
without holding the entire directory in memory) and interact with GS/OS
|
||||
(forked files have a single filename, files have type/auxtype). The IIgs
|
||||
port was never started.
|
||||
|
||||
|
||||
Legalese
|
||||
========
|
||||
|
||||
NufxLib, a NuFX archive manipulation library.
|
||||
Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
Copyright (C) 2000-2014 by Andy McFadden, All Rights Reserved.
|
||||
|
||||
See COPYING for license.
|
||||
|
||||
|
|
795
nufxlib/Record.c
795
nufxlib/Record.c
File diff suppressed because it is too large
Load Diff
|
@ -19,13 +19,12 @@
|
|||
/*
|
||||
* Allocate a new DataSource structure.
|
||||
*/
|
||||
static NuError
|
||||
Nu_DataSourceNew(NuDataSource** ppDataSource)
|
||||
static NuError Nu_DataSourceNew(NuDataSource** ppDataSource)
|
||||
{
|
||||
Assert(ppDataSource != nil);
|
||||
Assert(ppDataSource != NULL);
|
||||
|
||||
*ppDataSource = Nu_Malloc(nil, sizeof(**ppDataSource));
|
||||
if (*ppDataSource == nil)
|
||||
*ppDataSource = Nu_Malloc(NULL, sizeof(**ppDataSource));
|
||||
if (*ppDataSource == NULL)
|
||||
return kNuErrMalloc;
|
||||
|
||||
(*ppDataSource)->sourceType = kNuDataSourceUnknown;
|
||||
|
@ -47,10 +46,9 @@ Nu_DataSourceNew(NuDataSource** ppDataSource)
|
|||
* needed in the first place.) Buffer sources are a little scary since
|
||||
* they include a "curOffset" value.
|
||||
*
|
||||
* Returns nil on error.
|
||||
* Returns NULL on error.
|
||||
*/
|
||||
NuDataSource*
|
||||
Nu_DataSourceCopy(NuDataSource* pDataSource)
|
||||
NuDataSource* Nu_DataSourceCopy(NuDataSource* pDataSource)
|
||||
{
|
||||
Assert(pDataSource->common.refCount >= 1);
|
||||
pDataSource->common.refCount++;
|
||||
|
@ -59,18 +57,18 @@ Nu_DataSourceCopy(NuDataSource* pDataSource)
|
|||
#if 0 /* we used to copy them -- very bad idea */
|
||||
NuDataSource* pNewDataSource;
|
||||
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
|
||||
if (Nu_DataSourceNew(&pNewDataSource) != kNuErrNone)
|
||||
return nil;
|
||||
Assert(pNewDataSource != nil);
|
||||
return NULL;
|
||||
Assert(pNewDataSource != NULL);
|
||||
|
||||
/* this gets most of it */
|
||||
memcpy(pNewDataSource, pDataSource, sizeof(*pNewDataSource));
|
||||
|
||||
/* copy anything we're sure to free up */
|
||||
if (pDataSource->sourceType == kNuDataSourceFromFile) {
|
||||
Assert(pDataSource->fromFile.fp == nil); /* does this matter? */
|
||||
Assert(pDataSource->fromFile.fp == NULL); /* does this matter? */
|
||||
pNewDataSource->fromFile.pathname =
|
||||
strdup(pDataSource->fromFile.pathname);
|
||||
}
|
||||
|
@ -89,10 +87,9 @@ Nu_DataSourceCopy(NuDataSource* pDataSource)
|
|||
/*
|
||||
* Free a data source structure, and any type-specific elements.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSourceFree(NuDataSource* pDataSource)
|
||||
NuError Nu_DataSourceFree(NuDataSource* pDataSource)
|
||||
{
|
||||
if (pDataSource == nil)
|
||||
if (pDataSource == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
Assert(pDataSource->common.refCount > 0);
|
||||
|
@ -103,25 +100,25 @@ Nu_DataSourceFree(NuDataSource* pDataSource)
|
|||
|
||||
switch (pDataSource->sourceType) {
|
||||
case kNuDataSourceFromFile:
|
||||
Nu_Free(nil, pDataSource->fromFile.pathname);
|
||||
if (pDataSource->fromFile.fp != nil) {
|
||||
Nu_Free(NULL, pDataSource->fromFile.pathnameUNI);
|
||||
if (pDataSource->fromFile.fp != NULL) {
|
||||
fclose(pDataSource->fromFile.fp);
|
||||
pDataSource->fromFile.fp = nil;
|
||||
pDataSource->fromFile.fp = NULL;
|
||||
}
|
||||
break;
|
||||
case kNuDataSourceFromFP:
|
||||
if (pDataSource->fromFP.fcloseFunc != nil &&
|
||||
pDataSource->fromFP.fp != nil)
|
||||
if (pDataSource->fromFP.fcloseFunc != NULL &&
|
||||
pDataSource->fromFP.fp != NULL)
|
||||
{
|
||||
(*pDataSource->fromFP.fcloseFunc)(nil, pDataSource->fromFP.fp);
|
||||
pDataSource->fromFP.fp = nil;
|
||||
(*pDataSource->fromFP.fcloseFunc)(NULL, pDataSource->fromFP.fp);
|
||||
pDataSource->fromFP.fp = NULL;
|
||||
}
|
||||
break;
|
||||
case kNuDataSourceFromBuffer:
|
||||
if (pDataSource->fromBuffer.freeFunc != nil) {
|
||||
(*pDataSource->fromBuffer.freeFunc)(nil,
|
||||
if (pDataSource->fromBuffer.freeFunc != NULL) {
|
||||
(*pDataSource->fromBuffer.freeFunc)(NULL,
|
||||
(void*)pDataSource->fromBuffer.buffer);
|
||||
pDataSource->fromBuffer.buffer = nil;
|
||||
pDataSource->fromBuffer.buffer = NULL;
|
||||
}
|
||||
break;
|
||||
case kNuDataSourceUnknown:
|
||||
|
@ -131,7 +128,7 @@ Nu_DataSourceFree(NuDataSource* pDataSource)
|
|||
return kNuErrInternal;
|
||||
}
|
||||
|
||||
Nu_Free(nil, pDataSource);
|
||||
Nu_Free(NULL, pDataSource);
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
||||
|
@ -139,15 +136,15 @@ Nu_DataSourceFree(NuDataSource* pDataSource)
|
|||
/*
|
||||
* Create a data source for an unopened file.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSourceFile_New(NuThreadFormat threadFormat, ulong otherLen,
|
||||
const char* pathname, Boolean isFromRsrcFork, NuDataSource** ppDataSource)
|
||||
NuError Nu_DataSourceFile_New(NuThreadFormat threadFormat, uint32_t otherLen,
|
||||
const UNICHAR* pathnameUNI, Boolean isFromRsrcFork,
|
||||
NuDataSource** ppDataSource)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if (pathname == nil ||
|
||||
if (pathnameUNI == NULL ||
|
||||
!(isFromRsrcFork == true || isFromRsrcFork == false) ||
|
||||
ppDataSource == nil)
|
||||
ppDataSource == NULL)
|
||||
{
|
||||
return kNuErrInvalidArg;
|
||||
}
|
||||
|
@ -162,9 +159,9 @@ Nu_DataSourceFile_New(NuThreadFormat threadFormat, ulong otherLen,
|
|||
(*ppDataSource)->common.otherLen = otherLen;
|
||||
(*ppDataSource)->common.refCount = 1;
|
||||
|
||||
(*ppDataSource)->fromFile.pathname = strdup(pathname);
|
||||
(*ppDataSource)->fromFile.pathnameUNI = strdup(pathnameUNI);
|
||||
(*ppDataSource)->fromFile.fromRsrcFork = isFromRsrcFork;
|
||||
(*ppDataSource)->fromFile.fp = nil; /* to be filled in later */
|
||||
(*ppDataSource)->fromFile.fp = NULL; /* to be filled in later */
|
||||
|
||||
bail:
|
||||
return err;
|
||||
|
@ -175,20 +172,19 @@ bail:
|
|||
* Create a data source for an open file at a specific offset. The FILE*
|
||||
* must be seekable.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSourceFP_New(NuThreadFormat threadFormat, ulong otherLen,
|
||||
NuError Nu_DataSourceFP_New(NuThreadFormat threadFormat, uint32_t otherLen,
|
||||
FILE* fp, long offset, long length, NuCallback fcloseFunc,
|
||||
NuDataSource** ppDataSource)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if (fp == nil || offset < 0 || length < 0 ||
|
||||
ppDataSource == nil)
|
||||
if (fp == NULL || offset < 0 || length < 0 ||
|
||||
ppDataSource == NULL)
|
||||
{
|
||||
return kNuErrInvalidArg;
|
||||
}
|
||||
|
||||
if (otherLen && otherLen < (ulong)length) {
|
||||
if (otherLen && otherLen < (uint32_t)length) {
|
||||
DBUG(("--- rejecting FP len=%ld other=%ld\n", length, otherLen));
|
||||
err = kNuErrPreSizeOverflow;
|
||||
goto bail;
|
||||
|
@ -216,28 +212,27 @@ bail:
|
|||
/*
|
||||
* Create a data source for a buffer.
|
||||
*
|
||||
* We allow "buffer" to be nil so long as "offset" and "length" are also
|
||||
* nil. This is useful for creating empty pre-sized buffers, such as
|
||||
* We allow "buffer" to be NULL so long as "offset" and "length" are also
|
||||
* NULL. This is useful for creating empty pre-sized buffers, such as
|
||||
* blank comment fields.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSourceBuffer_New(NuThreadFormat threadFormat, ulong otherLen,
|
||||
const uchar* buffer, long offset, long length, NuCallback freeFunc,
|
||||
NuError Nu_DataSourceBuffer_New(NuThreadFormat threadFormat, uint32_t otherLen,
|
||||
const uint8_t* buffer, long offset, long length, NuCallback freeFunc,
|
||||
NuDataSource** ppDataSource)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if (offset < 0 || length < 0 || ppDataSource == nil)
|
||||
if (offset < 0 || length < 0 || ppDataSource == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
if (buffer == nil && (offset != 0 || length != 0))
|
||||
if (buffer == NULL && (offset != 0 || length != 0))
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
if (buffer == nil) {
|
||||
if (buffer == NULL) {
|
||||
DBUG(("+++ zeroing freeFunc for empty-buffer DataSource\n"));
|
||||
freeFunc = nil;
|
||||
freeFunc = NULL;
|
||||
}
|
||||
|
||||
if (otherLen && otherLen < (ulong)length) {
|
||||
if (otherLen && otherLen < (uint32_t)length) {
|
||||
DBUG(("--- rejecting buffer len=%ld other=%ld\n", length, otherLen));
|
||||
err = kNuErrPreSizeOverflow;
|
||||
goto bail;
|
||||
|
@ -267,34 +262,31 @@ bail:
|
|||
/*
|
||||
* Get the type of a NuDataSource.
|
||||
*/
|
||||
NuDataSourceType
|
||||
Nu_DataSourceGetType(const NuDataSource* pDataSource)
|
||||
NuDataSourceType Nu_DataSourceGetType(const NuDataSource* pDataSource)
|
||||
{
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
return pDataSource->sourceType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the threadFormat for a data source.
|
||||
*/
|
||||
NuThreadFormat
|
||||
Nu_DataSourceGetThreadFormat(const NuDataSource* pDataSource)
|
||||
NuThreadFormat Nu_DataSourceGetThreadFormat(const NuDataSource* pDataSource)
|
||||
{
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
return pDataSource->common.threadFormat;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get "dataLen" from a dataSource.
|
||||
*/
|
||||
ulong
|
||||
Nu_DataSourceGetDataLen(const NuDataSource* pDataSource)
|
||||
uint32_t Nu_DataSourceGetDataLen(const NuDataSource* pDataSource)
|
||||
{
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
|
||||
if (pDataSource->sourceType == kNuDataSourceFromFile) {
|
||||
/* dataLen can only be valid if file has been opened */
|
||||
Assert(pDataSource->fromFile.fp != nil);
|
||||
Assert(pDataSource->fromFile.fp != NULL);
|
||||
}
|
||||
|
||||
return pDataSource->common.dataLen;
|
||||
|
@ -303,20 +295,18 @@ Nu_DataSourceGetDataLen(const NuDataSource* pDataSource)
|
|||
/*
|
||||
* Get "otherLen" from a dataSource.
|
||||
*/
|
||||
ulong
|
||||
Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource)
|
||||
uint32_t Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource)
|
||||
{
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
return pDataSource->common.otherLen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the "otherLen" value.
|
||||
*/
|
||||
void
|
||||
Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen)
|
||||
void Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen)
|
||||
{
|
||||
Assert(pDataSource != nil && otherLen > 0);
|
||||
Assert(pDataSource != NULL && otherLen > 0);
|
||||
pDataSource->common.otherLen = otherLen;
|
||||
}
|
||||
|
||||
|
@ -324,10 +314,9 @@ Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen)
|
|||
/*
|
||||
* Get the "raw CRC" value.
|
||||
*/
|
||||
ushort
|
||||
Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource)
|
||||
uint16_t Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource)
|
||||
{
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
return pDataSource->common.rawCrc;
|
||||
}
|
||||
|
||||
|
@ -335,10 +324,9 @@ Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource)
|
|||
* Set the "raw CRC" value. You would want to do this if the input was
|
||||
* already-compressed data, and you wanted to propagate the thread CRC.
|
||||
*/
|
||||
void
|
||||
Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, ushort crc)
|
||||
void Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, uint16_t crc)
|
||||
{
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
pDataSource->common.rawCrc = crc;
|
||||
}
|
||||
|
||||
|
@ -346,11 +334,11 @@ Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, ushort crc)
|
|||
/*
|
||||
* Prepare a data source for action.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSourcePrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
|
||||
NuError Nu_DataSourcePrepareInput(NuArchive* pArchive,
|
||||
NuDataSource* pDataSource)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
FILE* fileFp = nil;
|
||||
FILE* fileFp = NULL;
|
||||
|
||||
/*
|
||||
* Doesn't apply to buffer sources.
|
||||
|
@ -372,11 +360,11 @@ Nu_DataSourcePrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
|
|||
* We're adding from a file on disk. Open it.
|
||||
*/
|
||||
err = Nu_OpenInputFile(pArchive,
|
||||
pDataSource->fromFile.pathname, pDataSource->fromFile.fromRsrcFork,
|
||||
&fileFp);
|
||||
pDataSource->fromFile.pathnameUNI,
|
||||
pDataSource->fromFile.fromRsrcFork, &fileFp);
|
||||
BailError(err);
|
||||
|
||||
Assert(fileFp != nil);
|
||||
Assert(fileFp != NULL);
|
||||
pDataSource->fromFile.fp = fileFp;
|
||||
err = Nu_GetFileLength(pArchive, fileFp,
|
||||
(long*)&pDataSource->common.dataLen);
|
||||
|
@ -403,49 +391,47 @@ bail:
|
|||
* call will take care of this eventually -- but for normal operation on
|
||||
* a large number of files, it's vital.
|
||||
*/
|
||||
void
|
||||
Nu_DataSourceUnPrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
|
||||
void Nu_DataSourceUnPrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
|
||||
{
|
||||
if (Nu_DataSourceGetType(pDataSource) != kNuDataSourceFromFile)
|
||||
return;
|
||||
|
||||
if (pDataSource->fromFile.fp != nil) {
|
||||
if (pDataSource->fromFile.fp != NULL) {
|
||||
fclose(pDataSource->fromFile.fp);
|
||||
pDataSource->fromFile.fp = nil;
|
||||
pDataSource->fromFile.fp = NULL;
|
||||
pDataSource->common.dataLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the pathname from a "from-file" dataSource.
|
||||
* Get the pathname from a "from-file" dataSource. Returned string is UTF-8.
|
||||
*/
|
||||
const char*
|
||||
Nu_DataSourceFile_GetPathname(NuDataSource* pDataSource)
|
||||
const char* Nu_DataSourceFile_GetPathname(NuDataSource* pDataSource)
|
||||
{
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
Assert(pDataSource->sourceType == kNuDataSourceFromFile);
|
||||
Assert(pDataSource->fromFile.pathname != nil);
|
||||
Assert(pDataSource->fromFile.pathnameUNI != NULL);
|
||||
|
||||
return pDataSource->fromFile.pathname;
|
||||
return pDataSource->fromFile.pathnameUNI;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read a block of data from a dataSource.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSourceGetBlock(NuDataSource* pDataSource, uchar* buf, ulong len)
|
||||
NuError Nu_DataSourceGetBlock(NuDataSource* pDataSource, uint8_t* buf,
|
||||
uint32_t len)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
Assert(pDataSource != nil);
|
||||
Assert(buf != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
Assert(buf != NULL);
|
||||
Assert(len > 0);
|
||||
|
||||
switch (pDataSource->sourceType) {
|
||||
case kNuDataSourceFromFile:
|
||||
Assert(pDataSource->fromFile.fp != nil);
|
||||
Assert(pDataSource->fromFile.fp != NULL);
|
||||
err = Nu_FRead(pDataSource->fromFile.fp, buf, len);
|
||||
if (feof(pDataSource->fromFile.fp))
|
||||
Nu_ReportError(NU_NILBLOB, err, "EOF hit unexpectedly");
|
||||
|
@ -479,16 +465,15 @@ Nu_DataSourceGetBlock(NuDataSource* pDataSource, uchar* buf, ulong len)
|
|||
/*
|
||||
* Rewind a data source to the start of its input.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSourceRewind(NuDataSource* pDataSource)
|
||||
NuError Nu_DataSourceRewind(NuDataSource* pDataSource)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
Assert(pDataSource != nil);
|
||||
Assert(pDataSource != NULL);
|
||||
|
||||
switch (pDataSource->sourceType) {
|
||||
case kNuDataSourceFromFile:
|
||||
Assert(pDataSource->fromFile.fp != nil);
|
||||
Assert(pDataSource->fromFile.fp != NULL);
|
||||
err = Nu_FSeek(pDataSource->fromFile.fp, 0, SEEK_SET);
|
||||
break; /* fall through with error */
|
||||
case kNuDataSourceFromFP:
|
||||
|
@ -518,13 +503,12 @@ Nu_DataSourceRewind(NuDataSource* pDataSource)
|
|||
/*
|
||||
* Allocate a new DataSink structure.
|
||||
*/
|
||||
static NuError
|
||||
Nu_DataSinkNew(NuDataSink** ppDataSink)
|
||||
static NuError Nu_DataSinkNew(NuDataSink** ppDataSink)
|
||||
{
|
||||
Assert(ppDataSink != nil);
|
||||
Assert(ppDataSink != NULL);
|
||||
|
||||
*ppDataSink = Nu_Malloc(nil, sizeof(**ppDataSink));
|
||||
if (*ppDataSink == nil)
|
||||
*ppDataSink = Nu_Malloc(NULL, sizeof(**ppDataSink));
|
||||
if (*ppDataSink == NULL)
|
||||
return kNuErrMalloc;
|
||||
|
||||
(*ppDataSink)->sinkType = kNuDataSinkUnknown;
|
||||
|
@ -536,16 +520,15 @@ Nu_DataSinkNew(NuDataSink** ppDataSink)
|
|||
/*
|
||||
* Free a data sink structure, and any type-specific elements.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSinkFree(NuDataSink* pDataSink)
|
||||
NuError Nu_DataSinkFree(NuDataSink* pDataSink)
|
||||
{
|
||||
if (pDataSink == nil)
|
||||
if (pDataSink == NULL)
|
||||
return kNuErrNone;
|
||||
|
||||
switch (pDataSink->sinkType) {
|
||||
case kNuDataSinkToFile:
|
||||
Nu_DataSinkFile_Close(pDataSink);
|
||||
Nu_Free(nil, pDataSink->toFile.pathname);
|
||||
Nu_Free(NULL, pDataSink->toFile.pathnameUNI);
|
||||
break;
|
||||
case kNuDataSinkToFP:
|
||||
break;
|
||||
|
@ -560,7 +543,7 @@ Nu_DataSinkFree(NuDataSink* pDataSink)
|
|||
return kNuErrInternal;
|
||||
}
|
||||
|
||||
Nu_Free(nil, pDataSink);
|
||||
Nu_Free(NULL, pDataSink);
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
||||
|
@ -568,18 +551,17 @@ Nu_DataSinkFree(NuDataSink* pDataSink)
|
|||
/*
|
||||
* Create a data sink for an unopened file.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL, const char* pathname,
|
||||
char fssep, NuDataSink** ppDataSink)
|
||||
NuError Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL,
|
||||
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if ((doExpand != true && doExpand != false) ||
|
||||
(convertEOL != kNuConvertOff && convertEOL != kNuConvertOn &&
|
||||
convertEOL != kNuConvertAuto) ||
|
||||
pathname == nil ||
|
||||
pathnameUNI == NULL ||
|
||||
fssep == 0 ||
|
||||
ppDataSink == nil)
|
||||
ppDataSink == NULL)
|
||||
{
|
||||
return kNuErrInvalidArg;
|
||||
}
|
||||
|
@ -594,10 +576,10 @@ Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL, const char* pathname,
|
|||
else
|
||||
(*ppDataSink)->common.convertEOL = kNuConvertOff;
|
||||
(*ppDataSink)->common.outCount = 0;
|
||||
(*ppDataSink)->toFile.pathname = strdup(pathname);
|
||||
(*ppDataSink)->toFile.pathnameUNI = strdup(pathnameUNI);
|
||||
(*ppDataSink)->toFile.fssep = fssep;
|
||||
|
||||
(*ppDataSink)->toFile.fp = nil;
|
||||
(*ppDataSink)->toFile.fp = NULL;
|
||||
|
||||
bail:
|
||||
return err;
|
||||
|
@ -607,8 +589,7 @@ bail:
|
|||
/*
|
||||
* Create a data sink based on a file pointer.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
|
||||
NuError Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
|
||||
NuDataSink** ppDataSink)
|
||||
{
|
||||
NuError err;
|
||||
|
@ -616,8 +597,8 @@ Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
|
|||
if ((doExpand != true && doExpand != false) ||
|
||||
(convertEOL != kNuConvertOff && convertEOL != kNuConvertOn &&
|
||||
convertEOL != kNuConvertAuto) ||
|
||||
fp == nil ||
|
||||
ppDataSink == nil)
|
||||
fp == NULL ||
|
||||
ppDataSink == NULL)
|
||||
{
|
||||
return kNuErrInvalidArg;
|
||||
}
|
||||
|
@ -642,18 +623,17 @@ bail:
|
|||
/*
|
||||
* Create a data sink for a buffer in memory.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSinkBuffer_New(Boolean doExpand, NuValue convertEOL, uchar* buffer,
|
||||
ulong bufLen, NuDataSink** ppDataSink)
|
||||
NuError Nu_DataSinkBuffer_New(Boolean doExpand, NuValue convertEOL,
|
||||
uint8_t* buffer, uint32_t bufLen, NuDataSink** ppDataSink)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
if ((doExpand != true && doExpand != false) ||
|
||||
(convertEOL != kNuConvertOff && convertEOL != kNuConvertOn &&
|
||||
convertEOL != kNuConvertAuto) ||
|
||||
buffer == nil ||
|
||||
buffer == NULL ||
|
||||
bufLen == 0 ||
|
||||
ppDataSink == nil)
|
||||
ppDataSink == NULL)
|
||||
{
|
||||
return kNuErrInvalidArg;
|
||||
}
|
||||
|
@ -681,14 +661,13 @@ bail:
|
|||
/*
|
||||
* Create a data sink that goes nowhere.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSinkVoid_New(Boolean doExpand, NuValue convertEOL,
|
||||
NuError Nu_DataSinkVoid_New(Boolean doExpand, NuValue convertEOL,
|
||||
NuDataSink** ppDataSink)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
Assert(doExpand == true || doExpand == false);
|
||||
Assert(ppDataSink != nil);
|
||||
Assert(ppDataSink != NULL);
|
||||
|
||||
err = Nu_DataSinkNew(ppDataSink);
|
||||
BailErrorQuiet(err);
|
||||
|
@ -706,10 +685,9 @@ bail:
|
|||
/*
|
||||
* Get the type of a NuDataSink.
|
||||
*/
|
||||
NuDataSinkType
|
||||
Nu_DataSinkGetType(const NuDataSink* pDataSink)
|
||||
NuDataSinkType Nu_DataSinkGetType(const NuDataSink* pDataSink)
|
||||
{
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
return pDataSink->sinkType;
|
||||
}
|
||||
|
||||
|
@ -717,8 +695,7 @@ Nu_DataSinkGetType(const NuDataSink* pDataSink)
|
|||
/*
|
||||
* Return the "doExpand" parameter from any kind of sink.
|
||||
*/
|
||||
Boolean
|
||||
Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink)
|
||||
Boolean Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink)
|
||||
{
|
||||
return pDataSink->common.doExpand;
|
||||
}
|
||||
|
@ -726,8 +703,7 @@ Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink)
|
|||
/*
|
||||
* Return the "convertEOL" parameter from any kind of sink.
|
||||
*/
|
||||
NuValue
|
||||
Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink)
|
||||
NuValue Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink)
|
||||
{
|
||||
return pDataSink->common.convertEOL;
|
||||
}
|
||||
|
@ -735,32 +711,29 @@ Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink)
|
|||
/*
|
||||
* Return the #of bytes written to the sink.
|
||||
*/
|
||||
ulong
|
||||
Nu_DataSinkGetOutCount(const NuDataSink* pDataSink)
|
||||
uint32_t Nu_DataSinkGetOutCount(const NuDataSink* pDataSink)
|
||||
{
|
||||
return pDataSink->common.outCount;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get "pathname" from a to-file sink.
|
||||
* Get "pathname" from a to-file sink. Returned string is UTF-8.
|
||||
*/
|
||||
const char*
|
||||
Nu_DataSinkFile_GetPathname(const NuDataSink* pDataSink)
|
||||
const char* Nu_DataSinkFile_GetPathname(const NuDataSink* pDataSink)
|
||||
{
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
Assert(pDataSink->sinkType == kNuDataSinkToFile);
|
||||
|
||||
return pDataSink->toFile.pathname;
|
||||
return pDataSink->toFile.pathnameUNI;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get "fssep" from a to-file sink.
|
||||
*/
|
||||
char
|
||||
Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink)
|
||||
UNICHAR Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink)
|
||||
{
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
Assert(pDataSink->sinkType == kNuDataSinkToFile);
|
||||
|
||||
return pDataSink->toFile.fssep;
|
||||
|
@ -769,10 +742,9 @@ Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink)
|
|||
/*
|
||||
* Get the "fp" for a file sink.
|
||||
*/
|
||||
FILE*
|
||||
Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink)
|
||||
FILE* Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink)
|
||||
{
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
Assert(pDataSink->sinkType == kNuDataSinkToFile);
|
||||
|
||||
return pDataSink->toFile.fp;
|
||||
|
@ -781,10 +753,9 @@ Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink)
|
|||
/*
|
||||
* Set the "fp" for a file sink.
|
||||
*/
|
||||
void
|
||||
Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp)
|
||||
void Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp)
|
||||
{
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
Assert(pDataSink->sinkType == kNuDataSinkToFile);
|
||||
|
||||
pDataSink->toFile.fp = fp;
|
||||
|
@ -793,14 +764,13 @@ Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp)
|
|||
/*
|
||||
* Close a to-file sink.
|
||||
*/
|
||||
void
|
||||
Nu_DataSinkFile_Close(NuDataSink* pDataSink)
|
||||
void Nu_DataSinkFile_Close(NuDataSink* pDataSink)
|
||||
{
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
|
||||
if (pDataSink->toFile.fp != nil) {
|
||||
if (pDataSink->toFile.fp != NULL) {
|
||||
fclose(pDataSink->toFile.fp);
|
||||
pDataSink->toFile.fp = nil;
|
||||
pDataSink->toFile.fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,24 +778,24 @@ Nu_DataSinkFile_Close(NuDataSink* pDataSink)
|
|||
/*
|
||||
* Write a block of data to a DataSink.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len)
|
||||
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uint8_t* buf,
|
||||
uint32_t len)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
Assert(pDataSink != nil);
|
||||
Assert(buf != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
Assert(buf != NULL);
|
||||
Assert(len > 0);
|
||||
|
||||
switch (pDataSink->sinkType) {
|
||||
case kNuDataSinkToFile:
|
||||
Assert(pDataSink->toFile.fp != nil);
|
||||
Assert(pDataSink->toFile.fp != NULL);
|
||||
err = Nu_FWrite(pDataSink->toFile.fp, buf, len);
|
||||
if (err != kNuErrNone)
|
||||
return err;
|
||||
break;
|
||||
case kNuDataSinkToFP:
|
||||
Assert(pDataSink->toFP.fp != nil);
|
||||
Assert(pDataSink->toFP.fp != NULL);
|
||||
err = Nu_FWrite(pDataSink->toFP.fp, buf, len);
|
||||
if (err != kNuErrNone)
|
||||
return err;
|
||||
|
@ -856,12 +826,11 @@ Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len)
|
|||
/*
|
||||
* Figure out if one of our earlier writes has failed.
|
||||
*/
|
||||
NuError
|
||||
Nu_DataSinkGetError(NuDataSink* pDataSink)
|
||||
NuError Nu_DataSinkGetError(NuDataSink* pDataSink)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pDataSink != NULL);
|
||||
|
||||
switch (pDataSink->sinkType) {
|
||||
case kNuDataSinkToFile:
|
||||
|
|
|
@ -77,13 +77,13 @@ typedef struct EncTreeNode {
|
|||
typedef struct SQState {
|
||||
NuArchive* pArchive;
|
||||
int doCalcCRC; /* boolean; if set, compute CRC on input */
|
||||
ushort crc;
|
||||
uint16_t crc;
|
||||
|
||||
NuStraw* pStraw;
|
||||
long uncompRemaining;
|
||||
|
||||
#ifdef FULL_SQ_HEADER
|
||||
ushort checksum;
|
||||
uint16_t checksum;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -98,12 +98,12 @@ typedef struct SQState {
|
|||
*/
|
||||
EncTreeNode node[kNuSQNumNodes];
|
||||
|
||||
int treeHead; /* index to head node of final tree */
|
||||
int treeHead; /* index to head node of final tree */
|
||||
|
||||
/* encoding table */
|
||||
int codeLen[kNuSQNumVals]; /* number of bits in code for symbol N */
|
||||
ushort code[kNuSQNumVals]; /* bits for symbol N (first bit in lsb) */
|
||||
ushort tmpCode; /* temporary code value */
|
||||
uint16_t code[kNuSQNumVals]; /* bits for symbol N (first bit in lsb) */
|
||||
uint16_t tmpCode; /* temporary code value */
|
||||
} SQState;
|
||||
|
||||
|
||||
|
@ -117,11 +117,10 @@ typedef struct SQState {
|
|||
*
|
||||
* Returns kNuSQEOFToken as the value when we're out of data.
|
||||
*/
|
||||
static NuError
|
||||
Nu_SQGetcCRC(SQState* pSqState, int* pSym)
|
||||
static NuError Nu_SQGetcCRC(SQState* pSqState, int* pSym)
|
||||
{
|
||||
NuError err;
|
||||
uchar c;
|
||||
uint8_t c;
|
||||
|
||||
if (!pSqState->uncompRemaining) {
|
||||
*pSym = kNuSQEOFToken;
|
||||
|
@ -148,8 +147,7 @@ Nu_SQGetcCRC(SQState* pSqState, int* pSym)
|
|||
*
|
||||
* Returns kNuSQEOFToken in "*pSum" when we reach the end of the input.
|
||||
*/
|
||||
static NuError
|
||||
Nu_SQGetcRLE(SQState* pSqState, int* pSym)
|
||||
static NuError Nu_SQGetcRLE(SQState* pSqState, int* pSym)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
int likeCount, newSym;
|
||||
|
@ -275,8 +273,7 @@ bail:
|
|||
/*
|
||||
* Return the greater of two integers.
|
||||
*/
|
||||
static int
|
||||
Nu_SQMax(int a, int b)
|
||||
static int Nu_SQMax(int a, int b)
|
||||
{
|
||||
if (a > b)
|
||||
return a;
|
||||
|
@ -289,8 +286,7 @@ Nu_SQMax(int a, int b)
|
|||
* Priority is given to weight, then depth. "a" and "b" are heaps,
|
||||
* so we only need to look at the root element.
|
||||
*/
|
||||
static int
|
||||
Nu_SQCmpTrees(SQState* pSqState, int a, int b)
|
||||
static int Nu_SQCmpTrees(SQState* pSqState, int a, int b)
|
||||
{
|
||||
if (pSqState->node[a].weight > pSqState->node[b].weight)
|
||||
return true;
|
||||
|
@ -312,8 +308,7 @@ Nu_SQCmpTrees(SQState* pSqState, int a, int b)
|
|||
/*
|
||||
* Recursively make a heap from a heap with a new top.
|
||||
*/
|
||||
static void
|
||||
Nu_SQHeapAdjust(SQState* pSqState, int list[], int top, int bottom)
|
||||
static void Nu_SQHeapAdjust(SQState* pSqState, int list[], int top, int bottom)
|
||||
{
|
||||
int k, temp;
|
||||
|
||||
|
@ -337,8 +332,7 @@ Nu_SQHeapAdjust(SQState* pSqState, int list[], int top, int bottom)
|
|||
/*
|
||||
* Create a heap.
|
||||
*/
|
||||
static void
|
||||
Nu_SQHeap(SQState* pSqState, int list[], int length)
|
||||
static void Nu_SQHeap(SQState* pSqState, int list[], int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -365,8 +359,7 @@ Nu_SQHeap(SQState* pSqState, int list[], int length)
|
|||
* moving the last element over the top element and
|
||||
* reheaping the shorter list.
|
||||
*/
|
||||
static void
|
||||
Nu_SQBuildTree(SQState* pSqState, int list[], int len)
|
||||
static void Nu_SQBuildTree(SQState* pSqState, int list[], int len)
|
||||
{
|
||||
int freenode; /* next free node in tree */
|
||||
EncTreeNode* frnp; /* free node pointer */
|
||||
|
@ -422,8 +415,7 @@ Nu_SQBuildTree(SQState* pSqState, int list[], int len)
|
|||
*
|
||||
* Returns zero on success, nonzero if codes are too long.
|
||||
*/
|
||||
static int
|
||||
Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
|
||||
static int Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
|
||||
{
|
||||
int l, r;
|
||||
|
||||
|
@ -437,7 +429,7 @@ Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
|
|||
*/
|
||||
pSqState->codeLen[root] = level;
|
||||
pSqState->code[root] =
|
||||
pSqState->tmpCode & (((ushort)~0) >> (16 - level));
|
||||
pSqState->tmpCode & (((uint16_t)~0) >> (16 - level));
|
||||
return (level > 16) ? -1 : 0;
|
||||
} else {
|
||||
if (l != kNuSQNoChild) {
|
||||
|
@ -470,12 +462,11 @@ Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
|
|||
* the codes will fit in an unsigned integer. Rescaling is
|
||||
* used if necessary to limit the code length.
|
||||
*/
|
||||
static void
|
||||
Nu_SQScale(SQState* pSqState, int ceiling)
|
||||
static void Nu_SQScale(SQState* pSqState, int ceiling)
|
||||
{
|
||||
int i;
|
||||
int wt, ovflw, divisor;
|
||||
ushort sum;
|
||||
uint16_t sum;
|
||||
int increased; /* flag */
|
||||
|
||||
do {
|
||||
|
@ -510,8 +501,7 @@ Nu_SQScale(SQState* pSqState, int ceiling)
|
|||
* Build a frequency table from the post-RLE input stream, then generate
|
||||
* an encoding tree from the results.
|
||||
*/
|
||||
static NuError
|
||||
Nu_SQComputeHuffTree(SQState* pSqState)
|
||||
static NuError Nu_SQComputeHuffTree(SQState* pSqState)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
int btreeList[kNuSQNumVals]; /* list of intermediate binary trees */
|
||||
|
@ -610,12 +600,12 @@ bail:
|
|||
* Compress data from input to output, using the values in the "code"
|
||||
* and "codeLen" arrays.
|
||||
*/
|
||||
static NuError
|
||||
Nu_SQCompressInput(SQState* pSqState, FILE* fp, long* pCompressedLen)
|
||||
static NuError Nu_SQCompressInput(SQState* pSqState, FILE* fp,
|
||||
long* pCompressedLen)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
int sym = kNuSQEOFToken-1;
|
||||
unsigned long bits, code; /* must hold at least 23 bits */
|
||||
uint32_t bits, code; /* must hold at least 23 bits */
|
||||
int codeLen, gotbits;
|
||||
long compressedLen;
|
||||
|
||||
|
@ -661,11 +651,10 @@ bail:
|
|||
/*
|
||||
* Write a 16-bit value in little-endian order.
|
||||
*/
|
||||
static NuError
|
||||
Nu_SQWriteShort(FILE* outfp, short val)
|
||||
static NuError Nu_SQWriteShort(FILE* outfp, short val)
|
||||
{
|
||||
NuError err;
|
||||
uchar tmpc;
|
||||
uint8_t tmpc;
|
||||
|
||||
tmpc = val & 0xff;
|
||||
err = Nu_FWrite(outfp, &tmpc, 1);
|
||||
|
@ -689,9 +678,8 @@ bail:
|
|||
* it an empty file. "xsq" works fine, creating an empty tree that
|
||||
* "xusq" unpacks.
|
||||
*/
|
||||
NuError
|
||||
Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
ulong srcLen, ulong* pDstLen, ushort* pCrc)
|
||||
NuError Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
SQState sqState;
|
||||
|
@ -704,7 +692,7 @@ Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
|
||||
sqState.pArchive = pArchive;
|
||||
sqState.crc = 0;
|
||||
if (pCrc == nil) {
|
||||
if (pCrc == NULL) {
|
||||
sqState.doCalcCRC = false;
|
||||
} else {
|
||||
sqState.doCalcCRC = true;
|
||||
|
@ -727,7 +715,7 @@ Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
|||
err = Nu_SQComputeHuffTree(&sqState);
|
||||
BailError(err);
|
||||
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = sqState.crc;
|
||||
|
||||
/*
|
||||
|
@ -822,8 +810,8 @@ bail:
|
|||
* State during uncompression.
|
||||
*/
|
||||
typedef struct USQState {
|
||||
ulong dataInBuffer;
|
||||
uchar* dataPtr;
|
||||
uint32_t dataInBuffer;
|
||||
uint8_t* dataPtr;
|
||||
int bitPosn;
|
||||
int bits;
|
||||
|
||||
|
@ -842,8 +830,7 @@ typedef struct USQState {
|
|||
/*
|
||||
* Decode the next symbol from the Huffman stream.
|
||||
*/
|
||||
static NuError
|
||||
Nu_USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
|
||||
static NuError Nu_USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
|
||||
{
|
||||
short val = 0;
|
||||
int bits, bitPosn;
|
||||
|
@ -879,8 +866,7 @@ Nu_USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
|
|||
/*
|
||||
* Read two bytes of signed data out of the buffer.
|
||||
*/
|
||||
static inline NuError
|
||||
Nu_USQReadShort(USQState* pUsqState, short* pShort)
|
||||
static inline NuError Nu_USQReadShort(USQState* pUsqState, short* pShort)
|
||||
{
|
||||
if (pUsqState->dataInBuffer < 2)
|
||||
return kNuErrBufferUnderrun;
|
||||
|
@ -898,24 +884,23 @@ Nu_USQReadShort(USQState* pUsqState, short* pShort)
|
|||
* Because we have a stop symbol, knowing the uncompressed length of
|
||||
* the file is not essential.
|
||||
*/
|
||||
NuError
|
||||
Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
|
||||
NuError Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
USQState usqState;
|
||||
ulong compRemaining, getSize;
|
||||
uint32_t compRemaining, getSize;
|
||||
#ifdef FULL_SQ_HEADER
|
||||
ushort magic, fileChecksum, checksum;
|
||||
uint16_t magic, fileChecksum, checksum;
|
||||
#endif
|
||||
short nodeCount;
|
||||
int i, inrep;
|
||||
uchar lastc = 0;
|
||||
uint8_t lastc = 0;
|
||||
|
||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||
if (err != kNuErrNone)
|
||||
return err;
|
||||
Assert(pArchive->compBuf != nil);
|
||||
Assert(pArchive->compBuf != NULL);
|
||||
|
||||
usqState.dataInBuffer = 0;
|
||||
usqState.dataPtr = pArchive->compBuf;
|
||||
|
@ -945,7 +930,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
err = Nu_FRead(infp, usqState.dataPtr, getSize);
|
||||
if (err != kNuErrNone) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"failed reading compressed data (%ld bytes)", getSize);
|
||||
"failed reading compressed data (%u bytes)", getSize);
|
||||
goto bail;
|
||||
}
|
||||
usqState.dataInBuffer += getSize;
|
||||
|
@ -1046,7 +1031,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
getSize);
|
||||
if (err != kNuErrNone) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"failed reading compressed data (%ld bytes)", getSize);
|
||||
"failed reading compressed data (%u bytes)", getSize);
|
||||
goto bail;
|
||||
}
|
||||
usqState.dataInBuffer += getSize;
|
||||
|
@ -1080,7 +1065,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
val = 2;
|
||||
}
|
||||
while (--val) {
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);
|
||||
err = Nu_FunnelWrite(pArchive, pFunnel, &lastc, 1);
|
||||
#ifdef FULL_SQ_HEADER
|
||||
|
@ -1095,7 +1080,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
inrep = true;
|
||||
} else {
|
||||
lastc = val;
|
||||
if (pCrc != nil)
|
||||
if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);
|
||||
err = Nu_FunnelWrite(pArchive, pFunnel, &lastc, 1);
|
||||
#ifdef FULL_SQ_HEADER
|
||||
|
@ -1135,7 +1120,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
if (usqState.dataInBuffer > 1) {
|
||||
DBUG(("--- Found %ld bytes following compressed data (compRem=%ld)\n",
|
||||
usqState.dataInBuffer, compRemaining));
|
||||
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) unexpected fluff (%ld)",
|
||||
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) unexpected fluff (%u)",
|
||||
usqState.dataInBuffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING-LIB.
|
||||
*
|
||||
* This file was adapted from Devin Reade's "sunos4.h" in NuLib 3.2.5.
|
||||
* It is provided for compilation under SunOS 4.x, when an ANSI compiler
|
||||
* (such as gcc) is used. The system header files aren't quite sufficient
|
||||
* to eliminate hordes of warnings.
|
||||
*/
|
||||
#ifndef __SunOS4__
|
||||
#define __SunOS4__
|
||||
|
||||
#ifdef __GNUC__
|
||||
extern int _flsbuf(int, FILE*);
|
||||
extern int _filbuf(FILE*);
|
||||
#endif
|
||||
|
||||
extern void bcopy(char*, char*, int);
|
||||
extern int fclose(FILE*);
|
||||
extern int fflush(FILE*);
|
||||
extern int fprintf(FILE*, const char*, ...);
|
||||
extern int fread(char*, int, int, FILE *);
|
||||
extern int fseek(FILE*, long, int);
|
||||
extern int ftruncate(int, off_t);
|
||||
extern int fwrite(const char*, int, int, FILE*);
|
||||
extern char* mktemp(char *template);
|
||||
extern time_t mktime(struct tm*);
|
||||
extern int perror(const char*);
|
||||
extern int printf(const char*, ...);
|
||||
extern int remove(const char*);
|
||||
extern int rename(const char*, const char*);
|
||||
extern int tolower(int);
|
||||
extern int setvbuf(FILE*, char*, int, int);
|
||||
extern int sscanf(char*, const char*, ...);
|
||||
extern int strcasecmp(const char*, const char*);
|
||||
extern int strncasecmp(const char*, const char*, size_t);
|
||||
extern long strtol(const char *, char **, int);
|
||||
extern int system(const char*);
|
||||
extern time_t timelocal(struct tm*);
|
||||
extern time_t time(time_t*);
|
||||
extern int toupper(int);
|
||||
extern int vfprintf(FILE*, const char *, va_list);
|
||||
extern char* vsprintf(char *str, const char *format, va_list ap);
|
||||
|
||||
#endif /*__SunOS4__*/
|
|
@ -6,8 +6,8 @@
|
|||
*
|
||||
* External type definitions and function prototypes.
|
||||
*/
|
||||
#ifndef __SysDefs__
|
||||
#define __SysDefs__
|
||||
#ifndef NUFXLIB_SYSDEFS_H
|
||||
#define NUFXLIB_SYSDEFS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
|
@ -18,7 +18,6 @@
|
|||
#endif
|
||||
|
||||
/* these should exist everywhere */
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
|
@ -55,10 +54,6 @@
|
|||
# define SNPRINTF_DECLARED
|
||||
# define VSNPRINTF_DECLARED
|
||||
# define SPRINTF_RETURNS_INT
|
||||
# define uchar unsigned char
|
||||
# define ushort unsigned short
|
||||
# define uint unsigned int
|
||||
# define ulong unsigned long
|
||||
# define inline /*Visual C++6.0 can't inline ".c" files*/
|
||||
# define mode_t int
|
||||
# define ENABLE_SQ
|
||||
|
@ -72,8 +67,11 @@
|
|||
# include <direct.h>
|
||||
# define FOPEN_WANTS_B
|
||||
# define HAVE_CHSIZE
|
||||
# define snprintf _snprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# if _MSC_VER < 1900 /* no snprintf until Visual Studio 2015 */
|
||||
# define snprintf _snprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MALLOC_H
|
||||
|
@ -123,26 +121,18 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* resource forks on UFS filesystem under Mac OS X are a kluge */
|
||||
/*#ifdef MAC*/
|
||||
/*# define HAS_RESOURCE_FORKS*/
|
||||
/*#endif*/
|
||||
|
||||
#if defined(__ORCAC__) || defined(MAC_LIKE)
|
||||
# define HAS_RESOURCE_FORKS
|
||||
#endif
|
||||
/* not currently using filesystem resource forks */
|
||||
//#if defined(__ORCAC__) || defined(MAC_LIKE)
|
||||
//# define HAS_RESOURCE_FORKS
|
||||
//#endif
|
||||
|
||||
/* __FUNCTION__ was missing from BeOS __MWERKS__, and might be gcc-only */
|
||||
#ifdef __GNUC__
|
||||
# define HAS__FUNCTION__
|
||||
#endif
|
||||
|
||||
#if defined(__sun__) && !defined(__SVR4)
|
||||
# include "SunOS4.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# define HAS_MALLOC_CHECK_
|
||||
#endif
|
||||
|
||||
#endif /*__SysDefs__*/
|
||||
#endif /*NUFXLIB_SYSDEFS_H*/
|
||||
|
|
381
nufxlib/Thread.c
381
nufxlib/Thread.c
|
@ -6,7 +6,6 @@
|
|||
*
|
||||
* Thread-level operations.
|
||||
*/
|
||||
#define __Thread_c__ 1
|
||||
#include "NufxLibPriv.h"
|
||||
|
||||
|
||||
|
@ -16,6 +15,17 @@
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns thread N, or NULL if the index is invalid.
|
||||
*/
|
||||
NuThread* Nu_GetThread(const NuRecord* pRecord, int idx)
|
||||
{
|
||||
if (idx >= (int)pRecord->recTotalThreads)
|
||||
return NULL;
|
||||
else
|
||||
return &pRecord->pThreads[idx];
|
||||
}
|
||||
|
||||
/*
|
||||
* ShrinkIt v3.0.0 had a bug where the filename thread would get created
|
||||
* with the high bits set. We want to undo that without stomping on
|
||||
|
@ -26,16 +36,15 @@
|
|||
* This high-bit-ism was also done for disk archives by most older versions
|
||||
* of ShrinkIt.
|
||||
*/
|
||||
void
|
||||
Nu_StripHiIfAllSet(char* str)
|
||||
void Nu_StripHiIfAllSet(char* str)
|
||||
{
|
||||
uchar* cp;
|
||||
uint8_t* cp;
|
||||
|
||||
for (cp = (uchar*)str; *cp != '\0'; cp++)
|
||||
for (cp = (uint8_t*)str; *cp != '\0'; cp++)
|
||||
if (!(*cp & 0x80))
|
||||
return;
|
||||
|
||||
for (cp = (uchar*)str; *cp != '\0'; cp++)
|
||||
for (cp = (uint8_t*)str; *cp != '\0'; cp++)
|
||||
*cp &= 0x7f;
|
||||
}
|
||||
|
||||
|
@ -44,8 +53,7 @@ Nu_StripHiIfAllSet(char* str)
|
|||
* Decide if a thread is pre-sized (i.e. has a fixed maximum size with a
|
||||
* lesser amount of uncompressed data within) based on the threadID.
|
||||
*/
|
||||
Boolean
|
||||
Nu_IsPresizedThreadID(NuThreadID threadID)
|
||||
Boolean Nu_IsPresizedThreadID(NuThreadID threadID)
|
||||
{
|
||||
if (threadID == kNuThreadIDFilename || threadID == kNuThreadIDComment)
|
||||
return true;
|
||||
|
@ -58,8 +66,7 @@ Nu_IsPresizedThreadID(NuThreadID threadID)
|
|||
* Return an indication of whether the type of thread specified by ThreadID
|
||||
* should ever be compressed. Right now, that's only data-class threads.
|
||||
*/
|
||||
Boolean
|
||||
Nu_IsCompressibleThreadID(NuThreadID threadID)
|
||||
Boolean Nu_IsCompressibleThreadID(NuThreadID threadID)
|
||||
{
|
||||
if (NuThreadIDGetClass(threadID) == kNuThreadClassData)
|
||||
return true;
|
||||
|
@ -72,8 +79,7 @@ Nu_IsCompressibleThreadID(NuThreadID threadID)
|
|||
* Decide if the thread has a CRC, based on the record version and the
|
||||
* threadID.
|
||||
*/
|
||||
Boolean
|
||||
Nu_ThreadHasCRC(long recordVersion, NuThreadID threadID)
|
||||
Boolean Nu_ThreadHasCRC(uint16_t recordVersion, NuThreadID threadID)
|
||||
{
|
||||
return recordVersion >= 3 &&
|
||||
NuThreadIDGetClass(threadID) == kNuThreadClassData;
|
||||
|
@ -83,8 +89,7 @@ Nu_ThreadHasCRC(long recordVersion, NuThreadID threadID)
|
|||
/*
|
||||
* Search through a given NuRecord for the specified thread.
|
||||
*/
|
||||
NuError
|
||||
Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
|
||||
NuError Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
|
||||
NuThread** ppThread)
|
||||
{
|
||||
NuThread* pThread;
|
||||
|
@ -92,7 +97,7 @@ Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
|
|||
|
||||
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
|
||||
pThread = Nu_GetThread(pRecord, idx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
if (pThread->threadIdx == thread) {
|
||||
*ppThread = pThread;
|
||||
|
@ -108,8 +113,7 @@ Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
|
|||
* Search through a given NuRecord for the first thread with a matching
|
||||
* threadID.
|
||||
*/
|
||||
NuError
|
||||
Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
|
||||
NuError Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
|
||||
NuThread** ppThread)
|
||||
{
|
||||
NuThread* pThread;
|
||||
|
@ -117,7 +121,7 @@ Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
|
|||
|
||||
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
|
||||
pThread = Nu_GetThread(pRecord, idx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
if (NuGetThreadID(pThread) == threadID) {
|
||||
*ppThread = pThread;
|
||||
|
@ -132,11 +136,10 @@ Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
|
|||
/*
|
||||
* Copy the contents of a NuThread.
|
||||
*/
|
||||
void
|
||||
Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread)
|
||||
void Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread)
|
||||
{
|
||||
Assert(pDstThread != nil);
|
||||
Assert(pSrcThread != nil);
|
||||
Assert(pDstThread != NULL);
|
||||
Assert(pSrcThread != NULL);
|
||||
|
||||
memcpy(pDstThread, pSrcThread, sizeof(*pDstThread));
|
||||
}
|
||||
|
@ -151,14 +154,14 @@ Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread)
|
|||
/*
|
||||
* Read a single thread header from the archive.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ReadThreadHeader(NuArchive* pArchive, NuThread* pThread, ushort* pCrc)
|
||||
static NuError Nu_ReadThreadHeader(NuArchive* pArchive, NuThread* pThread,
|
||||
uint16_t* pCrc)
|
||||
{
|
||||
FILE* fp;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
fp = pArchive->archiveFp;
|
||||
|
||||
|
@ -184,17 +187,20 @@ Nu_ReadThreadHeader(NuArchive* pArchive, NuThread* pThread, ushort* pCrc)
|
|||
* have used a linked list like NuLib, but that doesn't really provide any
|
||||
* benefit for us, and adds complexity.
|
||||
*/
|
||||
NuError
|
||||
Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
|
||||
NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
|
||||
uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuThread* pThread;
|
||||
long count;
|
||||
Boolean hasData = false;
|
||||
Boolean needFakeData, needFakeRsrc;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pRecord != nil);
|
||||
Assert(pCrc != nil);
|
||||
needFakeData = true;
|
||||
needFakeRsrc = (pRecord->recStorageType == kNuStorageExtended);
|
||||
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pRecord != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
if (!pRecord->recTotalThreads) {
|
||||
/* not sure if this is reasonable, but we can handle it */
|
||||
|
@ -212,8 +218,16 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
|
|||
err = Nu_ReadThreadHeader(pArchive, pThread, pCrc);
|
||||
BailError(err);
|
||||
|
||||
if (pThread->thThreadClass == kNuThreadClassData)
|
||||
hasData = true;
|
||||
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||
if (pThread->thThreadKind == kNuThreadKindDataFork) {
|
||||
needFakeData = false;
|
||||
} else if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
|
||||
needFakeRsrc = false;
|
||||
} else if (pThread->thThreadKind == kNuThreadKindDiskImage) {
|
||||
/* needFakeRsrc shouldn't be set, but clear anyway */
|
||||
needFakeData = needFakeRsrc = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Some versions of ShrinkIt write an invalid thThreadEOF for disks,
|
||||
|
@ -255,13 +269,14 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
|
|||
* If "mask threadless" is set, create "fake" threads with empty
|
||||
* data and resource forks as needed.
|
||||
*/
|
||||
if (!hasData && pArchive->valMaskDataless) {
|
||||
Boolean needRsrc = (pRecord->recStorageType == kNuStorageExtended);
|
||||
if ((needFakeData || needFakeRsrc) && pArchive->valMaskDataless) {
|
||||
int firstNewThread = pRecord->recTotalThreads;
|
||||
|
||||
pRecord->recTotalThreads++;
|
||||
pRecord->fakeThreads++;
|
||||
if (needRsrc) {
|
||||
if (needFakeData) {
|
||||
pRecord->recTotalThreads++;
|
||||
pRecord->fakeThreads++;
|
||||
}
|
||||
if (needFakeRsrc) {
|
||||
pRecord->recTotalThreads++;
|
||||
pRecord->fakeThreads++;
|
||||
}
|
||||
|
@ -272,22 +287,23 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
|
|||
|
||||
pThread = pRecord->pThreads + firstNewThread;
|
||||
|
||||
pThread->thThreadClass = kNuThreadClassData;
|
||||
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
||||
pThread->thThreadKind = 0x0000; /* data fork */
|
||||
pThread->thThreadCRC = kNuInitialThreadCRC;
|
||||
pThread->thThreadEOF = 0;
|
||||
pThread->thCompThreadEOF = 0;
|
||||
pThread->threadIdx = Nu_GetNextThreadIdx(pArchive);
|
||||
pThread->actualThreadEOF = 0;
|
||||
pThread->fileOffset = -99999999;
|
||||
pThread->used = false;
|
||||
|
||||
if (needRsrc) {
|
||||
pThread++;
|
||||
if (needFakeData) {
|
||||
pThread->thThreadClass = kNuThreadClassData;
|
||||
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
||||
pThread->thThreadKind = 0x0002; /* rsrc fork */
|
||||
pThread->thThreadKind = kNuThreadKindDataFork;
|
||||
pThread->thThreadCRC = kNuInitialThreadCRC;
|
||||
pThread->thThreadEOF = 0;
|
||||
pThread->thCompThreadEOF = 0;
|
||||
pThread->threadIdx = Nu_GetNextThreadIdx(pArchive);
|
||||
pThread->actualThreadEOF = 0;
|
||||
pThread->fileOffset = -99999999;
|
||||
pThread->used = false;
|
||||
pThread++;
|
||||
}
|
||||
if (needFakeRsrc) {
|
||||
pThread->thThreadClass = kNuThreadClassData;
|
||||
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
||||
pThread->thThreadKind = kNuThreadKindRsrcFork;
|
||||
pThread->thThreadCRC = kNuInitialThreadCRC;
|
||||
pThread->thThreadEOF = 0;
|
||||
pThread->thCompThreadEOF = 0;
|
||||
|
@ -306,17 +322,16 @@ bail:
|
|||
/*
|
||||
* Write a single thread header to the archive.
|
||||
*/
|
||||
static NuError
|
||||
Nu_WriteThreadHeader(NuArchive* pArchive, const NuThread* pThread, FILE* fp,
|
||||
ushort* pCrc)
|
||||
static NuError Nu_WriteThreadHeader(NuArchive* pArchive,
|
||||
const NuThread* pThread, FILE* fp, uint16_t* pCrc)
|
||||
{
|
||||
Assert(pArchive != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(fp != nil);
|
||||
Assert(pCrc != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(fp != NULL);
|
||||
Assert(pCrc != NULL);
|
||||
|
||||
Nu_WriteTwoC(pArchive, fp, pThread->thThreadClass, pCrc);
|
||||
Nu_WriteTwoC(pArchive, fp, (ushort)pThread->thThreadFormat, pCrc);
|
||||
Nu_WriteTwoC(pArchive, fp, (uint16_t)pThread->thThreadFormat, pCrc);
|
||||
Nu_WriteTwoC(pArchive, fp, pThread->thThreadKind, pCrc);
|
||||
Nu_WriteTwoC(pArchive, fp, pThread->thThreadCRC, pCrc);
|
||||
Nu_WriteFourC(pArchive, fp, pThread->thThreadEOF, pCrc);
|
||||
|
@ -332,9 +347,8 @@ Nu_WriteThreadHeader(NuArchive* pArchive, const NuThread* pThread, FILE* fp,
|
|||
* 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,
|
||||
ushort* pCrc)
|
||||
NuError Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp,
|
||||
uint16_t* pCrc)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuThread* pThread;
|
||||
|
@ -342,7 +356,7 @@ Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp,
|
|||
|
||||
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
|
||||
pThread = Nu_GetThread(pRecord, idx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
err = Nu_WriteThreadHeader(pArchive, pThread, fp, pCrc);
|
||||
BailError(err);
|
||||
|
@ -366,14 +380,13 @@ bail:
|
|||
* Requires that the pArchive->currentOffset be set to the offset
|
||||
* immediately after the last of the thread headers.
|
||||
*/
|
||||
NuError
|
||||
Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord)
|
||||
NuError Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord)
|
||||
{
|
||||
NuThread* pThread;
|
||||
long fileOffset, count;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pRecord != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pRecord != NULL);
|
||||
|
||||
/*pRecord->totalLength = 0;*/
|
||||
pRecord->totalCompLength = 0;
|
||||
|
@ -407,15 +420,14 @@ Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord)
|
|||
* show to the application. (Someday I'll get AndyN for putting me
|
||||
* through this...)
|
||||
*/
|
||||
NuError
|
||||
Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
|
||||
NuError Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuThread* pThread;
|
||||
FILE* fp;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pRecord != nil);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pRecord != NULL);
|
||||
|
||||
fp = pArchive->archiveFp;
|
||||
|
||||
|
@ -423,23 +435,23 @@ Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
|
|||
|
||||
pThread = pRecord->pThreads;
|
||||
while (numThreads--) {
|
||||
if (pRecord->threadFilename == nil &&
|
||||
if (pRecord->threadFilenameMOR == NULL &&
|
||||
NuMakeThreadID(pThread->thThreadClass, pThread->thThreadKind) ==
|
||||
kNuThreadIDFilename)
|
||||
{
|
||||
/* it's the first filename thread, read the whole thing */
|
||||
if (pThread->thCompThreadEOF > kNuReasonableFilenameLen) {
|
||||
err = kNuErrBadRecord;
|
||||
Nu_ReportError(NU_BLOB, err, "Bad thread filename len (%lu)",
|
||||
Nu_ReportError(NU_BLOB, err, "Bad thread filename len (%u)",
|
||||
pThread->thCompThreadEOF);
|
||||
goto bail;
|
||||
}
|
||||
pRecord->threadFilename = Nu_Malloc(pArchive,
|
||||
pRecord->threadFilenameMOR = Nu_Malloc(pArchive,
|
||||
pThread->thCompThreadEOF +1);
|
||||
BailAlloc(pRecord->threadFilename);
|
||||
BailAlloc(pRecord->threadFilenameMOR);
|
||||
|
||||
/* note there is no CRC on a filename thread */
|
||||
(void) Nu_ReadBytes(pArchive, fp, pRecord->threadFilename,
|
||||
(void) Nu_ReadBytes(pArchive, fp, pRecord->threadFilenameMOR,
|
||||
pThread->thCompThreadEOF);
|
||||
if ((err = Nu_HeaderIOFailed(pArchive, fp)) != kNuErrNone) {
|
||||
Nu_ReportError(NU_BLOB, err, "Failed reading filename thread");
|
||||
|
@ -447,15 +459,15 @@ Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
|
|||
}
|
||||
|
||||
/* null-terminate on the actual len, not the buffer len */
|
||||
pRecord->threadFilename[pThread->thThreadEOF] = '\0';
|
||||
pRecord->threadFilenameMOR[pThread->thThreadEOF] = '\0';
|
||||
|
||||
Nu_StripHiIfAllSet(pRecord->threadFilename);
|
||||
Nu_StripHiIfAllSet(pRecord->threadFilenameMOR);
|
||||
|
||||
/* prefer this one over the record one, but only one should exist */
|
||||
if (pRecord->filename != nil) {
|
||||
if (pRecord->filenameMOR != NULL) {
|
||||
DBUG(("--- HEY: got record filename and thread filename\n"));
|
||||
}
|
||||
pRecord->filename = pRecord->threadFilename;
|
||||
pRecord->filenameMOR = pRecord->threadFilenameMOR;
|
||||
|
||||
} else {
|
||||
/* not a filename (or not first filename), skip past it */
|
||||
|
@ -473,9 +485,9 @@ Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
|
|||
* end up with a disk image that had no name attached. This will tend
|
||||
* to confuse things, so we go ahead and give it a name.
|
||||
*/
|
||||
if (pRecord->filename == nil) {
|
||||
if (pRecord->filenameMOR == NULL) {
|
||||
DBUG(("+++ no filename found, using default record name\n"));
|
||||
pRecord->filename = kNuDefaultRecordName;
|
||||
pRecord->filenameMOR = kNuDefaultRecordName;
|
||||
}
|
||||
|
||||
pArchive->currentOffset += pRecord->totalCompLength;
|
||||
|
@ -494,8 +506,7 @@ bail:
|
|||
* assumes that the file pointer is set to the start of the thread's data
|
||||
* already.
|
||||
*/
|
||||
NuError
|
||||
Nu_SkipThread(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
NuError Nu_SkipThread(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread)
|
||||
{
|
||||
NuError err;
|
||||
|
@ -522,12 +533,12 @@ Nu_SkipThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* If the archive is a stream, the stream must be positioned at the
|
||||
* start of pThread's data. If not, it will be seeked first.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ExtractThreadToDataSink(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, NuProgressData* pProgress, NuDataSink* pDataSink)
|
||||
static NuError Nu_ExtractThreadToDataSink(NuArchive* pArchive,
|
||||
const NuRecord* pRecord, const NuThread* pThread,
|
||||
NuProgressData* pProgress, NuDataSink* pDataSink)
|
||||
{
|
||||
NuError err;
|
||||
NuFunnel* pFunnel = nil;
|
||||
NuFunnel* pFunnel = NULL;
|
||||
|
||||
/* if it's not a stream, seek to the appropriate spot in the file */
|
||||
if (!Nu_IsStreaming(pArchive)) {
|
||||
|
@ -576,9 +587,8 @@ bail:
|
|||
* filters for every thread, which means we can reject specific kinds
|
||||
* of forks and/or give them different names. This is a good thing.
|
||||
*/
|
||||
static NuError
|
||||
Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread, NuDataSink* pDataSink)
|
||||
static NuError Nu_ExtractThreadCommon(NuArchive* pArchive,
|
||||
const NuRecord* pRecord, const NuThread* pThread, NuDataSink* pDataSink)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuSelectionProposal selProposal;
|
||||
|
@ -586,18 +596,19 @@ Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
NuProgressData progressData;
|
||||
NuProgressData* pProgressData;
|
||||
NuDataSink* pOrigDataSink;
|
||||
char* newPathStorage = nil;
|
||||
const char* newPathname;
|
||||
UNICHAR* newPathStorageUNI = NULL;
|
||||
UNICHAR* recFilenameStorageUNI = NULL;
|
||||
const UNICHAR* newPathnameUNI;
|
||||
NuResult result;
|
||||
uchar newFssep;
|
||||
uint8_t newFssep;
|
||||
Boolean doFreeSink = false;
|
||||
|
||||
Assert(pRecord != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(pDataSink != nil);
|
||||
Assert(pRecord != NULL);
|
||||
Assert(pThread != NULL);
|
||||
Assert(pDataSink != NULL);
|
||||
|
||||
memset(&progressData, 0, sizeof(progressData));
|
||||
pProgressData = nil;
|
||||
pProgressData = NULL;
|
||||
|
||||
/*
|
||||
* If we're just trying to verify the archive contents, create a
|
||||
|
@ -619,7 +630,7 @@ Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* use by the "bulk" extract, not the per-thread extract, but it
|
||||
* still applies if they so desire.
|
||||
*/
|
||||
if (pArchive->selectionFilterFunc != nil) {
|
||||
if (pArchive->selectionFilterFunc != NULL) {
|
||||
selProposal.pRecord = pRecord;
|
||||
selProposal.pThread = pThread;
|
||||
result = (*pArchive->selectionFilterFunc)(pArchive, &selProposal);
|
||||
|
@ -632,9 +643,11 @@ Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
}
|
||||
}
|
||||
|
||||
newPathname = nil;
|
||||
newPathnameUNI = NULL;
|
||||
newFssep = 0;
|
||||
|
||||
recFilenameStorageUNI = Nu_CopyMORToUNI(pRecord->filenameMOR);
|
||||
|
||||
retry_name:
|
||||
if (Nu_DataSinkGetType(pDataSink) == kNuDataSinkToFile) {
|
||||
/*
|
||||
|
@ -645,21 +658,21 @@ retry_name:
|
|||
* Start by resetting everything to defaults, in case this isn't
|
||||
* our first time through the "rename" loop.
|
||||
*/
|
||||
newPathname = Nu_DataSinkFile_GetPathname(pDataSink);
|
||||
newPathnameUNI = Nu_DataSinkFile_GetPathname(pDataSink);
|
||||
newFssep = Nu_DataSinkFile_GetFssep(pDataSink);
|
||||
pDataSink = pOrigDataSink;
|
||||
|
||||
/* if they don't have a pathname func defined, we just use default */
|
||||
if (pArchive->outputPathnameFunc != nil) {
|
||||
pathProposal.pathname = pRecord->filename;
|
||||
if (pArchive->outputPathnameFunc != NULL) {
|
||||
pathProposal.pathnameUNI = recFilenameStorageUNI;
|
||||
pathProposal.filenameSeparator =
|
||||
NuGetSepFromSysInfo(pRecord->recFileSysInfo);
|
||||
pathProposal.pRecord = pRecord;
|
||||
pathProposal.pThread = pThread;
|
||||
pathProposal.newPathname = nil;
|
||||
pathProposal.newPathnameUNI = NULL;
|
||||
pathProposal.newFilenameSeparator = '\0';
|
||||
/*pathProposal.newStorage = (NuThreadID)-1;*/
|
||||
pathProposal.newDataSink = nil;
|
||||
pathProposal.newDataSink = NULL;
|
||||
|
||||
result = (*pArchive->outputPathnameFunc)(pArchive, &pathProposal);
|
||||
|
||||
|
@ -671,35 +684,38 @@ retry_name:
|
|||
}
|
||||
|
||||
/* we don't own this string, so make a copy */
|
||||
if (pathProposal.newPathname != nil) {
|
||||
newPathStorage = strdup(pathProposal.newPathname);
|
||||
newPathname = newPathStorage;
|
||||
} else
|
||||
newPathname = nil;
|
||||
if (pathProposal.newPathnameUNI != NULL) {
|
||||
Nu_Free(pArchive, newPathStorageUNI);
|
||||
newPathStorageUNI = strdup(pathProposal.newPathnameUNI);
|
||||
newPathnameUNI = newPathStorageUNI;
|
||||
} else {
|
||||
newPathnameUNI = NULL;
|
||||
}
|
||||
if (pathProposal.newFilenameSeparator != '\0')
|
||||
newFssep = pathProposal.newFilenameSeparator;
|
||||
|
||||
/* if they want to send this somewhere else, let them */
|
||||
if (pathProposal.newDataSink != nil)
|
||||
if (pathProposal.newDataSink != NULL)
|
||||
pDataSink = pathProposal.newDataSink;
|
||||
}
|
||||
|
||||
/* at least one of these must be set */
|
||||
Assert(!(newPathname == nil && pathProposal.newDataSink == nil));
|
||||
Assert(!(newPathnameUNI == NULL && pathProposal.newDataSink == NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the progress data if this is a data thread.
|
||||
*/
|
||||
if (newPathname == nil) {
|
||||
if (newPathnameUNI == NULL) {
|
||||
/* using a data sink; get the pathname out of the record */
|
||||
newPathname = pRecord->filename;
|
||||
newPathnameUNI = recFilenameStorageUNI;
|
||||
newFssep = NuGetSepFromSysInfo(pRecord->recFileSysInfo);
|
||||
}
|
||||
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||
pProgressData = &progressData;
|
||||
err = Nu_ProgressDataInit_Expand(pArchive, pProgressData, pRecord,
|
||||
newPathname, newFssep, Nu_DataSinkGetConvertEOL(pOrigDataSink));
|
||||
newPathnameUNI, newFssep, recFilenameStorageUNI,
|
||||
Nu_DataSinkGetConvertEOL(pOrigDataSink));
|
||||
BailError(err);
|
||||
|
||||
/* send initial progress so they see the right name if "open" fails */
|
||||
|
@ -713,23 +729,23 @@ retry_name:
|
|||
* We're extracting to a file. Open it, creating it if necessary and
|
||||
* allowed.
|
||||
*/
|
||||
FILE* fileFp = nil;
|
||||
FILE* fileFp = NULL;
|
||||
|
||||
err = Nu_OpenOutputFile(pArchive, pRecord, pThread, newPathname,
|
||||
err = Nu_OpenOutputFile(pArchive, pRecord, pThread, newPathnameUNI,
|
||||
newFssep, &fileFp);
|
||||
if (err == kNuErrRename) {
|
||||
/* they want to rename; the OutputPathname callback handles this */
|
||||
Nu_Free(pArchive, newPathStorage);
|
||||
newPathStorage = nil;
|
||||
Nu_Free(pArchive, newPathStorageUNI);
|
||||
newPathStorageUNI = NULL;
|
||||
/* reset these just to be careful */
|
||||
newPathname = nil;
|
||||
fileFp = nil;
|
||||
newPathnameUNI = NULL;
|
||||
fileFp = NULL;
|
||||
goto retry_name;
|
||||
} else if (err != kNuErrNone) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
Assert(fileFp != nil);
|
||||
Assert(fileFp != NULL);
|
||||
(void) Nu_DataSinkFile_SetFP(pDataSink, fileFp);
|
||||
|
||||
DBUG(("+++ EXTRACTING 0x%08lx from '%s' at offset %0ld to '%s'\n",
|
||||
|
@ -752,13 +768,13 @@ retry_name:
|
|||
* permissions as appropriate.
|
||||
*/
|
||||
err = Nu_CloseOutputFile(pArchive, pRecord,
|
||||
Nu_DataSinkFile_GetFP(pDataSink), newPathname);
|
||||
Nu_DataSinkFile_SetFP(pDataSink, nil);
|
||||
Nu_DataSinkFile_GetFP(pDataSink), newPathnameUNI);
|
||||
Nu_DataSinkFile_SetFP(pDataSink, NULL);
|
||||
BailError(err);
|
||||
}
|
||||
|
||||
bail:
|
||||
if (err != kNuErrNone && pProgressData != nil) {
|
||||
if (err != kNuErrNone && pProgressData != NULL) {
|
||||
/* send a final progress message, indicating failure */
|
||||
if (err == kNuErrSkipped)
|
||||
pProgressData->state = kNuProgressSkipped;
|
||||
|
@ -773,7 +789,8 @@ bail:
|
|||
if (Nu_DataSinkGetType(pDataSink) == kNuDataSinkToFile)
|
||||
Nu_DataSinkFile_Close(pDataSink);
|
||||
|
||||
Nu_Free(pArchive, newPathStorage);
|
||||
Nu_Free(pArchive, newPathStorageUNI);
|
||||
Nu_Free(pArchive, recFilenameStorageUNI);
|
||||
|
||||
if (doFreeSink)
|
||||
Nu_DataSinkFree(pDataSink);
|
||||
|
@ -785,12 +802,12 @@ bail:
|
|||
*
|
||||
* Streaming archives must be properly positioned.
|
||||
*/
|
||||
NuError
|
||||
Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
NuError Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread)
|
||||
{
|
||||
NuError err;
|
||||
NuDataSink* pDataSink = nil;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
UNICHAR* recFilenameStorageUNI = NULL;
|
||||
NuValue eolConv;
|
||||
|
||||
/*
|
||||
|
@ -806,7 +823,8 @@ Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
eolConv = pArchive->valConvertExtractedEOL;
|
||||
if (NuGetThreadID(pThread) == kNuThreadIDDiskImage)
|
||||
eolConv = kNuConvertOff;
|
||||
err = Nu_DataSinkFile_New(true, eolConv, pRecord->filename,
|
||||
recFilenameStorageUNI = Nu_CopyMORToUNI(pRecord->filenameMOR);
|
||||
err = Nu_DataSinkFile_New(true, eolConv, recFilenameStorageUNI,
|
||||
NuGetSepFromSysInfo(pRecord->recFileSysInfo), &pDataSink);
|
||||
BailError(err);
|
||||
|
||||
|
@ -814,11 +832,12 @@ Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
BailError(err);
|
||||
|
||||
bail:
|
||||
if (pDataSink != nil) {
|
||||
if (pDataSink != NULL) {
|
||||
NuError err2 = Nu_DataSinkFree(pDataSink);
|
||||
if (err == kNuErrNone)
|
||||
err = err2;
|
||||
}
|
||||
Nu_Free(pArchive, recFilenameStorageUNI);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -827,8 +846,7 @@ bail:
|
|||
/*
|
||||
* Extract a thread, given the IDs and a data sink.
|
||||
*/
|
||||
NuError
|
||||
Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuError Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuDataSink* pDataSink)
|
||||
{
|
||||
NuError err;
|
||||
|
@ -837,7 +855,7 @@ Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
|
||||
if (Nu_IsStreaming(pArchive))
|
||||
return kNuErrUsage;
|
||||
if (threadIdx == 0 || pDataSink == nil)
|
||||
if (threadIdx == 0 || pDataSink == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
err = Nu_GetTOCIfNeeded(pArchive);
|
||||
BailError(err);
|
||||
|
@ -846,7 +864,7 @@ Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
err = Nu_RecordSet_FindByThreadIdx(&pArchive->origRecordSet, threadIdx,
|
||||
&pRecord, &pThread);
|
||||
BailError(err);
|
||||
Assert(pRecord != nil);
|
||||
Assert(pRecord != NULL);
|
||||
|
||||
/* extract away */
|
||||
err = Nu_ExtractThreadCommon(pArchive, pRecord, pThread, pDataSink);
|
||||
|
@ -872,9 +890,8 @@ bail:
|
|||
*
|
||||
* If a matching threadID is found, this returns an error.
|
||||
*/
|
||||
static NuError
|
||||
Nu_FindNoFutureThread(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
NuThreadID threadID)
|
||||
static NuError Nu_FindNoFutureThread(NuArchive* pArchive,
|
||||
const NuRecord* pRecord, NuThreadID threadID)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
const NuThread* pThread;
|
||||
|
@ -886,13 +903,13 @@ Nu_FindNoFutureThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
*/
|
||||
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
|
||||
pThread = Nu_GetThread(pRecord, idx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
if (NuGetThreadID(pThread) == threadID) {
|
||||
/* found a match, see if it has been deleted */
|
||||
pThreadMod = Nu_ThreadMod_FindByThreadIdx(pRecord,
|
||||
pThread->threadIdx);
|
||||
if (pThreadMod != nil &&
|
||||
if (pThreadMod != NULL &&
|
||||
pThreadMod->entry.kind == kNuThreadModDelete)
|
||||
{
|
||||
/* it's deleted, ignore it */
|
||||
|
@ -908,7 +925,7 @@ Nu_FindNoFutureThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* Now look for "add" threadMods with a matching threadID.
|
||||
*/
|
||||
pThreadMod = pRecord->pThreadMods;
|
||||
while (pThreadMod != nil) {
|
||||
while (pThreadMod != NULL) {
|
||||
if (pThreadMod->entry.kind == kNuThreadModAdd &&
|
||||
pThreadMod->entry.add.threadID == threadID)
|
||||
{
|
||||
|
@ -927,9 +944,8 @@ bail:
|
|||
/*
|
||||
* Like Nu_FindNoFutureThread, but tests against a whole class.
|
||||
*/
|
||||
static NuError
|
||||
Nu_FindNoFutureThreadClass(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
long threadClass)
|
||||
static NuError Nu_FindNoFutureThreadClass(NuArchive* pArchive,
|
||||
const NuRecord* pRecord, long threadClass)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
const NuThread* pThread;
|
||||
|
@ -941,13 +957,13 @@ Nu_FindNoFutureThreadClass(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
*/
|
||||
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
|
||||
pThread = Nu_GetThread(pRecord, idx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
if (pThread->thThreadClass == threadClass) {
|
||||
/* found a match, see if it has been deleted */
|
||||
pThreadMod = Nu_ThreadMod_FindByThreadIdx(pRecord,
|
||||
pThread->threadIdx);
|
||||
if (pThreadMod != nil &&
|
||||
if (pThreadMod != NULL &&
|
||||
pThreadMod->entry.kind == kNuThreadModDelete)
|
||||
{
|
||||
/* it's deleted, ignore it */
|
||||
|
@ -963,7 +979,7 @@ Nu_FindNoFutureThreadClass(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* Now look for "add" threadMods with a matching threadClass.
|
||||
*/
|
||||
pThreadMod = pRecord->pThreadMods;
|
||||
while (pThreadMod != nil) {
|
||||
while (pThreadMod != NULL) {
|
||||
if (pThreadMod->entry.kind == kNuThreadModAdd &&
|
||||
NuThreadIDGetClass(pThreadMod->entry.add.threadID) == threadClass)
|
||||
{
|
||||
|
@ -988,9 +1004,8 @@ bail:
|
|||
* The record and thread returned will always be from the "copy" set. An
|
||||
* error result is returned if the record and thread aren't found.
|
||||
*/
|
||||
static NuError
|
||||
Nu_FindThreadForWriteByIdx(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuRecord** ppFoundRecord, NuThread** ppFoundThread)
|
||||
static NuError Nu_FindThreadForWriteByIdx(NuArchive* pArchive,
|
||||
NuThreadIdx threadIdx, NuRecord** ppFoundRecord, NuThread** ppFoundThread)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -1001,7 +1016,7 @@ Nu_FindThreadForWriteByIdx(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
Assert(Nu_RecordSet_GetLoaded(&pArchive->origRecordSet));
|
||||
err = Nu_RecordSet_FindByThreadIdx(&pArchive->origRecordSet, threadIdx,
|
||||
ppFoundRecord, ppFoundThread);
|
||||
*ppFoundThread = nil; /* can't delete from here, wipe ptr */
|
||||
*ppFoundThread = NULL; /* can't delete from here, wipe ptr */
|
||||
}
|
||||
BailError(err);
|
||||
|
||||
|
@ -1009,13 +1024,13 @@ Nu_FindThreadForWriteByIdx(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
* The thread exists. If we were looking in the "orig" set, we have
|
||||
* to create a "copy" set, and delete it from that.
|
||||
*/
|
||||
if (*ppFoundThread == nil) {
|
||||
if (*ppFoundThread == NULL) {
|
||||
err = Nu_RecordSet_Clone(pArchive, &pArchive->copyRecordSet,
|
||||
&pArchive->origRecordSet);
|
||||
BailError(err);
|
||||
err = Nu_RecordSet_FindByThreadIdx(&pArchive->copyRecordSet, threadIdx,
|
||||
ppFoundRecord, ppFoundThread);
|
||||
Assert(err == kNuErrNone && *ppFoundThread != nil); /* must succeed */
|
||||
Assert(err == kNuErrNone && *ppFoundThread != NULL); /* must succeed */
|
||||
BailError(err);
|
||||
}
|
||||
|
||||
|
@ -1029,8 +1044,7 @@ bail:
|
|||
*
|
||||
* Returns with an error (kNuErrThreadAdd) if it's not okay.
|
||||
*/
|
||||
NuError
|
||||
Nu_OkayToAddThread(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
NuError Nu_OkayToAddThread(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
NuThreadID threadID)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
@ -1094,17 +1108,16 @@ bail:
|
|||
* On success, the NuThreadIdx of the newly-created record will be placed
|
||||
* in "*pThreadIdx", and "pDataSource" will be owned by NufxLib.
|
||||
*/
|
||||
NuError
|
||||
Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
|
||||
NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
|
||||
NuError Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx,
|
||||
NuThreadID threadID, NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
|
||||
{
|
||||
NuError err;
|
||||
NuRecord* pRecord;
|
||||
NuThreadMod* pThreadMod = nil;
|
||||
NuThreadMod* pThreadMod = NULL;
|
||||
NuThreadFormat threadFormat;
|
||||
|
||||
/* okay for pThreadIdx to be nil */
|
||||
if (recIdx == 0 || pDataSource == nil)
|
||||
/* okay for pThreadIdx to be NULL */
|
||||
if (recIdx == 0 || pDataSource == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
if (Nu_IsReadOnly(pArchive))
|
||||
|
@ -1123,7 +1136,7 @@ Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
|
|||
err = Nu_RecordSet_FindByIdx(&pArchive->newRecordSet, recIdx, &pRecord);
|
||||
}
|
||||
BailError(err);
|
||||
Assert(pRecord != nil);
|
||||
Assert(pRecord != NULL);
|
||||
|
||||
/*
|
||||
* Do some tests, looking for specific types of threads that conflict
|
||||
|
@ -1153,13 +1166,13 @@ Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
|
|||
err = Nu_ThreadModAdd_New(pArchive, threadID, threadFormat, pDataSource,
|
||||
&pThreadMod);
|
||||
BailError(err);
|
||||
Assert(pThreadMod != nil);
|
||||
Assert(pThreadMod != NULL);
|
||||
|
||||
/* add the thread mod to the record */
|
||||
Nu_RecordAddThreadMod(pRecord, pThreadMod);
|
||||
if (pThreadIdx != nil)
|
||||
if (pThreadIdx != NULL)
|
||||
*pThreadIdx = pThreadMod->entry.add.threadIdx;
|
||||
pThreadMod = nil; /* successful, don't free */
|
||||
pThreadMod = NULL; /* successful, don't free */
|
||||
|
||||
/*
|
||||
* If we've got a header filename and we're adding a filename thread,
|
||||
|
@ -1172,9 +1185,9 @@ Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
|
|||
}
|
||||
|
||||
bail:
|
||||
if (pThreadMod != nil)
|
||||
if (pThreadMod != NULL)
|
||||
Nu_ThreadModFree(pArchive, pThreadMod);
|
||||
if (err == kNuErrNone && pDataSource != nil) {
|
||||
if (err == kNuErrNone && pDataSource != NULL) {
|
||||
/* on success, we have ownership of the data source. ThreadMod
|
||||
made its own copy, so get rid of this one */
|
||||
Nu_DataSourceFree(pDataSource);
|
||||
|
@ -1194,16 +1207,15 @@ bail:
|
|||
* You aren't allowed to update threads that have been deleted. Updating
|
||||
* newly-added threads isn't possible, since they aren't really threads yet.
|
||||
*/
|
||||
NuError
|
||||
Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuDataSource* pDataSource, long* pMaxLen)
|
||||
NuError Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
||||
NuDataSource* pDataSource, int32_t* pMaxLen)
|
||||
{
|
||||
NuError err;
|
||||
NuThreadMod* pThreadMod = nil;
|
||||
NuThreadMod* pThreadMod = NULL;
|
||||
NuRecord* pFoundRecord;
|
||||
NuThread* pFoundThread;
|
||||
|
||||
if (pDataSource == nil) {
|
||||
if (pDataSource == NULL) {
|
||||
err = kNuErrInvalidArg;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -1239,14 +1251,14 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
goto bail;
|
||||
}
|
||||
|
||||
if (pMaxLen != nil)
|
||||
if (pMaxLen != NULL)
|
||||
*pMaxLen = pFoundThread->thCompThreadEOF;
|
||||
|
||||
/*
|
||||
* Check to see if somebody is trying to delete this, or has already
|
||||
* updated it.
|
||||
*/
|
||||
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != nil) {
|
||||
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != NULL) {
|
||||
DBUG(("--- Tried to modify a deleted or modified thread\n"));
|
||||
err = kNuErrModThreadChange;
|
||||
goto bail;
|
||||
|
@ -1269,7 +1281,7 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
Nu_DataSourceGetOtherLen(pDataSource))
|
||||
{
|
||||
err = kNuErrPreSizeOverflow;
|
||||
Nu_ReportError(NU_BLOB, err, "can't put %ld bytes into %ld",
|
||||
Nu_ReportError(NU_BLOB, err, "can't put %u bytes into %u",
|
||||
Nu_DataSourceGetOtherLen(pDataSource),
|
||||
pFoundThread->thCompThreadEOF);
|
||||
goto bail;
|
||||
|
@ -1281,7 +1293,7 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
Nu_DataSourceGetOtherLen(pDataSource) > kNuReasonableFilenameLen))
|
||||
{
|
||||
err = kNuErrInvalidFilename;
|
||||
Nu_ReportError(NU_BLOB, err, "invalid filename (%ld bytes)",
|
||||
Nu_ReportError(NU_BLOB, err, "invalid filename (%u bytes)",
|
||||
Nu_DataSourceGetOtherLen(pDataSource));
|
||||
goto bail;
|
||||
}
|
||||
|
@ -1294,7 +1306,7 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
|
|||
Assert(pFoundThread->thThreadFormat == kNuThreadFormatUncompressed);
|
||||
err = Nu_ThreadModUpdate_New(pArchive, threadIdx, pDataSource, &pThreadMod);
|
||||
BailError(err);
|
||||
Assert(pThreadMod != nil);
|
||||
Assert(pThreadMod != NULL);
|
||||
|
||||
/* add the thread mod to the record */
|
||||
Nu_RecordAddThreadMod(pFoundRecord, pThreadMod);
|
||||
|
@ -1322,11 +1334,10 @@ bail:
|
|||
* later on. Besides, it's sort of handy to hang on to the filename for
|
||||
* as long as possible.
|
||||
*/
|
||||
NuError
|
||||
Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
|
||||
NuError Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
|
||||
{
|
||||
NuError err;
|
||||
NuThreadMod* pThreadMod = nil;
|
||||
NuThreadMod* pThreadMod = NULL;
|
||||
NuRecord* pFoundRecord;
|
||||
NuThread* pFoundThread;
|
||||
|
||||
|
@ -1348,7 +1359,7 @@ Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
|
|||
* allowed. Deletion of threads from deleted records can't happen,
|
||||
* because deleted records are completely removed from the "copy" set.
|
||||
*/
|
||||
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != nil) {
|
||||
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != NULL) {
|
||||
DBUG(("--- Tried to delete a deleted or modified thread\n"));
|
||||
err = kNuErrModThreadChange;
|
||||
goto bail;
|
||||
|
@ -1361,7 +1372,7 @@ Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
|
|||
NuGetThreadID(pFoundThread), &pThreadMod);
|
||||
BailError(err);
|
||||
Nu_RecordAddThreadMod(pFoundRecord, pThreadMod);
|
||||
pThreadMod = nil; /* successful, don't free */
|
||||
pThreadMod = NULL; /* successful, don't free */
|
||||
|
||||
bail:
|
||||
Nu_ThreadModFree(pArchive, pThreadMod);
|
||||
|
|
|
@ -14,12 +14,11 @@
|
|||
/*
|
||||
* Get a configurable parameter.
|
||||
*/
|
||||
NuError
|
||||
Nu_GetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
|
||||
NuError Nu_GetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
if (pValue == nil)
|
||||
if (pValue == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
switch (ident) {
|
||||
|
@ -82,8 +81,7 @@ bail:
|
|||
/*
|
||||
* Set a configurable parameter.
|
||||
*/
|
||||
NuError
|
||||
Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
||||
NuError Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
||||
{
|
||||
NuError err = kNuErrInvalidArg;
|
||||
|
||||
|
@ -91,7 +89,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueAllowDuplicates:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueAllowDuplicates value %ld", value);
|
||||
"Invalid kNuValueAllowDuplicates value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valAllowDuplicates = value;
|
||||
|
@ -99,7 +97,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueConvertExtractedEOL:
|
||||
if (value < kNuConvertOff || value > kNuConvertAuto) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueConvertExtractedEOL value %ld", value);
|
||||
"Invalid kNuValueConvertExtractedEOL value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valConvertExtractedEOL = value;
|
||||
|
@ -107,7 +105,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueDataCompression:
|
||||
if (value < kNuCompressNone || value > kNuCompressBzip2) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueDataCompression value %ld", value);
|
||||
"Invalid kNuValueDataCompression value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valDataCompression = value;
|
||||
|
@ -115,7 +113,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueDiscardWrapper:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueDiscardWrapper value %ld", value);
|
||||
"Invalid kNuValueDiscardWrapper value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valDiscardWrapper = value;
|
||||
|
@ -123,7 +121,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueEOL:
|
||||
if (value < kNuEOLUnknown || value > kNuEOLCRLF) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueEOL value %ld", value);
|
||||
"Invalid kNuValueEOL value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valEOL = value;
|
||||
|
@ -131,7 +129,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueHandleExisting:
|
||||
if (value < kNuMaybeOverwrite || value > kNuMustOverwrite) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueHandleExisting value %ld", value);
|
||||
"Invalid kNuValueHandleExisting value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valHandleExisting = value;
|
||||
|
@ -139,7 +137,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueIgnoreCRC:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueIgnoreCRC value %ld", value);
|
||||
"Invalid kNuValueIgnoreCRC value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valIgnoreCRC = value;
|
||||
|
@ -147,7 +145,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueMaskDataless:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueMaskDataless value %ld", value);
|
||||
"Invalid kNuValueMaskDataless value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valMaskDataless = value;
|
||||
|
@ -155,7 +153,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueMimicSHK:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueMimicSHK value %ld", value);
|
||||
"Invalid kNuValueMimicSHK value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valMimicSHK = value;
|
||||
|
@ -163,7 +161,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueModifyOrig:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueModifyOrig value %ld", value);
|
||||
"Invalid kNuValueModifyOrig value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valModifyOrig = value;
|
||||
|
@ -171,7 +169,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueOnlyUpdateOlder:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueOnlyUpdateOlder value %ld", value);
|
||||
"Invalid kNuValueOnlyUpdateOlder value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valOnlyUpdateOlder = value;
|
||||
|
@ -179,7 +177,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueStripHighASCII:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueStripHighASCII value %ld", value);
|
||||
"Invalid kNuValueStripHighASCII value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valStripHighASCII = value;
|
||||
|
@ -187,7 +185,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueJunkSkipMax:
|
||||
if (value > kMaxJunkSkipMax) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueJunkSkipMax value %ld", value);
|
||||
"Invalid kNuValueJunkSkipMax value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valJunkSkipMax = value;
|
||||
|
@ -195,7 +193,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueIgnoreLZW2Len:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueIgnoreLZW2Len value %ld", value);
|
||||
"Invalid kNuValueIgnoreLZW2Len value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valIgnoreLZW2Len = value;
|
||||
|
@ -203,7 +201,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
|
|||
case kNuValueHandleBadMac:
|
||||
if (value != true && value != false) {
|
||||
Nu_ReportError(NU_BLOB, err,
|
||||
"Invalid kNuValueHandleBadMac value %ld", value);
|
||||
"Invalid kNuValueHandleBadMac value %u", value);
|
||||
goto bail;
|
||||
}
|
||||
pArchive->valHandleBadMac = value;
|
||||
|
@ -225,11 +223,10 @@ bail:
|
|||
* pry into pArchive to get at (like the archive type) or get the master
|
||||
* header (like the number of records).
|
||||
*/
|
||||
NuError
|
||||
Nu_GetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
|
||||
NuError Nu_GetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
if (pAttr == nil)
|
||||
if (pAttr == NULL)
|
||||
return kNuErrInvalidArg;
|
||||
|
||||
switch (ident) {
|
||||
|
@ -260,8 +257,8 @@ bail:
|
|||
*
|
||||
* Unsupported compression types cause a warning to be flagged.
|
||||
*/
|
||||
NuThreadFormat
|
||||
Nu_ConvertCompressValToFormat(NuArchive* pArchive, NuValue compValue)
|
||||
NuThreadFormat Nu_ConvertCompressValToFormat(NuArchive* pArchive,
|
||||
NuValue compValue)
|
||||
{
|
||||
NuThreadFormat threadFormat;
|
||||
Boolean unsup = false;
|
||||
|
@ -312,14 +309,14 @@ Nu_ConvertCompressValToFormat(NuArchive* pArchive, NuValue compValue)
|
|||
|
||||
default:
|
||||
Nu_ReportError(NU_BLOB, kNuErrInvalidArg,
|
||||
"Unknown compress value %ld", compValue);
|
||||
"Unknown compress value %u", compValue);
|
||||
Assert(false);
|
||||
return kNuThreadFormatUncompressed;
|
||||
}
|
||||
|
||||
if (unsup) {
|
||||
Nu_ReportError(NU_BLOB, kNuErrNone,
|
||||
"Unsupported compression 0x%04x requested (%ld), storing",
|
||||
"Unsupported compression 0x%04x requested (%u), storing",
|
||||
threadFormat, compValue);
|
||||
return kNuThreadFormatUncompressed;
|
||||
}
|
||||
|
|
|
@ -23,19 +23,18 @@ static const char gNuBuildFlags[] = "-";
|
|||
/*
|
||||
* Return the version number, date built, and build flags.
|
||||
*/
|
||||
NuError
|
||||
Nu_GetVersion(long* pMajorVersion, long* pMinorVersion, long* pBugVersion,
|
||||
const char** ppBuildDate, const char** ppBuildFlags)
|
||||
NuError Nu_GetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
|
||||
int32_t* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags)
|
||||
{
|
||||
if (pMajorVersion != nil)
|
||||
if (pMajorVersion != NULL)
|
||||
*pMajorVersion = kNuVersionMajor;
|
||||
if (pMinorVersion != nil)
|
||||
if (pMinorVersion != NULL)
|
||||
*pMinorVersion = kNuVersionMinor;
|
||||
if (pBugVersion != nil)
|
||||
if (pBugVersion != NULL)
|
||||
*pBugVersion = kNuVersionBug;
|
||||
if (ppBuildDate != nil)
|
||||
if (ppBuildDate != NULL)
|
||||
*ppBuildDate = gNuBuildDate;
|
||||
if (ppBuildFlags != nil)
|
||||
if (ppBuildFlags != NULL)
|
||||
*ppBuildFlags = gNuBuildFlags;
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
|
1456
nufxlib/config.guess
vendored
1456
nufxlib/config.guess
vendored
File diff suppressed because it is too large
Load Diff
|
@ -27,18 +27,6 @@
|
|||
/* Define if your <sys/time.h> declares struct tm. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define to `unsigned char' if <sys/types.h> doesn't define. */
|
||||
#undef uchar
|
||||
|
||||
/* Define to `unsigned short' if <sys/types.h> doesn't define. */
|
||||
#undef ushort
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> doesn't define. */
|
||||
#undef uint
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
|
||||
#undef ulong
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef mode_t
|
||||
|
||||
|
|
2785
nufxlib/config.sub
vendored
2785
nufxlib/config.sub
vendored
File diff suppressed because it is too large
Load Diff
100
nufxlib/configure
vendored
100
nufxlib/configure
vendored
|
@ -626,6 +626,7 @@ BUILD_FLAGS
|
|||
EGREP
|
||||
GREP
|
||||
CPP
|
||||
NUFX_VERSION
|
||||
RANLIB
|
||||
SET_MAKE
|
||||
INSTALL_DATA
|
||||
|
@ -665,6 +666,7 @@ infodir
|
|||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
|
@ -741,6 +743,7 @@ datadir='${datarootdir}'
|
|||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE}'
|
||||
|
@ -993,6 +996,15 @@ do
|
|||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
|
@ -1130,7 +1142,7 @@ fi
|
|||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
|
@ -1283,6 +1295,7 @@ Fine tuning of the installation directories:
|
|||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
|
@ -3273,6 +3286,10 @@ else
|
|||
fi
|
||||
|
||||
|
||||
NUFX_VERSION=3.1.0
|
||||
|
||||
|
||||
|
||||
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
|
@ -3879,50 +3896,6 @@ $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "uchar" "ac_cv_type_uchar" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_uchar" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define uchar unsigned char
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "ushort" "ac_cv_type_ushort" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_ushort" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ushort unsigned short
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "uint" "ac_cv_type_uint" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_uint" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define uint unsigned int
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "ulong" "ac_cv_type_ulong" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_ulong" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ulong unsigned long
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
for ac_func in fdopen ftruncate memmove mkdir mkstemp mktime timelocal \
|
||||
localtime_r snprintf strcasecmp strncasecmp strtoul strerror vsnprintf
|
||||
|
@ -3961,7 +3934,8 @@ rm -f conftest*
|
|||
fi
|
||||
|
||||
if test $nufxlib_cv_snprintf_in_header = "yes"; then
|
||||
$as_echo "#define SNPRINTF_DECLARED 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define SNPRINTF_DECLARED /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nufxlib_cv_snprintf_in_header" >&5
|
||||
|
@ -3990,7 +3964,8 @@ rm -f conftest*
|
|||
fi
|
||||
|
||||
if test $nufxlib_cv_vsnprintf_in_header = "yes"; then
|
||||
$as_echo "#define VSNPRINTF_DECLARED 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define VSNPRINTF_DECLARED /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nufxlib_cv_vsnprintf_in_header" >&5
|
||||
|
@ -4014,11 +3989,6 @@ elif test "$host_os" = "beos"; then
|
|||
SHARE_FLAGS='-nostartfiles -Xlinker -soname="$@"'
|
||||
fi
|
||||
|
||||
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
|
||||
echo "checking for Mac OS X... yes, adding -framework Carbon"
|
||||
LIBS="$LIBS -framework Carbon"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4063,7 +4033,7 @@ else
|
|||
int count;
|
||||
char buf[8];
|
||||
count = sprintf(buf, "123"); /* should return three */
|
||||
exit(count != 3);
|
||||
return count != 3;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
|
@ -4081,7 +4051,8 @@ fi
|
|||
|
||||
|
||||
if test $nufxlib_cv_sprintf_returns_int = "yes"; then
|
||||
$as_echo "#define SPRINTF_RETURNS_INT 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define SPRINTF_RETURNS_INT /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nufxlib_cv_sprintf_returns_int" >&5
|
||||
|
@ -4096,7 +4067,8 @@ else
|
|||
fi
|
||||
|
||||
if test $enable_sq = "yes"; then
|
||||
$as_echo "#define ENABLE_SQ 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define ENABLE_SQ /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
@ -4108,7 +4080,8 @@ else
|
|||
fi
|
||||
|
||||
if test $enable_lzw = "yes"; then
|
||||
$as_echo "#define ENABLE_LZW 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define ENABLE_LZW /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
@ -4120,7 +4093,8 @@ else
|
|||
fi
|
||||
|
||||
if test $enable_lzc = "yes"; then
|
||||
$as_echo "#define ENABLE_LZC 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define ENABLE_LZC /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
@ -4185,7 +4159,8 @@ fi
|
|||
fi
|
||||
if $got_zlibh; then
|
||||
echo " (found libz and zlib.h, enabling deflate)"
|
||||
$as_echo "#define ENABLE_DEFLATE 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define ENABLE_DEFLATE /**/" >>confdefs.h
|
||||
|
||||
else
|
||||
echo " (couldn't find libz and zlib.h, not enabling deflate)"
|
||||
|
@ -4253,7 +4228,8 @@ fi
|
|||
fi
|
||||
if $got_bzlibh; then
|
||||
echo " (found libbz2 and bzlib.h, enabling bzip2)"
|
||||
$as_echo "#define ENABLE_BZIP2 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define ENABLE_BZIP2 /**/" >>confdefs.h
|
||||
|
||||
else
|
||||
echo " (couldn't find libbz2 and bzlib.h, not enabling bzip2)"
|
||||
|
@ -4264,12 +4240,13 @@ fi
|
|||
# Check whether --enable-dmalloc was given.
|
||||
if test "${enable_dmalloc+set}" = set; then :
|
||||
enableval=$enable_dmalloc; echo "--- enabling dmalloc";
|
||||
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; $as_echo "#define USE_DMALLOC 1" >>confdefs.h
|
||||
LIBS="$LIBS -L/usr/local/lib -ldmalloc";
|
||||
$as_echo "#define USE_DMALLOC /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile samples/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile samples/Makefile nufxlib.pc"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
|
@ -4964,6 +4941,7 @@ do
|
|||
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||
"samples/Makefile") CONFIG_FILES="$CONFIG_FILES samples/Makefile" ;;
|
||||
"nufxlib.pc") CONFIG_FILES="$CONFIG_FILES nufxlib.pc" ;;
|
||||
|
||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||
esac
|
||||
|
|
|
@ -16,6 +16,10 @@ AC_PROG_INSTALL
|
|||
AC_PROG_MAKE_SET
|
||||
AC_PROG_RANLIB
|
||||
|
||||
NUFX_VERSION=3.1.0
|
||||
AC_SUBST(NUFX_VERSION)
|
||||
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(fcntl.h malloc.h stdlib.h sys/stat.h sys/time.h sys/types.h \
|
||||
sys/utime.h unistd.h utime.h)
|
||||
|
@ -29,10 +33,6 @@ AC_TYPE_MODE_T
|
|||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_STRUCT_TM
|
||||
AC_CHECK_TYPE(uchar, unsigned char)
|
||||
AC_CHECK_TYPE(ushort, unsigned short)
|
||||
AC_CHECK_TYPE(uint, unsigned int)
|
||||
AC_CHECK_TYPE(ulong, unsigned long)
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(fdopen ftruncate memmove mkdir mkstemp mktime timelocal \
|
||||
|
@ -46,7 +46,7 @@ AC_CACHE_VAL(nufxlib_cv_snprintf_in_header, [
|
|||
[nufxlib_cv_snprintf_in_header=no])
|
||||
])
|
||||
if test $nufxlib_cv_snprintf_in_header = "yes"; then
|
||||
AC_DEFINE(SNPRINTF_DECLARED)
|
||||
AC_DEFINE(SNPRINTF_DECLARED, [], [Define it SNPRINTF is declared in stdio.h.])
|
||||
fi
|
||||
AC_MSG_RESULT($nufxlib_cv_snprintf_in_header)
|
||||
|
||||
|
@ -58,7 +58,7 @@ AC_CACHE_VAL(nufxlib_cv_vsnprintf_in_header, [
|
|||
[nufxlib_cv_vsnprintf_in_header=no])
|
||||
])
|
||||
if test $nufxlib_cv_vsnprintf_in_header = "yes"; then
|
||||
AC_DEFINE(VSNPRINTF_DECLARED)
|
||||
AC_DEFINE(VSNPRINTF_DECLARED, [], [Define if VSNPRINTF is declared in stdio.h.])
|
||||
fi
|
||||
AC_MSG_RESULT($nufxlib_cv_vsnprintf_in_header)
|
||||
|
||||
|
@ -94,12 +94,6 @@ elif test "$host_os" = "beos"; then
|
|||
SHARE_FLAGS='-nostartfiles -Xlinker -soname="$@"'
|
||||
fi
|
||||
|
||||
dnl Mac OS X (powerpc-apple-darwin6.6) needs an extra flag.
|
||||
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
|
||||
echo "checking for Mac OS X... yes, adding -framework Carbon"
|
||||
LIBS="$LIBS -framework Carbon"
|
||||
fi
|
||||
|
||||
AC_SUBST(BUILD_FLAGS)
|
||||
AC_SUBST(SHARE_FLAGS)
|
||||
|
||||
|
@ -140,7 +134,7 @@ AC_CACHE_VAL(nufxlib_cv_sprintf_returns_int, [
|
|||
int count;
|
||||
char buf[8];
|
||||
count = sprintf(buf, "123"); /* should return three */
|
||||
exit(count != 3);
|
||||
return count != 3;
|
||||
}
|
||||
],
|
||||
[nufxlib_cv_sprintf_returns_int=yes], [nufxlib_cv_sprintf_returns_int=no],
|
||||
|
@ -148,7 +142,7 @@ AC_CACHE_VAL(nufxlib_cv_sprintf_returns_int, [
|
|||
])
|
||||
|
||||
if test $nufxlib_cv_sprintf_returns_int = "yes"; then
|
||||
AC_DEFINE(SPRINTF_RETURNS_INT)
|
||||
AC_DEFINE(SPRINTF_RETURNS_INT, [], [Define if sprintf returns an int.])
|
||||
fi
|
||||
AC_MSG_RESULT($nufxlib_cv_sprintf_returns_int)
|
||||
|
||||
|
@ -165,21 +159,21 @@ AC_ARG_ENABLE(sq,
|
|||
[ --disable-sq disable SQ compression],
|
||||
[ ], [ enable_sq=yes ])
|
||||
if test $enable_sq = "yes"; then
|
||||
AC_DEFINE(ENABLE_SQ)
|
||||
AC_DEFINE(ENABLE_SQ, [], [Define to include SQ (Huffman+RLE) compression.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(lzw,
|
||||
[ --disable-lzw disable LZW/1 and LZW/2 compression],
|
||||
[ ], [ enable_lzw=yes ])
|
||||
if test $enable_lzw = "yes"; then
|
||||
AC_DEFINE(ENABLE_LZW)
|
||||
AC_DEFINE(ENABLE_LZW, [], [Define to include LZW (ShrinkIt LZW/1 and LZW/2) compression.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(lzc,
|
||||
[ --disable-lzc disable 12- and 16-bit LZC compression],
|
||||
[ ], [ enable_lzc=yes ])
|
||||
if test $enable_lzc = "yes"; then
|
||||
AC_DEFINE(ENABLE_LZC)
|
||||
AC_DEFINE(ENABLE_LZC, [], [Define to include LZC (12-bit and 16-bit UNIX "compress") compression.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(deflate,
|
||||
|
@ -194,7 +188,7 @@ if test $enable_deflate = "yes"; then
|
|||
fi
|
||||
if $got_zlibh; then
|
||||
echo " (found libz and zlib.h, enabling deflate)"
|
||||
AC_DEFINE(ENABLE_DEFLATE)
|
||||
AC_DEFINE(ENABLE_DEFLATE, [], [Define to include deflate (zlib) compression (also need -l in Makefile).])
|
||||
else
|
||||
echo " (couldn't find libz and zlib.h, not enabling deflate)"
|
||||
fi
|
||||
|
@ -214,7 +208,7 @@ if test $enable_bzip2 = "yes"; then
|
|||
fi
|
||||
if $got_bzlibh; then
|
||||
echo " (found libbz2 and bzlib.h, enabling bzip2)"
|
||||
AC_DEFINE(ENABLE_BZIP2)
|
||||
AC_DEFINE(ENABLE_BZIP2, [], [Define to include bzip2 (libbz2) compression (also need -l in Makefile).])
|
||||
else
|
||||
echo " (couldn't find libbz2 and bzlib.h, not enabling bzip2)"
|
||||
fi
|
||||
|
@ -223,6 +217,6 @@ fi
|
|||
|
||||
AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc do dmalloc stuff],
|
||||
[ echo "--- enabling dmalloc";
|
||||
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC) ])
|
||||
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC, [], [Define if we want to use the dmalloc library (also need -l in Makefile).]) ])
|
||||
|
||||
AC_OUTPUT(Makefile samples/Makefile)
|
||||
AC_OUTPUT(Makefile samples/Makefile nufxlib.pc)
|
||||
|
|
|
@ -16,6 +16,8 @@ EXPORTS
|
|||
NuAddThread
|
||||
NuClose
|
||||
NuContents
|
||||
NuConvertMORToUNI
|
||||
NuConvertUNIToMOR
|
||||
NuCreateDataSinkForBuffer
|
||||
NuCreateDataSinkForFP
|
||||
NuCreateDataSinkForFile
|
||||
|
|
10
nufxlib/nufxlib.pc.in
Normal file
10
nufxlib/nufxlib.pc.in
Normal file
|
@ -0,0 +1,10 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: nufxlib
|
||||
Description: NuFX archive manipulation library.
|
||||
Version: @NUFX_VERSION@
|
||||
Libs: -L${libdir} -lnufx @LIBS@
|
||||
Cflags: -I${includedir}
|
|
@ -6,8 +6,8 @@
|
|||
*
|
||||
* Common functions for NuLib tests.
|
||||
*/
|
||||
#ifndef __Common__
|
||||
#define __Common__
|
||||
#ifndef NUFXLIB_SAMPLES_COMMON_H
|
||||
#define NUFXLIB_SAMPLES_COMMON_H
|
||||
|
||||
#include "SysDefs.h" /* might as well draft off the autoconf */
|
||||
#include "NufxLib.h"
|
||||
|
@ -16,8 +16,6 @@
|
|||
# include "dmalloc.h"
|
||||
#endif
|
||||
|
||||
#define nil NULL /* this is seriously habit-forming */
|
||||
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
@ -65,4 +63,4 @@
|
|||
# define PATH_SEP '/'
|
||||
#endif
|
||||
|
||||
#endif /*__Common__*/
|
||||
#endif /*NUFXLIB_SAMPLES_COMMON_H*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,8 +16,7 @@
|
|||
#include "Common.h"
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
static int
|
||||
strcasecmp(const char *str1, const char *str2)
|
||||
static int strcasecmp(const char *str1, const char *str2)
|
||||
{
|
||||
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
|
||||
str1++, str2++;
|
||||
|
@ -51,35 +50,33 @@ strcasecmp(const char *str1, const char *str2)
|
|||
typedef struct ImgHeader {
|
||||
char magic[4];
|
||||
char creator[4];
|
||||
short headerLen;
|
||||
short version;
|
||||
long imageFormat;
|
||||
unsigned long flags;
|
||||
long numBlocks;
|
||||
long dataOffset;
|
||||
long dataLen;
|
||||
long cmntOffset;
|
||||
long cmntLen;
|
||||
long creatorOffset;
|
||||
long creatorLen;
|
||||
long spare[4];
|
||||
uint16_t headerLen;
|
||||
uint16_t version;
|
||||
uint32_t imageFormat;
|
||||
uint32_t flags;
|
||||
uint32_t numBlocks;
|
||||
uint32_t dataOffset;
|
||||
uint32_t dataLen;
|
||||
uint32_t cmntOffset;
|
||||
uint32_t cmntLen;
|
||||
uint32_t creatorOffset;
|
||||
uint32_t creatorLen;
|
||||
uint32_t spare[4];
|
||||
} ImgHeader;
|
||||
|
||||
/*
|
||||
* Read a two-byte little-endian value.
|
||||
*/
|
||||
void
|
||||
ReadShortLE(FILE* fp, short* pBuf)
|
||||
void ReadShortLE(FILE* fp, uint16_t* pBuf)
|
||||
{
|
||||
*pBuf = getc(fp);
|
||||
*pBuf += (short) getc(fp) << 8;
|
||||
*pBuf += (uint16_t) getc(fp) << 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a two-byte little-endian value.
|
||||
*/
|
||||
void
|
||||
WriteShortLE(FILE* fp, unsigned short val)
|
||||
void WriteShortLE(FILE* fp, uint16_t val)
|
||||
{
|
||||
putc(val, fp);
|
||||
putc(val >> 8, fp);
|
||||
|
@ -88,20 +85,18 @@ WriteShortLE(FILE* fp, unsigned short val)
|
|||
/*
|
||||
* Read a four-byte little-endian value.
|
||||
*/
|
||||
void
|
||||
ReadLongLE(FILE* fp, long* pBuf)
|
||||
void ReadLongLE(FILE* fp, uint32_t* pBuf)
|
||||
{
|
||||
*pBuf = getc(fp);
|
||||
*pBuf += (long) getc(fp) << 8;
|
||||
*pBuf += (long) getc(fp) << 16;
|
||||
*pBuf += (long) getc(fp) << 24;
|
||||
*pBuf += (uint32_t) getc(fp) << 8;
|
||||
*pBuf += (uint32_t) getc(fp) << 16;
|
||||
*pBuf += (uint32_t) getc(fp) << 24;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a four-byte little-endian value.
|
||||
*/
|
||||
void
|
||||
WriteLongLE(FILE* fp, unsigned long val)
|
||||
void WriteLongLE(FILE* fp, uint32_t val)
|
||||
{
|
||||
putc(val, fp);
|
||||
putc(val >> 8, fp);
|
||||
|
@ -112,8 +107,7 @@ WriteLongLE(FILE* fp, unsigned long val)
|
|||
/*
|
||||
* Read the header from a 2IMG file.
|
||||
*/
|
||||
int
|
||||
ReadImgHeader(FILE* fp, ImgHeader* pHeader)
|
||||
int ReadImgHeader(FILE* fp, ImgHeader* pHeader)
|
||||
{
|
||||
size_t ignored;
|
||||
ignored = fread(pHeader->magic, 4, 1, fp);
|
||||
|
@ -121,7 +115,7 @@ ReadImgHeader(FILE* fp, ImgHeader* pHeader)
|
|||
ReadShortLE(fp, &pHeader->headerLen);
|
||||
ReadShortLE(fp, &pHeader->version);
|
||||
ReadLongLE(fp, &pHeader->imageFormat);
|
||||
ReadLongLE(fp, (long*)&pHeader->flags);
|
||||
ReadLongLE(fp, &pHeader->flags);
|
||||
ReadLongLE(fp, &pHeader->numBlocks);
|
||||
ReadLongLE(fp, &pHeader->dataOffset);
|
||||
ReadLongLE(fp, &pHeader->dataLen);
|
||||
|
@ -154,8 +148,7 @@ ReadImgHeader(FILE* fp, ImgHeader* pHeader)
|
|||
/*
|
||||
* Write the header to a 2IMG file.
|
||||
*/
|
||||
int
|
||||
WriteImgHeader(FILE* fp, ImgHeader* pHeader)
|
||||
int WriteImgHeader(FILE* fp, ImgHeader* pHeader)
|
||||
{
|
||||
fwrite(pHeader->magic, 4, 1, fp);
|
||||
fwrite(pHeader->creator, 4, 1, fp);
|
||||
|
@ -185,23 +178,22 @@ WriteImgHeader(FILE* fp, ImgHeader* pHeader)
|
|||
/*
|
||||
* Dump the contents of an ImgHeader.
|
||||
*/
|
||||
void
|
||||
DumpImgHeader(ImgHeader* pHeader)
|
||||
void DumpImgHeader(ImgHeader* pHeader)
|
||||
{
|
||||
printf("--- header contents:\n");
|
||||
printf("\tmagic = '%.4s'\n", pHeader->magic);
|
||||
printf("\tcreator = '%.4s'\n", pHeader->creator);
|
||||
printf("\theaderLen = %d\n", pHeader->headerLen);
|
||||
printf("\tversion = %d\n", pHeader->version);
|
||||
printf("\timageFormat = %ld\n", pHeader->imageFormat);
|
||||
printf("\tflags = 0x%08lx\n", pHeader->flags);
|
||||
printf("\tnumBlocks = %ld\n", pHeader->numBlocks);
|
||||
printf("\tdataOffset = %ld\n", pHeader->dataOffset);
|
||||
printf("\tdataLen = %ld\n", pHeader->dataLen);
|
||||
printf("\tcmntOffset = %ld\n", pHeader->cmntOffset);
|
||||
printf("\tcmntLen = %ld\n", pHeader->cmntLen);
|
||||
printf("\tcreatorOffset = %ld\n", pHeader->creatorOffset);
|
||||
printf("\tcreatorLen = %ld\n", pHeader->creatorLen);
|
||||
printf("\timageFormat = %u\n", pHeader->imageFormat);
|
||||
printf("\tflags = 0x%08x\n", pHeader->flags);
|
||||
printf("\tnumBlocks = %u\n", pHeader->numBlocks);
|
||||
printf("\tdataOffset = %u\n", pHeader->dataOffset);
|
||||
printf("\tdataLen = %u\n", pHeader->dataLen);
|
||||
printf("\tcmntOffset = %u\n", pHeader->cmntOffset);
|
||||
printf("\tcmntLen = %u\n", pHeader->cmntLen);
|
||||
printf("\tcreatorOffset = %u\n", pHeader->creatorOffset);
|
||||
printf("\tcreatorLen = %u\n", pHeader->creatorLen);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -217,8 +209,7 @@ typedef enum ArchiveKind { kKindUnknown, kKindShk, kKindImg } ArchiveKind;
|
|||
/*
|
||||
* This gets called when a buffer DataSource is no longer needed.
|
||||
*/
|
||||
NuResult
|
||||
FreeCallback(NuArchive* pArchive, void* args)
|
||||
NuResult FreeCallback(NuArchive* pArchive, void* args)
|
||||
{
|
||||
free(args);
|
||||
return kNuOK;
|
||||
|
@ -227,8 +218,7 @@ FreeCallback(NuArchive* pArchive, void* args)
|
|||
/*
|
||||
* This gets called when an "FP" DataSource is no longer needed.
|
||||
*/
|
||||
NuResult
|
||||
FcloseCallback(NuArchive* pArchive, void* args)
|
||||
NuResult FcloseCallback(NuArchive* pArchive, void* args)
|
||||
{
|
||||
fclose((FILE*) args);
|
||||
return kNuOK;
|
||||
|
@ -242,8 +232,7 @@ FcloseCallback(NuArchive* pArchive, void* args)
|
|||
* of NufxLib. We could just as easily not set it and call fclose()
|
||||
* ourselves, because the structure of this program is pretty simple.
|
||||
*/
|
||||
NuError
|
||||
CreateProdosSource(const ImgHeader* pHeader, FILE* fp,
|
||||
NuError CreateProdosSource(const ImgHeader* pHeader, FILE* fp,
|
||||
NuDataSource** ppDataSource)
|
||||
{
|
||||
return NuCreateDataSourceForFP(kNuThreadFormatUncompressed, 0, fp,
|
||||
|
@ -254,17 +243,16 @@ CreateProdosSource(const ImgHeader* pHeader, FILE* fp,
|
|||
* Create a data source for a DOS-ordered image. This is a little harder,
|
||||
* since we have to reorder the blocks into ProDOS ordering for ShrinkIt.
|
||||
*/
|
||||
NuError
|
||||
CreateDosSource(const ImgHeader* pHeader, FILE* fp,
|
||||
NuError CreateDosSource(const ImgHeader* pHeader, FILE* fp,
|
||||
NuDataSource** ppDataSource)
|
||||
{
|
||||
NuError err;
|
||||
char* diskBuffer = nil;
|
||||
char* diskBuffer = NULL;
|
||||
long offset;
|
||||
|
||||
if (pHeader->dataLen % 4096) {
|
||||
fprintf(stderr,
|
||||
"ERROR: image size must be multiple of 4096 (%ld isn't)\n",
|
||||
"ERROR: image size must be multiple of 4096 (%u isn't)\n",
|
||||
pHeader->dataLen);
|
||||
err = kNuErrGeneric;
|
||||
goto bail;
|
||||
|
@ -277,8 +265,8 @@ CreateDosSource(const ImgHeader* pHeader, FILE* fp,
|
|||
}
|
||||
|
||||
diskBuffer = malloc(pHeader->dataLen);
|
||||
if (diskBuffer == nil) {
|
||||
fprintf(stderr, "ERROR: malloc(%ld) failed\n", pHeader->dataLen);
|
||||
if (diskBuffer == NULL) {
|
||||
fprintf(stderr, "ERROR: malloc(%u) failed\n", pHeader->dataLen);
|
||||
err = kNuErrMalloc;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -288,7 +276,7 @@ CreateDosSource(const ImgHeader* pHeader, FILE* fp,
|
|||
* reversible transformation, i.e. if you do this twice you're back
|
||||
* to ProDOS ordering.
|
||||
*/
|
||||
for (offset = 0; offset < pHeader->dataLen; offset += 4096) {
|
||||
for (offset = 0; offset < (long) pHeader->dataLen; offset += 4096) {
|
||||
size_t ignored;
|
||||
ignored = fread(diskBuffer + offset + 0x0000, 256, 1, fp);
|
||||
ignored = fread(diskBuffer + offset + 0x0e00, 256, 1, fp);
|
||||
|
@ -319,13 +307,13 @@ CreateDosSource(const ImgHeader* pHeader, FILE* fp,
|
|||
* "true", so NufxLib will free the buffer for us.
|
||||
*/
|
||||
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed, 0,
|
||||
(const unsigned char*) diskBuffer, 0, pHeader->dataLen,
|
||||
(const uint8_t*) diskBuffer, 0, pHeader->dataLen,
|
||||
FreeCallback, ppDataSource);
|
||||
if (err == kNuErrNone)
|
||||
diskBuffer = nil;
|
||||
diskBuffer = NULL;
|
||||
|
||||
bail:
|
||||
if (diskBuffer != nil)
|
||||
if (diskBuffer != NULL)
|
||||
free(diskBuffer);
|
||||
return err;
|
||||
}
|
||||
|
@ -338,18 +326,17 @@ bail:
|
|||
* This requires opening up the 2IMG file, verifying that it's okay, and
|
||||
* then creating a new disk image record and thread.
|
||||
*/
|
||||
int
|
||||
ConvertFromImgToShk(const char* srcName, const char* dstName)
|
||||
int ConvertFromImgToShk(const char* srcName, const char* dstName)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuDataSource* pDataSource = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
NuDataSource* pDataSource = NULL;
|
||||
NuRecordIdx recordIdx;
|
||||
NuFileDetails fileDetails;
|
||||
ImgHeader header;
|
||||
FILE* fp = nil;
|
||||
long flushStatus;
|
||||
char* storageName = nil;
|
||||
FILE* fp = NULL;
|
||||
uint32_t flushStatus;
|
||||
char* storageName = NULL;
|
||||
char* cp;
|
||||
|
||||
printf("Converting 2IMG file '%s' to ShrinkIt archive '%s'\n\n",
|
||||
|
@ -394,10 +381,10 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
|
|||
/* create the name that will be stored in the archive */
|
||||
storageName = strdup(dstName);
|
||||
cp = strrchr(storageName, '.');
|
||||
if (cp != nil)
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
cp = strrchr(storageName, kLocalFssep);
|
||||
if (cp != nil && *(cp+1) != '\0')
|
||||
if (cp != NULL && *(cp+1) != '\0')
|
||||
cp++;
|
||||
else
|
||||
cp = storageName;
|
||||
|
@ -410,7 +397,7 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
|
|||
|
||||
/* set up the contents of the NuFX Record */
|
||||
memset(&fileDetails, 0, sizeof(fileDetails));
|
||||
fileDetails.storageName = cp;
|
||||
fileDetails.storageNameMOR = cp;
|
||||
fileDetails.fileSysID = kNuFileSysUnknown; /* DOS? ProDOS? */
|
||||
fileDetails.fileSysInfo = kLocalFssep;
|
||||
fileDetails.access = kNuAccessUnlocked;
|
||||
|
@ -433,11 +420,11 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
|
|||
switch (header.imageFormat) {
|
||||
case kImageFormatDOS:
|
||||
err = CreateDosSource(&header, fp, &pDataSource);
|
||||
fp = nil;
|
||||
fp = NULL;
|
||||
break;
|
||||
case kImageFormatProDOS:
|
||||
err = CreateProdosSource(&header, fp, &pDataSource);
|
||||
fp = nil;
|
||||
fp = NULL;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "How the heck did I get here?");
|
||||
|
@ -451,17 +438,17 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
|
|||
|
||||
/* add a disk image thread */
|
||||
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDiskImage, pDataSource,
|
||||
nil);
|
||||
NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to create thread (err=%d)\n", err);
|
||||
goto bail;
|
||||
}
|
||||
pDataSource = nil; /* library owns it now */
|
||||
pDataSource = NULL; /* library owns it now */
|
||||
|
||||
/* nothing happens until we Flush */
|
||||
err = NuFlush(pArchive, &flushStatus);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04lx)\n",
|
||||
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04x)\n",
|
||||
err, flushStatus);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -470,17 +457,17 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
|
|||
fprintf(stderr, "ERROR: close failed (err=%d)\n", err);
|
||||
goto bail;
|
||||
}
|
||||
pArchive = nil;
|
||||
pArchive = NULL;
|
||||
|
||||
bail:
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
(void)NuAbort(pArchive);
|
||||
(void)NuClose(pArchive);
|
||||
}
|
||||
NuFreeDataSource(pDataSource);
|
||||
if (storageName != nil)
|
||||
if (storageName != NULL)
|
||||
free(storageName);
|
||||
if (fp != nil)
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
return (err == kNuErrNone) ? 0 : -1;
|
||||
}
|
||||
|
@ -492,17 +479,16 @@ bail:
|
|||
* This takes a simple-minded approach and assumes that the first record
|
||||
* in the archive has the disk image in it. If it doesn't, we give up.
|
||||
*/
|
||||
int
|
||||
ConvertFromShkToImg(const char* srcName, const char* dstName)
|
||||
int ConvertFromShkToImg(const char* srcName, const char* dstName)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuDataSink* pDataSink = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
NuRecordIdx recordIdx;
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread = nil;
|
||||
const NuThread* pThread = NULL;
|
||||
ImgHeader header;
|
||||
FILE* fp = nil;
|
||||
FILE* fp = NULL;
|
||||
int idx;
|
||||
|
||||
printf("Converting ShrinkIt archive '%s' to 2IMG file '%s'\n\n",
|
||||
|
@ -592,10 +578,10 @@ ConvertFromShkToImg(const char* srcName, const char* dstName)
|
|||
}
|
||||
|
||||
bail:
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
NuClose(pArchive);
|
||||
NuFreeDataSink(pDataSink);
|
||||
if (fp != nil)
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
return (err == kNuErrNone) ? 0 : -1;
|
||||
}
|
||||
|
@ -604,13 +590,12 @@ bail:
|
|||
/*
|
||||
* Figure out what kind of archive this is by looking at the filename.
|
||||
*/
|
||||
ArchiveKind
|
||||
DetermineKind(const char* filename)
|
||||
ArchiveKind DetermineKind(const char* filename)
|
||||
{
|
||||
const char* dot;
|
||||
|
||||
dot = strrchr(filename, '.');
|
||||
if (dot == nil)
|
||||
if (dot == NULL)
|
||||
return kKindUnknown;
|
||||
|
||||
if (strcasecmp(dot, ".shk") == 0 || strcasecmp(dot, ".sdk") == 0)
|
||||
|
@ -626,8 +611,7 @@ DetermineKind(const char* filename)
|
|||
/*
|
||||
* Figure out what we want to do.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ArchiveKind kind;
|
||||
int cc;
|
||||
|
|
|
@ -47,8 +47,7 @@ char gSentRecordWarning = false;
|
|||
/*
|
||||
* This gets called when a buffer DataSource is no longer needed.
|
||||
*/
|
||||
NuResult
|
||||
FreeCallback(NuArchive* pArchive, void* args)
|
||||
NuResult FreeCallback(NuArchive* pArchive, void* args)
|
||||
{
|
||||
free(args);
|
||||
return kNuOK;
|
||||
|
@ -60,14 +59,13 @@ FreeCallback(NuArchive* pArchive, void* args)
|
|||
* This assumes the library is configured for compression (it defaults
|
||||
* to LZW/2, so this is a reasonable assumption).
|
||||
*/
|
||||
NuError
|
||||
CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
||||
NuError CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
||||
long flags, const NuThread* pThread, long newRecordIdx)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuDataSource* pDataSource = nil;
|
||||
NuDataSink* pDataSink = nil;
|
||||
uchar* buffer = nil;
|
||||
NuDataSource* pDataSource = NULL;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
uint8_t* buffer = NULL;
|
||||
|
||||
/*
|
||||
* Allocate a buffer large enough to hold all the uncompressed data, and
|
||||
|
@ -77,7 +75,7 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
*/
|
||||
if (pThread->actualThreadEOF) {
|
||||
buffer = malloc(pThread->actualThreadEOF);
|
||||
if (buffer == nil) {
|
||||
if (buffer == NULL) {
|
||||
err = kNuErrMalloc;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -95,7 +93,7 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
*/
|
||||
err = NuExtractThread(pInArchive, pThread->threadIdx, pDataSink);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to extract thread %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: unable to extract thread %u (err=%d)\n",
|
||||
pThread->threadIdx, err);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -111,7 +109,7 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
* We always use "actualThreadEOF" because "thThreadEOF" is broken
|
||||
* for disk archives created by certain versions of ShrinkIt.
|
||||
*
|
||||
* It's okay to pass in a nil value for "buffer", so long as the
|
||||
* It's okay to pass in a NULL value for "buffer", so long as the
|
||||
* amount of data in the buffer is also zero. The library will do
|
||||
* the right thing.
|
||||
*/
|
||||
|
@ -134,25 +132,25 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
goto bail;
|
||||
}
|
||||
}
|
||||
buffer = nil; /* doClose was set, so it's owned by the data source */
|
||||
buffer = NULL; /* doClose was set, so it's owned by the data source */
|
||||
|
||||
/*
|
||||
* Schedule the data for addition to the record.
|
||||
*/
|
||||
err = NuAddThread(pOutArchive, newRecordIdx, NuGetThreadID(pThread),
|
||||
pDataSource, nil);
|
||||
pDataSource, NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to add thread (err=%d)\n", err);
|
||||
goto bail;
|
||||
}
|
||||
pDataSource = nil; /* library owns it now */
|
||||
pDataSource = NULL; /* library owns it now */
|
||||
|
||||
bail:
|
||||
if (pDataSource != nil)
|
||||
if (pDataSource != NULL)
|
||||
NuFreeDataSource(pDataSource);
|
||||
if (pDataSink != nil)
|
||||
if (pDataSink != NULL)
|
||||
NuFreeDataSink(pDataSink);
|
||||
if (buffer != nil)
|
||||
if (buffer != NULL)
|
||||
free(buffer);
|
||||
return err;
|
||||
}
|
||||
|
@ -174,14 +172,13 @@ bail:
|
|||
* reliable but extracts a little more than we need on pre-sized
|
||||
* threads (filenames, comments).
|
||||
*/
|
||||
NuError
|
||||
CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
||||
NuError CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
||||
long flags, const NuThread* pThread, long newRecordIdx)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuDataSource* pDataSource = nil;
|
||||
NuDataSink* pDataSink = nil;
|
||||
uchar* buffer = nil;
|
||||
NuDataSource* pDataSource = NULL;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
uint8_t* buffer = NULL;
|
||||
|
||||
/*
|
||||
* If we have some data files that were left uncompressed, perhaps
|
||||
|
@ -207,7 +204,7 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
* wrap a data sink around it.
|
||||
*/
|
||||
buffer = malloc(pThread->thCompThreadEOF);
|
||||
if (buffer == nil) {
|
||||
if (buffer == NULL) {
|
||||
err = kNuErrMalloc;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -225,7 +222,7 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
*/
|
||||
err = NuExtractThread(pInArchive, pThread->threadIdx, pDataSink);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to extract thread %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: unable to extract thread %u (err=%d)\n",
|
||||
pThread->threadIdx, err);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -265,7 +262,7 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
goto bail;
|
||||
}
|
||||
}
|
||||
buffer = nil; /* doClose was set, so it's owned by the data source */
|
||||
buffer = NULL; /* doClose was set, so it's owned by the data source */
|
||||
|
||||
/* yes, this is a kluge... sigh */
|
||||
err = NuDataSourceSetRawCrc(pDataSource, pThread->thThreadCRC);
|
||||
|
@ -281,19 +278,19 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
|
|||
* "doClose" on our copy, so we are free to dispose of pDataSource.
|
||||
*/
|
||||
err = NuAddThread(pOutArchive, newRecordIdx, NuGetThreadID(pThread),
|
||||
pDataSource, nil);
|
||||
pDataSource, NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to add thread (err=%d)\n", err);
|
||||
goto bail;
|
||||
}
|
||||
pDataSource = nil; /* library owns it now */
|
||||
pDataSource = NULL; /* library owns it now */
|
||||
|
||||
bail:
|
||||
if (pDataSource != nil)
|
||||
if (pDataSource != NULL)
|
||||
NuFreeDataSource(pDataSource);
|
||||
if (pDataSink != nil)
|
||||
if (pDataSink != NULL)
|
||||
NuFreeDataSink(pDataSink);
|
||||
if (buffer != nil)
|
||||
if (buffer != NULL)
|
||||
free(buffer);
|
||||
return err;
|
||||
}
|
||||
|
@ -305,8 +302,7 @@ bail:
|
|||
* Depending on "flags", this will either copy it raw or uncompress and
|
||||
* recompress.
|
||||
*/
|
||||
NuError
|
||||
CopyThread(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
||||
NuError CopyThread(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
||||
const NuThread* pThread, long newRecordIdx)
|
||||
{
|
||||
if (flags & kFlagCopyOnly) {
|
||||
|
@ -327,8 +323,7 @@ CopyThread(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
|||
* of which will not usually have any effect since NufxLib imposes a
|
||||
* specific thread ordering on most common types) depending on "flags".
|
||||
*/
|
||||
NuError
|
||||
CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
||||
NuError CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
||||
NuRecordIdx recordIdx)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
@ -344,7 +339,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
|||
*/
|
||||
err = NuGetRecord(pInArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to get recordIdx %ld\n", recordIdx);
|
||||
fprintf(stderr, "ERROR: unable to get recordIdx %u\n", recordIdx);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
@ -362,7 +357,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
|||
|
||||
numThreads = NuRecordGetNumThreads(pRecord);
|
||||
if (!numThreads) {
|
||||
fprintf(stderr, "WARNING: recordIdx=%ld was empty\n", recordIdx);
|
||||
fprintf(stderr, "WARNING: recordIdx=%u was empty\n", recordIdx);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
@ -370,7 +365,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
|||
* Create a new record that looks just like the original.
|
||||
*/
|
||||
memset(&fileDetails, 0, sizeof(fileDetails));
|
||||
fileDetails.storageName = pRecord->filename;
|
||||
fileDetails.storageNameMOR = pRecord->filenameMOR;
|
||||
fileDetails.fileSysID = pRecord->recFileSysID;
|
||||
fileDetails.fileSysInfo = pRecord->recFileSysInfo;
|
||||
fileDetails.access = pRecord->recAccess;
|
||||
|
@ -393,7 +388,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
|||
if (flags & kFlagReverseThreads) {
|
||||
for (idx = numThreads-1; idx >= 0; idx--) {
|
||||
pThread = NuGetThread(pRecord, idx);
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
|
||||
err = CopyThread(pInArchive, pOutArchive, flags, pThread,
|
||||
newRecordIdx);
|
||||
|
@ -403,7 +398,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
|
|||
} else {
|
||||
for (idx = 0; idx < numThreads; idx++) {
|
||||
pThread = NuGetThread(pRecord, idx);
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
|
||||
err = CopyThread(pInArchive, pOutArchive, flags, pThread,
|
||||
newRecordIdx);
|
||||
|
@ -422,16 +417,15 @@ bail:
|
|||
*
|
||||
* Returns 0 on success, nonzero on failure.
|
||||
*/
|
||||
int
|
||||
LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
|
||||
long flags)
|
||||
int LaunderArchive(const char* inFile, const char* outFile,
|
||||
NuValue compressMethod, long flags)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuArchive* pInArchive = nil;
|
||||
NuArchive* pOutArchive = nil;
|
||||
NuArchive* pInArchive = NULL;
|
||||
NuArchive* pOutArchive = NULL;
|
||||
const NuMasterHeader* pMasterHeader;
|
||||
NuRecordIdx recordIdx;
|
||||
long idx, flushStatus;
|
||||
uint32_t idx, flushStatus;
|
||||
|
||||
err = NuOpenRO(inFile, &pInArchive);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -487,10 +481,10 @@ LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
|
|||
/*
|
||||
* Iterate through the set of records.
|
||||
*/
|
||||
for (idx = 0; idx < (int)pMasterHeader->mhTotalRecords; idx++) {
|
||||
for (idx = 0; idx < pMasterHeader->mhTotalRecords; idx++) {
|
||||
err = NuGetRecordIdxByPosition(pInArchive, idx, &recordIdx);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record #%ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: couldn't get record #%u (err=%d)\n",
|
||||
idx, err);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -525,7 +519,7 @@ LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
|
|||
err = NuFlush(pOutArchive, &flushStatus);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: flush failed (err=%d, status=0x%04lx)\n",
|
||||
"ERROR: flush failed (err=%d, status=0x%04x)\n",
|
||||
err, flushStatus);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -535,15 +529,15 @@ LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
|
|||
/* first and only flush if frequent-flushing wasn't enabled */
|
||||
err = NuFlush(pOutArchive, &flushStatus);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04lx)\n",
|
||||
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04x)\n",
|
||||
err, flushStatus);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
if (pInArchive != nil)
|
||||
if (pInArchive != NULL)
|
||||
NuClose(pInArchive);
|
||||
if (pOutArchive != nil) {
|
||||
if (pOutArchive != NULL) {
|
||||
if (err != kNuErrNone)
|
||||
NuAbort(pOutArchive);
|
||||
NuClose(pOutArchive); /* flush pending changes and close */
|
||||
|
@ -559,12 +553,11 @@ bail:
|
|||
* does everything we need here.
|
||||
*/
|
||||
int myoptind = 0;
|
||||
char* myoptarg = nil;
|
||||
const char* curchar = nil;
|
||||
char* myoptarg = NULL;
|
||||
const char* curchar = NULL;
|
||||
int skipnext = false;
|
||||
|
||||
int
|
||||
mygetopt(int argc, char** argv, const char* optstr)
|
||||
int mygetopt(int argc, char** argv, const char* optstr)
|
||||
{
|
||||
if (!myoptind) {
|
||||
myoptind = 1;
|
||||
|
@ -609,8 +602,7 @@ mygetopt(int argc, char** argv, const char* optstr)
|
|||
/*
|
||||
* Print usage info.
|
||||
*/
|
||||
void
|
||||
Usage(const char* argv0)
|
||||
void Usage(const char* argv0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-crfat] [-m method] infile.shk outfile.shk\n",
|
||||
argv0);
|
||||
|
@ -627,19 +619,18 @@ Usage(const char* argv0)
|
|||
/*
|
||||
* Grab the name of an archive to read.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
NuValue compressMethod = kNuCompressLZW2;
|
||||
long major, minor, bug;
|
||||
int32_t major, minor, bug;
|
||||
const char* pBuildDate;
|
||||
long flags = 0;
|
||||
int errorFlag;
|
||||
int ic;
|
||||
int cc;
|
||||
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
|
||||
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n",
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
|
||||
printf("Using NuFX lib %d.%d.%d built on or after %s\n",
|
||||
major, minor, bug, pBuildDate);
|
||||
|
||||
errorFlag = false;
|
||||
|
|
|
@ -28,49 +28,35 @@ ALL_SRCS = Exerciser.c ImgConv.c Launder.c TestBasic.c \
|
|||
|
||||
NUFXLIB = -L.. -lnufx
|
||||
|
||||
PRODUCTS = exerciser imgconv launder test-basic test-extract test-simple \
|
||||
test-twirl
|
||||
|
||||
#ifdef PURIFY_BUILD
|
||||
# PURIFY = purify
|
||||
# CFLAGS += -DPURIFY
|
||||
#endif
|
||||
#ifdef QUANTIFY_BUILD
|
||||
# QUANTIFY = quantify
|
||||
# CFLAGS += -DQUANTIFY
|
||||
#endif
|
||||
PRODUCTS = exerciser imgconv launder test-basic test-extract test-names \
|
||||
test-simple test-twirl
|
||||
|
||||
all: $(PRODUCTS)
|
||||
@true
|
||||
|
||||
#quantify:
|
||||
# -rm -f $(PRODUCT)
|
||||
# @$(MAKE) QUANTIFY_BUILD=1
|
||||
#
|
||||
#purify:
|
||||
# -rm -f $(PRODUCT)
|
||||
# @$(MAKE) PURIFY_BUILD=1
|
||||
|
||||
exerciser: Exerciser.o $(LIB_PRODUCT)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ Exerciser.o $(NUFXLIB) @LIBS@
|
||||
$(CC) -o $@ Exerciser.o $(NUFXLIB) @LIBS@
|
||||
|
||||
imgconv: ImgConv.o $(LIB_PRODUCT)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ ImgConv.o $(NUFXLIB) @LIBS@
|
||||
$(CC) -o $@ ImgConv.o $(NUFXLIB) @LIBS@
|
||||
|
||||
launder: Launder.o $(LIB_PRODUCT)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ Launder.o $(NUFXLIB) @LIBS@
|
||||
$(CC) -o $@ Launder.o $(NUFXLIB) @LIBS@
|
||||
|
||||
test-basic: TestBasic.o $(LIB_PRODUCT)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestBasic.o $(NUFXLIB) @LIBS@
|
||||
|
||||
test-simple: TestSimple.o $(LIB_PRODUCT)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestSimple.o $(NUFXLIB) @LIBS@
|
||||
$(CC) -o $@ TestBasic.o $(NUFXLIB) @LIBS@
|
||||
|
||||
test-extract: TestExtract.o $(LIB_PRODUCT)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestExtract.o $(NUFXLIB) @LIBS@
|
||||
$(CC) -o $@ TestExtract.o $(NUFXLIB) @LIBS@
|
||||
|
||||
test-names: TestNames.o $(LIB_PRODUCT)
|
||||
$(CC) -o $@ TestNames.o $(NUFXLIB) @LIBS@
|
||||
|
||||
test-simple: TestSimple.o $(LIB_PRODUCT)
|
||||
$(CC) -o $@ TestSimple.o $(NUFXLIB) @LIBS@
|
||||
|
||||
test-twirl: TestTwirl.o $(LIB_PRODUCT)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestTwirl.o $(NUFXLIB) @LIBS@
|
||||
$(CC) -o $@ TestTwirl.o $(NUFXLIB) @LIBS@
|
||||
|
||||
tags::
|
||||
ctags --totals -R ../*
|
||||
|
@ -84,8 +70,12 @@ distclean: clean
|
|||
-rm -f tags
|
||||
-rm -f Makefile Makefile.bak
|
||||
|
||||
depend:
|
||||
makedepend -- $(CFLAGS) -I/usr/local/include -- $(ALL_SRCS)
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
COMMON_HDRS = ../NufxLibPriv.h ../NufxLib.h ../MiscStuff.h ../SysDefs.h
|
||||
Exerciser.o: Exerciser.c $(COMMON_HDRS)
|
||||
ImgConv.o: ImgConv.c $(COMMON_HDRS)
|
||||
Launder.o: Launder.c $(COMMON_HDRS)
|
||||
TestBasic.o: TestBasic.c $(COMMON_HDRS)
|
||||
TestExtract.o: TestExtract.c $(COMMON_HDRS)
|
||||
TestNames.o: TestNames.c $(COMMON_HDRS)
|
||||
TestSimple.o: TestSimple.c $(COMMON_HDRS)
|
||||
TestTwirl.o: TestTwirl.c $(COMMON_HDRS)
|
||||
|
|
|
@ -8,6 +8,9 @@ test-basic
|
|||
|
||||
Basic tests. Run this to verify that things are working.
|
||||
|
||||
On Win32 there will be a second executable, test-basic-d, that links against
|
||||
the DLL rather than the static library.
|
||||
|
||||
|
||||
exerciser
|
||||
=========
|
||||
|
@ -82,6 +85,15 @@ of memory on very large archives, you can reduce the memory requirements
|
|||
by specifying the "-f" flag.
|
||||
|
||||
|
||||
test-names
|
||||
==========
|
||||
|
||||
Tests Unicode filename handling. Run without arguments.
|
||||
|
||||
(This currently fails on Win32 because the Unicode filename support is
|
||||
incomplete there.)
|
||||
|
||||
|
||||
test-simple
|
||||
===========
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#define kTestTempFile "nlbt.tmp"
|
||||
|
||||
#define kNumEntries 3 /* how many records are we going to add? */
|
||||
|
||||
/* stick to ASCII characters for these -- not doing conversions just yet */
|
||||
#define kTestEntryBytes "bytes"
|
||||
#define kTestEntryBytesUPPER "BYTES"
|
||||
#define kTestEntryEnglish "English"
|
||||
|
@ -39,12 +41,11 @@ char gSuppressError = false;
|
|||
/*
|
||||
* Get a single character of input from the user.
|
||||
*/
|
||||
static char
|
||||
TGetReplyChar(char defaultReply)
|
||||
static char TGetReplyChar(char defaultReply)
|
||||
{
|
||||
char tmpBuf[32];
|
||||
|
||||
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == nil)
|
||||
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == NULL)
|
||||
return defaultReply;
|
||||
if (tmpBuf[0] == '\n' || tmpBuf[0] == '\r')
|
||||
return defaultReply;
|
||||
|
@ -52,14 +53,13 @@ TGetReplyChar(char defaultReply)
|
|||
return tmpBuf[0];
|
||||
}
|
||||
|
||||
NuError
|
||||
AddSimpleRecord(NuArchive* pArchive, const char* filename,
|
||||
NuError AddSimpleRecord(NuArchive* pArchive, const char* filenameMOR,
|
||||
NuRecordIdx* pRecordIdx)
|
||||
{
|
||||
NuFileDetails fileDetails;
|
||||
|
||||
memset(&fileDetails, 0, sizeof(fileDetails));
|
||||
fileDetails.storageName = filename;
|
||||
fileDetails.storageNameMOR = filenameMOR;
|
||||
fileDetails.fileSysInfo = kLocalFssep;
|
||||
fileDetails.access = kNuAccessUnlocked;
|
||||
|
||||
|
@ -70,8 +70,7 @@ AddSimpleRecord(NuArchive* pArchive, const char* filename,
|
|||
/*
|
||||
* Display error messages... or not.
|
||||
*/
|
||||
NuResult
|
||||
ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
|
||||
NuResult ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
|
||||
{
|
||||
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
|
||||
|
||||
|
@ -80,12 +79,12 @@ ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
|
|||
|
||||
if (pErrorMessage->isDebug) {
|
||||
fprintf(stderr, "%sNufxLib says: [%s:%d %s] %s\n",
|
||||
pArchive == nil ? "GLOBAL>" : "",
|
||||
pArchive == NULL ? "GLOBAL>" : "",
|
||||
pErrorMessage->file, pErrorMessage->line, pErrorMessage->function,
|
||||
pErrorMessage->message);
|
||||
} else {
|
||||
fprintf(stderr, "%sNufxLib says: %s\n",
|
||||
pArchive == nil ? "GLOBAL>" : "",
|
||||
pArchive == NULL ? "GLOBAL>" : "",
|
||||
pErrorMessage->message);
|
||||
}
|
||||
|
||||
|
@ -95,13 +94,37 @@ ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
|
|||
/*
|
||||
* This gets called when a buffer DataSource is no longer needed.
|
||||
*/
|
||||
NuResult
|
||||
FreeCallback(NuArchive* pArchive, void* args)
|
||||
NuResult FreeCallback(NuArchive* pArchive, void* args)
|
||||
{
|
||||
free(args);
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the test file currently exists, ask the user if it's okay to remove
|
||||
* it.
|
||||
*
|
||||
* Returns 0 if the file was successfully removed, -1 if the file could not
|
||||
* be removed (because the unlink failed, or the user refused).
|
||||
*/
|
||||
int RemoveTestFile(const char* title, const char* fileName)
|
||||
{
|
||||
char answer;
|
||||
|
||||
if (access(fileName, F_OK) == 0) {
|
||||
printf("%s '%s' exists, remove (y/n)? ", title, fileName);
|
||||
fflush(stdout);
|
||||
answer = TGetReplyChar('n');
|
||||
if (tolower(answer) != 'y')
|
||||
return -1;
|
||||
if (unlink(fileName) < 0) {
|
||||
perror("unlink");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
|
@ -113,21 +136,20 @@ FreeCallback(NuArchive* pArchive, void* args)
|
|||
* Make sure the flags that control how we open the file work right,
|
||||
* and verify that we handle existing zero-byte archive files correctly.
|
||||
*/
|
||||
int
|
||||
Test_OpenFlags(void)
|
||||
int Test_OpenFlags(void)
|
||||
{
|
||||
NuError err;
|
||||
FILE* fp = nil;
|
||||
NuArchive* pArchive = nil;
|
||||
FILE* fp = NULL;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
printf("... open zero-byte existing\n");
|
||||
fp = fopen(kTestArchive, kNuFileOpenWriteTrunc);
|
||||
if (fp == nil) {
|
||||
if (fp == NULL) {
|
||||
perror("fopen kTestArchive");
|
||||
goto failed;
|
||||
}
|
||||
fclose(fp);
|
||||
fp = nil;
|
||||
fp = NULL;
|
||||
|
||||
FAIL_OK;
|
||||
err = NuOpenRW(kTestArchive, kTestTempFile, kNuOpenCreat|kNuOpenExcl,
|
||||
|
@ -149,7 +171,7 @@ Test_OpenFlags(void)
|
|||
fprintf(stderr, "ERROR: close failed\n");
|
||||
goto failed;
|
||||
}
|
||||
pArchive = nil;
|
||||
pArchive = NULL;
|
||||
|
||||
if (access(kTestArchive, F_OK) == 0) {
|
||||
fprintf(stderr, "ERROR: archive should have been removed but wasn't\n");
|
||||
|
@ -159,7 +181,7 @@ Test_OpenFlags(void)
|
|||
return 0;
|
||||
|
||||
failed:
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
NuAbort(pArchive);
|
||||
NuClose(pArchive);
|
||||
}
|
||||
|
@ -170,14 +192,13 @@ failed:
|
|||
/*
|
||||
* Add some files to the archive. These will be used by later tests.
|
||||
*/
|
||||
int
|
||||
Test_AddStuff(NuArchive* pArchive)
|
||||
int Test_AddStuff(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
uchar* buf = nil;
|
||||
NuDataSource* pDataSource = nil;
|
||||
uint8_t* buf = NULL;
|
||||
NuDataSource* pDataSource = NULL;
|
||||
NuRecordIdx recordIdx;
|
||||
long status;
|
||||
uint32_t status;
|
||||
int i;
|
||||
static const char* testMsg =
|
||||
"This is a nice test message that has linefeeds in it so we can\n"
|
||||
|
@ -185,20 +206,20 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
"all. It's certainly nice to know that everything works the way\n"
|
||||
"it's supposed to, which I suppose is why we have this nifty test\n"
|
||||
"program available. It sure would be nice if everybody tested\n"
|
||||
"there code, but where would Microsoft be without endless upgrades\n"
|
||||
"their code, but where would Microsoft be without endless upgrades\n"
|
||||
"and service packs? Bugs are what America was built on, and\n"
|
||||
"anybody who says otherwise is a pinko commie lowlife. Verily.\n";
|
||||
|
||||
printf("... add 'bytes' record\n");
|
||||
buf = malloc(131072);
|
||||
if (buf == nil)
|
||||
if (buf == NULL)
|
||||
goto failed;
|
||||
for (i = 0; i < 131072; i++)
|
||||
*(buf+i) = i & 0xff;
|
||||
|
||||
FAIL_OK;
|
||||
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
|
||||
0, nil, 0, 131072, FreeCallback, &pDataSource);
|
||||
0, NULL, 0, 131072, FreeCallback, &pDataSource);
|
||||
FAIL_BAD;
|
||||
if (err == kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: that should've failed!\n");
|
||||
|
@ -215,7 +236,7 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
"ERROR: 'bytes' data source create failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
buf = nil; /* now owned by library */
|
||||
buf = NULL; /* now owned by library */
|
||||
|
||||
err = AddSimpleRecord(pArchive, kTestEntryBytes, &recordIdx);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -224,12 +245,12 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
}
|
||||
|
||||
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
|
||||
nil);
|
||||
NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: 'bytes' thread add failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
pDataSource = nil; /* now owned by library */
|
||||
pDataSource = NULL; /* now owned by library */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -237,7 +258,7 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
*/
|
||||
printf("... add 'English' record\n");
|
||||
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
|
||||
0, (const uchar*)testMsg, 0, strlen(testMsg), nil, &pDataSource);
|
||||
0, (const uint8_t*)testMsg, 0, strlen(testMsg), NULL, &pDataSource);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: 'English' source create failed (err=%d)\n", err);
|
||||
|
@ -246,7 +267,7 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
|
||||
FAIL_OK;
|
||||
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
|
||||
nil);
|
||||
NULL);
|
||||
FAIL_BAD;
|
||||
if (err == kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: 'English' add should've conflicted!\n");
|
||||
|
@ -268,20 +289,21 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
}
|
||||
|
||||
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
|
||||
nil);
|
||||
NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: 'English' thread add failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
pDataSource = nil; /* now owned by library */
|
||||
pDataSource = NULL; /* now owned by library */
|
||||
|
||||
|
||||
/*
|
||||
* Create an empty file with a rather non-empty name.
|
||||
* Create an empty file with a rather non-empty name. Add it as
|
||||
* a resource fork.
|
||||
*/
|
||||
printf("... add 'long' record\n");
|
||||
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
|
||||
0, nil, 0, 0, nil, &pDataSource);
|
||||
0, NULL, 0, 0, NULL, &pDataSource);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: 'English' source create failed (err=%d)\n", err);
|
||||
|
@ -295,12 +317,12 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
}
|
||||
|
||||
err = NuAddThread(pArchive, recordIdx, kNuThreadIDRsrcFork, pDataSource,
|
||||
nil);
|
||||
NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: 'long' thread add failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
pDataSource = nil; /* now owned by library */
|
||||
pDataSource = NULL; /* now owned by library */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -308,7 +330,7 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
*/
|
||||
err = NuFlush(pArchive, &status);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr,"ERROR: couldn't flush after add (err=%d, status=%ld)\n",
|
||||
fprintf(stderr, "ERROR: couldn't flush after add (err=%d, status=%u)\n",
|
||||
err, status);
|
||||
goto failed;
|
||||
}
|
||||
|
@ -318,16 +340,16 @@ Test_AddStuff(NuArchive* pArchive)
|
|||
*/
|
||||
err = NuFlush(pArchive, &status);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr,"ERROR: second add flush failed (err=%d, status=%ld)\n",
|
||||
fprintf(stderr, "ERROR: second add flush failed (err=%d, status=%u)\n",
|
||||
err, status);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
failed:
|
||||
if (pDataSource != nil)
|
||||
if (pDataSource != NULL)
|
||||
NuFreeDataSource(pDataSource);
|
||||
if (buf != nil)
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
@ -336,19 +358,18 @@ failed:
|
|||
/*
|
||||
* Make sure that what we're seeing makes sense.
|
||||
*/
|
||||
NuResult
|
||||
TestContentsCallback(NuArchive* pArchive, void* vpRecord)
|
||||
NuResult TestContentsCallback(NuArchive* pArchive, void* vpRecord)
|
||||
{
|
||||
const NuRecord* pRecord = (NuRecord*) vpRecord;
|
||||
|
||||
if (strcmp(pRecord->filename, kTestEntryBytes) == 0 ||
|
||||
strcmp(pRecord->filename, kTestEntryEnglish) == 0 ||
|
||||
strcmp(pRecord->filename, kTestEntryLong) == 0)
|
||||
if (strcmp(pRecord->filenameMOR, kTestEntryBytes) == 0 ||
|
||||
strcmp(pRecord->filenameMOR, kTestEntryEnglish) == 0 ||
|
||||
strcmp(pRecord->filenameMOR, kTestEntryLong) == 0)
|
||||
{
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
fprintf(stderr, "ERROR: found mystery entry '%s'\n", pRecord->filename);
|
||||
fprintf(stderr, "ERROR: found mystery entry '%s'\n", pRecord->filenameMOR);
|
||||
return kNuAbort;
|
||||
}
|
||||
|
||||
|
@ -356,8 +377,7 @@ TestContentsCallback(NuArchive* pArchive, void* vpRecord)
|
|||
/*
|
||||
* Verify that the contents look about right.
|
||||
*/
|
||||
int
|
||||
Test_Contents(NuArchive* pArchive)
|
||||
int Test_Contents(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
long posn;
|
||||
|
@ -386,21 +406,21 @@ Test_Contents(NuArchive* pArchive)
|
|||
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
assert(pRecord != nil);
|
||||
assert(pRecord != NULL);
|
||||
|
||||
switch (posn) {
|
||||
case 0:
|
||||
cc = strcmp(pRecord->filename, kTestEntryBytes);
|
||||
cc = strcmp(pRecord->filenameMOR, kTestEntryBytes);
|
||||
break;
|
||||
case 1:
|
||||
cc = strcmp(pRecord->filename, kTestEntryEnglish);
|
||||
cc = strcmp(pRecord->filenameMOR, kTestEntryEnglish);
|
||||
break;
|
||||
case 2:
|
||||
cc = strcmp(pRecord->filename, kTestEntryLong);
|
||||
cc = strcmp(pRecord->filenameMOR, kTestEntryLong);
|
||||
if (!cc)
|
||||
cc = !(pRecord->recStorageType == kNuStorageExtended);
|
||||
break;
|
||||
|
@ -411,8 +431,8 @@ Test_Contents(NuArchive* pArchive)
|
|||
}
|
||||
|
||||
if (cc) {
|
||||
fprintf(stderr, "ERROR: got '%s' for %ld (%ld), not expected\n",
|
||||
pRecord->filename, posn, recordIdx);
|
||||
fprintf(stderr, "ERROR: got '%s' for %ld (%u), not expected\n",
|
||||
pRecord->filenameMOR, posn, recordIdx);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
@ -435,19 +455,19 @@ failed:
|
|||
|
||||
|
||||
/*
|
||||
* Selection callback filter for "test". This gets called once per record.
|
||||
* Selection callback filter for "test". This gets called once per record,
|
||||
* twice per record for forked files.
|
||||
*/
|
||||
NuResult
|
||||
VerifySelectionCallback(NuArchive* pArchive, void* vpProposal)
|
||||
NuResult VerifySelectionCallback(NuArchive* pArchive, void* vpProposal)
|
||||
{
|
||||
NuError err;
|
||||
const NuSelectionProposal* pProposal = vpProposal;
|
||||
long count;
|
||||
|
||||
if (pProposal->pRecord == nil || pProposal->pThread == nil ||
|
||||
pProposal->pRecord->filename == nil)
|
||||
if (pProposal->pRecord == NULL || pProposal->pThread == NULL ||
|
||||
pProposal->pRecord->filenameMOR == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: unexpected nil in proposal\n");
|
||||
fprintf(stderr, "ERROR: unexpected NULL in proposal\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -473,8 +493,7 @@ failed:
|
|||
/*
|
||||
* Verify the archive contents.
|
||||
*/
|
||||
int
|
||||
Test_Verify(NuArchive* pArchive)
|
||||
int Test_Verify(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
long count;
|
||||
|
@ -506,7 +525,9 @@ Test_Verify(NuArchive* pArchive)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
if (count != kNumEntries) {
|
||||
/* the count will be one higher than the number of records because
|
||||
the last entry is forked, and each fork is tested separately */
|
||||
if (count != kNumEntries + 1) {
|
||||
fprintf(stderr, "ERROR: verified %ld when expecting %d\n", count,
|
||||
kNumEntries);
|
||||
goto failed;
|
||||
|
@ -520,15 +541,14 @@ failed:
|
|||
/*
|
||||
* Extract stuff.
|
||||
*/
|
||||
int
|
||||
Test_Extract(NuArchive* pArchive)
|
||||
int Test_Extract(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
NuRecordIdx recordIdx;
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread;
|
||||
NuDataSink* pDataSink = nil;
|
||||
uchar* buf = nil;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
uint8_t* buf = NULL;
|
||||
|
||||
printf("... extracting files\n");
|
||||
|
||||
|
@ -549,24 +569,24 @@ Test_Extract(NuArchive* pArchive)
|
|||
}
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
assert(pRecord != nil);
|
||||
assert(pRecord != NULL);
|
||||
|
||||
/* we're not using ShrinkIt compat mode, so there should not be a comment */
|
||||
pThread = NuGetThread(pRecord, 1);
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
if (NuGetThreadID(pThread) != kNuThreadIDDataFork) {
|
||||
fprintf(stderr, "ERROR: 'bytes' had unexpected threadID 0x%08lx\n",
|
||||
fprintf(stderr, "ERROR: 'bytes' had unexpected threadID 0x%08x\n",
|
||||
NuGetThreadID(pThread));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
buf = malloc(pThread->actualThreadEOF);
|
||||
if (buf == nil) {
|
||||
fprintf(stderr, "ERROR: malloc(%ld) failed\n",pThread->actualThreadEOF);
|
||||
if (buf == NULL) {
|
||||
fprintf(stderr, "ERROR: malloc(%u) failed\n",pThread->actualThreadEOF);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -587,7 +607,7 @@ Test_Extract(NuArchive* pArchive)
|
|||
goto failed;
|
||||
}
|
||||
NuFreeDataSink(pDataSink);
|
||||
pDataSink = nil;
|
||||
pDataSink = NULL;
|
||||
|
||||
/*
|
||||
* Try to extract with "on" conversion, which should fail because the
|
||||
|
@ -608,7 +628,7 @@ Test_Extract(NuArchive* pArchive)
|
|||
goto failed;
|
||||
}
|
||||
NuFreeDataSink(pDataSink);
|
||||
pDataSink = nil;
|
||||
pDataSink = NULL;
|
||||
|
||||
/*
|
||||
* Try to extract with "auto" conversion, which should conclude that
|
||||
|
@ -628,12 +648,12 @@ Test_Extract(NuArchive* pArchive)
|
|||
goto failed;
|
||||
}
|
||||
NuFreeDataSink(pDataSink);
|
||||
pDataSink = nil;
|
||||
pDataSink = NULL;
|
||||
|
||||
|
||||
|
||||
free(buf);
|
||||
buf = nil;
|
||||
buf = NULL;
|
||||
|
||||
|
||||
|
||||
|
@ -648,24 +668,24 @@ Test_Extract(NuArchive* pArchive)
|
|||
}
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
assert(pRecord != nil);
|
||||
assert(pRecord != NULL);
|
||||
|
||||
/* we're not using ShrinkIt compat mode, so there should not be a comment */
|
||||
pThread = NuGetThread(pRecord, 1);
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
if (NuGetThreadID(pThread) != kNuThreadIDDataFork) {
|
||||
fprintf(stderr, "ERROR: 'English' had unexpected threadID 0x%08lx\n",
|
||||
fprintf(stderr, "ERROR: 'English' had unexpected threadID 0x%08x\n",
|
||||
NuGetThreadID(pThread));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
buf = malloc(pThread->actualThreadEOF);
|
||||
if (buf == nil) {
|
||||
fprintf(stderr, "ERROR: malloc(%ld) failed\n",pThread->actualThreadEOF);
|
||||
if (buf == NULL) {
|
||||
fprintf(stderr, "ERROR: malloc(%u) failed\n", pThread->actualThreadEOF);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -686,7 +706,7 @@ Test_Extract(NuArchive* pArchive)
|
|||
goto failed;
|
||||
}
|
||||
NuFreeDataSink(pDataSink);
|
||||
pDataSink = nil;
|
||||
pDataSink = NULL;
|
||||
|
||||
/*
|
||||
* Try to extract with "auto" conversion, which should fail because the
|
||||
|
@ -707,12 +727,12 @@ Test_Extract(NuArchive* pArchive)
|
|||
goto failed;
|
||||
}
|
||||
NuFreeDataSink(pDataSink);
|
||||
pDataSink = nil;
|
||||
pDataSink = NULL;
|
||||
|
||||
|
||||
|
||||
/*Free(buf);*/
|
||||
/*buf = nil;*/
|
||||
/*buf = NULL;*/
|
||||
|
||||
|
||||
|
||||
|
@ -727,17 +747,17 @@ Test_Extract(NuArchive* pArchive)
|
|||
}
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
assert(pRecord != nil);
|
||||
assert(pRecord != NULL);
|
||||
|
||||
/* we're not using ShrinkIt compat mode, so there should not be a comment */
|
||||
pThread = NuGetThread(pRecord, 1);
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
if (NuGetThreadID(pThread) != kNuThreadIDRsrcFork) {
|
||||
fprintf(stderr, "ERROR: 'Long' had unexpected threadID 0x%08lx\n",
|
||||
fprintf(stderr, "ERROR: 'Long' had unexpected threadID 0x%08x\n",
|
||||
NuGetThreadID(pThread));
|
||||
goto failed;
|
||||
}
|
||||
|
@ -759,20 +779,20 @@ Test_Extract(NuArchive* pArchive)
|
|||
goto failed;
|
||||
}
|
||||
NuFreeDataSink(pDataSink);
|
||||
pDataSink = nil;
|
||||
pDataSink = NULL;
|
||||
|
||||
|
||||
|
||||
free(buf);
|
||||
buf = nil;
|
||||
buf = NULL;
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
failed:
|
||||
if (buf != nil)
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
if (pDataSink != nil)
|
||||
if (pDataSink != NULL)
|
||||
(void) NuFreeDataSink(pDataSink);
|
||||
return -1;
|
||||
}
|
||||
|
@ -780,13 +800,12 @@ failed:
|
|||
/*
|
||||
* Delete the first and last records. Does *not* flush the archive.
|
||||
*/
|
||||
int
|
||||
Test_Delete(NuArchive* pArchive)
|
||||
int Test_Delete(NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
NuRecordIdx recordIdx;
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread = nil;
|
||||
const NuThread* pThread = NULL;
|
||||
long count;
|
||||
int idx;
|
||||
|
||||
|
@ -802,33 +821,33 @@ Test_Delete(NuArchive* pArchive)
|
|||
}
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
assert(pRecord != nil);
|
||||
assert(pRecord != NULL);
|
||||
assert(pRecord->recTotalThreads > 0);
|
||||
|
||||
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
|
||||
pThread = NuGetThread(pRecord, idx);
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
|
||||
err = NuDeleteThread(pArchive, pThread->threadIdx);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: couldn't delete thread #%d (%ld) (err=%d)\n",
|
||||
"ERROR: couldn't delete thread #%d (%u) (err=%d)\n",
|
||||
idx, recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* try to re-delete the same thread */
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
FAIL_OK;
|
||||
err = NuDeleteThread(pArchive, pThread->threadIdx);
|
||||
FAIL_BAD;
|
||||
if (err == kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: allowed to re-delete thread (%ld) (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: allowed to re-delete thread (%u) (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
|
@ -839,7 +858,7 @@ Test_Delete(NuArchive* pArchive)
|
|||
FAIL_BAD;
|
||||
if (err == kNuErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: able to delete modified record (%ld) (err=%d)\n",
|
||||
"ERROR: able to delete modified record (%u) (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
|
@ -847,7 +866,8 @@ Test_Delete(NuArchive* pArchive)
|
|||
/*
|
||||
* Make sure the attr hasn't been updated yet.
|
||||
*/
|
||||
err = NuGetAttr(pArchive, kNuAttrNumRecords, (unsigned long*) &count);
|
||||
count = 0;
|
||||
err = NuGetAttr(pArchive, kNuAttrNumRecords, (uint32_t*) &count);
|
||||
if (count != kNumEntries) {
|
||||
fprintf(stderr, "ERROR: kNuAttrNumRecords %ld vs %d\n",
|
||||
count, kNumEntries);
|
||||
|
@ -864,19 +884,19 @@ Test_Delete(NuArchive* pArchive)
|
|||
}
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
assert(pRecord != nil);
|
||||
assert(pRecord != NULL);
|
||||
|
||||
/* grab the first thread before we whack the record */
|
||||
pThread = NuGetThread(pRecord, 0);
|
||||
assert(pThread != nil);
|
||||
assert(pThread != NULL);
|
||||
|
||||
err = NuDeleteRecord(pArchive, recordIdx);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to delete record #%d (%ld) (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: unable to delete record #%d (%u) (err=%d)\n",
|
||||
kNumEntries-1, recordIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
|
@ -887,7 +907,7 @@ Test_Delete(NuArchive* pArchive)
|
|||
FAIL_BAD;
|
||||
if (err == kNuErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: allowed to delete from deleted (%ld) (err=%d)\n",
|
||||
"ERROR: allowed to delete from deleted (%u) (err=%d)\n",
|
||||
pThread->threadIdx, err);
|
||||
goto failed;
|
||||
}
|
||||
|
@ -901,8 +921,7 @@ failed:
|
|||
/*
|
||||
* Verify that the count in the master header has been updated.
|
||||
*/
|
||||
int
|
||||
Test_MasterCount(NuArchive* pArchive, long expected)
|
||||
int Test_MasterCount(NuArchive* pArchive, long expected)
|
||||
{
|
||||
NuError err;
|
||||
const NuMasterHeader* pMasterHeader;
|
||||
|
@ -915,8 +934,8 @@ Test_MasterCount(NuArchive* pArchive, long expected)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
if (pMasterHeader->mhTotalRecords != (ulong)expected) {
|
||||
fprintf(stderr, "ERROR: unexpected MH count (%ld vs %ld)\n",
|
||||
if (pMasterHeader->mhTotalRecords != (uint32_t)expected) {
|
||||
fprintf(stderr, "ERROR: unexpected MH count (%u vs %ld)\n",
|
||||
pMasterHeader->mhTotalRecords, expected);
|
||||
goto failed;
|
||||
}
|
||||
|
@ -932,41 +951,21 @@ failed:
|
|||
*
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
DoTests(void)
|
||||
int DoTests(void)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
long status;
|
||||
NuArchive* pArchive = NULL;
|
||||
uint32_t status;
|
||||
int cc, result = 0;
|
||||
char answer;
|
||||
|
||||
/*
|
||||
* Make sure we're starting with a clean slate.
|
||||
*/
|
||||
if (access(kTestArchive, F_OK) == 0) {
|
||||
printf("Test archive '%s' exists, remove (y/n)? ", kTestArchive);
|
||||
fflush(stdout);
|
||||
answer = TGetReplyChar('n');
|
||||
if (tolower(answer) != 'y')
|
||||
goto failed;
|
||||
cc = unlink(kTestArchive);
|
||||
if (cc < 0) {
|
||||
perror("unlink kTestArchive");
|
||||
goto failed;
|
||||
}
|
||||
if (RemoveTestFile("Test archive", kTestArchive) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
if (access(kTestTempFile, F_OK) == 0) {
|
||||
printf("Test temp file '%s' exists, remove (y/n)? ", kTestTempFile);
|
||||
fflush(stdout);
|
||||
answer = TGetReplyChar('n');
|
||||
if (tolower(answer) != 'y')
|
||||
goto failed;
|
||||
cc = unlink(kTestTempFile);
|
||||
if (cc < 0) {
|
||||
perror("unlink kTestTempFile");
|
||||
goto failed;
|
||||
}
|
||||
if (RemoveTestFile("Test temp file", kTestTempFile) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1013,7 +1012,7 @@ DoTests(void)
|
|||
fprintf(stderr, "ERROR: mid NuClose failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
pArchive = nil;
|
||||
pArchive = NULL;
|
||||
|
||||
err = NuOpenRO(kTestArchive, &pArchive);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -1028,14 +1027,14 @@ DoTests(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Make sure the contents are still what we expect.
|
||||
* Make sure the TOC (i.e. list of files) is still what we expect.
|
||||
*/
|
||||
printf("... checking contents\n");
|
||||
if (Test_Contents(pArchive) != 0)
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
* Verify the archive contents.
|
||||
* Verify the archive data.
|
||||
*/
|
||||
if (Test_Verify(pArchive) != 0)
|
||||
goto failed;
|
||||
|
@ -1055,7 +1054,7 @@ DoTests(void)
|
|||
fprintf(stderr, "ERROR: late NuClose failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
pArchive = nil;
|
||||
pArchive = NULL;
|
||||
|
||||
err = NuOpenRW(kTestArchive, kTestTempFile, 0, &pArchive);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -1107,7 +1106,7 @@ DoTests(void)
|
|||
*/
|
||||
err = NuFlush(pArchive, &status);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: flush failed (err=%d, status=%ld)\n",
|
||||
fprintf(stderr, "ERROR: flush failed (err=%d, status=%d)\n",
|
||||
err, status);
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1122,7 +1121,7 @@ DoTests(void)
|
|||
* That's all, folks...
|
||||
*/
|
||||
NuClose(pArchive);
|
||||
pArchive = nil;
|
||||
pArchive = NULL;
|
||||
|
||||
printf("... removing '%s'\n", kTestArchive);
|
||||
cc = unlink(kTestArchive);
|
||||
|
@ -1133,7 +1132,7 @@ DoTests(void)
|
|||
|
||||
|
||||
leave:
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
NuAbort(pArchive);
|
||||
NuClose(pArchive);
|
||||
}
|
||||
|
@ -1148,16 +1147,15 @@ failed:
|
|||
/*
|
||||
* Crank away.
|
||||
*/
|
||||
int
|
||||
main(void)
|
||||
int main(void)
|
||||
{
|
||||
long major, minor, bug;
|
||||
int32_t major, minor, bug;
|
||||
const char* pBuildDate;
|
||||
const char* pBuildFlags;
|
||||
int cc;
|
||||
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, &pBuildFlags);
|
||||
printf("Using NuFX library v%ld.%ld.%ld, built on or after\n"
|
||||
printf("Using NuFX library v%d.%d.%d, built on or after\n"
|
||||
" %s with [%s]\n\n",
|
||||
major, minor, bug, pBuildDate, pBuildFlags);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* Track an archive record.
|
||||
*/
|
||||
typedef struct ArchiveRecord {
|
||||
char* filename;
|
||||
char* filenameMOR;
|
||||
NuRecordIdx recordIdx;
|
||||
|
||||
long numThreads;
|
||||
|
@ -50,25 +50,24 @@ typedef struct ArchiveRecord {
|
|||
/*
|
||||
* Alloc a new ArchiveRecord.
|
||||
*/
|
||||
ArchiveRecord*
|
||||
ArchiveRecord_New(const NuRecord* pRecord)
|
||||
ArchiveRecord* ArchiveRecord_New(const NuRecord* pRecord)
|
||||
{
|
||||
ArchiveRecord* pArcRec = nil;
|
||||
ArchiveRecord* pArcRec = NULL;
|
||||
|
||||
pArcRec = malloc(sizeof(*pArcRec));
|
||||
if (pArcRec == nil)
|
||||
return nil;
|
||||
if (pArcRec == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pRecord->filename == nil)
|
||||
pArcRec->filename = strdup("<unknown>");
|
||||
if (pRecord->filenameMOR == NULL)
|
||||
pArcRec->filenameMOR = strdup("<unknown>");
|
||||
else
|
||||
pArcRec->filename = strdup((char*)pRecord->filename);
|
||||
pArcRec->filenameMOR = strdup(pRecord->filenameMOR);
|
||||
|
||||
pArcRec->recordIdx = pRecord->recordIdx;
|
||||
pArcRec->numThreads = NuRecordGetNumThreads(pRecord);
|
||||
(void) NuRecordCopyThreads(pRecord, &pArcRec->pThreads);
|
||||
|
||||
pArcRec->pNext = nil;
|
||||
pArcRec->pNext = NULL;
|
||||
|
||||
return pArcRec;
|
||||
}
|
||||
|
@ -76,15 +75,14 @@ ArchiveRecord_New(const NuRecord* pRecord)
|
|||
/*
|
||||
* Free up an ArchiveRecord.
|
||||
*/
|
||||
void
|
||||
ArchiveRecord_Free(ArchiveRecord* pArcRec)
|
||||
void ArchiveRecord_Free(ArchiveRecord* pArcRec)
|
||||
{
|
||||
if (pArcRec == nil)
|
||||
if (pArcRec == NULL)
|
||||
return;
|
||||
|
||||
if (pArcRec->filename != nil)
|
||||
free(pArcRec->filename);
|
||||
if (pArcRec->pThreads != nil)
|
||||
if (pArcRec->filenameMOR != NULL)
|
||||
free(pArcRec->filenameMOR);
|
||||
if (pArcRec->pThreads != NULL)
|
||||
free(pArcRec->pThreads);
|
||||
free(pArcRec);
|
||||
}
|
||||
|
@ -92,8 +90,8 @@ ArchiveRecord_Free(ArchiveRecord* pArcRec)
|
|||
/*
|
||||
* Find a thread with a matching NuThreadID.
|
||||
*/
|
||||
const NuThread*
|
||||
ArchiveRecord_FindThreadByID(const ArchiveRecord* pArcRec, NuThreadID threadID)
|
||||
const NuThread* ArchiveRecord_FindThreadByID(const ArchiveRecord* pArcRec,
|
||||
NuThreadID threadID)
|
||||
{
|
||||
const NuThread* pThread;
|
||||
int i;
|
||||
|
@ -104,44 +102,38 @@ ArchiveRecord_FindThreadByID(const ArchiveRecord* pArcRec, NuThreadID threadID)
|
|||
return pThread;
|
||||
}
|
||||
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
ArchiveRecord_GetFilename(const ArchiveRecord* pArcRec)
|
||||
const char* ArchiveRecord_GetFilename(const ArchiveRecord* pArcRec)
|
||||
{
|
||||
return pArcRec->filename;
|
||||
return pArcRec->filenameMOR;
|
||||
}
|
||||
|
||||
NuRecordIdx
|
||||
ArchiveRecord_GetRecordIdx(const ArchiveRecord* pArcRec)
|
||||
NuRecordIdx ArchiveRecord_GetRecordIdx(const ArchiveRecord* pArcRec)
|
||||
{
|
||||
return pArcRec->recordIdx;
|
||||
}
|
||||
|
||||
long
|
||||
ArchiveRecord_GetNumThreads(const ArchiveRecord* pArcRec)
|
||||
long ArchiveRecord_GetNumThreads(const ArchiveRecord* pArcRec)
|
||||
{
|
||||
return pArcRec->numThreads;
|
||||
}
|
||||
|
||||
const NuThread*
|
||||
ArchiveRecord_GetThread(const ArchiveRecord* pArcRec, int idx)
|
||||
const NuThread* ArchiveRecord_GetThread(const ArchiveRecord* pArcRec, int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= pArcRec->numThreads)
|
||||
return nil;
|
||||
return NULL;
|
||||
return NuThreadGetByIdx(pArcRec->pThreads, idx);
|
||||
}
|
||||
|
||||
void
|
||||
ArchiveRecord_SetNext(ArchiveRecord* pArcRec, ArchiveRecord* pNextRec)
|
||||
void ArchiveRecord_SetNext(ArchiveRecord* pArcRec, ArchiveRecord* pNextRec)
|
||||
{
|
||||
pArcRec->pNext = pNextRec;
|
||||
}
|
||||
|
||||
ArchiveRecord*
|
||||
ArchiveRecord_GetNext(const ArchiveRecord* pArcRec)
|
||||
ArchiveRecord* ArchiveRecord_GetNext(const ArchiveRecord* pArcRec)
|
||||
{
|
||||
return pArcRec->pNext;
|
||||
}
|
||||
|
@ -163,31 +155,29 @@ typedef struct ArchiveData {
|
|||
} ArchiveData;
|
||||
|
||||
|
||||
ArchiveData*
|
||||
ArchiveData_New(void)
|
||||
ArchiveData* ArchiveData_New(void)
|
||||
{
|
||||
ArchiveData* pArcData;
|
||||
|
||||
pArcData = malloc(sizeof(*pArcData));
|
||||
if (pArcData == nil)
|
||||
return nil;
|
||||
if (pArcData == NULL)
|
||||
return NULL;
|
||||
|
||||
pArcData->numRecords = 0;
|
||||
pArcData->pRecordHead = pArcData->pRecordTail = nil;
|
||||
pArcData->pRecordHead = pArcData->pRecordTail = NULL;
|
||||
|
||||
return pArcData;
|
||||
}
|
||||
|
||||
void
|
||||
ArchiveData_Free(ArchiveData* pArcData)
|
||||
void ArchiveData_Free(ArchiveData* pArcData)
|
||||
{
|
||||
ArchiveRecord* pNext;
|
||||
|
||||
if (pArcData == nil)
|
||||
if (pArcData == NULL)
|
||||
return;
|
||||
|
||||
printf("*** Deleting %ld records!\n", pArcData->numRecords);
|
||||
while (pArcData->pRecordHead != nil) {
|
||||
while (pArcData->pRecordHead != NULL) {
|
||||
pNext = ArchiveRecord_GetNext(pArcData->pRecordHead);
|
||||
ArchiveRecord_Free(pArcData->pRecordHead);
|
||||
pArcData->pRecordHead = pNext;
|
||||
|
@ -197,22 +187,20 @@ ArchiveData_Free(ArchiveData* pArcData)
|
|||
}
|
||||
|
||||
|
||||
ArchiveRecord*
|
||||
ArchiveData_GetRecordHead(const ArchiveData* pArcData)
|
||||
ArchiveRecord* ArchiveData_GetRecordHead(const ArchiveData* pArcData)
|
||||
{
|
||||
return pArcData->pRecordHead;
|
||||
}
|
||||
|
||||
|
||||
/* add an ArchiveRecord to the list pointed at by ArchiveData */
|
||||
void
|
||||
ArchiveData_AddRecord(ArchiveData* pArcData, ArchiveRecord* pRecord)
|
||||
void ArchiveData_AddRecord(ArchiveData* pArcData, ArchiveRecord* pRecord)
|
||||
{
|
||||
assert(pRecord != nil);
|
||||
assert((pArcData->pRecordHead == nil && pArcData->pRecordTail == nil) ||
|
||||
(pArcData->pRecordHead != nil && pArcData->pRecordTail != nil));
|
||||
assert(pRecord != NULL);
|
||||
assert((pArcData->pRecordHead == NULL && pArcData->pRecordTail == NULL) ||
|
||||
(pArcData->pRecordHead != NULL && pArcData->pRecordTail != NULL));
|
||||
|
||||
if (pArcData->pRecordHead == nil) {
|
||||
if (pArcData->pRecordHead == NULL) {
|
||||
/* first */
|
||||
pArcData->pRecordHead = pArcData->pRecordTail = pRecord;
|
||||
} else {
|
||||
|
@ -225,24 +213,23 @@ ArchiveData_AddRecord(ArchiveData* pArcData, ArchiveRecord* pRecord)
|
|||
}
|
||||
|
||||
/* dump the contents of the ArchiveData to stdout */
|
||||
void
|
||||
ArchiveData_DumpContents(const ArchiveData* pArcData)
|
||||
void ArchiveData_DumpContents(const ArchiveData* pArcData)
|
||||
{
|
||||
ArchiveRecord* pArcRec;
|
||||
|
||||
pArcRec = pArcData->pRecordHead;
|
||||
while (pArcRec != nil) {
|
||||
while (pArcRec != NULL) {
|
||||
const NuThread* pThread;
|
||||
int i, count;
|
||||
|
||||
printf("%5ld '%s'\n",
|
||||
printf("%5u '%s'\n",
|
||||
ArchiveRecord_GetRecordIdx(pArcRec),
|
||||
ArchiveRecord_GetFilename(pArcRec));
|
||||
|
||||
count = ArchiveRecord_GetNumThreads(pArcRec);
|
||||
for (i = 0; i < count; i++) {
|
||||
pThread = ArchiveRecord_GetThread(pArcRec, i);
|
||||
printf(" %5ld 0x%04x 0x%04x\n", pThread->threadIdx,
|
||||
printf(" %5u 0x%04x 0x%04x\n", pThread->threadIdx,
|
||||
pThread->thThreadClass, pThread->thThreadKind);
|
||||
}
|
||||
|
||||
|
@ -260,18 +247,18 @@ ArchiveData_DumpContents(const ArchiveData* pArcData)
|
|||
/*
|
||||
* Callback function to collect archive information.
|
||||
*/
|
||||
NuResult
|
||||
GatherContents(NuArchive* pArchive, void* vpRecord)
|
||||
NuResult GatherContents(NuArchive* pArchive, void* vpRecord)
|
||||
{
|
||||
NuRecord* pRecord = (NuRecord*) vpRecord;
|
||||
ArchiveData* pArchiveData = nil;
|
||||
ArchiveData* pArchiveData = NULL;
|
||||
ArchiveRecord* pArchiveRecord = ArchiveRecord_New(pRecord);
|
||||
|
||||
NuGetExtraData(pArchive, (void**)&pArchiveData);
|
||||
assert(pArchiveData != nil);
|
||||
assert(pArchiveData != NULL);
|
||||
|
||||
printf("*** Filename = '%s'\n",
|
||||
pRecord->filename == nil ? "<unknown>":(const char*)pRecord->filename);
|
||||
pRecord->filenameMOR == NULL ?
|
||||
"<unknown>" : pRecord->filenameMOR);
|
||||
|
||||
ArchiveData_AddRecord(pArchiveData, pArchiveRecord);
|
||||
|
||||
|
@ -282,8 +269,7 @@ GatherContents(NuArchive* pArchive, void* vpRecord)
|
|||
/*
|
||||
* Copy the filename thread from every record to "pDataSink".
|
||||
*/
|
||||
NuError
|
||||
ReadAllFilenameThreads(NuArchive* pArchive, ArchiveData* pArchiveData,
|
||||
NuError ReadAllFilenameThreads(NuArchive* pArchive, ArchiveData* pArchiveData,
|
||||
NuDataSink* pDataSink)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
@ -291,10 +277,10 @@ ReadAllFilenameThreads(NuArchive* pArchive, ArchiveData* pArchiveData,
|
|||
const NuThread* pThread;
|
||||
|
||||
pArchiveRecord = ArchiveData_GetRecordHead(pArchiveData);
|
||||
while (pArchiveRecord != nil) {
|
||||
while (pArchiveRecord != NULL) {
|
||||
pThread = ArchiveRecord_FindThreadByID(pArchiveRecord,
|
||||
kNuThreadIDFilename);
|
||||
if (pThread != nil) {
|
||||
if (pThread != NULL) {
|
||||
err = NuExtractThread(pArchive, pThread->threadIdx, pDataSink);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "*** Extract failed (%d)\n", err);
|
||||
|
@ -310,11 +296,10 @@ bail:
|
|||
|
||||
|
||||
/* extract every filename thread into a single file, overwriting each time */
|
||||
NuError
|
||||
ExtractToFile(NuArchive* pArchive, ArchiveData* pArchiveData)
|
||||
NuError ExtractToFile(NuArchive* pArchive, ArchiveData* pArchiveData)
|
||||
{
|
||||
NuError err;
|
||||
NuDataSink* pDataSink = nil;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
|
||||
err = NuCreateDataSinkForFile(true, kNuConvertOff, "out.file", PATH_SEP,
|
||||
&pDataSink);
|
||||
|
@ -337,14 +322,13 @@ bail:
|
|||
}
|
||||
|
||||
/* extract every filename thread into a FILE*, appending */
|
||||
NuError
|
||||
ExtractToFP(NuArchive* pArchive, ArchiveData* pArchiveData)
|
||||
NuError ExtractToFP(NuArchive* pArchive, ArchiveData* pArchiveData)
|
||||
{
|
||||
NuError err;
|
||||
FILE* fp = nil;
|
||||
NuDataSink* pDataSink = nil;
|
||||
FILE* fp = NULL;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
|
||||
if ((fp = fopen("out.fp", kNuFileOpenWriteTrunc)) == nil)
|
||||
if ((fp = fopen("out.fp", kNuFileOpenWriteTrunc)) == NULL)
|
||||
return kNuErrFileOpen;
|
||||
|
||||
err = NuCreateDataSinkForFP(true, kNuConvertOff, fp, &pDataSink);
|
||||
|
@ -357,7 +341,7 @@ ExtractToFP(NuArchive* pArchive, ArchiveData* pArchiveData)
|
|||
|
||||
bail:
|
||||
(void) NuFreeDataSink(pDataSink);
|
||||
if (fp != nil)
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
if (err == kNuErrNone)
|
||||
printf("*** FP write complete\n");
|
||||
|
@ -365,13 +349,12 @@ bail:
|
|||
}
|
||||
|
||||
/* extract every filename thread into a buffer, advancing as we go */
|
||||
NuError
|
||||
ExtractToBuffer(NuArchive* pArchive, ArchiveData* pArchiveData)
|
||||
NuError ExtractToBuffer(NuArchive* pArchive, ArchiveData* pArchiveData)
|
||||
{
|
||||
NuError err;
|
||||
unsigned char buffer[kHappySize];
|
||||
NuDataSink* pDataSink = nil;
|
||||
unsigned long count;
|
||||
uint8_t buffer[kHappySize];
|
||||
NuDataSink* pDataSink = NULL;
|
||||
uint32_t count;
|
||||
|
||||
err = NuCreateDataSinkForBuffer(true, kNuConvertOff, buffer, kHappySize,
|
||||
&pDataSink);
|
||||
|
@ -389,9 +372,9 @@ ExtractToBuffer(NuArchive* pArchive, ArchiveData* pArchiveData)
|
|||
(void) NuDataSinkGetOutCount(pDataSink, &count);
|
||||
if (count > 0) {
|
||||
FILE* fp;
|
||||
if ((fp = fopen("out.buf", kNuFileOpenWriteTrunc)) != nil) {
|
||||
if ((fp = fopen("out.buf", kNuFileOpenWriteTrunc)) != NULL) {
|
||||
|
||||
printf("*** Writing %ld bytes\n", count);
|
||||
printf("*** Writing %u bytes\n", count);
|
||||
if (fwrite(buffer, count, 1, fp) != 1)
|
||||
err = kNuErrFileWrite;
|
||||
fclose(fp);
|
||||
|
@ -409,14 +392,13 @@ bail:
|
|||
/*
|
||||
* Do file stuff.
|
||||
*/
|
||||
int
|
||||
DoFileStuff(const char* filename)
|
||||
int DoFileStuff(const UNICHAR* filenameUNI)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
ArchiveData* pArchiveData = ArchiveData_New();
|
||||
|
||||
err = NuOpenRO(filename, &pArchive);
|
||||
err = NuOpenRO(filenameUNI, &pArchive);
|
||||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
|
||||
|
@ -444,7 +426,7 @@ bail:
|
|||
if (err != kNuErrNone)
|
||||
fprintf(stderr, "*** ERROR: got error %d\n", err);
|
||||
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
NuError err2 = NuClose(pArchive);
|
||||
if (err == kNuErrNone && err2 != kNuErrNone)
|
||||
err = err2;
|
||||
|
@ -459,21 +441,20 @@ bail:
|
|||
/*
|
||||
* Grab the name of an archive to read. If no name was provided, use stdin.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
long major, minor, bug;
|
||||
int32_t major, minor, bug;
|
||||
const char* pBuildDate;
|
||||
FILE* infp = nil;
|
||||
FILE* infp = NULL;
|
||||
int cc;
|
||||
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
|
||||
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n",
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
|
||||
printf("Using NuFX lib %d.%d.%d built on or after %s\n",
|
||||
major, minor, bug, pBuildDate);
|
||||
|
||||
if (argc == 2) {
|
||||
infp = fopen(argv[1], kNuFileOpenReadOnly);
|
||||
if (infp == nil) {
|
||||
if (infp == NULL) {
|
||||
perror("fopen failed");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -484,7 +465,7 @@ main(int argc, char** argv)
|
|||
|
||||
cc = DoFileStuff(argv[1]);
|
||||
|
||||
if (infp != nil)
|
||||
if (infp != NULL)
|
||||
fclose(infp);
|
||||
|
||||
exit(cc != 0);
|
||||
|
|
580
nufxlib/samples/TestNames.c
Normal file
580
nufxlib/samples/TestNames.c
Normal file
|
@ -0,0 +1,580 @@
|
|||
/*
|
||||
* NuFX archive manipulation library
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.LIB.
|
||||
*
|
||||
* Test local and storage names with Unicode and Mac OS Roman content.
|
||||
*
|
||||
* On Windows, opening files with fancy filenames requires UTF-16 and
|
||||
* special functions. On Linux and Mac OS X we're just writing UTF-8 data,
|
||||
* so they don't really need to do anything special other than be 8-bit
|
||||
* clean. NufxLib functions take UTF-8 strings, so on Windows we define
|
||||
* everything in UTF-16 and convert to UTF-8. (We need the UTF-16 form so
|
||||
* we can use "wide" I/O functions to confirm that the file was created
|
||||
* with the correct name.)
|
||||
*
|
||||
* To see files with the correct appearance with "ls", you may need to
|
||||
* do something like:
|
||||
*
|
||||
* % LC_ALL=en_US.UTF-8 ls
|
||||
*
|
||||
* (Many users set LC_ALL=POSIX to avoid GNU grep slowdowns and altered
|
||||
* sort ordering in ls.)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "NufxLib.h"
|
||||
#include "Common.h"
|
||||
|
||||
/*
|
||||
* Test filenames.
|
||||
*
|
||||
* The local filename (kTestArchive) contains non-MOR Unicode values
|
||||
* (two Japanese characters that Google Translate claims form the verb
|
||||
* "shrink"). The temp file name is similar.
|
||||
*
|
||||
* The entry name uses a mix of simple ASCII, CP1252 MOR, and
|
||||
* non-CP1252 MOR characters: fl ligature, double dagger, copyright symbol,
|
||||
* Apple logo (the latter of which doesn't have a glyph on Windows or Linux).
|
||||
* All of the characters have MOR translations.
|
||||
*/
|
||||
#ifdef USE_UTF16
|
||||
const UNICHAR kTestArchive[] = L"nlTest\u7e2e\u3080.shk";
|
||||
const UNICHAR kTestEntryName[] = L"nl-test\u2013\ufb01_\u2021_\u00a9\uf8ff!";
|
||||
const UNICHAR kTestTempFile[] = L"nlTest\4e00\u6642\u30d5\u30a1\u30a4\u30eb.tmp";
|
||||
#else
|
||||
const UNICHAR kTestArchive[] = "nlTest\xe7\xb8\xae\xe3\x82\x80.shk";
|
||||
const UNICHAR kTestEntryName[] = "nl-test\xe2\x80\x93\xef\xac\x81_\xe2\x80\xa1_"
|
||||
"\xc2\xa9\xef\xa3\xbf!";
|
||||
const UNICHAR kTestTempFile[] = "nlTest\xe4\xb8\x80\xe6\x99\x82\xe3\x83\x95"
|
||||
"\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab.tmp";
|
||||
#endif
|
||||
|
||||
const UNICHAR kLocalFssep = '|';
|
||||
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
* Helper functions
|
||||
* ===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get a single character of input from the user.
|
||||
*/
|
||||
static char TGetReplyChar(char defaultReply)
|
||||
{
|
||||
char tmpBuf[32];
|
||||
|
||||
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == NULL)
|
||||
return defaultReply;
|
||||
if (tmpBuf[0] == '\n' || tmpBuf[0] == '\r')
|
||||
return defaultReply;
|
||||
|
||||
return tmpBuf[0];
|
||||
}
|
||||
|
||||
NuError AddSimpleRecord(NuArchive* pArchive, const char* fileNameMOR,
|
||||
NuRecordIdx* pRecordIdx)
|
||||
{
|
||||
NuFileDetails fileDetails;
|
||||
|
||||
memset(&fileDetails, 0, sizeof(fileDetails));
|
||||
fileDetails.storageNameMOR = fileNameMOR;
|
||||
fileDetails.fileSysInfo = kLocalFssep;
|
||||
fileDetails.access = kNuAccessUnlocked;
|
||||
|
||||
return NuAddRecord(pArchive, &fileDetails, pRecordIdx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display error messages... or not.
|
||||
*/
|
||||
NuResult ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
|
||||
{
|
||||
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
|
||||
|
||||
//if (gSuppressError)
|
||||
// return kNuOK;
|
||||
|
||||
if (pErrorMessage->isDebug) {
|
||||
fprintf(stderr, "%sNufxLib says: [%s:%d %s] %s\n",
|
||||
pArchive == NULL ? "GLOBAL>" : "",
|
||||
pErrorMessage->file, pErrorMessage->line, pErrorMessage->function,
|
||||
pErrorMessage->message);
|
||||
} else {
|
||||
fprintf(stderr, "%sNufxLib says: %s\n",
|
||||
pArchive == NULL ? "GLOBAL>" : "",
|
||||
pErrorMessage->message);
|
||||
}
|
||||
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
#ifdef USE_UTF16
|
||||
TODO - use _waccess, _wunlink, etc.
|
||||
#else
|
||||
int RemoveTestFile(const char* title, const char* fileName)
|
||||
{
|
||||
char answer;
|
||||
|
||||
if (access(fileName, F_OK) == 0) {
|
||||
printf("%s '%s' exists, remove (y/n)? ", title, fileName);
|
||||
fflush(stdout);
|
||||
answer = TGetReplyChar('n');
|
||||
if (tolower(answer) != 'y')
|
||||
return -1;
|
||||
if (unlink(fileName) < 0) {
|
||||
perror("unlink");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Utility function that wraps NuConvertUNIToMOR, allocating a new
|
||||
* buffer to hold the converted string. The caller must free the result.
|
||||
*/
|
||||
char* CopyUNIToMOR(const UNICHAR* stringUNI)
|
||||
{
|
||||
size_t morLen;
|
||||
char* morBuf;
|
||||
|
||||
morLen = NuConvertUNIToMOR(stringUNI, NULL, 0);
|
||||
if (morLen == (size_t) -1) {
|
||||
return NULL;
|
||||
}
|
||||
morBuf = (char*) malloc(morLen);
|
||||
(void) NuConvertUNIToMOR(stringUNI, morBuf, morLen);
|
||||
return morBuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function that wraps NuConvertMORToUNI, allocating a new
|
||||
* buffer to hold the converted string. The caller must free the result.
|
||||
*/
|
||||
UNICHAR* CopyMORToUNI(const char* stringMOR)
|
||||
{
|
||||
size_t uniLen;
|
||||
char* uniBuf;
|
||||
|
||||
uniLen = NuConvertMORToUNI(stringMOR, NULL, 0);
|
||||
if (uniLen == (size_t) -1) {
|
||||
return NULL;
|
||||
}
|
||||
uniBuf = (UNICHAR*) malloc(uniLen);
|
||||
(void) NuConvertMORToUNI(stringMOR, uniBuf, uniLen);
|
||||
return uniBuf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
* Tests
|
||||
* ===========================================================================
|
||||
*/
|
||||
|
||||
void DumpMorString(const char* str)
|
||||
{
|
||||
printf("(%d) ", (int) strlen(str));
|
||||
while (*str != '\0') {
|
||||
if (*str >= 0x20 && *str < 0x7f) {
|
||||
putchar(*str);
|
||||
} else {
|
||||
printf("\\x%02x", (uint8_t) *str);
|
||||
}
|
||||
str++;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void DumpUnicharString(const UNICHAR* str)
|
||||
{
|
||||
printf("(%d) ", (int) strlen(str));
|
||||
while (*str != '\0') {
|
||||
if (*str >= 0x20 && *str < 0x7f) {
|
||||
putchar(*str);
|
||||
} else {
|
||||
if (sizeof(UNICHAR) == 1) {
|
||||
printf("\\x%02x", (uint8_t) *str);
|
||||
} else {
|
||||
printf("\\u%04x", (uint16_t) *str);
|
||||
}
|
||||
}
|
||||
str++;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* Some basic string conversion unit tests.
|
||||
*
|
||||
* TODO: test with short buffer, make sure we don't get partial code
|
||||
* points when converting to Unicode
|
||||
*/
|
||||
int TestStringConversion(void)
|
||||
{
|
||||
static const char kMORTest[] = "test\xe0\xe9\xed\xf3\xfa#\xf0\xb0";
|
||||
|
||||
size_t outLen;
|
||||
char morBuf[512];
|
||||
UNICHAR uniBuf[512];
|
||||
|
||||
// convert test string to Unicode
|
||||
memset(uniBuf, 0xcc, sizeof(uniBuf));
|
||||
//printf("MOR: "); DumpMorString(kMORTest);
|
||||
|
||||
outLen = NuConvertMORToUNI(kMORTest, NULL, 0);
|
||||
//printf("outLen is %u\n", (unsigned int) outLen);
|
||||
if (NuConvertMORToUNI(kMORTest, uniBuf, sizeof(uniBuf)) != outLen) {
|
||||
fprintf(stderr, "Inconsistent MORToUNI len\n");
|
||||
return -1;
|
||||
}
|
||||
//printf("UNI: "); DumpUnicharString(uniBuf);
|
||||
if (strlen(uniBuf) + 1 != outLen) {
|
||||
fprintf(stderr, "Expected length != actual length\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// convert Unicode back to MOR
|
||||
memset(morBuf, 0xcc, sizeof(morBuf));
|
||||
|
||||
outLen = NuConvertUNIToMOR(uniBuf, NULL, 0);
|
||||
//printf("outLen is %u\n", (unsigned int) outLen);
|
||||
if (NuConvertUNIToMOR(uniBuf, morBuf, sizeof(morBuf)) != outLen) {
|
||||
fprintf(stderr, "Inconsistent UNIToMOR len\n");
|
||||
return -1;
|
||||
}
|
||||
//printf("MOR: "); DumpMorString(morBuf);
|
||||
if (strlen(morBuf) + 1 != outLen) {
|
||||
fprintf(stderr, "Expected length != actual length\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check vs. original
|
||||
if (strcmp(kMORTest, morBuf) != 0) {
|
||||
fprintf(stderr, "Test string corrupted by double conversion\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_UTF16
|
||||
static const UNICHAR kNonMorUniStr[] = L"nlTest\u7e2e\u3080.shk";
|
||||
static const UNICHAR kBadUniStr[] = L"nlTest\u7e2e\x30";
|
||||
#else
|
||||
static const UNICHAR kNonMorUniStr[] = "nlTest\xe7\xb8\xae\xe3\x82\x80.shk";
|
||||
static const UNICHAR kBadUniStr[] = "nlTest\x81\xe7";
|
||||
#endif
|
||||
static const char kNonMorExpected[] = "nlTest??.shk";
|
||||
static const char kBadExpected[] = "nlTest??";
|
||||
|
||||
NuConvertUNIToMOR(kNonMorUniStr, morBuf, sizeof(morBuf));
|
||||
if (strcmp(morBuf, kNonMorExpected) != 0) {
|
||||
fprintf(stderr, "Non-MOR string conversion failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
NuConvertUNIToMOR(kBadUniStr, morBuf, sizeof(morBuf));
|
||||
if (strcmp(morBuf, kBadExpected) != 0) {
|
||||
fprintf(stderr, "Bad UNI string conversion failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("... string conversion tests successful\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new entry and give it a trivial data fork.
|
||||
*/
|
||||
int AddTestEntry(NuArchive* pArchive, const char* entryNameMOR)
|
||||
{
|
||||
NuDataSource* pDataSource = NULL;
|
||||
NuRecordIdx recordIdx;
|
||||
static const char* kTestMsg = "Hello, world!\n";
|
||||
uint32_t status;
|
||||
NuError err;
|
||||
|
||||
/*
|
||||
* Add our test entry.
|
||||
*/
|
||||
err = AddSimpleRecord(pArchive, entryNameMOR, &recordIdx);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: add record failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
|
||||
0, (const uint8_t*)kTestMsg, 0, strlen(kTestMsg), NULL,
|
||||
&pDataSource);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: source create failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
|
||||
NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: thread add failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
pDataSource = NULL; /* now owned by library */
|
||||
|
||||
/*
|
||||
* Flush changes.
|
||||
*/
|
||||
err = NuFlush(pArchive, &status);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't flush after add (err=%d, status=%u)\n",
|
||||
err, status);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
failed:
|
||||
if (pDataSource != NULL)
|
||||
NuFreeDataSource(pDataSource);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the file we created.
|
||||
*/
|
||||
int TestExtract(NuArchive* pArchive, const char* entryNameMOR)
|
||||
{
|
||||
const NuRecord* pRecord;
|
||||
NuRecordIdx recordIdx;
|
||||
NuError err;
|
||||
|
||||
err = NuGetRecordIdxByName(pArchive, entryNameMOR, &recordIdx);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't find '%s' (err=%d)\n",
|
||||
entryNameMOR, err);
|
||||
return -1;
|
||||
}
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
return -1;
|
||||
}
|
||||
assert(pRecord != NULL);
|
||||
|
||||
const NuThread* pThread = NULL;
|
||||
uint32_t idx;
|
||||
for (idx = 0; idx < NuRecordGetNumThreads(pRecord); idx++) {
|
||||
pThread = NuGetThread(pRecord, idx);
|
||||
|
||||
if (NuGetThreadID(pThread) == kNuThreadIDDataFork)
|
||||
break;
|
||||
}
|
||||
if (pThread == NULL) {
|
||||
fprintf(stderr, "ERROR: no data thread?\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the output file.
|
||||
*/
|
||||
UNICHAR* entryNameUNI = CopyMORToUNI(entryNameMOR);
|
||||
NuDataSink* pDataSink = NULL;
|
||||
err = NuCreateDataSinkForFile(true, kNuConvertOff, entryNameUNI,
|
||||
kLocalFssep, &pDataSink);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to create data sink for file (err=%d)\n",
|
||||
err);
|
||||
free(entryNameUNI);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = NuExtractThread(pArchive, pThread->threadIdx, pDataSink);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: extract failed (err=%d)\n", err);
|
||||
(void) NuFreeDataSink(pDataSink);
|
||||
free(entryNameUNI);
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void) NuFreeDataSink(pDataSink);
|
||||
|
||||
printf("... confirming extraction of '%s'\n", entryNameUNI);
|
||||
if (access(entryNameUNI, F_OK) != 0) {
|
||||
fprintf(stderr, "ERROR: unable to read '%s' (err=%d)\n",
|
||||
entryNameUNI, errno);
|
||||
free(entryNameUNI);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlink(entryNameUNI) < 0) {
|
||||
perror("unlink test entry");
|
||||
free(entryNameUNI);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(entryNameUNI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run some tests.
|
||||
*
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
int DoTests(void)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = NULL;
|
||||
char* testEntryNameMOR = NULL;
|
||||
int result = 0;
|
||||
|
||||
if (TestStringConversion() < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we're starting with a clean slate.
|
||||
*/
|
||||
if (RemoveTestFile("Test archive", kTestArchive) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
if (RemoveTestFile("Test temp file", kTestTempFile) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
if (RemoveTestFile("Test entry", kTestEntryName) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
testEntryNameMOR = CopyUNIToMOR(kTestEntryName);
|
||||
|
||||
/*
|
||||
* Create a new archive to play with.
|
||||
*/
|
||||
err = NuOpenRW(kTestArchive, kTestTempFile, kNuOpenCreat|kNuOpenExcl,
|
||||
&pArchive);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: NuOpenRW failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
if (NuSetErrorMessageHandler(pArchive, ErrorMessageHandler) ==
|
||||
kNuInvalidCallback)
|
||||
{
|
||||
fprintf(stderr, "ERROR: couldn't set message handler\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a single entry.
|
||||
*/
|
||||
if (AddTestEntry(pArchive, testEntryNameMOR) != 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
printf("... checking presence of '%s' and '%s'\n",
|
||||
kTestArchive, kTestTempFile);
|
||||
|
||||
if (access(kTestTempFile, F_OK) != 0) {
|
||||
/* in theory, NufxLib doesn't need to use the temp file we provide,
|
||||
so this test isn't entirely sound */
|
||||
fprintf(stderr, "ERROR: did not find %s (err=%d)\n",
|
||||
kTestTempFile, err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close it and confirm that the file has the expected name.
|
||||
*/
|
||||
err = NuClose(pArchive);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: mid NuClose failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
pArchive = NULL;
|
||||
|
||||
if (access(kTestArchive, F_OK) != 0) {
|
||||
fprintf(stderr, "ERROR: did not find %s (err=%d)\n", kTestArchive, err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reopen it read-only.
|
||||
*/
|
||||
printf("... reopening archive read-only\n");
|
||||
err = NuOpenRO(kTestArchive, &pArchive);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: NuOpenRO failed (err=%d)\n", err);
|
||||
goto failed;
|
||||
}
|
||||
if (NuSetErrorMessageHandler(pArchive, ErrorMessageHandler) ==
|
||||
kNuInvalidCallback)
|
||||
{
|
||||
fprintf(stderr, "ERROR: couldn't set message handler\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the file.
|
||||
*/
|
||||
if (TestExtract(pArchive, testEntryNameMOR) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* That's all, folks...
|
||||
*/
|
||||
NuClose(pArchive);
|
||||
pArchive = NULL;
|
||||
|
||||
printf("... removing '%s'\n", kTestArchive);
|
||||
if (unlink(kTestArchive) < 0) {
|
||||
perror("unlink kTestArchive");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
if (pArchive != NULL) {
|
||||
NuAbort(pArchive);
|
||||
NuClose(pArchive);
|
||||
}
|
||||
free(testEntryNameMOR);
|
||||
return result;
|
||||
|
||||
failed:
|
||||
result = -1;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Start here.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
int32_t major, minor, bug;
|
||||
const char* pBuildDate;
|
||||
const char* pBuildFlags;
|
||||
int cc;
|
||||
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, &pBuildFlags);
|
||||
printf("Using NuFX library v%d.%d.%d, built on or after\n"
|
||||
" %s with [%s]\n\n",
|
||||
major, minor, bug, pBuildDate, pBuildFlags);
|
||||
|
||||
if (NuSetGlobalErrorMessageHandler(ErrorMessageHandler) ==
|
||||
kNuInvalidCallback)
|
||||
{
|
||||
fprintf(stderr, "ERROR: can't set the global message handler");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("... starting tests\n");
|
||||
|
||||
cc = DoTests();
|
||||
|
||||
printf("... tests ended, %s\n", cc == 0 ? "SUCCESS" : "FAILURE");
|
||||
exit(cc != 0);
|
||||
}
|
||||
|
|
@ -21,12 +21,20 @@
|
|||
* header, a filename thread, or a default value ("UNKNOWN", stuffed in
|
||||
* when a record has no filename at all).
|
||||
*/
|
||||
NuResult
|
||||
ShowContents(NuArchive* pArchive, void* vpRecord)
|
||||
NuResult ShowContents(NuArchive* pArchive, void* vpRecord)
|
||||
{
|
||||
const NuRecord* pRecord = (NuRecord*) vpRecord;
|
||||
|
||||
printf("*** Filename = '%s'\n", pRecord->filename);
|
||||
size_t bufLen = NuConvertMORToUNI(pRecord->filenameMOR, NULL, 0);
|
||||
if (bufLen == (size_t) -1) {
|
||||
fprintf(stderr, "GLITCH: unable to convert '%s'\n",
|
||||
pRecord->filenameMOR);
|
||||
} else {
|
||||
UNICHAR* buf = (UNICHAR*) malloc(bufLen);
|
||||
NuConvertMORToUNI(pRecord->filenameMOR, buf, bufLen);
|
||||
printf("*** Filename = '%s'\n", buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
return kNuOK;
|
||||
}
|
||||
|
@ -38,11 +46,10 @@ ShowContents(NuArchive* pArchive, void* vpRecord)
|
|||
* If we're not interested in handling an archive on stdin, we could just
|
||||
* pass the filename in here and use NuOpenRO instead.
|
||||
*/
|
||||
int
|
||||
DoStreamStuff(FILE* fp)
|
||||
int DoStreamStuff(FILE* fp)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
err = NuStreamOpenRO(fp, &pArchive);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -59,7 +66,7 @@ DoStreamStuff(FILE* fp)
|
|||
}
|
||||
|
||||
bail:
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
NuError err2 = NuClose(pArchive);
|
||||
if (err == kNuErrNone)
|
||||
err = err2;
|
||||
|
@ -72,16 +79,15 @@ bail:
|
|||
/*
|
||||
* Grab the name of an archive to read. If "-" was given, use stdin.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
long major, minor, bug;
|
||||
int32_t major, minor, bug;
|
||||
const char* pBuildDate;
|
||||
FILE* infp = nil;
|
||||
FILE* infp = NULL;
|
||||
int cc;
|
||||
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
|
||||
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n",
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
|
||||
printf("Using NuFX lib %d.%d.%d built on or after %s\n",
|
||||
major, minor, bug, pBuildDate);
|
||||
|
||||
if (argc != 2) {
|
||||
|
@ -93,7 +99,7 @@ main(int argc, char** argv)
|
|||
infp = stdin;
|
||||
else {
|
||||
infp = fopen(argv[1], kNuFileOpenReadOnly);
|
||||
if (infp == nil) {
|
||||
if (infp == NULL) {
|
||||
fprintf(stderr, "ERROR: unable to open '%s'\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -29,16 +29,15 @@ const int kMaxHeldLen = 1024 * 1024;
|
|||
* A list of CRCs.
|
||||
*/
|
||||
typedef struct CRCList {
|
||||
int numEntries;
|
||||
unsigned short* entries;
|
||||
int numEntries;
|
||||
uint16_t* entries;
|
||||
} CRCList;
|
||||
|
||||
|
||||
/*
|
||||
* Returns true if the compression type is supported, false otherwise.
|
||||
*/
|
||||
int
|
||||
CompressionSupported(NuValue compression)
|
||||
int CompressionSupported(NuValue compression)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -76,8 +75,7 @@ CompressionSupported(NuValue compression)
|
|||
/*
|
||||
* This gets called when a buffer DataSource is no longer needed.
|
||||
*/
|
||||
NuResult
|
||||
FreeCallback(NuArchive* pArchive, void* args)
|
||||
NuResult FreeCallback(NuArchive* pArchive, void* args)
|
||||
{
|
||||
free(args);
|
||||
return kNuOK;
|
||||
|
@ -87,8 +85,7 @@ FreeCallback(NuArchive* pArchive, void* args)
|
|||
/*
|
||||
* Dump a CRC list.
|
||||
*/
|
||||
void
|
||||
DumpCRCs(const CRCList* pCRCList)
|
||||
void DumpCRCs(const CRCList* pCRCList)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -101,10 +98,9 @@ DumpCRCs(const CRCList* pCRCList)
|
|||
/*
|
||||
* Free a CRC list.
|
||||
*/
|
||||
void
|
||||
FreeCRCs(CRCList* pCRCList)
|
||||
void FreeCRCs(CRCList* pCRCList)
|
||||
{
|
||||
if (pCRCList == nil)
|
||||
if (pCRCList == NULL)
|
||||
return;
|
||||
|
||||
free(pCRCList->entries);
|
||||
|
@ -117,21 +113,20 @@ FreeCRCs(CRCList* pCRCList)
|
|||
* We assume there are at most two data threads (e.g. data fork and rsrc
|
||||
* fork) in a record.
|
||||
*
|
||||
* Returns the list on success, nil on failure.
|
||||
* Returns the list on success, NULL on failure.
|
||||
*/
|
||||
CRCList*
|
||||
GatherCRCs(NuArchive* pArchive)
|
||||
CRCList* GatherCRCs(NuArchive* pArchive)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
const NuMasterHeader* pMasterHeader;
|
||||
CRCList* pCRCList = nil;
|
||||
unsigned short* pEntries = nil;
|
||||
CRCList* pCRCList = NULL;
|
||||
uint16_t* pEntries = NULL;
|
||||
long recCount, maxCRCs;
|
||||
long recIdx, crcIdx;
|
||||
int i;
|
||||
|
||||
pCRCList = malloc(sizeof(*pCRCList));
|
||||
if (pCRCList == nil) {
|
||||
if (pCRCList == NULL) {
|
||||
fprintf(stderr, "ERROR: couldn't alloc CRC list\n");
|
||||
err = kNuErrGeneric;
|
||||
goto bail;
|
||||
|
@ -148,7 +143,7 @@ GatherCRCs(NuArchive* pArchive)
|
|||
maxCRCs = recCount * 2;
|
||||
|
||||
pEntries = malloc(sizeof(*pEntries) * maxCRCs);
|
||||
if (pEntries == nil) {
|
||||
if (pEntries == NULL) {
|
||||
fprintf(stderr, "ERROR: unable to alloc CRC list (%ld entries)\n",
|
||||
maxCRCs);
|
||||
err = kNuErrGeneric;
|
||||
|
@ -178,17 +173,18 @@ GatherCRCs(NuArchive* pArchive)
|
|||
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to get recordIdx %ld\n", recordIdx);
|
||||
fprintf(stderr, "ERROR: unable to get recordIdx %u\n", recordIdx);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (NuRecordGetNumThreads(pRecord) == 0) {
|
||||
fprintf(stderr, "ERROR: not expecting empty record (%ld)!\n",
|
||||
fprintf(stderr, "ERROR: not expecting empty record (%u)!\n",
|
||||
recordIdx);
|
||||
err = kNuErrGeneric;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
int rsrcCrcIdx = -1;
|
||||
for (i = 0; i < (int)NuRecordGetNumThreads(pRecord); i++) {
|
||||
pThread = NuGetThread(pRecord, i);
|
||||
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||
|
@ -199,7 +195,30 @@ GatherCRCs(NuArchive* pArchive)
|
|||
goto bail;
|
||||
}
|
||||
|
||||
pEntries[crcIdx++] = pThread->thThreadCRC;
|
||||
/*
|
||||
* Ensure that the data fork CRC comes first. Otherwise
|
||||
* we can fail if it gets rearranged. This is only a
|
||||
* problem for GSHK-created archives that don't have
|
||||
* threads for every fork, so "mask dataless" is create
|
||||
* fake entries.
|
||||
*
|
||||
* The correct way to do this is to store a tuple
|
||||
* { thread-kind, crc }, but that's more work.
|
||||
*/
|
||||
if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
|
||||
rsrcCrcIdx = crcIdx;
|
||||
}
|
||||
|
||||
if (pThread->thThreadKind == kNuThreadKindDataFork &&
|
||||
rsrcCrcIdx != -1)
|
||||
{
|
||||
/* this is the data fork, we've already seen the
|
||||
resource fork; swap entries */
|
||||
pEntries[crcIdx++] = pEntries[rsrcCrcIdx];
|
||||
pEntries[rsrcCrcIdx] = pThread->thThreadCRC;
|
||||
} else {
|
||||
pEntries[crcIdx++] = pThread->thThreadCRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +230,7 @@ GatherCRCs(NuArchive* pArchive)
|
|||
bail:
|
||||
if (err != kNuErrNone) {
|
||||
FreeCRCs(pCRCList);
|
||||
pCRCList = nil;
|
||||
pCRCList = NULL;
|
||||
}
|
||||
return pCRCList;
|
||||
}
|
||||
|
@ -228,16 +247,15 @@ bail:
|
|||
*
|
||||
* Returns 0 on success, nonzero on failure.
|
||||
*/
|
||||
int
|
||||
CompareCRCs(NuArchive* pArchive, const CRCList* pOldCRCList)
|
||||
int CompareCRCs(NuArchive* pArchive, const CRCList* pOldCRCList)
|
||||
{
|
||||
CRCList* pNewCRCList = nil;
|
||||
CRCList* pNewCRCList = NULL;
|
||||
int result = -1;
|
||||
int badCrc = 0;
|
||||
int i;
|
||||
|
||||
pNewCRCList = GatherCRCs(pArchive);
|
||||
if (pNewCRCList == nil) {
|
||||
if (pNewCRCList == NULL) {
|
||||
fprintf(stderr, "ERROR: unable to gather new list\n");
|
||||
goto bail;
|
||||
}
|
||||
|
@ -274,18 +292,17 @@ bail:
|
|||
*
|
||||
* All of this good stuff gets queued up until the next NuFlush call.
|
||||
*/
|
||||
NuError
|
||||
RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
NuError RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
|
||||
const NuThread* pThread)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuDataSource* pDataSource = nil;
|
||||
NuDataSink* pDataSink = nil;
|
||||
unsigned char* buf = nil;
|
||||
NuDataSource* pDataSource = NULL;
|
||||
NuDataSink* pDataSink = NULL;
|
||||
uint8_t* buf = NULL;
|
||||
|
||||
if (pThread->actualThreadEOF == 0) {
|
||||
buf = malloc(1);
|
||||
if (buf == nil) {
|
||||
if (buf == NULL) {
|
||||
fprintf(stderr, "ERROR: failed allocating trivial buffer\n");
|
||||
err = kNuErrGeneric;
|
||||
goto bail;
|
||||
|
@ -295,8 +312,8 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
* Create a buffer and data sink to hold the data.
|
||||
*/
|
||||
buf = malloc(pThread->actualThreadEOF);
|
||||
if (buf == nil) {
|
||||
fprintf(stderr, "ERROR: failed allocating %ld bytes\n",
|
||||
if (buf == NULL) {
|
||||
fprintf(stderr, "ERROR: failed allocating %u bytes\n",
|
||||
pThread->actualThreadEOF);
|
||||
err = kNuErrGeneric;
|
||||
goto bail;
|
||||
|
@ -314,8 +331,8 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
*/
|
||||
err = NuExtractThread(pArchive, pThread->threadIdx, pDataSink);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: failed extracting thread %ld in '%s': %s\n",
|
||||
pThread->threadIdx, pRecord->filename, NuStrError(err));
|
||||
fprintf(stderr, "ERROR: failed extracting thread %u in '%s': %s\n",
|
||||
pThread->threadIdx, pRecord->filenameMOR, NuStrError(err));
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +342,7 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
*/
|
||||
err = NuDeleteThread(pArchive, pThread->threadIdx);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to delete thread %ld\n",
|
||||
fprintf(stderr, "ERROR: unable to delete thread %u\n",
|
||||
pThread->threadIdx);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -340,19 +357,19 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
|
|||
fprintf(stderr, "ERROR: unable to create data source (err=%d)\n", err);
|
||||
goto bail;
|
||||
}
|
||||
buf = nil;
|
||||
buf = NULL;
|
||||
|
||||
/*
|
||||
* Create replacement thread.
|
||||
*/
|
||||
err = NuAddThread(pArchive, pRecord->recordIdx, NuGetThreadID(pThread),
|
||||
pDataSource, nil);
|
||||
pDataSource, NULL);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to add new thread ID=0x%08lx (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: unable to add new thread ID=0x%08x (err=%d)\n",
|
||||
NuGetThreadID(pThread), err);
|
||||
goto bail;
|
||||
}
|
||||
pDataSource = nil; /* now owned by NufxLib */
|
||||
pDataSource = NULL; /* now owned by NufxLib */
|
||||
|
||||
bail:
|
||||
NuFreeDataSink(pDataSink);
|
||||
|
@ -367,21 +384,20 @@ bail:
|
|||
* The amount of data we're holding in memory as a result of the
|
||||
* recompression is placed in "*pLen".
|
||||
*/
|
||||
NuError
|
||||
RecompressRecord(NuArchive* pArchive, NuRecordIdx recordIdx, long* pLen)
|
||||
NuError RecompressRecord(NuArchive* pArchive, NuRecordIdx recordIdx, long* pLen)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
const NuRecord* pRecord;
|
||||
const NuThread* pThread;
|
||||
int i;
|
||||
|
||||
printf(" Recompressing %ld\n", recordIdx);
|
||||
printf(" Recompressing %u\n", recordIdx);
|
||||
|
||||
*pLen = 0;
|
||||
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to get record %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: unable to get record %u (err=%d)\n",
|
||||
recordIdx, err);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -393,8 +409,8 @@ RecompressRecord(NuArchive* pArchive, NuRecordIdx recordIdx, long* pLen)
|
|||
NuGetThreadID(pThread));*/
|
||||
err = RecompressThread(pArchive, pRecord, pThread);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: failed recompressing thread %ld "
|
||||
" in record %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: failed recompressing thread %u "
|
||||
" in record %u (err=%d)\n",
|
||||
pThread->threadIdx, pRecord->recordIdx, err);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -412,23 +428,22 @@ bail:
|
|||
/*
|
||||
* Recompress every data thread in the archive.
|
||||
*/
|
||||
NuError
|
||||
RecompressArchive(NuArchive* pArchive, NuValue compression)
|
||||
NuError RecompressArchive(NuArchive* pArchive, NuValue compression)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuRecordIdx* pIndices = nil;
|
||||
NuRecordIdx* pIndices = NULL;
|
||||
NuAttr countAttr;
|
||||
long heldLen;
|
||||
long idx;
|
||||
|
||||
err = NuSetValue(pArchive, kNuValueDataCompression, compression);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to set compression to %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: unable to set compression to %u (err=%d)\n",
|
||||
compression, err);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
printf("Recompressing threads with compression type %ld\n", compression);
|
||||
printf("Recompressing threads with compression type %u\n", compression);
|
||||
|
||||
err = NuGetAttr(pArchive, kNuAttrNumRecords, &countAttr);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -446,8 +461,8 @@ RecompressArchive(NuArchive* pArchive, NuValue compression)
|
|||
* record to "disappear" during processing, we will know about it.
|
||||
*/
|
||||
pIndices = malloc(countAttr * sizeof(*pIndices));
|
||||
if (pIndices == nil) {
|
||||
fprintf(stderr, "ERROR: malloc on %ld indices failed\n", countAttr);
|
||||
if (pIndices == NULL) {
|
||||
fprintf(stderr, "ERROR: malloc on %u indices failed\n", countAttr);
|
||||
err = kNuErrGeneric;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -470,7 +485,7 @@ RecompressArchive(NuArchive* pArchive, NuValue compression)
|
|||
|
||||
err = RecompressRecord(pArchive, pIndices[idx], &recHeldLen);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: failed recompressing record %ld (err=%d)\n",
|
||||
fprintf(stderr, "ERROR: failed recompressing record %u (err=%d)\n",
|
||||
pIndices[idx], err);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -478,7 +493,7 @@ RecompressArchive(NuArchive* pArchive, NuValue compression)
|
|||
heldLen += recHeldLen;
|
||||
|
||||
if (heldLen > kMaxHeldLen) {
|
||||
long statusFlags;
|
||||
uint32_t statusFlags;
|
||||
|
||||
printf(" (flush)\n");
|
||||
err = NuFlush(pArchive, &statusFlags);
|
||||
|
@ -500,12 +515,11 @@ bail:
|
|||
/*
|
||||
* Initiate the twirling.
|
||||
*/
|
||||
int
|
||||
TwirlArchive(const char* filename)
|
||||
int TwirlArchive(const char* filename)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuArchive* pArchive = nil;
|
||||
CRCList* pCRCList = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
CRCList* pCRCList = NULL;
|
||||
int compression;
|
||||
int cc;
|
||||
|
||||
|
@ -534,7 +548,7 @@ TwirlArchive(const char* filename)
|
|||
}
|
||||
|
||||
pCRCList = GatherCRCs(pArchive);
|
||||
if (pCRCList == nil) {
|
||||
if (pCRCList == NULL) {
|
||||
fprintf(stderr, "ERROR: unable to get CRC list\n");
|
||||
goto bail;
|
||||
}
|
||||
|
@ -545,7 +559,7 @@ TwirlArchive(const char* filename)
|
|||
for (compression = kNuCompressNone; compression <= kNuCompressBzip2;
|
||||
compression++)
|
||||
{
|
||||
long statusFlags;
|
||||
uint32_t statusFlags;
|
||||
|
||||
if (!CompressionSupported(compression))
|
||||
continue;
|
||||
|
@ -571,7 +585,7 @@ TwirlArchive(const char* filename)
|
|||
for (compression = kNuCompressBzip2; compression >= kNuCompressNone;
|
||||
compression--)
|
||||
{
|
||||
long statusFlags;
|
||||
uint32_t statusFlags;
|
||||
|
||||
if (!CompressionSupported(compression))
|
||||
continue;
|
||||
|
@ -599,7 +613,7 @@ TwirlArchive(const char* filename)
|
|||
|
||||
bail:
|
||||
FreeCRCs(pCRCList);
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
NuAbort(pArchive);
|
||||
NuClose(pArchive);
|
||||
}
|
||||
|
@ -611,22 +625,21 @@ bail:
|
|||
/*
|
||||
* Copy from the current offset in "srcfp" to a new file called
|
||||
* "outFileName". Returns a writable file descriptor for the new file
|
||||
* on success, or nil on error.
|
||||
* on success, or NULL on error.
|
||||
*
|
||||
* (Note "CopyFile()" exists under Win32.)
|
||||
*/
|
||||
FILE*
|
||||
MyCopyFile(const char* outFileName, FILE* srcfp)
|
||||
FILE* MyCopyFile(const char* outFileName, FILE* srcfp)
|
||||
{
|
||||
char buf[24576];
|
||||
FILE* outfp;
|
||||
size_t count;
|
||||
|
||||
outfp = fopen(outFileName, kNuFileOpenWriteTrunc);
|
||||
if (outfp == nil) {
|
||||
if (outfp == NULL) {
|
||||
fprintf(stderr, "ERROR: unable to open '%s' (err=%d)\n", outFileName,
|
||||
errno);
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (!feof(srcfp)) {
|
||||
|
@ -636,14 +649,14 @@ MyCopyFile(const char* outFileName, FILE* srcfp)
|
|||
if (fwrite(buf, 1, count, outfp) != count) {
|
||||
fprintf(stderr, "ERROR: failed writing outfp (err=%d)\n", errno);
|
||||
fclose(outfp);
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(srcfp)) {
|
||||
fprintf(stderr, "ERROR: failed reading srcfp (err=%d)\n", errno);
|
||||
fclose(outfp);
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return outfp;
|
||||
|
@ -652,26 +665,25 @@ MyCopyFile(const char* outFileName, FILE* srcfp)
|
|||
/*
|
||||
* Let's get started.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
long major, minor, bug;
|
||||
int32_t major, minor, bug;
|
||||
const char* pBuildDate;
|
||||
FILE* srcfp = nil;
|
||||
FILE* infp = nil;
|
||||
FILE* srcfp = NULL;
|
||||
FILE* infp = NULL;
|
||||
int cc;
|
||||
|
||||
/* don't buffer output */
|
||||
setvbuf(stdout, nil, _IONBF, 0);
|
||||
setvbuf(stderr, nil, _IONBF, 0);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
|
||||
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n\n",
|
||||
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
|
||||
printf("Using NuFX lib %d.%d.%d built on or after %s\n\n",
|
||||
major, minor, bug, pBuildDate);
|
||||
|
||||
if (argc == 2) {
|
||||
srcfp = fopen(argv[1], kNuFileOpenReadOnly);
|
||||
if (srcfp == nil) {
|
||||
if (srcfp == NULL) {
|
||||
perror("fopen failed");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -683,7 +695,7 @@ main(int argc, char** argv)
|
|||
printf("Copying '%s' to '%s'\n", argv[1], kWorkFileName);
|
||||
|
||||
infp = MyCopyFile(kWorkFileName, srcfp);
|
||||
if (infp == nil) {
|
||||
if (infp == NULL) {
|
||||
fprintf(stderr, "Copy failed, bailing.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
26
nulib2/Add.c
26
nulib2/Add.c
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Add files to or update files in the archive.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
static NuError AddToArchive(NulibState* pState, NuArchive* pArchive);
|
||||
|
||||
|
@ -14,21 +14,20 @@ static NuError AddToArchive(NulibState* pState, NuArchive* pArchive);
|
|||
/*
|
||||
* Add the specified files to a new or existing archive.
|
||||
*/
|
||||
NuError
|
||||
DoAdd(NulibState* pState)
|
||||
NuError DoAdd(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
long flushStatus;
|
||||
NuArchive* pArchive = NULL;
|
||||
uint32_t flushStatus;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
err = OpenArchiveReadWrite(pState);
|
||||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
|
||||
pArchive = NState_GetNuArchive(pState);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
NState_SetMatchCount(pState, 0);
|
||||
|
||||
|
@ -43,7 +42,7 @@ DoAdd(NulibState* pState)
|
|||
printf("%s: no records matched\n", gProgName);
|
||||
|
||||
bail:
|
||||
if (pArchive != nil) {
|
||||
if (pArchive != NULL) {
|
||||
NuError err2;
|
||||
|
||||
#if 0
|
||||
|
@ -62,7 +61,7 @@ bail:
|
|||
"failed afterward");
|
||||
} else {
|
||||
ReportError(err,
|
||||
"Unable to flush archive changes (status=0x%04lx)",
|
||||
"Unable to flush archive changes (status=0x%04x)",
|
||||
flushStatus);
|
||||
}
|
||||
NuAbort(pArchive);
|
||||
|
@ -84,15 +83,14 @@ bail:
|
|||
* This just results in NuAddFile calls; the deferred write operation
|
||||
* isn't initiated.
|
||||
*/
|
||||
static NuError
|
||||
AddToArchive(NulibState* pState, NuArchive* pArchive)
|
||||
static NuError AddToArchive(NulibState* pState, NuArchive* pArchive)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
char* const* pSpec;
|
||||
int i;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
if (!NState_GetFilespecCount(pState)) {
|
||||
err = kNuErrSyntax;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Common archive-related utility functions.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -24,19 +24,18 @@
|
|||
* The buffer we return to the archive library will be overwritten the
|
||||
* next time this function gets called. This is expected.
|
||||
*/
|
||||
static NuResult
|
||||
OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
|
||||
static NuResult OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
|
||||
{
|
||||
NuPathnameProposal* pathProposal = vproposal;
|
||||
NulibState* pState;
|
||||
const char* newPathname;
|
||||
const UNICHAR* newPathnameUNI;
|
||||
NuRecordIdx renameFromIdx;
|
||||
char* renameToStr;
|
||||
char* resultBuf;
|
||||
UNICHAR* renameToStrUNI;
|
||||
UNICHAR* resultBufUNI;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
(void) NuGetExtraData(pArchive, (void**) &pState);
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
/* handle extract-to-pipe */
|
||||
if (NState_GetCommand(pState) == kCommandExtractToPipe) {
|
||||
|
@ -50,22 +49,22 @@ OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
|
|||
* the output through the normalizer; if the user typed it, assume
|
||||
* that it's okay (and let the OS tell them if it isn't).
|
||||
*/
|
||||
renameToStr = NState_GetRenameToStr(pState);
|
||||
if (renameToStr != nil) {
|
||||
renameToStrUNI = NState_GetRenameToStr(pState);
|
||||
if (renameToStrUNI != NULL) {
|
||||
renameFromIdx = NState_GetRenameFromIdx(pState);
|
||||
|
||||
if (renameFromIdx == pathProposal->pRecord->recordIdx) {
|
||||
/* right source file, proceed with the rename */
|
||||
NState_SetTempPathnameLen(pState, strlen(renameToStr) +1);
|
||||
resultBuf = NState_GetTempPathnameBuf(pState);
|
||||
Assert(resultBuf != nil);
|
||||
strcpy(resultBuf, renameToStr);
|
||||
NState_SetTempPathnameLen(pState, strlen(renameToStrUNI) +1);
|
||||
resultBufUNI = NState_GetTempPathnameBuf(pState);
|
||||
Assert(resultBufUNI != NULL);
|
||||
strcpy(resultBufUNI, renameToStrUNI);
|
||||
|
||||
pathProposal->newPathname = resultBuf;
|
||||
pathProposal->newPathnameUNI = resultBufUNI;
|
||||
}
|
||||
|
||||
/* free up renameToStr */
|
||||
NState_SetRenameToStr(pState, nil);
|
||||
/* free up renameToStrUNI */
|
||||
NState_SetRenameToStr(pState, NULL);
|
||||
|
||||
goto bail;
|
||||
}
|
||||
|
@ -73,13 +72,13 @@ OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
|
|||
/*
|
||||
* Convert the pathname into something suitable for the current OS.
|
||||
*/
|
||||
newPathname = NormalizePath(pState, pathProposal);
|
||||
if (newPathname == nil) {
|
||||
newPathnameUNI = NormalizePath(pState, pathProposal);
|
||||
if (newPathnameUNI == NULL) {
|
||||
ReportError(kNuErrNone, "unable to convert pathname");
|
||||
return kNuAbort;
|
||||
}
|
||||
|
||||
pathProposal->newPathname = newPathname;
|
||||
pathProposal->newPathnameUNI = newPathnameUNI;
|
||||
|
||||
bail:
|
||||
return kNuOK;
|
||||
|
@ -99,12 +98,11 @@ bail:
|
|||
* first character. A fancier version would play with line disciplines
|
||||
* so you wouldn't have to hit "return".
|
||||
*/
|
||||
static char
|
||||
GetReplyChar(char defaultReply)
|
||||
static char GetReplyChar(char defaultReply)
|
||||
{
|
||||
char tmpBuf[32];
|
||||
|
||||
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == nil)
|
||||
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == NULL)
|
||||
return defaultReply;
|
||||
if (tmpBuf[0] == '\n' || tmpBuf[0] == '\r')
|
||||
return defaultReply;
|
||||
|
@ -120,8 +118,7 @@ GetReplyChar(char defaultReply)
|
|||
*
|
||||
* String returned should be freed by the caller.
|
||||
*/
|
||||
static char*
|
||||
GetReplyString(const char* prompt)
|
||||
static char* GetReplyString(const char* prompt)
|
||||
{
|
||||
char buf[kMaxInputLen];
|
||||
char* result;
|
||||
|
@ -130,10 +127,10 @@ GetReplyString(const char* prompt)
|
|||
printf("%s", prompt);
|
||||
fflush(stdout);
|
||||
result = fgets(buf, sizeof(buf), stdin);
|
||||
if (result == nil || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
|
||||
if (result == NULL || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
|
||||
buf[0] == '\n')
|
||||
{
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* nuke the terminating '\n', which is lots of fun in filenames */
|
||||
|
@ -148,30 +145,29 @@ GetReplyString(const char* prompt)
|
|||
/*
|
||||
* Get a one-line comment from the user, of at most "maxLen" bytes.
|
||||
*
|
||||
* If the user enters a blank line, return "nil".
|
||||
* If the user enters a blank line, return "NULL".
|
||||
*
|
||||
* A pointer to a newly-allocated buffer is returned.
|
||||
*/
|
||||
char*
|
||||
GetSimpleComment(NulibState* pState, const char* pathname, int maxLen)
|
||||
char* GetSimpleComment(NulibState* pState, const char* pathname, int maxLen)
|
||||
{
|
||||
char* buf = nil;
|
||||
char* buf = NULL;
|
||||
char* result;
|
||||
int len;
|
||||
|
||||
buf = Malloc(maxLen);
|
||||
if (buf == nil)
|
||||
return nil;
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
printf("Enter one-line comment for '%s'\n: ", pathname);
|
||||
fflush(stdout);
|
||||
|
||||
result = fgets(buf, maxLen, stdin);
|
||||
if (result == nil || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
|
||||
if (result == NULL || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
|
||||
buf[0] == '\n')
|
||||
{
|
||||
Free(buf);
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* nuke the terminating '\n', which we don't need */
|
||||
|
@ -196,8 +192,8 @@ GetSimpleComment(NulibState* pState, const char* pathname, int maxLen)
|
|||
*
|
||||
* (Someday "spec" might be a regexp.)
|
||||
*/
|
||||
static Boolean
|
||||
SpecMatchesRecord(NulibState* pState, const char* spec, const NuRecord* pRecord)
|
||||
static Boolean SpecMatchesRecord(NulibState* pState, const char* spec,
|
||||
const NuRecord* pRecord)
|
||||
{
|
||||
#ifdef NU_CASE_SENSITIVE
|
||||
if (NState_GetModRecurse(pState))
|
||||
|
@ -206,9 +202,9 @@ SpecMatchesRecord(NulibState* pState, const char* spec, const NuRecord* pRecord)
|
|||
return (strcmp(spec, pRecord->filename) == 0);
|
||||
#else
|
||||
if (NState_GetModRecurse(pState))
|
||||
return (strncasecmp(spec, pRecord->filename, strlen(spec)) == 0);
|
||||
return (strncasecmp(spec, pRecord->filenameMOR, strlen(spec)) == 0);
|
||||
else
|
||||
return (strcasecmp(spec, pRecord->filename) == 0);
|
||||
return (strcasecmp(spec, pRecord->filenameMOR) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -222,8 +218,7 @@ SpecMatchesRecord(NulibState* pState, const char* spec, const NuRecord* pRecord)
|
|||
* extraction by criteria other than name, e.g. all text files or all
|
||||
* files archived before a certain date.
|
||||
*/
|
||||
Boolean
|
||||
IsSpecified(NulibState* pState, const NuRecord* pRecord)
|
||||
Boolean IsSpecified(NulibState* pState, const NuRecord* pRecord)
|
||||
{
|
||||
char* const* pSpec;
|
||||
int i;
|
||||
|
@ -245,36 +240,36 @@ IsSpecified(NulibState* pState, const NuRecord* pRecord)
|
|||
* General-purpose selection filter, invoked as a callback. Compares the
|
||||
* selection proposal with the filenames in "filespec".
|
||||
*/
|
||||
NuResult
|
||||
SelectionFilter(NuArchive* pArchive, void* vproposal)
|
||||
NuResult SelectionFilter(NuArchive* pArchive, void* vproposal)
|
||||
{
|
||||
const NuSelectionProposal* selProposal = vproposal;
|
||||
NulibState* pState;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
(void) NuGetExtraData(pArchive, (void**) &pState);
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (IsSpecified(pState, selProposal->pRecord)) {
|
||||
NState_IncMatchCount(pState);
|
||||
|
||||
/* we don't get progress notifications for delete, so do it here */
|
||||
if (NState_GetCommand(pState) == kCommandDelete)
|
||||
printf("Deleting %s\n", selProposal->pRecord->filename);
|
||||
if (NState_GetCommand(pState) == kCommandDelete) {
|
||||
printf("Deleting %s\n", selProposal->pRecord->filenameMOR);
|
||||
}
|
||||
|
||||
return kNuOK;
|
||||
} else
|
||||
} else {
|
||||
return kNuSkip;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print a three-digit progress percentage; range is 0% to 100%.
|
||||
*/
|
||||
void
|
||||
PrintPercentage(ulong total, ulong progress)
|
||||
void PrintPercentage(uint32_t total, uint32_t progress)
|
||||
{
|
||||
ulong perc;
|
||||
uint32_t perc;
|
||||
|
||||
if (!total) {
|
||||
/*printf(" %%");*/
|
||||
|
@ -292,15 +287,14 @@ PrintPercentage(ulong total, ulong progress)
|
|||
perc = 100;
|
||||
}
|
||||
|
||||
printf("%3ld%%", perc);
|
||||
printf("%3d%%", perc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show our progress, unless we're expanding to a pipe. Invoked as a
|
||||
* callback by nufxlib.
|
||||
*/
|
||||
NuResult
|
||||
ProgressUpdater(NuArchive* pArchive, void* vProgress)
|
||||
NuResult ProgressUpdater(NuArchive* pArchive, void* vProgress)
|
||||
{
|
||||
const NuProgressData* pProgress = vProgress;
|
||||
NulibState* pState;
|
||||
|
@ -309,14 +303,14 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
|
|||
char nameBuf[kMaxDisplayLen+1];
|
||||
Boolean showName, eolConv;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
(void) NuGetExtraData(pArchive, (void**) &pState);
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (NState_GetSuppressOutput(pState))
|
||||
return kNuOK;
|
||||
|
||||
percStr = nil;
|
||||
percStr = NULL;
|
||||
showName = false;
|
||||
eolConv = false;
|
||||
|
||||
|
@ -384,19 +378,19 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
|
|||
|
||||
switch (pProgress->state) {
|
||||
case kNuProgressDone:
|
||||
actionStr = nil;
|
||||
actionStr = NULL;
|
||||
percStr = "DONE\n";
|
||||
break;
|
||||
case kNuProgressSkipped:
|
||||
actionStr = nil;
|
||||
actionStr = NULL;
|
||||
percStr = "SKIP\n";
|
||||
break;
|
||||
case kNuProgressAborted: /* not currently possible in NuLib2 */
|
||||
actionStr = nil;
|
||||
actionStr = NULL;
|
||||
percStr = "CNCL\n";
|
||||
break;
|
||||
case kNuProgressFailed:
|
||||
actionStr = nil;
|
||||
actionStr = NULL;
|
||||
percStr = "FAIL\n";
|
||||
break;
|
||||
default:
|
||||
|
@ -409,21 +403,22 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
|
|||
* Could also use "origPathname", but I like to show what they're
|
||||
* getting instead of what they're giving.
|
||||
*/
|
||||
int len = strlen(pProgress->pathname);
|
||||
int len = strlen(pProgress->pathnameUNI);
|
||||
if (len < sizeof(nameBuf)) {
|
||||
strcpy(nameBuf, pProgress->pathname);
|
||||
strcpy(nameBuf, pProgress->pathnameUNI);
|
||||
} else {
|
||||
nameBuf[0] = nameBuf[1] = '.';
|
||||
strncpy(nameBuf+2, pProgress->pathname + len - (sizeof(nameBuf)-3),
|
||||
strncpy(nameBuf+2,
|
||||
pProgress->pathnameUNI + len - (sizeof(nameBuf)-3),
|
||||
sizeof(nameBuf)-3);
|
||||
nameBuf[sizeof(nameBuf)-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (actionStr == nil && percStr != nil) {
|
||||
if (actionStr == NULL && percStr != NULL) {
|
||||
printf("\r%s", percStr);
|
||||
} else if (actionStr != nil && percStr == nil) {
|
||||
if (percStr == nil) {
|
||||
} else if (actionStr != NULL && percStr == NULL) {
|
||||
if (percStr == NULL) {
|
||||
putc('\r', stdout);
|
||||
PrintPercentage(pProgress->uncompressedLength,
|
||||
pProgress->uncompressedProgress);
|
||||
|
@ -449,17 +444,16 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
|
|||
* Decide whether or not to replace an existing file (during extract)
|
||||
* or record (during add).
|
||||
*/
|
||||
static NuResult
|
||||
HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
|
||||
static NuResult HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
|
||||
const NuErrorStatus* pErrorStatus)
|
||||
{
|
||||
NuResult result = kNuOK;
|
||||
char* renameName;
|
||||
char reply;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pErrorStatus != nil);
|
||||
Assert(pErrorStatus->pathname != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pErrorStatus != NULL);
|
||||
Assert(pErrorStatus->pathnameUNI != NULL);
|
||||
|
||||
Assert(pErrorStatus->canOverwrite);
|
||||
Assert(pErrorStatus->canSkip);
|
||||
|
@ -474,7 +468,7 @@ HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
|
|||
|
||||
while (1) {
|
||||
printf("\n Replace %s? [y]es, [n]o, [A]ll, [N]one",
|
||||
pErrorStatus->pathname);
|
||||
pErrorStatus->pathnameUNI);
|
||||
if (pErrorStatus->canRename) /* renaming record adds not allowed */
|
||||
printf(", [r]ename: ");
|
||||
else
|
||||
|
@ -506,10 +500,10 @@ HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
|
|||
break; /* continue in "while" loop */
|
||||
}
|
||||
renameName = GetReplyString("New name: ");
|
||||
if (renameName == nil)
|
||||
if (renameName == NULL)
|
||||
break; /* continue in "while" loop */
|
||||
if (pErrorStatus->pRecord == nil) {
|
||||
ReportError(kNuErrNone, "Unexpected nil record");
|
||||
if (pErrorStatus->pRecord == NULL) {
|
||||
ReportError(kNuErrNone, "Unexpected NULL record");
|
||||
break; /* continue in "while" loop */
|
||||
}
|
||||
NState_SetRenameFromIdx(pState,
|
||||
|
@ -534,18 +528,17 @@ bail:
|
|||
/*
|
||||
* Found a bad CRC... should we press onward?
|
||||
*
|
||||
* Note pErrorStatus->pathname may be nil if the error was found in the
|
||||
* Note pErrorStatus->pathname may be NULL if the error was found in the
|
||||
* master header or in the record header.
|
||||
*/
|
||||
static NuResult
|
||||
HandleBadCRC(NulibState* pState, NuArchive* pArchive,
|
||||
static NuResult HandleBadCRC(NulibState* pState, NuArchive* pArchive,
|
||||
const NuErrorStatus* pErrorStatus)
|
||||
{
|
||||
NuResult result = kNuOK;
|
||||
char reply;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pErrorStatus != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pErrorStatus != NULL);
|
||||
|
||||
if (NState_GetInputUnavailable(pState)) {
|
||||
putc('\n', stderr);
|
||||
|
@ -555,9 +548,9 @@ HandleBadCRC(NulibState* pState, NuArchive* pArchive,
|
|||
}
|
||||
|
||||
while (1) {
|
||||
if (pErrorStatus->pathname != nil)
|
||||
if (pErrorStatus->pathnameUNI != NULL)
|
||||
fprintf(stderr, "\n Found a bad CRC in %s\n",
|
||||
pErrorStatus->pathname);
|
||||
pErrorStatus->pathnameUNI);
|
||||
else
|
||||
fprintf(stderr, "\n Found a bad CRC in the archive\n");
|
||||
|
||||
|
@ -597,16 +590,15 @@ bail:
|
|||
* the system equivalent of readdir to scan a directory, so deleting a
|
||||
* file just means it won't get added.
|
||||
*/
|
||||
static NuResult
|
||||
HandleAddNotFound(NulibState* pState, NuArchive* pArchive,
|
||||
static NuResult HandleAddNotFound(NulibState* pState, NuArchive* pArchive,
|
||||
const NuErrorStatus* pErrorStatus)
|
||||
{
|
||||
NuResult result = kNuOK;
|
||||
char reply;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pErrorStatus != nil);
|
||||
Assert(pErrorStatus->pathname != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pErrorStatus != NULL);
|
||||
Assert(pErrorStatus->pathnameUNI != NULL);
|
||||
|
||||
if (NState_GetInputUnavailable(pState)) {
|
||||
putc('\n', stdout);
|
||||
|
@ -617,7 +609,7 @@ HandleAddNotFound(NulibState* pState, NuArchive* pArchive,
|
|||
|
||||
while (1) {
|
||||
fprintf(stderr, "\n Couldn't find %s, continue? [y]es, [n]o: ",
|
||||
pErrorStatus->pathname);
|
||||
pErrorStatus->pathnameUNI);
|
||||
fflush(stderr);
|
||||
|
||||
reply = GetReplyChar('n');
|
||||
|
@ -644,16 +636,15 @@ bail:
|
|||
* Something failed, and the user may want to choose how to handle it.
|
||||
* Invoked as a callback.
|
||||
*/
|
||||
NuResult
|
||||
ErrorHandler(NuArchive* pArchive, void* vErrorStatus)
|
||||
NuResult ErrorHandler(NuArchive* pArchive, void* vErrorStatus)
|
||||
{
|
||||
const NuErrorStatus* pErrorStatus = vErrorStatus;
|
||||
NulibState* pState;
|
||||
NuResult result;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
(void) NuGetExtraData(pArchive, (void**) &pState);
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
/* default action is to abort the current operation */
|
||||
result = kNuAbort;
|
||||
|
@ -722,13 +713,12 @@ ErrorHandler(NuArchive* pArchive, void* vErrorStatus)
|
|||
* (This was just a test to see if it worked... NufxLib's default behavior
|
||||
* is fine for NuLib2.)
|
||||
*/
|
||||
NuResult
|
||||
ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
|
||||
NuResult ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
|
||||
{
|
||||
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
|
||||
|
||||
fprintf(stderr, "%s%d %3d %s:%d %s %s\n",
|
||||
pArchive == nil ? "(GLOBAL)" : "",
|
||||
pArchive == NULL ? "(GLOBAL)" : "",
|
||||
pErrorMessage->isDebug, pErrorMessage->err, pErrorMessage->file,
|
||||
pErrorMessage->line, pErrorMessage->function, pErrorMessage->message);
|
||||
return kNuOK;
|
||||
|
@ -752,8 +742,7 @@ static const char* kStdinArchive = "-";
|
|||
*
|
||||
* Uses a simplified view of the access flags.
|
||||
*/
|
||||
Boolean
|
||||
IsRecordReadOnly(const NuRecord* pRecord)
|
||||
Boolean IsRecordReadOnly(const NuRecord* pRecord)
|
||||
{
|
||||
if (pRecord->recAccess == 0x21L || pRecord->recAccess == 0x01L)
|
||||
return true;
|
||||
|
@ -765,10 +754,9 @@ IsRecordReadOnly(const NuRecord* pRecord)
|
|||
/*
|
||||
* Returns "true" if "archiveName" is the name we use to represent stdin.
|
||||
*/
|
||||
Boolean
|
||||
IsFilenameStdin(const char* archiveName)
|
||||
Boolean IsFilenameStdin(const char* archiveName)
|
||||
{
|
||||
Assert(archiveName != nil);
|
||||
Assert(archiveName != NULL);
|
||||
return (strcmp(archiveName, kStdinArchive) == 0);
|
||||
}
|
||||
|
||||
|
@ -779,13 +767,12 @@ IsFilenameStdin(const char* archiveName)
|
|||
* Open the archive in read-only mode. We use "file mode" for a file, or
|
||||
* "streaming mode" for stdin.
|
||||
*/
|
||||
NuError
|
||||
OpenArchiveReadOnly(NulibState* pState)
|
||||
NuError OpenArchiveReadOnly(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (IsFilenameStdin(NState_GetArchiveFilename(pState))) {
|
||||
err = NuStreamOpenRO(stdin, &pArchive);
|
||||
|
@ -881,10 +868,10 @@ OpenArchiveReadOnly(NulibState* pState)
|
|||
BailError(err);
|
||||
|
||||
bail:
|
||||
if (err != kNuErrNone && pArchive != nil) {
|
||||
if (err != kNuErrNone && pArchive != NULL) {
|
||||
/* clean up */
|
||||
(void) NuClose(pArchive);
|
||||
NState_SetNuArchive(pState, nil);
|
||||
NState_SetNuArchive(pState, NULL);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -896,18 +883,17 @@ bail:
|
|||
*
|
||||
* "Streaming mode" isn't allowed.
|
||||
*/
|
||||
NuError
|
||||
OpenArchiveReadWrite(NulibState* pState)
|
||||
NuError OpenArchiveReadWrite(NulibState* pState)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NuArchive* pArchive = nil;
|
||||
char* tempName = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
char* tempName = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(IsFilenameStdin(NState_GetArchiveFilename(pState)) == false);
|
||||
|
||||
tempName = MakeTempArchiveName(pState);
|
||||
if (tempName == nil)
|
||||
if (tempName == NULL)
|
||||
goto bail;
|
||||
DBUG(("TEMP NAME = '%s'\n", tempName));
|
||||
|
||||
|
@ -979,11 +965,11 @@ OpenArchiveReadWrite(NulibState* pState)
|
|||
|
||||
bail:
|
||||
Free(tempName);
|
||||
if (err != kNuErrNone && pArchive != nil) {
|
||||
if (err != kNuErrNone && pArchive != NULL) {
|
||||
/* clean up */
|
||||
NuAbort(pArchive);
|
||||
(void) NuClose(pArchive);
|
||||
NState_SetNuArchive(pState, nil);
|
||||
NState_SetNuArchive(pState, NULL);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
237
nulib2/Binary2.c
237
nulib2/Binary2.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
|
@ -17,7 +17,7 @@
|
|||
*
|
||||
* TO DO: add "junk skipping" like NufxLib has.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
|
@ -44,13 +44,12 @@
|
|||
* Open a file read-only. We abstract this so we get "r" vs "rb" right.
|
||||
* (Moves this to SysUtils.c if anybody else needs it.)
|
||||
*/
|
||||
NuError
|
||||
OpenFileReadOnly(const char* filename, FILE** pFp)
|
||||
NuError OpenFileReadOnly(const char* filename, FILE** pFp)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
*pFp = fopen(filename, kFileOpenReadOnly);
|
||||
if (*pFp == nil)
|
||||
if (*pFp == NULL)
|
||||
err = errno ? errno : kNuErrFileOpen;
|
||||
|
||||
return err;
|
||||
|
@ -62,8 +61,7 @@ OpenFileReadOnly(const char* filename, FILE** pFp)
|
|||
*
|
||||
* If no filespec was provided, then all records are "specified".
|
||||
*/
|
||||
Boolean
|
||||
NameIsSpecified(NulibState* pState, const char* filename)
|
||||
Boolean NameIsSpecified(NulibState* pState, const char* filename)
|
||||
{
|
||||
char* const* pSpec;
|
||||
int i;
|
||||
|
@ -125,37 +123,36 @@ typedef struct BNYArchive {
|
|||
* something else follows this entry.
|
||||
*/
|
||||
typedef struct BNYEntry {
|
||||
ushort access;
|
||||
ushort fileType;
|
||||
ulong auxType;
|
||||
uchar storageType;
|
||||
ulong fileSize; /* in 512-byte blocks */
|
||||
ushort prodosModDate;
|
||||
ushort prodosModTime;
|
||||
uint16_t access;
|
||||
uint16_t fileType;
|
||||
uint32_t auxType;
|
||||
uint8_t storageType;
|
||||
uint32_t fileSize; /* in 512-byte blocks */
|
||||
uint16_t prodosModDate;
|
||||
uint16_t prodosModTime;
|
||||
NuDateTime modWhen; /* computed from previous two fields */
|
||||
ushort prodosCreateDate;
|
||||
ushort prodosCreateTime;
|
||||
uint16_t prodosCreateDate;
|
||||
uint16_t prodosCreateTime;
|
||||
NuDateTime createWhen; /* computed from previous two fields */
|
||||
ulong eof;
|
||||
ulong realEOF; /* eof is bogus for directories */
|
||||
char fileName[kBNYMaxFileName+1];
|
||||
uint32_t eof;
|
||||
uint32_t realEOF; /* eof is bogus for directories */
|
||||
char fileName[kBNYMaxFileName+1]; /* ASCII only */
|
||||
char nativeName[kBNYMaxNativeName+1];
|
||||
ulong diskSpace; /* in 512-byte blocks */
|
||||
uchar osType; /* not exactly same as NuFileSysID */
|
||||
ushort nativeFileType;
|
||||
uchar phantomFlag;
|
||||
uchar dataFlags; /* advisory flags */
|
||||
uchar version;
|
||||
uchar filesToFollow; /* #of files after this one */
|
||||
uint32_t diskSpace; /* in 512-byte blocks */
|
||||
uint8_t osType; /* not exactly same as NuFileSysID */
|
||||
uint16_t nativeFileType;
|
||||
uint8_t phantomFlag;
|
||||
uint8_t dataFlags; /* advisory flags */
|
||||
uint8_t version;
|
||||
uint8_t filesToFollow; /* #of files after this one */
|
||||
|
||||
uchar blockBuf[kBNYBlockSize];
|
||||
uint8_t blockBuf[kBNYBlockSize];
|
||||
} BNYEntry;
|
||||
|
||||
/*
|
||||
* Test for the magic number on a file in SQueezed format.
|
||||
*/
|
||||
static inline Boolean
|
||||
IsSqueezed(uchar one, uchar two)
|
||||
static inline Boolean IsSqueezed(uint8_t one, uint8_t two)
|
||||
{
|
||||
return (one == 0x76 && two == 0xff);
|
||||
}
|
||||
|
@ -163,8 +160,7 @@ IsSqueezed(uchar one, uchar two)
|
|||
/*
|
||||
* Test if this entry is a directory.
|
||||
*/
|
||||
static inline Boolean
|
||||
IsDir(BNYEntry* pEntry)
|
||||
static inline Boolean IsDir(BNYEntry* pEntry)
|
||||
{
|
||||
/*
|
||||
* NuLib and "unblu.c" compared against file type 15 (DIR), so I'm
|
||||
|
@ -178,8 +174,7 @@ IsDir(BNYEntry* pEntry)
|
|||
/*
|
||||
* Initialize a BNYArchive structure.
|
||||
*/
|
||||
static BNYArchive*
|
||||
BNYInit(NulibState* pState)
|
||||
static BNYArchive* BNYInit(NulibState* pState)
|
||||
{
|
||||
BNYArchive* pBny;
|
||||
|
||||
|
@ -194,11 +189,10 @@ BNYInit(NulibState* pState)
|
|||
/*
|
||||
* Free up a BNYArchive, disposing of anything inside it.
|
||||
*/
|
||||
static void
|
||||
BNYFree(BNYArchive* pBny)
|
||||
static void BNYFree(BNYArchive* pBny)
|
||||
{
|
||||
/* don't need to do this on stdin, but won't really hurt */
|
||||
if (pBny->fp != nil)
|
||||
if (pBny->fp != NULL)
|
||||
fclose(pBny->fp);
|
||||
|
||||
Free(pBny);
|
||||
|
@ -209,15 +203,14 @@ BNYFree(BNYArchive* pBny)
|
|||
* Open a Binary II archive read-only. Might be a file on disk or a
|
||||
* stream on stdin.
|
||||
*/
|
||||
static NuError
|
||||
BNYOpenReadOnly(BNYArchive* pBny)
|
||||
static NuError BNYOpenReadOnly(BNYArchive* pBny)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NulibState* pState;
|
||||
|
||||
Assert(pBny != nil);
|
||||
Assert(pBny->pState != nil);
|
||||
Assert(pBny->fp == nil);
|
||||
Assert(pBny != NULL);
|
||||
Assert(pBny->pState != NULL);
|
||||
Assert(pBny->fp == NULL);
|
||||
|
||||
pState = pBny->pState;
|
||||
|
||||
|
@ -248,15 +241,14 @@ bail:
|
|||
* Wrapper for fread(). Note the arguments resemble read(2) rather
|
||||
* than fread(3S).
|
||||
*/
|
||||
static NuError
|
||||
BNYRead(BNYArchive* pBny, void* buf, size_t nbyte)
|
||||
static NuError BNYRead(BNYArchive* pBny, void* buf, size_t nbyte)
|
||||
{
|
||||
size_t result;
|
||||
|
||||
Assert(pBny != nil);
|
||||
Assert(buf != nil);
|
||||
Assert(pBny != NULL);
|
||||
Assert(buf != NULL);
|
||||
Assert(nbyte > 0);
|
||||
Assert(pBny->fp != nil);
|
||||
Assert(pBny->fp != NULL);
|
||||
|
||||
errno = 0;
|
||||
result = fread(buf, 1, nbyte, pBny->fp);
|
||||
|
@ -270,12 +262,11 @@ BNYRead(BNYArchive* pBny, void* buf, size_t nbyte)
|
|||
* and don't need to special-case anything, we only allow relative
|
||||
* forward seeks.
|
||||
*/
|
||||
static NuError
|
||||
BNYSeek(BNYArchive* pBny, long offset)
|
||||
static NuError BNYSeek(BNYArchive* pBny, long offset)
|
||||
{
|
||||
Assert(pBny != nil);
|
||||
Assert(pBny->fp != nil);
|
||||
Assert(pBny->pState != nil);
|
||||
Assert(pBny != NULL);
|
||||
Assert(pBny->fp != NULL);
|
||||
Assert(pBny->pState != NULL);
|
||||
Assert(offset > 0);
|
||||
|
||||
/*DBUG(("--- seeking forward %ld bytes\n", offset));*/
|
||||
|
@ -299,8 +290,8 @@ BNYSeek(BNYArchive* pBny, long offset)
|
|||
/*
|
||||
* Convert from ProDOS compact date format to the expanded DateTime format.
|
||||
*/
|
||||
static void
|
||||
BNYConvertDateTime(ushort prodosDate, ushort prodosTime, NuDateTime* pWhen)
|
||||
static void BNYConvertDateTime(uint16_t prodosDate, uint16_t prodosTime,
|
||||
NuDateTime* pWhen)
|
||||
{
|
||||
pWhen->second = 0;
|
||||
pWhen->minute = prodosTime & 0x3f;
|
||||
|
@ -320,15 +311,14 @@ BNYConvertDateTime(ushort prodosDate, ushort prodosTime, NuDateTime* pWhen)
|
|||
* See the File Type Note for $e0/8000 to decipher the buffer offsets
|
||||
* and meanings.
|
||||
*/
|
||||
static NuError
|
||||
BNYDecodeHeader(BNYArchive* pBny, BNYEntry* pEntry)
|
||||
static NuError BNYDecodeHeader(BNYArchive* pBny, BNYEntry* pEntry)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
uchar* raw;
|
||||
uint8_t* raw;
|
||||
int len;
|
||||
|
||||
Assert(pBny != nil);
|
||||
Assert(pEntry != nil);
|
||||
Assert(pBny != NULL);
|
||||
Assert(pEntry != NULL);
|
||||
|
||||
raw = pEntry->blockBuf;
|
||||
|
||||
|
@ -406,8 +396,7 @@ bail:
|
|||
* We return the new path, which is stored in NulibState's temporary
|
||||
* filename buffer.
|
||||
*/
|
||||
const char*
|
||||
BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
|
||||
const char* BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
|
||||
{
|
||||
NuPathnameProposal pathProposal;
|
||||
NuRecord fakeRecord;
|
||||
|
@ -417,14 +406,14 @@ BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
|
|||
memset(&fakeRecord, 0xa1, sizeof(fakeRecord));
|
||||
memset(&fakeThread, 0xa5, sizeof(fakeThread));
|
||||
|
||||
pathProposal.pathname = pEntry->fileName;
|
||||
pathProposal.pathnameUNI = pEntry->fileName;
|
||||
pathProposal.filenameSeparator = '/'; /* BNY always uses ProDOS conv */
|
||||
pathProposal.pRecord = &fakeRecord;
|
||||
pathProposal.pThread = &fakeThread;
|
||||
|
||||
pathProposal.newPathname = nil;
|
||||
pathProposal.newPathnameUNI = NULL;
|
||||
pathProposal.newFilenameSeparator = '\0';
|
||||
pathProposal.newDataSink = nil;
|
||||
pathProposal.newDataSink = NULL;
|
||||
|
||||
/* need the filetype and auxtype for -e/-ee */
|
||||
fakeRecord.recFileType = pEntry->fileType;
|
||||
|
@ -448,8 +437,7 @@ BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
|
|||
*
|
||||
* Uses pEntry->blockBuf, which already has the first 128 bytes in it.
|
||||
*/
|
||||
static NuError
|
||||
BNYCopyBlocks(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
||||
static NuError BNYCopyBlocks(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
long bytesLeft;
|
||||
|
@ -464,7 +452,7 @@ BNYCopyBlocks(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
|||
if (toWrite > kBNYBlockSize)
|
||||
toWrite = kBNYBlockSize;
|
||||
|
||||
if (outfp != nil) {
|
||||
if (outfp != NULL) {
|
||||
if (fwrite(pEntry->blockBuf, toWrite, 1, outfp) != 1) {
|
||||
err = errno ? errno : kNuErrFileWrite;
|
||||
ReportError(err, "BNY write failed");
|
||||
|
@ -522,8 +510,8 @@ bail:
|
|||
* State during uncompression.
|
||||
*/
|
||||
typedef struct USQState {
|
||||
ulong dataInBuffer;
|
||||
uchar* dataPtr;
|
||||
uint32_t dataInBuffer;
|
||||
uint8_t* dataPtr;
|
||||
int bitPosn;
|
||||
int bits;
|
||||
|
||||
|
@ -542,8 +530,7 @@ typedef struct USQState {
|
|||
/*
|
||||
* Decode the next symbol from the Huffman stream.
|
||||
*/
|
||||
static NuError
|
||||
USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
|
||||
static NuError USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
|
||||
{
|
||||
short val = 0;
|
||||
int bits, bitPosn;
|
||||
|
@ -579,8 +566,7 @@ USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
|
|||
/*
|
||||
* Read two bytes of signed data out of the buffer.
|
||||
*/
|
||||
static inline NuError
|
||||
USQReadShort(USQState* pUsqState, short* pShort)
|
||||
static inline NuError USQReadShort(USQState* pUsqState, short* pShort)
|
||||
{
|
||||
if (pUsqState->dataInBuffer < 2)
|
||||
return kNuErrBufferUnderrun;
|
||||
|
@ -598,22 +584,21 @@ USQReadShort(USQState* pUsqState, short* pShort)
|
|||
* Because we have a stop symbol, knowing the uncompressed length of
|
||||
* the file is not essential.
|
||||
*/
|
||||
static NuError
|
||||
BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
||||
static NuError BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
USQState usqState;
|
||||
ulong compRemaining, getSize;
|
||||
uint32_t compRemaining, getSize;
|
||||
#ifdef FULL_SQ_HEADER
|
||||
ushort magic, fileChecksum, checksum;
|
||||
uint16_t magic, fileChecksum, checksum;
|
||||
#endif
|
||||
short nodeCount;
|
||||
int i, inrep;
|
||||
uchar* tmpBuf = nil;
|
||||
uchar lastc = 0;
|
||||
uint8_t* tmpBuf = NULL;
|
||||
uint8_t lastc = 0;
|
||||
|
||||
tmpBuf = Malloc(kSqBufferSize);
|
||||
if (tmpBuf == nil) {
|
||||
if (tmpBuf == NULL) {
|
||||
err = kNuErrMalloc;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -677,7 +662,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
|||
err = BNYRead(pBny, usqState.dataPtr, getSize);
|
||||
if (err != kNuErrNone) {
|
||||
ReportError(err,
|
||||
"failed reading compressed data (%ld bytes)", getSize);
|
||||
"failed reading compressed data (%u bytes)", getSize);
|
||||
goto bail;
|
||||
}
|
||||
usqState.dataInBuffer += getSize;
|
||||
|
@ -787,7 +772,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
|||
getSize);
|
||||
if (err != kNuErrNone) {
|
||||
ReportError(err,
|
||||
"failed reading compressed data (%ld bytes)", getSize);
|
||||
"failed reading compressed data (%u bytes)", getSize);
|
||||
goto bail;
|
||||
}
|
||||
usqState.dataInBuffer += getSize;
|
||||
|
@ -824,9 +809,9 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
|||
val = 2;
|
||||
}
|
||||
while (--val) {
|
||||
/*if (pCrc != nil)
|
||||
/*if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);*/
|
||||
if (outfp != nil)
|
||||
if (outfp != NULL)
|
||||
putc(lastc, outfp);
|
||||
#ifdef FULL_SQ_HEADER
|
||||
checksum += lastc;
|
||||
|
@ -840,9 +825,9 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
|||
inrep = true;
|
||||
} else {
|
||||
lastc = val;
|
||||
/*if (pCrc != nil)
|
||||
/*if (pCrc != NULL)
|
||||
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);*/
|
||||
if (outfp != nil)
|
||||
if (outfp != NULL)
|
||||
putc(lastc, outfp);
|
||||
#ifdef FULL_SQ_HEADER
|
||||
checksum += lastc;
|
||||
|
@ -876,7 +861,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
|||
*/
|
||||
if (compRemaining > kSqBufferSize) {
|
||||
err = kNuErrBadData;
|
||||
ReportError(err, "wow: found %ld bytes left over", compRemaining);
|
||||
ReportError(err, "wow: found %u bytes left over", compRemaining);
|
||||
goto bail;
|
||||
}
|
||||
if (compRemaining) {
|
||||
|
@ -889,7 +874,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
|
|||
}
|
||||
|
||||
bail:
|
||||
if (outfp != nil)
|
||||
if (outfp != NULL)
|
||||
fflush(outfp);
|
||||
Free(tmpBuf);
|
||||
return err;
|
||||
|
@ -909,23 +894,22 @@ typedef NuError (*BNYIteratorFunc)(BNYArchive* pBny, BNYEntry* pEntry,
|
|||
* Iterate through a Binary II archive, calling "func" to perform
|
||||
* operations on the file.
|
||||
*/
|
||||
static NuError
|
||||
BNYIterate(NulibState* pState, BNYIteratorFunc func)
|
||||
static NuError BNYIterate(NulibState* pState, BNYIteratorFunc func)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
BNYArchive* pBny = nil;
|
||||
BNYArchive* pBny = NULL;
|
||||
BNYEntry entry;
|
||||
Boolean consumed;
|
||||
int first = true;
|
||||
int toFollow;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(func != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(func != NULL);
|
||||
|
||||
NState_SetMatchCount(pState, 0);
|
||||
|
||||
pBny = BNYInit(pState);
|
||||
if (pBny == nil) {
|
||||
if (pBny == NULL) {
|
||||
err = kNuErrMalloc;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -1012,7 +996,7 @@ BNYIterate(NulibState* pState, BNYIteratorFunc func)
|
|||
printf("%s: no records match\n", gProgName);
|
||||
|
||||
bail:
|
||||
if (pBny != nil)
|
||||
if (pBny != NULL)
|
||||
BNYFree(pBny);
|
||||
if (err != kNuErrNone) {
|
||||
DBUG(("--- Iterator returning failure %d\n", err));
|
||||
|
@ -1023,8 +1007,8 @@ bail:
|
|||
/*
|
||||
* Get a quick table of contents.
|
||||
*/
|
||||
static NuError
|
||||
BNYListShort(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
||||
static NuError BNYListShort(BNYArchive* pBny, BNYEntry* pEntry,
|
||||
Boolean* pConsumedFlag)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
|
@ -1036,8 +1020,8 @@ BNYListShort(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
/*
|
||||
* Get a verbose listing of contents.
|
||||
*/
|
||||
static NuError
|
||||
BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
||||
static NuError BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry,
|
||||
Boolean* pConsumedFlag)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Boolean isSqueezed, isReadOnly;
|
||||
|
@ -1077,7 +1061,7 @@ BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
printf("%c..%-25.25s ",
|
||||
isReadOnly ? '+' : ' ', pEntry->fileName + len - 25);
|
||||
}
|
||||
printf("%s $%04lX ",
|
||||
printf("%s $%04X ",
|
||||
GetFileTypeString(pEntry->fileType), pEntry->auxType);
|
||||
|
||||
printf("%s ", FormatDateShort(&pEntry->modWhen, date1));
|
||||
|
@ -1086,7 +1070,7 @@ BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
else
|
||||
printf("unc ");
|
||||
|
||||
printf("%8ld", pEntry->realEOF);
|
||||
printf("%8u", pEntry->realEOF);
|
||||
|
||||
printf("\n");
|
||||
|
||||
|
@ -1102,8 +1086,8 @@ BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
/*
|
||||
* Get a verbose table of contents.
|
||||
*/
|
||||
static NuError
|
||||
BNYListDebug(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
||||
static NuError BNYListDebug(BNYArchive* pBny, BNYEntry* pEntry,
|
||||
Boolean* pConsumedFlag)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
|
@ -1123,9 +1107,9 @@ BNYListDebug(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
pEntry->createWhen.year+1900, pEntry->createWhen.month,
|
||||
pEntry->createWhen.day, pEntry->createWhen.hour,
|
||||
pEntry->createWhen.minute);
|
||||
printf(" FileType: 0x%04x AuxType: 0x%08lx StorageType: 0x%02x\n",
|
||||
printf(" FileType: 0x%04x AuxType: 0x%08x StorageType: 0x%02x\n",
|
||||
pEntry->fileType, pEntry->auxType, pEntry->storageType);
|
||||
printf(" EOF: %ld FileSize: %ld blocks DiskSpace: %ld blocks\n",
|
||||
printf(" EOF: %u FileSize: %u blocks DiskSpace: %u blocks\n",
|
||||
pEntry->eof, pEntry->fileSize, pEntry->diskSpace);
|
||||
printf(" Access: 0x%04x OSType: %d NativeFileType: 0x%04x\n",
|
||||
pEntry->access, pEntry->osType, pEntry->nativeFileType);
|
||||
|
@ -1146,8 +1130,8 @@ typedef enum { kBNYExtNormal, kBNYExtPipe, kBNYExtTest } ExtMode;
|
|||
/*
|
||||
* Handle "extraction" of a directory.
|
||||
*/
|
||||
static NuError
|
||||
BNYExtractDirectory(BNYArchive* pBny, BNYEntry* pEntry, ExtMode extMode)
|
||||
static NuError BNYExtractDirectory(BNYArchive* pBny, BNYEntry* pEntry,
|
||||
ExtMode extMode)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
const char* newName;
|
||||
|
@ -1173,7 +1157,7 @@ BNYExtractDirectory(BNYArchive* pBny, BNYEntry* pEntry, ExtMode extMode)
|
|||
*/
|
||||
/*newName = BNYNormalizePath(pBny, pEntry);*/
|
||||
newName = pEntry->fileName;
|
||||
if (newName == nil)
|
||||
if (newName == NULL)
|
||||
goto bail;
|
||||
|
||||
err = TestFileExistence(newName, &isDir);
|
||||
|
@ -1209,14 +1193,14 @@ bail:
|
|||
/*
|
||||
* Handle "extract", "extract to pipe", and "test".
|
||||
*/
|
||||
static NuError
|
||||
BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
||||
static NuError BNYExtract(BNYArchive* pBny, BNYEntry* pEntry,
|
||||
Boolean* pConsumedFlag)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
NulibState* pState;
|
||||
ExtMode extMode;
|
||||
const char* actionStr = "HOSED";
|
||||
FILE* outfp = nil;
|
||||
FILE* outfp = NULL;
|
||||
Boolean eolConv;
|
||||
|
||||
pState = pBny->pState;
|
||||
|
@ -1275,7 +1259,7 @@ BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
}
|
||||
|
||||
newName = BNYNormalizePath(pBny, pEntry);
|
||||
if (newName == nil)
|
||||
if (newName == NULL)
|
||||
goto bail;
|
||||
|
||||
err = TestFileExistence(newName, &isDir);
|
||||
|
@ -1303,13 +1287,13 @@ BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
|
||||
/* open it, overwriting anything present */
|
||||
outfp = fopen(newName, "w");
|
||||
if (outfp == nil) {
|
||||
if (outfp == NULL) {
|
||||
err = kNuErrFileOpen;
|
||||
goto bail;
|
||||
}
|
||||
} else {
|
||||
/* outfp == nil means we're in test mode */
|
||||
Assert(outfp == nil);
|
||||
/* outfp == NULL means we're in test mode */
|
||||
Assert(outfp == NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1358,8 +1342,16 @@ BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
|
|||
*pConsumedFlag = true;
|
||||
|
||||
bail:
|
||||
if (outfp != nil && outfp != stdout)
|
||||
if (outfp != NULL && outfp != stdout) {
|
||||
#if defined(MAC_LIKE)
|
||||
if (SetFinderInfo(fileno(outfp), pEntry->fileType,
|
||||
pEntry->auxType) != kNuErrNone)
|
||||
{
|
||||
fprintf(stderr, "WARNING: unable to set finder info\n");
|
||||
}
|
||||
#endif
|
||||
fclose(outfp);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1370,8 +1362,7 @@ bail:
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
NuError
|
||||
BNYDoExtract(NulibState* pState)
|
||||
NuError BNYDoExtract(NulibState* pState)
|
||||
{
|
||||
if (NState_GetModConvertText(pState) ||
|
||||
NState_GetModConvertAll(pState))
|
||||
|
@ -1402,26 +1393,22 @@ BNYDoExtract(NulibState* pState)
|
|||
return BNYIterate(pState, BNYExtract);
|
||||
}
|
||||
|
||||
NuError
|
||||
BNYDoTest(NulibState* pState)
|
||||
NuError BNYDoTest(NulibState* pState)
|
||||
{
|
||||
return BNYIterate(pState, BNYExtract);
|
||||
}
|
||||
|
||||
NuError
|
||||
BNYDoListShort(NulibState* pState)
|
||||
NuError BNYDoListShort(NulibState* pState)
|
||||
{
|
||||
return BNYIterate(pState, BNYListShort);
|
||||
}
|
||||
|
||||
NuError
|
||||
BNYDoListVerbose(NulibState* pState)
|
||||
NuError BNYDoListVerbose(NulibState* pState)
|
||||
{
|
||||
return BNYIterate(pState, BNYListVerbose);
|
||||
}
|
||||
|
||||
NuError
|
||||
BNYDoListDebug(NulibState* pState)
|
||||
NuError BNYDoListDebug(NulibState* pState)
|
||||
{
|
||||
return BNYIterate(pState, BNYListDebug);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
2017/09/21 ***** v3.1.0 shipped *****
|
||||
|
||||
2015/12/26 fadden
|
||||
- Fix handling of entries with missing threads.
|
||||
- Improve handling of Mac OS X file type attributes.
|
||||
- Updated "recognized extensions" table.
|
||||
|
||||
2015/01/09 ***** v3.0.0 shipped *****
|
||||
|
||||
2015/01/03 fadden
|
||||
- Mac OS X: get file/aux type from FinderInfo when adding files.
|
||||
- Mac OS X: set file type and creator when extracting from Binary ][.
|
||||
|
||||
2015/01/02 fadden
|
||||
- Distinguish Unicode and Mac OS Roman strings.
|
||||
|
||||
2014/12/22 fadden
|
||||
- Source code cleanup.
|
||||
|
||||
2014/10/30 ***** v2.2.2 shipped *****
|
||||
|
||||
2014/10/28 fadden
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Delete files from the archive.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -15,19 +15,18 @@
|
|||
* This uses the "bulk" delete call, allowing the SelectionFilter callback
|
||||
* to do the matching against specified filenames.
|
||||
*/
|
||||
NuError
|
||||
DoDelete(NulibState* pState)
|
||||
NuError DoDelete(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
err = OpenArchiveReadWrite(pState);
|
||||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
pArchive = NState_GetNuArchive(pState);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
NState_SetMatchCount(pState, 0);
|
||||
|
||||
|
@ -39,7 +38,7 @@ DoDelete(NulibState* pState)
|
|||
printf("%s: no records matched\n", gProgName);
|
||||
|
||||
bail:
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
(void) NuClose(pArchive);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Extract files and test archives.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -17,8 +17,7 @@
|
|||
* show them while we're extracting the files, we have to manually find
|
||||
* and extract them.
|
||||
*/
|
||||
static NuError
|
||||
ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
|
||||
static NuError ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
|
||||
{
|
||||
NuError err;
|
||||
const NuRecord* pRecord;
|
||||
|
@ -41,7 +40,7 @@ ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
|
|||
|
||||
err = NuGetRecord(pArchive, recordIdx, &pRecord);
|
||||
if (err != kNuErrNone) {
|
||||
fprintf(stderr, "ERROR: unable to get recordIdx %ld\n", recordIdx);
|
||||
fprintf(stderr, "ERROR: unable to get recordIdx %u\n", recordIdx);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
@ -53,16 +52,18 @@ ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
|
|||
/*
|
||||
* Look for a comment thread.
|
||||
*/
|
||||
for (threadIdx = 0; (ulong)threadIdx < pRecord->recTotalThreads;
|
||||
for (threadIdx = 0; (uint32_t)threadIdx < pRecord->recTotalThreads;
|
||||
threadIdx++)
|
||||
{
|
||||
pThread = NuGetThread(pRecord, threadIdx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
if (NuGetThreadID(pThread) == kNuThreadIDComment &&
|
||||
pThread->actualThreadEOF > 0)
|
||||
{
|
||||
printf("----- '%s':\n", pRecord->filename);
|
||||
UNICHAR* filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
|
||||
printf("----- '%s':\n", filenameUNI);
|
||||
free(filenameUNI);
|
||||
err = NuExtractThread(pArchive, pThread->threadIdx,
|
||||
NState_GetCommentSink(pState));
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -87,13 +88,12 @@ bail:
|
|||
/*
|
||||
* Extract the specified files.
|
||||
*/
|
||||
NuError
|
||||
DoExtract(NulibState* pState)
|
||||
NuError DoExtract(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (NState_GetModBinaryII(pState))
|
||||
return BNYDoExtract(pState);
|
||||
|
@ -104,7 +104,7 @@ DoExtract(NulibState* pState)
|
|||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
pArchive = NState_GetNuArchive(pState);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
NState_SetMatchCount(pState, 0);
|
||||
|
||||
|
@ -126,7 +126,7 @@ DoExtract(NulibState* pState)
|
|||
printf("%s: no records match\n", gProgName);
|
||||
|
||||
bail:
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
(void) NuClose(pArchive);
|
||||
return err;
|
||||
}
|
||||
|
@ -135,8 +135,7 @@ bail:
|
|||
/*
|
||||
* Extract the specified files to stdout.
|
||||
*/
|
||||
NuError
|
||||
DoExtractToPipe(NulibState* pState)
|
||||
NuError DoExtractToPipe(NulibState* pState)
|
||||
{
|
||||
/* we handle the "to pipe" part farther down */
|
||||
return DoExtract(pState);
|
||||
|
@ -146,13 +145,12 @@ DoExtractToPipe(NulibState* pState)
|
|||
/*
|
||||
* Do an integrity check on one or more records in the archive.
|
||||
*/
|
||||
NuError
|
||||
DoTest(NulibState* pState)
|
||||
NuError DoTest(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (NState_GetModBinaryII(pState))
|
||||
return BNYDoTest(pState);
|
||||
|
@ -163,7 +161,7 @@ DoTest(NulibState* pState)
|
|||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
pArchive = NState_GetNuArchive(pState);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
NState_SetMatchCount(pState, 0);
|
||||
|
||||
|
@ -175,7 +173,7 @@ DoTest(NulibState* pState)
|
|||
printf("%s: no records match\n", gProgName);
|
||||
|
||||
bail:
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
(void) NuClose(pArchive);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Filename manipulation, including file type preservation.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
|
@ -72,31 +72,31 @@ static const char gFileTypeNames[256][4] = {
|
|||
* file rather than a hard-coded table. Ought to fix that someday.
|
||||
*/
|
||||
static const struct {
|
||||
const char* label;
|
||||
ushort fileType;
|
||||
ulong auxType;
|
||||
uchar flags;
|
||||
const char* label;
|
||||
uint8_t fileType;
|
||||
uint16_t auxType;
|
||||
} gRecognizedExtensions[] = {
|
||||
{ "ASM", 0xb0, 0x0003, 0 }, /* APW assembly source */
|
||||
{ "C", 0xb0, 0x000a, 0 }, /* APW C source */
|
||||
{ "H", 0xb0, 0x000a, 0 }, /* APW C header */
|
||||
{ "BNY", 0xe0, 0x8000, 0 }, /* Binary II lib */
|
||||
{ "BQY", 0xe0, 0x8000, 0 }, /* Binary II lib, w/ compress */
|
||||
{ "BXY", 0xe0, 0x8000, 0 }, /* Binary II wrap around SHK */
|
||||
{ "BSE", 0xe0, 0x8000, 0 }, /* Binary II wrap around SEA */
|
||||
{ "SEA", 0xb3, 0xdb07, 0 }, /* GSHK SEA */
|
||||
{ "GIF", 0xc0, 0x8006, 0 }, /* GIF image */
|
||||
{ "JPG", 0x06, 0x0000, 0 }, /* JPEG (nicer than 'NON') */
|
||||
{ "JPEG", 0x06, 0x0000, 0 }, /* JPEG (nicer than 'NON') */
|
||||
{ "SHK", 0xe0, 0x8002, 0 }, /* ShrinkIt archive */
|
||||
{ "ASM", 0xb0, 0x0003 }, /* APW assembly source */
|
||||
{ "C", 0xb0, 0x000a }, /* APW C source */
|
||||
{ "H", 0xb0, 0x000a }, /* APW C header */
|
||||
{ "CPP", 0xb0, 0x0000 }, /* generic source file */
|
||||
{ "BNY", 0xe0, 0x8000 }, /* Binary II lib */
|
||||
{ "BQY", 0xe0, 0x8000 }, /* Binary II lib, w/ compress */
|
||||
{ "BXY", 0xe0, 0x8000 }, /* Binary II wrap around SHK */
|
||||
{ "BSE", 0xe0, 0x8000 }, /* Binary II wrap around SEA */
|
||||
{ "SEA", 0xb3, 0xdb07 }, /* GSHK SEA */
|
||||
{ "TEXT", 0x04, 0x0000 }, /* ASCII text */
|
||||
{ "GIF", 0xc0, 0x8006 }, /* GIF image */
|
||||
{ "JPG", 0x06, 0x0000 }, /* JPEG (nicer than 'NON') */
|
||||
{ "JPEG", 0x06, 0x0000 }, /* JPEG (nicer than 'NON') */
|
||||
{ "SHK", 0xe0, 0x8002 }, /* ShrinkIt archive */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a pointer to the three-letter representation of the file type name.
|
||||
*/
|
||||
const char*
|
||||
GetFileTypeString(ulong fileType)
|
||||
const char* GetFileTypeString(uint32_t fileType)
|
||||
{
|
||||
if (fileType < NELEM(gFileTypeNames))
|
||||
return gFileTypeNames[fileType];
|
||||
|
@ -117,8 +117,7 @@ GetFileTypeString(ulong fileType)
|
|||
* "pathBuf" is assumed to have enough space to hold the current path
|
||||
* plus kMaxPathGrowth more. It will be modified in place.
|
||||
*/
|
||||
static void
|
||||
AddPreservationString(NulibState* pState,
|
||||
static void AddPreservationString(NulibState* pState,
|
||||
const NuPathnameProposal* pPathProposal, char* pathBuf)
|
||||
{
|
||||
char extBuf[kMaxPathGrowth +1];
|
||||
|
@ -127,15 +126,15 @@ AddPreservationString(NulibState* pState,
|
|||
NuThreadID threadID;
|
||||
char* cp;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pPathProposal != nil);
|
||||
Assert(pathBuf != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pPathProposal != NULL);
|
||||
Assert(pathBuf != NULL);
|
||||
Assert(NState_GetModPreserveType(pState));
|
||||
|
||||
pRecord = pPathProposal->pRecord;
|
||||
pThread = pPathProposal->pThread;
|
||||
Assert(pRecord != nil);
|
||||
Assert(pThread != nil);
|
||||
Assert(pRecord != NULL);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
cp = extBuf;
|
||||
|
||||
|
@ -144,11 +143,11 @@ AddPreservationString(NulibState* pState,
|
|||
* return the #of characters written, so we add it up manually.
|
||||
*/
|
||||
if (pRecord->recFileType < 0x100 && pRecord->recExtraType < 0x10000) {
|
||||
sprintf(cp, "%c%02lx%04lx", kPreserveIndic, pRecord->recFileType,
|
||||
sprintf(cp, "%c%02x%04x", kPreserveIndic, pRecord->recFileType,
|
||||
pRecord->recExtraType);
|
||||
cp += 7;
|
||||
} else {
|
||||
sprintf(cp, "%c%08lx%08lx", kPreserveIndic, pRecord->recFileType,
|
||||
sprintf(cp, "%c%08x%08x", kPreserveIndic, pRecord->recFileType,
|
||||
pRecord->recExtraType);
|
||||
cp += 17;
|
||||
}
|
||||
|
@ -179,26 +178,26 @@ AddPreservationString(NulibState* pState,
|
|||
* to be ".txt", and perhaps do something clever for some others.
|
||||
*/
|
||||
if (pRecord->recFileType == 0x04 || threadID == kNuThreadIDDiskImage)
|
||||
pExt = nil;
|
||||
pExt = NULL;
|
||||
else
|
||||
pExt = FindExtension(pState, pathBuf);
|
||||
if (pExt != nil) {
|
||||
if (pExt != NULL) {
|
||||
pExt++; /* skip past the '.' */
|
||||
|
||||
if (strlen(pExt) >= kMaxExtLen) {
|
||||
/* too long, forget it */
|
||||
pExt = nil;
|
||||
pExt = NULL;
|
||||
} else {
|
||||
/* if strictly decimal-numeric, don't use it (.1, .2, etc) */
|
||||
(void) strtoul(pExt, &end, 10);
|
||||
if (*end == '\0') {
|
||||
pExt = nil;
|
||||
pExt = NULL;
|
||||
} else {
|
||||
/* if '#' appears in it, don't use it -- it'll confuse us */
|
||||
const char* ccp = pExt;
|
||||
while (*ccp != '\0') {
|
||||
if (*ccp == '#') {
|
||||
pExt = nil;
|
||||
pExt = NULL;
|
||||
break;
|
||||
}
|
||||
ccp++;
|
||||
|
@ -217,11 +216,11 @@ AddPreservationString(NulibState* pState,
|
|||
else if (pRecord->recFileType) {
|
||||
pExt = GetFileTypeString(pRecord->recFileType);
|
||||
if (pExt[0] == '?' || pExt[0] == '$')
|
||||
pExt = nil;
|
||||
pExt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pExt != nil) {
|
||||
if (pExt != NULL) {
|
||||
*cp++ = kFilenameExtDelim;
|
||||
strcpy(cp, pExt);
|
||||
cp += strlen(pExt);
|
||||
|
@ -248,8 +247,7 @@ AddPreservationString(NulibState* pState,
|
|||
* This returns the new pathname, which is held in NulibState's temporary
|
||||
* pathname buffer.
|
||||
*/
|
||||
const char*
|
||||
NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
||||
const char* NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
char* pathBuf;
|
||||
|
@ -259,9 +257,9 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
|||
char localFssep;
|
||||
int newBufLen;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pPathProposal != nil);
|
||||
Assert(pPathProposal->pathname != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pPathProposal != NULL);
|
||||
Assert(pPathProposal->pathnameUNI != NULL);
|
||||
|
||||
localFssep = NState_GetSystemPathSeparator(pState);
|
||||
|
||||
|
@ -270,14 +268,14 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
|||
* requires converting all chars to '%' codes and adding the longest
|
||||
* possible preservation string.
|
||||
*/
|
||||
newBufLen = strlen(pPathProposal->pathname)*3 + kMaxPathGrowth +1;
|
||||
newBufLen = strlen(pPathProposal->pathnameUNI)*3 + kMaxPathGrowth +1;
|
||||
NState_SetTempPathnameLen(pState, newBufLen);
|
||||
pathBuf = NState_GetTempPathnameBuf(pState);
|
||||
Assert(pathBuf != nil);
|
||||
if (pathBuf == nil)
|
||||
return nil;
|
||||
Assert(pathBuf != NULL);
|
||||
if (pathBuf == NULL)
|
||||
return NULL;
|
||||
|
||||
startp = pPathProposal->pathname;
|
||||
startp = pPathProposal->pathnameUNI;
|
||||
dstp = pathBuf;
|
||||
while (*startp == pPathProposal->filenameSeparator) {
|
||||
/* ignore leading path sep; always extract to current dir */
|
||||
|
@ -285,9 +283,9 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
|||
}
|
||||
|
||||
/* normalize all directory components and the filename component */
|
||||
while (startp != nil) {
|
||||
while (startp != NULL) {
|
||||
endp = strchr(startp, pPathProposal->filenameSeparator);
|
||||
if (endp != nil) {
|
||||
if (endp != NULL) {
|
||||
/* normalize directory component */
|
||||
err = NormalizeDirectoryName(pState, startp, endp - startp,
|
||||
pPathProposal->filenameSeparator, &dstp,
|
||||
|
@ -312,15 +310,17 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
|||
AddPreservationString(pState, pPathProposal, pathBuf);
|
||||
} else if (NuGetThreadID(pPathProposal->pThread) == kNuThreadIDRsrcFork)
|
||||
{
|
||||
#ifndef HAS_RESOURCE_FORKS
|
||||
/* add this in lieu of the preservation extension */
|
||||
strcat(pathBuf, kResourceStr);
|
||||
#endif
|
||||
}
|
||||
|
||||
startp = nil; /* we're done */
|
||||
startp = NULL; /* we're done */
|
||||
}
|
||||
}
|
||||
|
||||
pPathProposal->newPathname = pathBuf;
|
||||
pPathProposal->newPathnameUNI = pathBuf;
|
||||
pPathProposal->newFilenameSeparator = localFssep;
|
||||
|
||||
/* check for overflow */
|
||||
|
@ -332,7 +332,7 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
|||
if (NState_GetModJunkPaths(pState)) {
|
||||
char* lastFssep;
|
||||
lastFssep = strrchr(pathBuf, localFssep);
|
||||
if (lastFssep != nil) {
|
||||
if (lastFssep != NULL) {
|
||||
Assert(*(lastFssep+1) != '\0'); /* should already have been caught*/
|
||||
memmove(pathBuf, lastFssep+1, strlen(lastFssep+1)+1);
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
|
|||
|
||||
bail:
|
||||
if (err != kNuErrNone)
|
||||
return nil;
|
||||
return NULL;
|
||||
return pathBuf;
|
||||
}
|
||||
|
||||
|
@ -357,9 +357,8 @@ bail:
|
|||
* This checks the standard list of ProDOS types (which should catch things
|
||||
* like "TXT" and "BIN") and the separate list of recognized extensions.
|
||||
*/
|
||||
static void
|
||||
LookupExtension(NulibState* pState, const char* ext, ulong* pFileType,
|
||||
ulong* pAuxType)
|
||||
static void LookupExtension(NulibState* pState, const char* ext,
|
||||
uint32_t* pFileType, uint32_t* pAuxType)
|
||||
{
|
||||
char uext3[4];
|
||||
int i, extLen;
|
||||
|
@ -409,19 +408,18 @@ bail:
|
|||
/*
|
||||
* Try to associate some meaning with the file extension.
|
||||
*/
|
||||
void
|
||||
InterpretExtension(NulibState* pState, const char* pathName, ulong* pFileType,
|
||||
ulong* pAuxType)
|
||||
void InterpretExtension(NulibState* pState, const char* pathName,
|
||||
uint32_t* pFileType, uint32_t* pAuxType)
|
||||
{
|
||||
const char* pExt;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pathName != nil);
|
||||
Assert(pFileType != nil);
|
||||
Assert(pAuxType != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pathName != NULL);
|
||||
Assert(pFileType != NULL);
|
||||
Assert(pAuxType != NULL);
|
||||
|
||||
pExt = FindExtension(pState, pathName);
|
||||
if (pExt != nil)
|
||||
if (pExt != NULL)
|
||||
LookupExtension(pState, pExt+1, pFileType, pAuxType);
|
||||
}
|
||||
|
||||
|
@ -434,25 +432,24 @@ InterpretExtension(NulibState* pState, const char* pathName, ulong* pFileType,
|
|||
* We have to be careful not to trip on false-positive occurrences of '#'
|
||||
* in the filename.
|
||||
*/
|
||||
Boolean
|
||||
ExtractPreservationString(NulibState* pState, char* pathname, ulong* pFileType,
|
||||
ulong* pAuxType, NuThreadID* pThreadID)
|
||||
Boolean ExtractPreservationString(NulibState* pState, char* pathname,
|
||||
uint32_t* pFileType, uint32_t* pAuxType, NuThreadID* pThreadID)
|
||||
{
|
||||
char numBuf[9];
|
||||
ulong fileType, auxType;
|
||||
uint32_t fileType, auxType;
|
||||
NuThreadID threadID;
|
||||
char* pPreserve;
|
||||
char* cp;
|
||||
int digitCount;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pathname != nil);
|
||||
Assert(pFileType != nil);
|
||||
Assert(pAuxType != nil);
|
||||
Assert(pThreadID != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pathname != NULL);
|
||||
Assert(pFileType != NULL);
|
||||
Assert(pAuxType != NULL);
|
||||
Assert(pThreadID != NULL);
|
||||
|
||||
pPreserve = strrchr(pathname, kPreserveIndic);
|
||||
if (pPreserve == nil)
|
||||
if (pPreserve == NULL)
|
||||
return false;
|
||||
|
||||
/* count up the #of hex digits */
|
||||
|
@ -528,8 +525,7 @@ ExtractPreservationString(NulibState* pState, char* pathname, ulong* pFileType,
|
|||
* This always results in the filename staying the same length or getting
|
||||
* smaller, so we can do it in place in the buffer.
|
||||
*/
|
||||
void
|
||||
DenormalizePath(NulibState* pState, char* pathBuf)
|
||||
void DenormalizePath(NulibState* pState, char* pathBuf)
|
||||
{
|
||||
const char* srcp;
|
||||
char* dstp;
|
||||
|
@ -583,20 +579,19 @@ DenormalizePath(NulibState* pState, char* pathBuf)
|
|||
* Find the filename component of a local pathname. Uses the fssep defined
|
||||
* in pState.
|
||||
*
|
||||
* Always returns a pointer to a string; never returns nil.
|
||||
* Always returns a pointer to a string; never returns NULL.
|
||||
*/
|
||||
const char*
|
||||
FilenameOnly(NulibState* pState, const char* pathname)
|
||||
const char* FilenameOnly(NulibState* pState, const char* pathname)
|
||||
{
|
||||
const char* retstr;
|
||||
const char* pSlash;
|
||||
char* tmpStr = nil;
|
||||
char* tmpStr = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pathname != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pathname != NULL);
|
||||
|
||||
pSlash = strrchr(pathname, NState_GetSystemPathSeparator(pState));
|
||||
if (pSlash == nil) {
|
||||
if (pSlash == NULL) {
|
||||
retstr = pathname; /* whole thing is the filename */
|
||||
goto bail;
|
||||
}
|
||||
|
@ -614,7 +609,7 @@ FilenameOnly(NulibState* pState, const char* pathname)
|
|||
tmpStr[strlen(pathname)-1] = '\0';
|
||||
pSlash = strrchr(tmpStr, NState_GetSystemPathSeparator(pState));
|
||||
|
||||
if (pSlash == nil) {
|
||||
if (pSlash == NULL) {
|
||||
retstr = pathname; /* just a filename with a '/' after it */
|
||||
goto bail;
|
||||
}
|
||||
|
@ -642,11 +637,10 @@ bail:
|
|||
* An extension is the stuff following the last '.' in the filename. If
|
||||
* there is nothing following the last '.', then there is no extension.
|
||||
*
|
||||
* Returns a pointer to the '.' preceding the extension, or nil if no
|
||||
* Returns a pointer to the '.' preceding the extension, or NULL if no
|
||||
* extension was found.
|
||||
*/
|
||||
const char*
|
||||
FindExtension(NulibState* pState, const char* pathname)
|
||||
const char* FindExtension(NulibState* pState, const char* pathname)
|
||||
{
|
||||
const char* pFilename;
|
||||
const char* pExt;
|
||||
|
@ -656,13 +650,13 @@ FindExtension(NulibState* pState, const char* pathname)
|
|||
* about "/foo.bar/file".
|
||||
*/
|
||||
pFilename = FilenameOnly(pState, pathname);
|
||||
Assert(pFilename != nil);
|
||||
Assert(pFilename != NULL);
|
||||
pExt = strrchr(pFilename, kFilenameExtDelim);
|
||||
|
||||
/* also check for "/blah/foo.", which doesn't count */
|
||||
if (pExt != nil && *(pExt+1) != '\0')
|
||||
if (pExt != NULL && *(pExt+1) != '\0')
|
||||
return pExt;
|
||||
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
145
nulib2/List.c
145
nulib2/List.c
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* List files in the archive.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
|
||||
/* kinds of records */
|
||||
|
@ -40,8 +40,7 @@ static const char* gMonths[] = {
|
|||
/*
|
||||
* Compute a percentage.
|
||||
*/
|
||||
int
|
||||
ComputePercent(ulong totalSize, ulong size)
|
||||
int ComputePercent(uint32_t totalSize, uint32_t size)
|
||||
{
|
||||
int perc;
|
||||
|
||||
|
@ -69,8 +68,7 @@ ComputePercent(ulong totalSize, ulong size)
|
|||
*
|
||||
* Returns "buffer" for the benefit of printf() calls.
|
||||
*/
|
||||
char*
|
||||
FormatDateShort(const NuDateTime* pDateTime, char* buffer)
|
||||
char* FormatDateShort(const NuDateTime* pDateTime, char* buffer)
|
||||
{
|
||||
/* is it valid? */
|
||||
if (pDateTime->day > 30 || pDateTime->month > 11 || pDateTime->hour > 24 ||
|
||||
|
@ -101,21 +99,21 @@ bail:
|
|||
/*
|
||||
* NuStream callback function. Displays the filename.
|
||||
*/
|
||||
static NuResult
|
||||
ShowContentsShort(NuArchive* pArchive, void* vpRecord)
|
||||
static NuResult ShowContentsShort(NuArchive* pArchive, void* vpRecord)
|
||||
{
|
||||
const NuRecord* pRecord = (NuRecord*) vpRecord;
|
||||
NulibState* pState;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
(void) NuGetExtraData(pArchive, (void**) &pState);
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (!IsSpecified(pState, pRecord))
|
||||
goto bail;
|
||||
|
||||
printf("%s\n",
|
||||
pRecord->filename == nil ? "<unknown>":(const char*)pRecord->filename);
|
||||
UNICHAR* filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
|
||||
printf("%s\n", filenameUNI == NULL ? "<unknown>" : filenameUNI);
|
||||
free(filenameUNI);
|
||||
|
||||
bail:
|
||||
return kNuOK;
|
||||
|
@ -137,18 +135,22 @@ bail:
|
|||
* a disk image thread, but it's a fair bet ShrinkIt would ignore one
|
||||
* or the other.
|
||||
*
|
||||
* NOTE: we don't currently work around the GSHK zero-length file bug.
|
||||
* Such records, which have a filename thread but no data threads at all,
|
||||
* will be categorized as "unknown". We could detect the situation and
|
||||
* correct it, but we might as well flag it in a user-visible way.
|
||||
* NOTE: GSHK likes to omit the data threads for zero-length data and
|
||||
* resource forks. That screws up analysis by scanning for threads. We
|
||||
* can work around missing resource forks by simply checking the record's
|
||||
* storage type. We could be clever and detect records that have no
|
||||
* data-class threads at all, and no additional threads other than a
|
||||
* comment and filename, but this is just for display. ShrinkIt doesn't
|
||||
* handle these records correctly in all cases, so flagging them in a
|
||||
* user-visible way seems reasonable.
|
||||
*/
|
||||
static NuError
|
||||
AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
|
||||
ushort* pFormat, ulong* pTotalLen, ulong* pTotalCompLen)
|
||||
static NuError AnalyzeRecord(const NuRecord* pRecord,
|
||||
enum RecordKind* pRecordKind, uint16_t* pFormat, uint32_t* pTotalLen,
|
||||
uint32_t* pTotalCompLen)
|
||||
{
|
||||
const NuThread* pThread;
|
||||
NuThreadID threadID;
|
||||
ulong idx;
|
||||
uint32_t idx;
|
||||
|
||||
*pRecordKind = kRecordKindUnknown;
|
||||
*pTotalLen = *pTotalCompLen = 0;
|
||||
|
@ -156,7 +158,7 @@ AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
|
|||
|
||||
for (idx = 0; idx < pRecord->recTotalThreads; idx++) {
|
||||
pThread = NuGetThread(pRecord, idx);
|
||||
Assert(pThread != nil);
|
||||
Assert(pThread != NULL);
|
||||
|
||||
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||
/* replace what's there if this might be more interesting */
|
||||
|
@ -179,6 +181,16 @@ AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix up the case where we have a forked file, but GSHK decided not
|
||||
* to include a resource fork in the record.
|
||||
*/
|
||||
if (pRecord->recStorageType == kNuStorageExtended &&
|
||||
*pRecordKind != kRecordKindForkedFile)
|
||||
{
|
||||
*pRecordKind = kRecordKindForkedFile;
|
||||
}
|
||||
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
||||
|
@ -188,22 +200,21 @@ AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
|
|||
* This is intended to mimic the output of some old version of ProDOS 8
|
||||
* ShrinkIt.
|
||||
*/
|
||||
static NuResult
|
||||
ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
|
||||
static NuResult ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
const NuRecord* pRecord = (NuRecord*) vpRecord;
|
||||
enum RecordKind recordKind;
|
||||
ulong totalLen, totalCompLen;
|
||||
ushort format;
|
||||
uint32_t totalLen, totalCompLen;
|
||||
uint16_t format;
|
||||
NulibState* pState;
|
||||
char date1[kDateOutputLen];
|
||||
char tmpbuf[16];
|
||||
int len;
|
||||
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
(void) NuGetExtraData(pArchive, (void**) &pState);
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (!IsSpecified(pState, pRecord))
|
||||
goto bail;
|
||||
|
@ -213,27 +224,45 @@ ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
|
|||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
|
||||
len = strlen(pRecord->filename);
|
||||
/*
|
||||
* Display the filename, truncating if it's longer than 27 characters.
|
||||
*
|
||||
* Attempting to do column layout with printf string formatting (e.g.
|
||||
* "%-27s") doesn't really work for UTF-8 because printf() is
|
||||
* operating on bytes, and the conversion to a Unicode code point
|
||||
* is happening in the terminal. We need to do the spacing ourselves,
|
||||
* using the fact that one MOR character turns into one Unicode character.
|
||||
*
|
||||
* If the display isn't converting multi-byte sequences to individual
|
||||
* characters, this won't look right, but we can't make everybody happy.
|
||||
*/
|
||||
static const char kSpaces[27+1] = " ";
|
||||
UNICHAR* filenameUNI;
|
||||
len = strlen(pRecord->filenameMOR);
|
||||
if (len <= 27) {
|
||||
printf("%c%-27.27s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
|
||||
pRecord->filename);
|
||||
filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
|
||||
printf("%c%s%s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
|
||||
filenameUNI, &kSpaces[len]);
|
||||
} else {
|
||||
printf("%c..%-25.25s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
|
||||
pRecord->filename + len - 25);
|
||||
filenameUNI = CopyMORToUNI(pRecord->filenameMOR + len - 25);
|
||||
printf("%c..%s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
|
||||
filenameUNI);
|
||||
}
|
||||
free(filenameUNI);
|
||||
|
||||
switch (recordKind) {
|
||||
case kRecordKindUnknown:
|
||||
printf("%s- $%04lX ",
|
||||
printf("%s- $%04X ",
|
||||
GetFileTypeString(pRecord->recFileType),
|
||||
pRecord->recExtraType);
|
||||
break;
|
||||
case kRecordKindDisk:
|
||||
sprintf(tmpbuf, "%ldk", totalLen / 1024);
|
||||
sprintf(tmpbuf, "%dk", totalLen / 1024);
|
||||
printf("Disk %-6s ", tmpbuf);
|
||||
break;
|
||||
case kRecordKindFile:
|
||||
case kRecordKindForkedFile:
|
||||
printf("%s%c $%04lX ",
|
||||
printf("%s%c $%04X ",
|
||||
GetFileTypeString(pRecord->recFileType),
|
||||
recordKind == kRecordKindForkedFile ? '+' : ' ',
|
||||
pRecord->recExtraType);
|
||||
|
@ -262,7 +291,7 @@ ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
|
|||
if (!totalLen && totalCompLen)
|
||||
printf(" ????"); /* weird */
|
||||
else
|
||||
printf("%8ld", totalLen);
|
||||
printf("%8u", totalLen);
|
||||
|
||||
printf("\n");
|
||||
|
||||
|
@ -270,8 +299,10 @@ ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
|
|||
|
||||
bail:
|
||||
if (err != kNuErrNone) {
|
||||
printf("(ERROR on '%s')\n", pRecord->filename == nil ?
|
||||
"<unknown>" : (const char*)pRecord->filename);
|
||||
filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
|
||||
printf("(ERROR on '%s')\n",
|
||||
filenameUNI == NULL ? "<unknown>" : filenameUNI);
|
||||
free(filenameUNI);
|
||||
}
|
||||
return kNuOK;
|
||||
}
|
||||
|
@ -279,13 +310,12 @@ bail:
|
|||
/*
|
||||
* Print a short listing of the contents of an archive.
|
||||
*/
|
||||
NuError
|
||||
DoListShort(NulibState* pState)
|
||||
NuError DoListShort(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (NState_GetModBinaryII(pState))
|
||||
return BNYDoListShort(pState);
|
||||
|
@ -296,13 +326,13 @@ DoListShort(NulibState* pState)
|
|||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
pArchive = NState_GetNuArchive(pState);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
err = NuContents(pArchive, ShowContentsShort);
|
||||
/* fall through with err */
|
||||
|
||||
bail:
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
(void) NuClose(pArchive);
|
||||
return err;
|
||||
}
|
||||
|
@ -311,18 +341,17 @@ bail:
|
|||
/*
|
||||
* Print a more verbose listing of the contents of an archive.
|
||||
*/
|
||||
NuError
|
||||
DoListVerbose(NulibState* pState)
|
||||
NuError DoListVerbose(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
const NuMasterHeader* pHeader;
|
||||
char date1[kDateOutputLen];
|
||||
char date2[kDateOutputLen];
|
||||
long totalLen, totalCompLen;
|
||||
const char* cp;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (NState_GetModBinaryII(pState))
|
||||
return BNYDoListVerbose(pState);
|
||||
|
@ -333,7 +362,7 @@ DoListVerbose(NulibState* pState)
|
|||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
pArchive = NState_GetNuArchive(pState);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
/*
|
||||
* Try to get just the filename.
|
||||
|
@ -348,7 +377,7 @@ DoListVerbose(NulibState* pState)
|
|||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
|
||||
printf(" %-15.15s Created:%s Mod:%s Recs:%5lu\n\n",
|
||||
printf(" %-15.15s Created:%s Mod:%s Recs:%5u\n\n",
|
||||
cp,
|
||||
FormatDateShort(&pHeader->mhArchiveCreateWhen, date1),
|
||||
FormatDateShort(&pHeader->mhArchiveModWhen, date2),
|
||||
|
@ -384,7 +413,7 @@ DoListVerbose(NulibState* pState)
|
|||
/*(void) NuDebugDumpArchive(pArchive);*/
|
||||
|
||||
bail:
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
(void) NuClose(pArchive);
|
||||
return err;
|
||||
}
|
||||
|
@ -394,8 +423,7 @@ bail:
|
|||
/*
|
||||
* Null callback, for those times when you don't really want to do anything.
|
||||
*/
|
||||
static NuResult
|
||||
NullCallback(NuArchive* pArchive, void* vpRecord)
|
||||
static NuResult NullCallback(NuArchive* pArchive, void* vpRecord)
|
||||
{
|
||||
return kNuOK;
|
||||
}
|
||||
|
@ -404,13 +432,12 @@ NullCallback(NuArchive* pArchive, void* vpRecord)
|
|||
* Print very detailed output, suitable for debugging (requires that
|
||||
* debug messages be enabled in nufxlib).
|
||||
*/
|
||||
NuError
|
||||
DoListDebug(NulibState* pState)
|
||||
NuError DoListDebug(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuArchive* pArchive = nil;
|
||||
NuArchive* pArchive = NULL;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
if (NState_GetModBinaryII(pState))
|
||||
return BNYDoListDebug(pState);
|
||||
|
@ -421,7 +448,7 @@ DoListDebug(NulibState* pState)
|
|||
if (err != kNuErrNone)
|
||||
goto bail;
|
||||
pArchive = NState_GetNuArchive(pState);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pArchive != NULL);
|
||||
|
||||
/* have to do something to force the library to scan the archive */
|
||||
err = NuContents(pArchive, NullCallback);
|
||||
|
@ -434,7 +461,7 @@ DoListDebug(NulibState* pState)
|
|||
/* fall through with err */
|
||||
|
||||
bail:
|
||||
if (pArchive != nil)
|
||||
if (pArchive != NULL)
|
||||
(void) NuClose(pArchive);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Main entry point and shell command argument processing.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
/*
|
||||
* Globals and constants.
|
||||
*/
|
||||
const char* gProgName = "Nulib2";
|
||||
const char* gProgName = "NuLib2";
|
||||
|
||||
|
||||
/*
|
||||
|
@ -42,10 +42,9 @@ static const ValidCombo gValidCombos[] = {
|
|||
/*
|
||||
* Find an entry in the gValidCombos table matching the specified command.
|
||||
*
|
||||
* Returns nil if not found.
|
||||
* Returns NULL if not found.
|
||||
*/
|
||||
static const ValidCombo*
|
||||
FindValidComboEntry(Command cmd)
|
||||
static const ValidCombo* FindValidComboEntry(Command cmd)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -54,21 +53,20 @@ FindValidComboEntry(Command cmd)
|
|||
return &gValidCombos[i];
|
||||
}
|
||||
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether the specified modifier is valid when used with the
|
||||
* current command.
|
||||
*/
|
||||
static Boolean
|
||||
IsValidModifier(Command cmd, char modifier)
|
||||
static Boolean IsValidModifier(Command cmd, char modifier)
|
||||
{
|
||||
const ValidCombo* pvc;
|
||||
|
||||
pvc = FindValidComboEntry(cmd);
|
||||
if (pvc != nil) {
|
||||
if (strchr(pvc->modifiers, modifier) == nil)
|
||||
if (pvc != NULL) {
|
||||
if (strchr(pvc->modifiers, modifier) == NULL)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
@ -79,13 +77,12 @@ IsValidModifier(Command cmd, char modifier)
|
|||
/*
|
||||
* Determine whether the specified command can be used with stdin as input.
|
||||
*/
|
||||
static Boolean
|
||||
IsValidOnPipe(Command cmd)
|
||||
static Boolean IsValidOnPipe(Command cmd)
|
||||
{
|
||||
const ValidCombo* pvc;
|
||||
|
||||
pvc = FindValidComboEntry(cmd);
|
||||
if (pvc != nil) {
|
||||
if (pvc != NULL) {
|
||||
return pvc->okayForPipe;
|
||||
} else
|
||||
return false;
|
||||
|
@ -94,13 +91,12 @@ IsValidOnPipe(Command cmd)
|
|||
/*
|
||||
* Determine whether the specified command can be used with stdin as input.
|
||||
*/
|
||||
static Boolean
|
||||
IsFilespecRequired(Command cmd)
|
||||
static Boolean IsFilespecRequired(Command cmd)
|
||||
{
|
||||
const ValidCombo* pvc;
|
||||
|
||||
pvc = FindValidComboEntry(cmd);
|
||||
if (pvc != nil) {
|
||||
if (pvc != NULL) {
|
||||
return pvc->filespecRequired;
|
||||
} else {
|
||||
/* command not found? warn about it here... */
|
||||
|
@ -114,8 +110,7 @@ IsFilespecRequired(Command cmd)
|
|||
/*
|
||||
* Separate the program name out of argv[0].
|
||||
*/
|
||||
static const char*
|
||||
GetProgName(const NulibState* pState, const char* argv0)
|
||||
static const char* GetProgName(const NulibState* pState, const char* argv0)
|
||||
{
|
||||
const char* result;
|
||||
char sep;
|
||||
|
@ -124,7 +119,7 @@ GetProgName(const NulibState* pState, const char* argv0)
|
|||
sep = NState_GetSystemPathSeparator(pState);
|
||||
|
||||
result = strrchr(argv0, sep);
|
||||
if (result == nil)
|
||||
if (result == NULL)
|
||||
result = argv0;
|
||||
else
|
||||
result++; /* advance past the separator */
|
||||
|
@ -136,20 +131,19 @@ GetProgName(const NulibState* pState, const char* argv0)
|
|||
/*
|
||||
* Print program usage.
|
||||
*/
|
||||
static void
|
||||
Usage(const NulibState* pState)
|
||||
static void Usage(const NulibState* pState)
|
||||
{
|
||||
long majorVersion, minorVersion, bugVersion;
|
||||
int32_t majorVersion, minorVersion, bugVersion;
|
||||
const char* nufxLibDate;
|
||||
const char* nufxLibFlags;
|
||||
|
||||
(void) NuGetVersion(&majorVersion, &minorVersion, &bugVersion,
|
||||
&nufxLibDate, &nufxLibFlags);
|
||||
|
||||
printf("\nNulib2 v%s, linked with NufxLib v%ld.%ld.%ld [%s]\n",
|
||||
printf("\nNuLib2 v%s, linked with NufxLib v%d.%d.%d [%s]\n",
|
||||
NState_GetProgramVersion(pState),
|
||||
majorVersion, minorVersion, bugVersion, nufxLibFlags);
|
||||
printf("Copyright (C) 2000-2014, Andy McFadden. All Rights Reserved.\n");
|
||||
printf("Copyright (C) 2000-2017, Andy McFadden. All Rights Reserved.\n");
|
||||
printf("This software is distributed under terms of the BSD License.\n");
|
||||
printf("Visit http://www.nulib.com/ for source code and documentation.\n\n");
|
||||
printf("Usage: %s -command[modifiers] archive [filename-list]\n\n",
|
||||
|
@ -184,8 +178,7 @@ Usage(const NulibState* pState)
|
|||
/*
|
||||
* Handle the "-h" command.
|
||||
*/
|
||||
NuError
|
||||
DoHelp(const NulibState* pState)
|
||||
NuError DoHelp(const NulibState* pState)
|
||||
{
|
||||
static const struct {
|
||||
Command cmd;
|
||||
|
@ -273,7 +266,7 @@ DoHelp(const NulibState* pState)
|
|||
int j;
|
||||
|
||||
pvc = FindValidComboEntry(help[i].cmd);
|
||||
if (pvc == nil) {
|
||||
if (pvc == NULL) {
|
||||
fprintf(stderr, "%s: internal error: couldn't find vc for %d\n",
|
||||
gProgName, help[i].cmd);
|
||||
continue;
|
||||
|
@ -315,8 +308,7 @@ DoHelp(const NulibState* pState)
|
|||
/*
|
||||
* Process the command-line options. The results are placed into "pState".
|
||||
*/
|
||||
static int
|
||||
ProcessOptions(NulibState* pState, int argc, char* const* argv)
|
||||
static int ProcessOptions(NulibState* pState, int argc, char* const* argv)
|
||||
{
|
||||
const char* cp;
|
||||
int idx;
|
||||
|
@ -328,7 +320,7 @@ ProcessOptions(NulibState* pState, int argc, char* const* argv)
|
|||
if (argc == 2 && (tolower(argv[1][0]) == 'h' ||
|
||||
(argv[1][0] == '-' && tolower(argv[1][1] == 'h')) ) )
|
||||
{
|
||||
DoHelp(nil);
|
||||
DoHelp(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -486,7 +478,7 @@ ProcessOptions(NulibState* pState, int argc, char* const* argv)
|
|||
gProgName);
|
||||
goto fail;
|
||||
}
|
||||
NState_SetFilespecPointer(pState, nil);
|
||||
NState_SetFilespecPointer(pState, NULL);
|
||||
NState_SetFilespecCount(pState, 0);
|
||||
}
|
||||
|
||||
|
@ -511,8 +503,7 @@ fail:
|
|||
*
|
||||
* Returns 0 on success, 1 on error.
|
||||
*/
|
||||
int
|
||||
DoWork(NulibState* pState)
|
||||
int DoWork(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
|
@ -558,17 +549,16 @@ DoWork(NulibState* pState)
|
|||
/*
|
||||
* Entry point.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
NulibState* pState = nil;
|
||||
long majorVersion, minorVersion, bugVersion;
|
||||
NulibState* pState = NULL;
|
||||
int32_t majorVersion, minorVersion, bugVersion;
|
||||
int result = 0;
|
||||
|
||||
(void) NuGetVersion(&majorVersion, &minorVersion, &bugVersion, nil, nil);
|
||||
(void) NuGetVersion(&majorVersion, &minorVersion, &bugVersion, NULL, NULL);
|
||||
if (majorVersion != kNuVersionMajor || minorVersion < kNuVersionMinor) {
|
||||
fprintf(stderr, "ERROR: wrong version of NufxLib --"
|
||||
" wanted %d.%d.x, got %ld.%ld.%ld.\n",
|
||||
" wanted %d.%d.x, got %d.%d.%d.\n",
|
||||
kNuVersionMajor, kNuVersionMinor,
|
||||
majorVersion, minorVersion, bugVersion);
|
||||
goto bail;
|
||||
|
|
|
@ -44,15 +44,6 @@ OPT = @CFLAGS@
|
|||
GCC_FLAGS = -Wall -Wwrite-strings -Wstrict-prototypes -Wpointer-arith -Wshadow
|
||||
CFLAGS = @BUILD_FLAGS@ -I. -I$(NUFXSRCDIR) -I$(includedir) @DEFS@
|
||||
|
||||
#ifdef PURIFY_BUILD
|
||||
# PURIFY = purify
|
||||
# CFLAGS += -DPURIFY
|
||||
#endif
|
||||
#ifdef QUANTIFY_BUILD
|
||||
# QUANTIFY = quantify
|
||||
# CFLAGS += -DQUANTIFY
|
||||
#endif
|
||||
|
||||
SRCS = Add.c ArcUtils.c Binary2.c Delete.c Extract.c Filename.c \
|
||||
List.c Main.c MiscStuff.c MiscUtils.c State.c SysUtils.c
|
||||
OBJS = Add.o ArcUtils.o Binary2.o Delete.o Extract.o Filename.o \
|
||||
|
@ -72,10 +63,10 @@ all: $(PRODUCT)
|
|||
@true
|
||||
|
||||
install: $(PRODUCT)
|
||||
$(srcdir)/mkinstalldirs $(bindir)
|
||||
$(INSTALL_PROGRAM) $(PRODUCT) $(bindir)
|
||||
$(srcdir)/mkinstalldirs $(mandir)/man1
|
||||
$(INSTALL_DATA) nulib2.1 $(mandir)/man1/
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
|
||||
$(INSTALL_PROGRAM) $(PRODUCT) $(DESTDIR)$(bindir)
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL_DATA) nulib2.1 $(DESTDIR)$(mandir)/man1/
|
||||
|
||||
install-shared:
|
||||
LIB_PRODUCT="libnufx.so" $(MAKE) -e install
|
||||
|
@ -87,16 +78,8 @@ install-shared:
|
|||
shared::
|
||||
LIB_PRODUCT="libnufx.so" $(MAKE) -e
|
||||
|
||||
quantify:
|
||||
-rm -f $(PRODUCT)
|
||||
@$(MAKE) QUANTIFY_BUILD=1
|
||||
|
||||
purify:
|
||||
-rm -f $(PRODUCT)
|
||||
@$(MAKE) PURIFY_BUILD=1
|
||||
|
||||
$(PRODUCT): $(OBJS) $(NUFXLIB)
|
||||
$(PURIFY) $(QUANTIFY) $(CC) -o $@ $(OBJS) -L$(NUFXSRCDIR) -L$(libdir) -lnufx @LIBS@
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) -L$(NUFXSRCDIR) -L$(libdir) -lnufx @LIBS@
|
||||
|
||||
clean:
|
||||
-rm -f *.o core
|
||||
|
@ -141,8 +124,19 @@ baktar:
|
|||
@gzip -9 nulib2.tar
|
||||
@mv -i nulib2.tar.gz /home/fadden/BAK/
|
||||
|
||||
depend:
|
||||
makedepend -- $(CFLAGS) -- $(SRCS)
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
# dependency info
|
||||
COMMON_HDRS = NuLib2.h SysDefs.h State.h MiscStuff.h config.h \
|
||||
$(NUFXSRCDIR)/NufxLib.h
|
||||
Add.o: Add.c $(COMMON_HDRS)
|
||||
ArcUtils.o: ArcUtils.c $(COMMON_HDRS)
|
||||
Binary2.o: Binary2.c $(COMMON_HDRS)
|
||||
Delete.o: Delete.c $(COMMON_HDRS)
|
||||
Extract.o: Extract.c $(COMMON_HDRS)
|
||||
Filename.o: Filename.c $(COMMON_HDRS)
|
||||
List.o: List.c $(COMMON_HDRS)
|
||||
Main.o: Main.c $(COMMON_HDRS)
|
||||
MiscStuff.o: MiscStuff.c $(COMMON_HDRS)
|
||||
MiscUtils.o: MiscUtils.c $(COMMON_HDRS)
|
||||
State.o: State.c $(COMMON_HDRS)
|
||||
SysUtils.o: SysUtils.c $(COMMON_HDRS)
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
* Return a pointer to the appropriate string in the system table, or NULL
|
||||
* if the value is out of bounds.
|
||||
*/
|
||||
const char*
|
||||
Nu_strerror(int errnum)
|
||||
const char* Nu_strerror(int errnum)
|
||||
{
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
@ -38,8 +37,7 @@ Nu_strerror(int errnum)
|
|||
* from BSD, is available in the PGP 2.6.2 distribution, but this should
|
||||
* suffice for those few systems that don't have memmove.
|
||||
*/
|
||||
void*
|
||||
Nu_memmove(void* dst, const void* src, size_t n)
|
||||
void* Nu_memmove(void* dst, const void* src, size_t n)
|
||||
{
|
||||
void* retval = dst;
|
||||
char* srcp = (char*)src;
|
||||
|
@ -80,8 +78,7 @@ Nu_memmove(void* dst, const void* src, size_t n)
|
|||
* For our purposes here, strtol does all we need it to. Someday
|
||||
* we should replace this with a "real" version.
|
||||
*/
|
||||
unsigned long
|
||||
Nu_strtoul(const char *nptr, char **endptr, int base)
|
||||
unsigned long Nu_strtoul(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return strtol(nptr, endptr, base);
|
||||
}
|
||||
|
@ -91,8 +88,7 @@ Nu_strtoul(const char *nptr, char **endptr, int base)
|
|||
/*
|
||||
* Compare two strings, case-insensitive.
|
||||
*/
|
||||
int
|
||||
Nu_strcasecmp(const char *str1, const char *str2)
|
||||
int Nu_strcasecmp(const char *str1, const char *str2)
|
||||
{
|
||||
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
|
||||
str1++, str2++;
|
||||
|
@ -105,8 +101,7 @@ Nu_strcasecmp(const char *str1, const char *str2)
|
|||
/*
|
||||
* Compare two strings, case-insensitive, stopping after "n" chars.
|
||||
*/
|
||||
int
|
||||
Nu_strncasecmp(const char *str1, const char *str2, size_t n)
|
||||
int Nu_strncasecmp(const char *str1, const char *str2, size_t n)
|
||||
{
|
||||
while (n && *str1 && *str2 && toupper(*str1) == toupper(*str2))
|
||||
str1++, str2++, n--;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* Misc stuff (shared between nufxlib and nulib2). This is a collection
|
||||
* of miscellaneous types and macros that I find generally useful.
|
||||
*/
|
||||
#ifndef __MiscStuff__
|
||||
#define __MiscStuff__
|
||||
#ifndef NULIB2_MISCSTUFF_H
|
||||
#define NULIB2_MISCSTUFF_H
|
||||
|
||||
#define VALGRIND /* assume we're using it */
|
||||
|
||||
|
@ -42,11 +42,7 @@ int Nu_strncasecmp(const char *s1, const char *s2, size_t n);
|
|||
* Misc types.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define nil NULL /* I can't seem to stop typing 'nil' now */
|
||||
|
||||
typedef uchar Boolean;
|
||||
typedef unsigned char Boolean;
|
||||
#define false (0)
|
||||
#define true (!false)
|
||||
|
||||
|
@ -63,7 +59,7 @@ typedef uchar Boolean;
|
|||
(x) <= '9' ? (x) - '0' : toupper(x) +10 - 'A' )
|
||||
|
||||
/* convert number from 0-15 to hex digit */
|
||||
#define HexConv(x) ( ((uint)(x)) <= 15 ? \
|
||||
#define HexConv(x) ( ((unsigned int)(x)) <= 15 ? \
|
||||
( (x) <= 9 ? (x) + '0' : (x) -10 + 'A') : -1 )
|
||||
|
||||
|
||||
|
@ -106,4 +102,4 @@ typedef uchar Boolean;
|
|||
|
||||
#define kInvalidPtr ((void*)0xa3a3a3a3)
|
||||
|
||||
#endif /*__MiscStuff__*/
|
||||
#endif /*NULIB2_MISCSTUFF_H*/
|
||||
|
|
|
@ -1,33 +1,31 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Misc support functions.
|
||||
*/
|
||||
#define __MiscUtils_c__
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
|
||||
/*
|
||||
* Similar to perror(), but takes the error as an argument, and knows
|
||||
* about NufxLib errors as well as system errors.
|
||||
*
|
||||
* If "format" is nil, just the error message itself is printed.
|
||||
* If "format" is NULL, just the error message itself is printed.
|
||||
*/
|
||||
void
|
||||
ReportError(NuError err, const char* format, ...)
|
||||
void ReportError(NuError err, const char* format, ...)
|
||||
{
|
||||
const char* msg;
|
||||
va_list args;
|
||||
|
||||
Assert(format != nil);
|
||||
Assert(format != NULL);
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
/* print the message, if any */
|
||||
if (format != nil) {
|
||||
if (format != NULL) {
|
||||
fprintf(stderr, "%s: ERROR: ", gProgName);
|
||||
vfprintf(stderr, format, args);
|
||||
}
|
||||
|
@ -36,16 +34,16 @@ ReportError(NuError err, const char* format, ...)
|
|||
if (err == kNuErrNone)
|
||||
fprintf(stderr, "\n");
|
||||
else {
|
||||
if (format != nil)
|
||||
if (format != NULL)
|
||||
fprintf(stderr, ": ");
|
||||
|
||||
msg = nil;
|
||||
msg = NULL;
|
||||
if (err >= 0)
|
||||
msg = strerror(err);
|
||||
if (msg == nil)
|
||||
if (msg == NULL)
|
||||
msg = NuStrError(err);
|
||||
|
||||
if (msg == nil)
|
||||
if (msg == NULL)
|
||||
fprintf(stderr, "(unknown err=%d)\n", err);
|
||||
else
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
|
@ -62,48 +60,44 @@ ReportError(NuError err, const char* format, ...)
|
|||
*/
|
||||
|
||||
#ifndef USE_DMALLOC
|
||||
void*
|
||||
Malloc(size_t size)
|
||||
void* Malloc(size_t size)
|
||||
{
|
||||
void* _result;
|
||||
|
||||
Assert(size > 0);
|
||||
_result = malloc(size);
|
||||
if (_result == nil) {
|
||||
ReportError(kNuErrMalloc, "malloc(%u) failed", (uint) size);
|
||||
if (_result == NULL) {
|
||||
ReportError(kNuErrMalloc, "malloc(%u) failed", (unsigned int) size);
|
||||
DebugAbort(); /* leave a core dump if we're built for it */
|
||||
}
|
||||
DebugFill(_result, size);
|
||||
return _result;
|
||||
}
|
||||
|
||||
void*
|
||||
Calloc(size_t size)
|
||||
void* Calloc(size_t size)
|
||||
{
|
||||
void* _cresult = Malloc(size);
|
||||
memset(_cresult, 0, size);
|
||||
return _cresult;
|
||||
}
|
||||
|
||||
void*
|
||||
Realloc(void* ptr, size_t size)
|
||||
void* Realloc(void* ptr, size_t size)
|
||||
{
|
||||
void* _result;
|
||||
|
||||
Assert(ptr != nil); /* disallow this usage */
|
||||
Assert(ptr != NULL); /* disallow this usage */
|
||||
Assert(size > 0); /* disallow this usage */
|
||||
_result = realloc(ptr, size);
|
||||
if (_result == nil) {
|
||||
ReportError(kNuErrMalloc, "realloc(%u) failed", (uint) size);
|
||||
if (_result == NULL) {
|
||||
ReportError(kNuErrMalloc, "realloc(%u) failed", (unsigned int) size);
|
||||
DebugAbort(); /* leave a core dump if we're built for it */
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
|
||||
void
|
||||
Free(void* ptr)
|
||||
void Free(void* ptr)
|
||||
{
|
||||
if (ptr != nil)
|
||||
if (ptr != NULL)
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
@ -111,11 +105,34 @@ Free(void* ptr)
|
|||
/*
|
||||
* This gets called when a buffer DataSource is no longer needed.
|
||||
*/
|
||||
NuResult
|
||||
FreeCallback(NuArchive* pArchive, void* args)
|
||||
NuResult FreeCallback(NuArchive* pArchive, void* args)
|
||||
{
|
||||
DBUG(("+++ free callback 0x%08lx\n", (long) args));
|
||||
Free(args);
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert Mac OS Roman to Unicode. The caller must free the string
|
||||
* returned.
|
||||
*
|
||||
* Returns NULL if stringMOR is NULL or if the conversion fails.
|
||||
*/
|
||||
UNICHAR* CopyMORToUNI(const char* stringMOR)
|
||||
{
|
||||
size_t uniLen;
|
||||
UNICHAR* uniBuf;
|
||||
|
||||
if (stringMOR == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uniLen = NuConvertMORToUNI(stringMOR, NULL, 0);
|
||||
if (uniLen == (size_t) -1) {
|
||||
return NULL;
|
||||
}
|
||||
uniBuf = (UNICHAR*) malloc(uniLen);
|
||||
NuConvertMORToUNI(stringMOR, uniBuf, uniLen);
|
||||
return uniBuf;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*/
|
||||
#ifndef __Nulib2__
|
||||
#define __Nulib2__
|
||||
#ifndef NULIB2_NULIB2_H
|
||||
#define NULIB2_NULIB2_H
|
||||
|
||||
#include "SysDefs.h" /* system-dependent defs; must come first */
|
||||
#include <NufxLib.h>
|
||||
|
@ -42,7 +42,7 @@ Boolean IsFilenameStdin(const char* archiveName);
|
|||
Boolean IsSpecified(NulibState* pState, const NuRecord* pRecord);
|
||||
NuError OpenArchiveReadOnly(NulibState* pState);
|
||||
NuError OpenArchiveReadWrite(NulibState* pState);
|
||||
const NuThread* GetThread(const NuRecord* pRecord, ulong idx);
|
||||
const NuThread* GetThread(const NuRecord* pRecord, uint32_t idx);
|
||||
Boolean IsRecordReadOnly(const NuRecord* pRecord);
|
||||
|
||||
/* Binary2.c */
|
||||
|
@ -61,12 +61,12 @@ NuError DoExtractToPipe(NulibState* pState);
|
|||
NuError DoTest(NulibState* pState);
|
||||
|
||||
/* Filename.c */
|
||||
const char* GetFileTypeString(ulong fileType);
|
||||
const char* GetFileTypeString(uint32_t fileType);
|
||||
const char* NormalizePath(NulibState* pState, NuPathnameProposal* pathProposal);
|
||||
void InterpretExtension(NulibState* pState, const char* pathName,
|
||||
ulong* pFileType, ulong* pAuxType);
|
||||
uint32_t* pFileType, uint32_t* pAuxType);
|
||||
Boolean ExtractPreservationString(NulibState* pState, char* pathname,
|
||||
ulong* pFileType, ulong* pAuxType, NuThreadID* pThreadID);
|
||||
uint32_t* pFileType, uint32_t* pAuxType, NuThreadID* pThreadID);
|
||||
void DenormalizePath(NulibState* pState, char* pathBuf);
|
||||
const char* FilenameOnly(NulibState* pState, const char* pathname);
|
||||
const char* FindExtension(NulibState* pState, const char* pathname);
|
||||
|
@ -90,7 +90,7 @@ void ReportError(NuError err, const char* format, ...)
|
|||
# define Malloc(size) malloc(size)
|
||||
# define Calloc(size) calloc(1, size)
|
||||
# define Realloc(ptr, size) realloc(ptr, size)
|
||||
# define Free(ptr) (ptr != nil ? free(ptr) : (void)0)
|
||||
# define Free(ptr) (ptr != NULL ? free(ptr) : (void)0)
|
||||
#else
|
||||
void* Malloc(size_t size);
|
||||
void* Calloc(size_t size);
|
||||
|
@ -98,6 +98,7 @@ void* Realloc(void* ptr, size_t size);
|
|||
void Free(void* ptr);
|
||||
#endif
|
||||
NuResult FreeCallback(NuArchive* pArchive, void* args);
|
||||
UNICHAR* CopyMORToUNI(const char* stringMOR);
|
||||
|
||||
/* SysUtils.c */
|
||||
NuError NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
||||
|
@ -105,9 +106,10 @@ NuError NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
|||
NuError NormalizeDirectoryName(NulibState* pState, const char* srcp,
|
||||
long srcLen, char fssep, char** pDstp, long dstLen);
|
||||
char* MakeTempArchiveName(NulibState* pState);
|
||||
NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux);
|
||||
NuError AddFile(NulibState* pState, NuArchive* pArchive,
|
||||
const char* pathname);
|
||||
NuError Mkdir(const char* dir);
|
||||
NuError TestFileExistence(const char* fileName, Boolean* pIsDir);
|
||||
|
||||
#endif /*__Nulib2__*/
|
||||
#endif /*NULIB2_NULIB2_H*/
|
|
@ -1,9 +1,9 @@
|
|||
NuLib2 README, updated 2004/03/10
|
||||
NuLib2 README, updated 2015/01/03
|
||||
http://www.nulib.com/
|
||||
|
||||
|
||||
To build NuLib2, you will also need a copy of NufxLib. This may have come
|
||||
in the same .tar.gz file. Build the nufxlib library first.
|
||||
To build NuLib2, you will also need a copy of NufxLib. This should have come
|
||||
in the same distribution file. Build the NufxLib library first.
|
||||
|
||||
|
||||
UNIX
|
||||
|
@ -59,10 +59,10 @@ If you're using BeOS/PPC, it will also do:
|
|||
Mac OS X
|
||||
========
|
||||
|
||||
This works just like the UNIX version. You'll see some warnings due to some
|
||||
namespace collisions between nufxlib and Carbon, but everything will work
|
||||
fine. The Carbon framework is used to enable support for filetypes and
|
||||
resource forks.
|
||||
This works just like the UNIX version, but includes support for resource
|
||||
forks and Finder file/aux types.
|
||||
|
||||
Tested with Xcode v5.1.1 and Mac OS 10.8.5.
|
||||
|
||||
|
||||
Win32
|
||||
|
@ -71,23 +71,25 @@ Win32
|
|||
If you're using an environment that supports "configure" scripts, such as
|
||||
DJGPP, follow the UNIX instructions.
|
||||
|
||||
NuLib2 has been tested with Microsoft Visual C++ 6.0. To build NuLib2,
|
||||
start up a DOS shell and run vcvars32.bat to set your environment. Run:
|
||||
nmake -f makefile.msc
|
||||
to build with debugging info, or
|
||||
nmake -f makefile.msc nodebug=1
|
||||
to build optimized.
|
||||
NuLib2 has been tested with Microsoft Visual C++ 12 (Visual Studio 2013).
|
||||
To build NuLib2, run the "Visual Studio 2013 x86 Native Tools Command
|
||||
Prompt" shortcut to get a shell. Change to the nulib2 directory, then:
|
||||
|
||||
See the notes in Makefile.msc for building with zlib, libbz2, and when
|
||||
NufxLib is in a DLL.
|
||||
nmake -f makefile.msc
|
||||
|
||||
If you want to have zlib support enabled, you will need to have zlib.lib
|
||||
copied into the directory. See "makefile.msc" for more details.
|
||||
|
||||
Unicode filename support has not been ported to Windows. Non-ASCII
|
||||
characters will be interpreted as the default character set (CP1252).
|
||||
This is the way NuLib2 has always worked in Windows, but it may not
|
||||
match with the behavior of CiderPress. In any event, this only affects
|
||||
files with non-ASCII filenames.
|
||||
|
||||
|
||||
Other Notes
|
||||
===========
|
||||
|
||||
All of the source code is now formatted with spaces instead of tabs.
|
||||
|
||||
|
||||
Fun benchmark of the day:
|
||||
|
||||
Time to compress 1525 files, totaling 19942152 bytes, on an Apple IIgs
|
||||
|
@ -140,7 +142,7 @@ Legalese
|
|||
========
|
||||
|
||||
NuLib2, a NuFX and Binary II archive application.
|
||||
Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
Copyright (C) 2000-2014 by Andy McFadden, All Rights Reserved.
|
||||
|
||||
See COPYING for license.
|
||||
|
||||
|
|
223
nulib2/State.c
223
nulib2/State.c
|
@ -1,27 +1,26 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* Global-ish state object.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
|
||||
static const char* gProgramVersion = "2.2.2";
|
||||
static const char* gProgramVersion = "3.1.0";
|
||||
|
||||
|
||||
/*
|
||||
* Allocate and initialize the semi-global Nulib2 state object.
|
||||
* Allocate and initialize the semi-global NuLib2 state object.
|
||||
*/
|
||||
NuError
|
||||
NState_Init(NulibState** ppState)
|
||||
NuError NState_Init(NulibState** ppState)
|
||||
{
|
||||
Assert(ppState != nil);
|
||||
Assert(ppState != NULL);
|
||||
|
||||
*ppState = Calloc(sizeof(**ppState));
|
||||
if (*ppState == nil)
|
||||
if (*ppState == NULL)
|
||||
return kNuErrMalloc;
|
||||
|
||||
/*
|
||||
|
@ -41,8 +40,7 @@ NState_Init(NulibState** ppState)
|
|||
/*
|
||||
* A little extra initialization, performed after arguments are parsed.
|
||||
*/
|
||||
NuError
|
||||
NState_ExtraInit(NulibState* pState)
|
||||
NuError NState_ExtraInit(NulibState* pState)
|
||||
{
|
||||
NuError err;
|
||||
NuValue convertEOL;
|
||||
|
@ -74,25 +72,23 @@ NState_ExtraInit(NulibState* pState)
|
|||
/*
|
||||
* Free up the state structure and its contents.
|
||||
*/
|
||||
void
|
||||
NState_Free(NulibState* pState)
|
||||
void NState_Free(NulibState* pState)
|
||||
{
|
||||
if (pState == nil)
|
||||
if (pState == NULL)
|
||||
return;
|
||||
|
||||
Free(pState->renameToStr); /* ?? */
|
||||
Free(pState->tempPathnameBuf);
|
||||
if (pState->pPipeSink != nil)
|
||||
if (pState->pPipeSink != NULL)
|
||||
NuFreeDataSink(pState->pPipeSink);
|
||||
if (pState->pCommentSink != nil)
|
||||
if (pState->pCommentSink != NULL)
|
||||
NuFreeDataSink(pState->pCommentSink);
|
||||
Free(pState);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_MSGS
|
||||
void
|
||||
NState_DebugDump(const NulibState* pState)
|
||||
void NState_DebugDump(const NulibState* pState)
|
||||
{
|
||||
/* this table will break if the code changes, but it's just for debugging */
|
||||
static const char* kCommandNames[] = {
|
||||
|
@ -108,7 +104,7 @@ NState_DebugDump(const NulibState* pState)
|
|||
"help",
|
||||
};
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pState != NULL);
|
||||
|
||||
printf("NState:\n");
|
||||
printf(" programVersion: '%s'\n", pState->programVersion);
|
||||
|
@ -162,153 +158,131 @@ NState_DebugDump(const NulibState* pState)
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
char
|
||||
NState_GetSystemPathSeparator(const NulibState* pState)
|
||||
char NState_GetSystemPathSeparator(const NulibState* pState)
|
||||
{
|
||||
return pState->systemPathSeparator;
|
||||
}
|
||||
|
||||
char
|
||||
NState_GetAltSystemPathSeparator(const NulibState* pState)
|
||||
char NState_GetAltSystemPathSeparator(const NulibState* pState)
|
||||
{
|
||||
return pState->altSystemPathSeparator;
|
||||
}
|
||||
|
||||
const char*
|
||||
NState_GetProgramVersion(const NulibState* pState)
|
||||
const char* NState_GetProgramVersion(const NulibState* pState)
|
||||
{
|
||||
return pState->programVersion;
|
||||
}
|
||||
|
||||
NuArchive*
|
||||
NState_GetNuArchive(const NulibState* pState)
|
||||
NuArchive* NState_GetNuArchive(const NulibState* pState)
|
||||
{
|
||||
return pState->pArchive;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetNuArchive(NulibState* pState, NuArchive* pArchive)
|
||||
void NState_SetNuArchive(NulibState* pState, NuArchive* pArchive)
|
||||
{
|
||||
pState->pArchive = pArchive;
|
||||
}
|
||||
|
||||
|
||||
Boolean
|
||||
NState_GetSuppressOutput(const NulibState* pState)
|
||||
Boolean NState_GetSuppressOutput(const NulibState* pState)
|
||||
{
|
||||
return pState->suppressOutput;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetSuppressOutput(NulibState* pState, Boolean doSuppress)
|
||||
void NState_SetSuppressOutput(NulibState* pState, Boolean doSuppress)
|
||||
{
|
||||
pState->suppressOutput = doSuppress;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetInputUnavailable(const NulibState* pState)
|
||||
Boolean NState_GetInputUnavailable(const NulibState* pState)
|
||||
{
|
||||
return pState->inputUnavailable;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetInputUnavailable(NulibState* pState, Boolean isUnavailable)
|
||||
void NState_SetInputUnavailable(NulibState* pState, Boolean isUnavailable)
|
||||
{
|
||||
pState->inputUnavailable = isUnavailable;
|
||||
}
|
||||
|
||||
NuRecordIdx
|
||||
NState_GetRenameFromIdx(const NulibState* pState)
|
||||
NuRecordIdx NState_GetRenameFromIdx(const NulibState* pState)
|
||||
{
|
||||
return pState->renameFromIdx;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetRenameFromIdx(NulibState* pState, NuRecordIdx recordIdx)
|
||||
void NState_SetRenameFromIdx(NulibState* pState, NuRecordIdx recordIdx)
|
||||
{
|
||||
pState->renameFromIdx = recordIdx;
|
||||
}
|
||||
|
||||
char*
|
||||
NState_GetRenameToStr(const NulibState* pState)
|
||||
char* NState_GetRenameToStr(const NulibState* pState)
|
||||
{
|
||||
return pState->renameToStr;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetRenameToStr(NulibState* pState, char* str)
|
||||
void NState_SetRenameToStr(NulibState* pState, char* str)
|
||||
{
|
||||
Free(pState->renameToStr);
|
||||
pState->renameToStr = str;
|
||||
}
|
||||
|
||||
|
||||
NuDataSink*
|
||||
NState_GetPipeSink(const NulibState* pState)
|
||||
NuDataSink* NState_GetPipeSink(const NulibState* pState)
|
||||
{
|
||||
return pState->pPipeSink;
|
||||
}
|
||||
|
||||
NuDataSink*
|
||||
NState_GetCommentSink(const NulibState* pState)
|
||||
NuDataSink* NState_GetCommentSink(const NulibState* pState)
|
||||
{
|
||||
return pState->pCommentSink;
|
||||
}
|
||||
|
||||
long
|
||||
NState_GetMatchCount(const NulibState* pState)
|
||||
long NState_GetMatchCount(const NulibState* pState)
|
||||
{
|
||||
return pState->matchCount;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetMatchCount(NulibState* pState, long count)
|
||||
void NState_SetMatchCount(NulibState* pState, long count)
|
||||
{
|
||||
pState->matchCount = count;
|
||||
}
|
||||
|
||||
void
|
||||
NState_IncMatchCount(NulibState* pState)
|
||||
void NState_IncMatchCount(NulibState* pState)
|
||||
{
|
||||
pState->matchCount++;
|
||||
}
|
||||
|
||||
void
|
||||
NState_AddToTotals(NulibState* pState, long len, long compLen)
|
||||
void NState_AddToTotals(NulibState* pState, long len, long compLen)
|
||||
{
|
||||
pState->totalLen += len;
|
||||
pState->totalCompLen += compLen;
|
||||
}
|
||||
|
||||
void
|
||||
NState_GetTotals(NulibState* pState, long* pTotalLen, long* pTotalCompLen)
|
||||
void NState_GetTotals(NulibState* pState, long* pTotalLen, long* pTotalCompLen)
|
||||
{
|
||||
*pTotalLen = pState->totalLen;
|
||||
*pTotalCompLen = pState->totalCompLen;
|
||||
}
|
||||
|
||||
long
|
||||
NState_GetTempPathnameLen(NulibState* pState)
|
||||
long NState_GetTempPathnameLen(NulibState* pState)
|
||||
{
|
||||
return pState->tempPathnameAlloc;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetTempPathnameLen(NulibState* pState, long len)
|
||||
void NState_SetTempPathnameLen(NulibState* pState, long len)
|
||||
{
|
||||
char* newBuf;
|
||||
|
||||
len++; /* add one for the '\0' */
|
||||
|
||||
if (pState->tempPathnameAlloc < len) {
|
||||
if (pState->tempPathnameBuf == nil)
|
||||
if (pState->tempPathnameBuf == NULL)
|
||||
newBuf = Malloc(len);
|
||||
else
|
||||
newBuf = Realloc(pState->tempPathnameBuf, len);
|
||||
Assert(newBuf != nil);
|
||||
if (newBuf == nil) {
|
||||
Assert(newBuf != NULL);
|
||||
if (newBuf == NULL) {
|
||||
Free(pState->tempPathnameBuf);
|
||||
pState->tempPathnameBuf = nil;
|
||||
pState->tempPathnameBuf = NULL;
|
||||
pState->tempPathnameAlloc = 0;
|
||||
ReportError(kNuErrMalloc, "buf realloc failed (%ld)", len);
|
||||
return;
|
||||
|
@ -319,237 +293,198 @@ NState_SetTempPathnameLen(NulibState* pState, long len)
|
|||
}
|
||||
}
|
||||
|
||||
char*
|
||||
NState_GetTempPathnameBuf(NulibState* pState)
|
||||
char* NState_GetTempPathnameBuf(NulibState* pState)
|
||||
{
|
||||
return pState->tempPathnameBuf;
|
||||
}
|
||||
|
||||
|
||||
Command
|
||||
NState_GetCommand(const NulibState* pState)
|
||||
Command NState_GetCommand(const NulibState* pState)
|
||||
{
|
||||
return pState->command;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetCommand(NulibState* pState, Command cmd)
|
||||
void NState_SetCommand(NulibState* pState, Command cmd)
|
||||
{
|
||||
pState->command = cmd;
|
||||
}
|
||||
|
||||
const char*
|
||||
NState_GetArchiveFilename(const NulibState* pState)
|
||||
const char* NState_GetArchiveFilename(const NulibState* pState)
|
||||
{
|
||||
return pState->archiveFilename;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetArchiveFilename(NulibState* pState, const char* archiveFilename)
|
||||
void NState_SetArchiveFilename(NulibState* pState, const char* archiveFilename)
|
||||
{
|
||||
pState->archiveFilename = archiveFilename;
|
||||
}
|
||||
|
||||
char* const*
|
||||
NState_GetFilespecPointer(const NulibState* pState)
|
||||
char* const* NState_GetFilespecPointer(const NulibState* pState)
|
||||
{
|
||||
return pState->filespecPointer;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetFilespecPointer(NulibState* pState, char* const* filespecPointer)
|
||||
void NState_SetFilespecPointer(NulibState* pState, char* const* filespecPointer)
|
||||
{
|
||||
pState->filespecPointer = filespecPointer;
|
||||
}
|
||||
|
||||
long
|
||||
NState_GetFilespecCount(const NulibState* pState)
|
||||
long NState_GetFilespecCount(const NulibState* pState)
|
||||
{
|
||||
return pState->filespecCount;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetFilespecCount(NulibState* pState, long filespecCount)
|
||||
void NState_SetFilespecCount(NulibState* pState, long filespecCount)
|
||||
{
|
||||
pState->filespecCount = filespecCount;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModUpdate(const NulibState* pState)
|
||||
Boolean NState_GetModUpdate(const NulibState* pState)
|
||||
{
|
||||
return pState->modUpdate;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModUpdate(NulibState* pState, Boolean val)
|
||||
void NState_SetModUpdate(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modUpdate = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModFreshen(const NulibState* pState)
|
||||
Boolean NState_GetModFreshen(const NulibState* pState)
|
||||
{
|
||||
return pState->modFreshen;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModFreshen(NulibState* pState, Boolean val)
|
||||
void NState_SetModFreshen(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modFreshen = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModRecurse(const NulibState* pState)
|
||||
Boolean NState_GetModRecurse(const NulibState* pState)
|
||||
{
|
||||
return pState->modRecurse;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModRecurse(NulibState* pState, Boolean val)
|
||||
void NState_SetModRecurse(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modRecurse = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModJunkPaths(const NulibState* pState)
|
||||
Boolean NState_GetModJunkPaths(const NulibState* pState)
|
||||
{
|
||||
return pState->modJunkPaths;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModJunkPaths(NulibState* pState, Boolean val)
|
||||
void NState_SetModJunkPaths(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modJunkPaths = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModNoCompression(const NulibState* pState)
|
||||
Boolean NState_GetModNoCompression(const NulibState* pState)
|
||||
{
|
||||
return pState->modNoCompression;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModNoCompression(NulibState* pState, Boolean val)
|
||||
void NState_SetModNoCompression(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modNoCompression = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModCompressDeflate(const NulibState* pState)
|
||||
Boolean NState_GetModCompressDeflate(const NulibState* pState)
|
||||
{
|
||||
return pState->modCompressDeflate;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModCompressDeflate(NulibState* pState, Boolean val)
|
||||
void NState_SetModCompressDeflate(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modCompressDeflate = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModCompressBzip2(const NulibState* pState)
|
||||
Boolean NState_GetModCompressBzip2(const NulibState* pState)
|
||||
{
|
||||
return pState->modCompressBzip2;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModCompressBzip2(NulibState* pState, Boolean val)
|
||||
void NState_SetModCompressBzip2(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modCompressBzip2 = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModComments(const NulibState* pState)
|
||||
Boolean NState_GetModComments(const NulibState* pState)
|
||||
{
|
||||
return pState->modComments;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModComments(NulibState* pState, Boolean val)
|
||||
void NState_SetModComments(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modComments = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModBinaryII(const NulibState* pState)
|
||||
Boolean NState_GetModBinaryII(const NulibState* pState)
|
||||
{
|
||||
return pState->modBinaryII;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModBinaryII(NulibState* pState, Boolean val)
|
||||
void NState_SetModBinaryII(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modBinaryII = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModConvertText(const NulibState* pState)
|
||||
Boolean NState_GetModConvertText(const NulibState* pState)
|
||||
{
|
||||
return pState->modConvertText;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModConvertText(NulibState* pState, Boolean val)
|
||||
void NState_SetModConvertText(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modConvertText = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModConvertAll(const NulibState* pState)
|
||||
Boolean NState_GetModConvertAll(const NulibState* pState)
|
||||
{
|
||||
return pState->modConvertAll;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModConvertAll(NulibState* pState, Boolean val)
|
||||
void NState_SetModConvertAll(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modConvertAll = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModOverwriteExisting(const NulibState* pState)
|
||||
Boolean NState_GetModOverwriteExisting(const NulibState* pState)
|
||||
{
|
||||
return pState->modOverwriteExisting;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModOverwriteExisting(NulibState* pState, Boolean val)
|
||||
void NState_SetModOverwriteExisting(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modOverwriteExisting = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModAddAsDisk(const NulibState* pState)
|
||||
Boolean NState_GetModAddAsDisk(const NulibState* pState)
|
||||
{
|
||||
return pState->modAddAsDisk;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModAddAsDisk(NulibState* pState, Boolean val)
|
||||
void NState_SetModAddAsDisk(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modAddAsDisk = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModPreserveType(const NulibState* pState)
|
||||
Boolean NState_GetModPreserveType(const NulibState* pState)
|
||||
{
|
||||
return pState->modPreserveType;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModPreserveType(NulibState* pState, Boolean val)
|
||||
void NState_SetModPreserveType(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modPreserveType = val;
|
||||
}
|
||||
|
||||
Boolean
|
||||
NState_GetModPreserveTypeExtended(const NulibState* pState)
|
||||
Boolean NState_GetModPreserveTypeExtended(const NulibState* pState)
|
||||
{
|
||||
return pState->modPreserveTypeExtended;
|
||||
}
|
||||
|
||||
void
|
||||
NState_SetModPreserveTypeExtended(NulibState* pState, Boolean val)
|
||||
void NState_SetModPreserveTypeExtended(NulibState* pState, Boolean val)
|
||||
{
|
||||
pState->modPreserveTypeExtended = val;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*/
|
||||
#ifndef __State__
|
||||
#define __State__
|
||||
#ifndef NULIB2_STATE_H
|
||||
#define NULIB2_STATE_H
|
||||
|
||||
#include "MiscStuff.h"
|
||||
#include "NufxLib.h"
|
||||
|
||||
/*
|
||||
* Things you can tell Nulib2 to do.
|
||||
* Things you can tell NuLib2 to do.
|
||||
*
|
||||
* (Some debug code in NState_DebugDump() is sensitive to the order here.)
|
||||
*/
|
||||
|
@ -154,4 +154,4 @@ void NState_SetModPreserveType(NulibState* pState, Boolean val);
|
|||
Boolean NState_GetModPreserveTypeExtended(const NulibState* pState);
|
||||
void NState_SetModPreserveTypeExtended(NulibState* pState, Boolean val);
|
||||
|
||||
#endif /*__State__*/
|
||||
#endif /*NULIB2_STATE_H*/
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING-LIB.
|
||||
*
|
||||
* This file was adapted from Devin Reade's "sunos4.h" in NuLib 3.2.5.
|
||||
* It is provided for compilation under SunOS 4.x, when an ANSI compiler
|
||||
* (such as gcc) is used. The system header files aren't quite sufficient
|
||||
* to eliminate hordes of warnings.
|
||||
*/
|
||||
#ifndef __SunOS4__
|
||||
#define __SunOS4__
|
||||
|
||||
#ifdef __GNUC__
|
||||
extern int _flsbuf(int, FILE*);
|
||||
extern int _filbuf(FILE*);
|
||||
#endif
|
||||
|
||||
extern void bcopy(char*, char*, int);
|
||||
extern int fclose(FILE*);
|
||||
extern int fflush(FILE*);
|
||||
extern int fprintf(FILE*, const char*, ...);
|
||||
extern int fread(char*, int, int, FILE *);
|
||||
extern int fseek(FILE*, long, int);
|
||||
extern int ftruncate(int, off_t);
|
||||
extern int fwrite(const char*, int, int, FILE*);
|
||||
extern char* mktemp(char *template);
|
||||
extern time_t mktime(struct tm*);
|
||||
extern int perror(const char*);
|
||||
extern int printf(const char*, ...);
|
||||
extern int remove(const char*);
|
||||
extern int rename(const char*, const char*);
|
||||
extern int tolower(int);
|
||||
extern int setvbuf(FILE*, char*, int, int);
|
||||
extern int sscanf(char*, const char*, ...);
|
||||
extern int strcasecmp(const char*, const char*);
|
||||
extern int strncasecmp(const char*, const char*, size_t);
|
||||
extern long strtol(const char *, char **, int);
|
||||
extern int system(const char*);
|
||||
extern time_t timelocal(struct tm*);
|
||||
extern time_t time(time_t*);
|
||||
extern int toupper(int);
|
||||
extern int vfprintf(FILE*, const char *, va_list);
|
||||
extern char* vsprintf(char *str, const char *format, va_list ap);
|
||||
|
||||
#endif /*__SunOS4__*/
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* This was adapted from gzip's "tailor.h" and NuLib's "nudefs.h".
|
||||
*/
|
||||
#ifndef __SysDefs__
|
||||
#define __SysDefs__
|
||||
#ifndef NULIB2_SYSDEFS_H
|
||||
#define NULIB2_SYSDEFS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
|
@ -18,6 +18,7 @@
|
|||
#endif
|
||||
|
||||
/* these should exist everywhere */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
@ -55,10 +56,6 @@
|
|||
# define SNPRINTF_DECLARED
|
||||
# define VSNPRINTF_DECLARED
|
||||
# define SPRINTF_RETURNS_INT
|
||||
# define uchar unsigned char
|
||||
# define ushort unsigned short
|
||||
# define uint unsigned int
|
||||
# define ulong unsigned long
|
||||
# define inline /*Visual C++6.0 can't inline ".c" files*/
|
||||
# define mode_t int
|
||||
# endif
|
||||
|
@ -67,8 +64,10 @@
|
|||
# include <direct.h>
|
||||
# define FOPEN_WANTS_B
|
||||
# define HAVE_CHSIZE
|
||||
# define snprintf _snprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# if _MSC_VER < 1900 /* no snprintf until Visual Studio 2015 */
|
||||
# define snprintf _snprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -177,6 +176,16 @@
|
|||
# define SYSTEM_DEFAULT_EOL "\r"
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__) /* OS X */
|
||||
# define MAC_LIKE
|
||||
# define UNIX_LIKE
|
||||
#endif
|
||||
|
||||
/* not currently using filesystem resource forks */
|
||||
//#if defined(__ORCAC__) || defined(MAC_LIKE)
|
||||
//# define HAS_RESOURCE_FORKS
|
||||
//#endif
|
||||
|
||||
#if defined(APW) || defined(__ORCAC__)
|
||||
# define __appleiigs__
|
||||
# pragma lint -1
|
||||
|
@ -195,10 +204,6 @@
|
|||
# define HAS__FUNCTION__
|
||||
#endif
|
||||
|
||||
#if defined(__sun__) && !defined(__SVR4)
|
||||
# include "SunOS4.h"
|
||||
#endif
|
||||
|
||||
/* general defaults, mainly for UNIX */
|
||||
|
||||
#ifndef PATH_SEP
|
||||
|
@ -211,4 +216,4 @@
|
|||
# define MAX_PATH_LEN 1024
|
||||
#endif
|
||||
|
||||
#endif /*__SysDefs__*/
|
||||
#endif /*NULIB2_SYSDEFS_H*/
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
/*
|
||||
* Nulib2
|
||||
* NuLib2
|
||||
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the BSD License, see the file COPYING.
|
||||
*
|
||||
* System-dependent utility functions.
|
||||
*/
|
||||
#include "Nulib2.h"
|
||||
#include "NuLib2.h"
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#ifdef MAC_LIKE
|
||||
# include <sys/xattr.h>
|
||||
#endif
|
||||
|
||||
/* get a grip on this opendir/readdir stuff */
|
||||
#if defined(UNIX_LIKE)
|
||||
|
@ -60,6 +63,7 @@
|
|||
* ===========================================================================
|
||||
*/
|
||||
|
||||
// 20150103: this makes me nervous
|
||||
#define kTempFileNameLen 20
|
||||
|
||||
|
||||
|
@ -71,9 +75,8 @@
|
|||
* as well just let the filesystem truncate if it gets too long, rather
|
||||
* than worry about truncating it cleverly.
|
||||
*/
|
||||
static NuError
|
||||
UNIXNormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
||||
char fssep, char** pDstp, long dstLen)
|
||||
static NuError UNIXNormalizeFileName(NulibState* pState, const char* srcp,
|
||||
long srcLen, char fssep, char** pDstp, long dstLen)
|
||||
{
|
||||
char* dstp = *pDstp;
|
||||
|
||||
|
@ -121,18 +124,17 @@ UNIXNormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
|||
* The list comes from the Linux kernel's fs/msdos/namei.c.
|
||||
*/
|
||||
static const char* fatReservedNames3[] = {
|
||||
"CON", "PRN", "NUL", "AUX", nil
|
||||
"CON", "PRN", "NUL", "AUX", NULL
|
||||
};
|
||||
static const char* fatReservedNames4[] = {
|
||||
"LPT1", "LPT2", "LPT3", "LPT4", "COM1", "COM2", "COM3", "COM4", nil
|
||||
"LPT1", "LPT2", "LPT3", "LPT4", "COM1", "COM2", "COM3", "COM4", NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Filename normalization for Win32 filesystems. You can't use [ \/:*?"<>| ].
|
||||
*/
|
||||
static NuError
|
||||
Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
||||
char fssep, char** pDstp, long dstLen)
|
||||
static NuError Win32NormalizeFileName(NulibState* pState, const char* srcp,
|
||||
long srcLen, char fssep, char** pDstp, long dstLen)
|
||||
{
|
||||
char* dstp = *pDstp;
|
||||
const char* startp = srcp;
|
||||
|
@ -142,7 +144,7 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
|||
if (srcLen >= 3) {
|
||||
const char** ppcch;
|
||||
|
||||
for (ppcch = fatReservedNames3; *ppcch != nil; ppcch++) {
|
||||
for (ppcch = fatReservedNames3; *ppcch != NULL; ppcch++) {
|
||||
if (strncasecmp(srcp, *ppcch, 3) == 0 &&
|
||||
srcp[3] == '.' || srcLen == 3)
|
||||
{
|
||||
|
@ -160,7 +162,7 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
|||
if (srcLen >= 4) {
|
||||
const char** ppcch;
|
||||
|
||||
for (ppcch = fatReservedNames4; *ppcch != nil; ppcch++) {
|
||||
for (ppcch = fatReservedNames4; *ppcch != NULL; ppcch++) {
|
||||
if (strncasecmp(srcp, *ppcch, 4) == 0 &&
|
||||
srcp[4] == '.' || srcLen == 4)
|
||||
{
|
||||
|
@ -185,7 +187,7 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
|||
if (NState_GetModPreserveType(pState))
|
||||
*dstp++ = *srcp;
|
||||
*dstp++ = *srcp++;
|
||||
} else if (strchr(kInvalid, *srcp) != nil) {
|
||||
} else if (strchr(kInvalid, *srcp) != NULL) {
|
||||
/* change invalid char to "%2f" or '_' */
|
||||
if (NState_GetModPreserveType(pState)) {
|
||||
*dstp++ = kForeignIndic;
|
||||
|
@ -219,17 +221,16 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
|||
*
|
||||
* The output buffer must be able to hold 3x the original string length.
|
||||
*/
|
||||
NuError
|
||||
NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
||||
NuError NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
||||
char fssep, char** pDstp, long dstLen)
|
||||
{
|
||||
NuError err;
|
||||
|
||||
Assert(srcp != nil);
|
||||
Assert(srcp != NULL);
|
||||
Assert(srcLen > 0);
|
||||
Assert(dstLen > srcLen);
|
||||
Assert(pDstp != nil);
|
||||
Assert(*pDstp != nil);
|
||||
Assert(pDstp != NULL);
|
||||
Assert(*pDstp != NULL);
|
||||
Assert(fssep > ' ' && fssep < 0x7f);
|
||||
|
||||
#if defined(UNIX_LIKE)
|
||||
|
@ -247,9 +248,8 @@ NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
|
|||
/*
|
||||
* Normalize a directory name to local filesystem conventions.
|
||||
*/
|
||||
NuError
|
||||
NormalizeDirectoryName(NulibState* pState, const char* srcp, long srcLen,
|
||||
char fssep, char** pDstp, long dstLen)
|
||||
NuError NormalizeDirectoryName(NulibState* pState, const char* srcp,
|
||||
long srcLen, char fssep, char** pDstp, long dstLen)
|
||||
{
|
||||
/* in general, directories and filenames are the same */
|
||||
return NormalizeFileName(pState, srcp, srcLen, fssep, pDstp, dstLen);
|
||||
|
@ -265,19 +265,18 @@ NormalizeDirectoryName(NulibState* pState, const char* srcp, long srcLen,
|
|||
* under GS/OS it has to be in the same directory. Not sure what Mac OS
|
||||
* or Windows requires, so it's safest to just put it in the same dir.
|
||||
*/
|
||||
char*
|
||||
MakeTempArchiveName(NulibState* pState)
|
||||
char* MakeTempArchiveName(NulibState* pState)
|
||||
{
|
||||
const char* archivePathname;
|
||||
char fssep;
|
||||
const char* nameStart;
|
||||
char* newName = nil;
|
||||
char* newName = NULL;
|
||||
char* namePtr;
|
||||
char* resultName = nil;
|
||||
char* resultName = NULL;
|
||||
long len;
|
||||
|
||||
archivePathname = NState_GetArchiveFilename(pState);
|
||||
Assert(archivePathname != nil);
|
||||
Assert(archivePathname != NULL);
|
||||
fssep = NState_GetSystemPathSeparator(pState);
|
||||
Assert(fssep != 0);
|
||||
|
||||
|
@ -292,7 +291,7 @@ MakeTempArchiveName(NulibState* pState)
|
|||
|
||||
/* figure out where the filename ends */
|
||||
nameStart = strrchr(archivePathname, fssep);
|
||||
if (nameStart == nil) {
|
||||
if (nameStart == NULL) {
|
||||
/* nothing but a filename */
|
||||
newName = Malloc(kTempFileNameLen +1);
|
||||
namePtr = newName;
|
||||
|
@ -302,7 +301,7 @@ MakeTempArchiveName(NulibState* pState)
|
|||
strcpy(newName, archivePathname);
|
||||
namePtr = newName + (nameStart - archivePathname);
|
||||
}
|
||||
if (newName == nil)
|
||||
if (newName == NULL)
|
||||
goto bail;
|
||||
|
||||
/*
|
||||
|
@ -313,7 +312,7 @@ MakeTempArchiveName(NulibState* pState)
|
|||
resultName = newName;
|
||||
|
||||
bail:
|
||||
if (resultName == nil)
|
||||
if (resultName == NULL)
|
||||
Free(newName);
|
||||
return resultName;
|
||||
}
|
||||
|
@ -353,17 +352,16 @@ bail:
|
|||
*
|
||||
* [ Someday we may want to modify this to handle symbolic links. ]
|
||||
*/
|
||||
NuError
|
||||
CheckFileStatus(const char* pathname, struct stat* psb, Boolean* pExists,
|
||||
Boolean* pIsReadable, Boolean* pIsDir)
|
||||
NuError CheckFileStatus(const char* pathname, struct stat* psb,
|
||||
Boolean* pExists, Boolean* pIsReadable, Boolean* pIsDir)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
int cc;
|
||||
|
||||
Assert(pathname != nil);
|
||||
Assert(pExists != nil);
|
||||
Assert(pIsReadable != nil);
|
||||
Assert(pIsDir != nil);
|
||||
Assert(pathname != NULL);
|
||||
Assert(pExists != NULL);
|
||||
Assert(pIsReadable != NULL);
|
||||
Assert(pIsDir != NULL);
|
||||
|
||||
*pExists = true;
|
||||
*pIsReadable = true;
|
||||
|
@ -398,13 +396,12 @@ bail:
|
|||
/*
|
||||
* Convert from time in seconds to DateTime format.
|
||||
*/
|
||||
static void
|
||||
UNIXTimeToDateTime(const time_t* pWhen, NuDateTime *pDateTime)
|
||||
static void UNIXTimeToDateTime(const time_t* pWhen, NuDateTime *pDateTime)
|
||||
{
|
||||
struct tm* ptm;
|
||||
|
||||
Assert(pWhen != nil);
|
||||
Assert(pDateTime != nil);
|
||||
Assert(pWhen != NULL);
|
||||
Assert(pDateTime != NULL);
|
||||
|
||||
ptm = localtime(pWhen);
|
||||
pDateTime->second = ptm->tm_sec;
|
||||
|
@ -418,13 +415,187 @@ UNIXTimeToDateTime(const time_t* pWhen, NuDateTime *pDateTime)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(MAC_LIKE)
|
||||
/*
|
||||
* Due to historical reasons, the XATTR_FINDERINFO_NAME (defined to be
|
||||
* ``com.apple.FinderInfo'') extended attribute must be 32 bytes; see the
|
||||
* ATTR_CMN_FNDRINFO section in getattrlist(2).
|
||||
*
|
||||
* The FinderInfo block is the concatenation of a FileInfo structure
|
||||
* and an ExtendedFileInfo (or ExtendedFolderInfo) structure -- see
|
||||
* ATTR_CMN_FNDRINFO in getattrlist(2).
|
||||
*
|
||||
* All we're really interested in is the file type and creator code,
|
||||
* which are stored big-endian in the first 8 bytes.
|
||||
*/
|
||||
static const int kFinderInfoSize = 32;
|
||||
|
||||
/*
|
||||
* Obtains the creator and file type from the Finder info block, if any,
|
||||
* and converts the types to ProDOS equivalents.
|
||||
*
|
||||
* If the attribute doesn't exist, this returns an error without modifying
|
||||
* the output args.
|
||||
*/
|
||||
static NuError GetTypesFromFinder(const char* pathnameUNI, uint32_t* pFileType,
|
||||
uint32_t* pAuxType)
|
||||
{
|
||||
uint8_t fiBuf[kFinderInfoSize];
|
||||
|
||||
size_t actual = getxattr(pathnameUNI, XATTR_FINDERINFO_NAME,
|
||||
fiBuf, sizeof(fiBuf), 0, 0);
|
||||
if (actual != kFinderInfoSize) {
|
||||
return kNuErrNotFound;
|
||||
}
|
||||
|
||||
uint32_t fileType, creator;
|
||||
fileType = (fiBuf[0] << 24) | (fiBuf[1] << 16) | (fiBuf[2] << 8) |
|
||||
fiBuf[3];
|
||||
creator = (fiBuf[4] << 24) | (fiBuf[5] << 16) | (fiBuf[6] << 8) |
|
||||
fiBuf[7];
|
||||
|
||||
Boolean found = false;
|
||||
uint8_t proType;
|
||||
uint16_t proAux;
|
||||
|
||||
/*
|
||||
* Convert to ProDOS file/aux type.
|
||||
*/
|
||||
if (creator == 'pdos') {
|
||||
/*
|
||||
* TODO: handle conversion from 'pdos'/'XY ' to $XY/$0000.
|
||||
* I think this conversion was deprecated and not widely used;
|
||||
* the inability to retain the aux type renders it inapplicable
|
||||
* to many files.
|
||||
*/
|
||||
if (fileType == 'PSYS') {
|
||||
proType = 0xFF; // SYS
|
||||
proAux = 0x0000;
|
||||
found = true;
|
||||
} else if (fileType == 'PS16') {
|
||||
proType = 0xB3; // S16
|
||||
proAux = 0x0000;
|
||||
found = true;
|
||||
} else {
|
||||
if (((fileType >> 24) & 0xFF) == 'p') {
|
||||
proType = (fileType >> 16) & 0xFF;
|
||||
proAux = (uint16_t) fileType;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
} else if (creator == 'dCpy') {
|
||||
if (fileType == 'dImg') {
|
||||
proType = 0xE0; // LBR
|
||||
proAux = 0x0005;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
switch (fileType) {
|
||||
case 'BINA':
|
||||
proType = 0x06; // BIN
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'TEXT':
|
||||
proType = 0x04; // TXT
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'MIDI':
|
||||
proType = 0xD7; // MDI
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'AIFF':
|
||||
proType = 0xD8; // SND
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
case 'AIFC':
|
||||
proType = 0xD8; // SND
|
||||
proAux = 0x0001;
|
||||
break;
|
||||
default:
|
||||
proType = 0x00; // NON
|
||||
proAux = 0x0000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*pFileType = proType;
|
||||
*pAuxType = proAux;
|
||||
return kNuErrNone;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the file type and creator type, based on the ProDOS file type
|
||||
* and aux type.
|
||||
*
|
||||
* This is a clone of the function in NufxLib; it exists for the
|
||||
* benefit of the Binary ][ code.
|
||||
*/
|
||||
NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux)
|
||||
{
|
||||
uint8_t fiBuf[kFinderInfoSize];
|
||||
|
||||
size_t actual = fgetxattr(fd, XATTR_FINDERINFO_NAME,
|
||||
fiBuf, sizeof(fiBuf), 0, 0);
|
||||
if (actual == (size_t) -1 && errno == ENOATTR) {
|
||||
// doesn't yet have Finder info
|
||||
memset(fiBuf, 0, sizeof(fiBuf));
|
||||
} else if (actual != kFinderInfoSize) {
|
||||
return kNuErrFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to use one of the convenience types. If nothing matches,
|
||||
* use the generic pdos/pXYZ approach. Note that PSYS/PS16 will
|
||||
* lose the file's aux type.
|
||||
*
|
||||
* I'm told this is from page 336 of _Programmer's Reference for
|
||||
* System 6.0_.
|
||||
*/
|
||||
uint8_t* fileTypeBuf = fiBuf;
|
||||
uint8_t* creatorBuf = fiBuf + 4;
|
||||
|
||||
memcpy(creatorBuf, "pdos", 4);
|
||||
if (proType == 0x00 && proAux == 0x0000) {
|
||||
memcpy(fileTypeBuf, "BINA", 4);
|
||||
} else if (proType == 0x04 && proAux == 0x0000) {
|
||||
memcpy(fileTypeBuf, "TEXT", 4);
|
||||
} else if (proType == 0xff) {
|
||||
memcpy(fileTypeBuf, "PSYS", 4);
|
||||
} else if (proType == 0xb3 && (proAux & 0xff00) != 0xdb00) {
|
||||
memcpy(fileTypeBuf, "PS16", 4);
|
||||
} else if (proType == 0xd7 && proAux == 0x0000) {
|
||||
memcpy(fileTypeBuf, "MIDI", 4);
|
||||
} else if (proType == 0xd8 && proAux == 0x0000) {
|
||||
memcpy(fileTypeBuf, "AIFF", 4);
|
||||
} else if (proType == 0xd8 && proAux == 0x0001) {
|
||||
memcpy(fileTypeBuf, "AIFC", 4);
|
||||
} else if (proType == 0xe0 && proAux == 0x0005) {
|
||||
memcpy(creatorBuf, "dCpy", 4);
|
||||
memcpy(fileTypeBuf, "dImg", 4);
|
||||
} else {
|
||||
fileTypeBuf[0] = 'p';
|
||||
fileTypeBuf[1] = proType;
|
||||
fileTypeBuf[2] = (uint8_t) (proAux >> 8);
|
||||
fileTypeBuf[3] = (uint8_t) proAux;
|
||||
}
|
||||
|
||||
if (fsetxattr(fd, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
|
||||
0, 0) != 0)
|
||||
{
|
||||
return kNuErrFile;
|
||||
}
|
||||
|
||||
return kNuErrNone;
|
||||
}
|
||||
#endif /*MAC_LIKE*/
|
||||
|
||||
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
|
||||
/*
|
||||
* Replace "oldc" with "newc". If we find an instance of "newc" already
|
||||
* in the string, replace it with "newSubst".
|
||||
*/
|
||||
static void
|
||||
ReplaceFssep(char* str, char oldc, char newc, char newSubst)
|
||||
static void ReplaceFssep(char* str, char oldc, char newc, char newSubst)
|
||||
{
|
||||
while (*str != '\0') {
|
||||
if (*str == oldc)
|
||||
|
@ -439,9 +610,8 @@ ReplaceFssep(char* str, char oldc, char newc, char newSubst)
|
|||
* Set the contents of a NuFileDetails structure, based on the pathname
|
||||
* and characteristics of the file.
|
||||
*/
|
||||
static NuError
|
||||
GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
|
||||
NuFileDetails* pDetails)
|
||||
static NuError GetFileDetails(NulibState* pState, const char* pathnameMOR,
|
||||
struct stat* psb, NuFileDetails* pDetails)
|
||||
{
|
||||
Boolean wasPreserved;
|
||||
Boolean doJunk = false;
|
||||
|
@ -450,15 +620,15 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
|
|||
char slashDotDotSlash[5] = "_.._";
|
||||
time_t now;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pathname != nil);
|
||||
Assert(pDetails != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pathnameMOR != NULL);
|
||||
Assert(pDetails != NULL);
|
||||
|
||||
/* set up the pathname buffer; note pDetails->storageName is const */
|
||||
NState_SetTempPathnameLen(pState, strlen(pathname) +1);
|
||||
NState_SetTempPathnameLen(pState, strlen(pathnameMOR) +1);
|
||||
livePathStr = NState_GetTempPathnameBuf(pState);
|
||||
Assert(livePathStr != nil);
|
||||
strcpy(livePathStr, pathname);
|
||||
Assert(livePathStr != NULL);
|
||||
strcpy(livePathStr, pathnameMOR);
|
||||
|
||||
/* under Win32, both '/' and '\' work... we want to settle on one */
|
||||
if (NState_GetAltSystemPathSeparator(pState) != '\0') {
|
||||
|
@ -471,8 +641,8 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
|
|||
/* init to defaults */
|
||||
memset(pDetails, 0, sizeof(*pDetails));
|
||||
pDetails->threadID = kNuThreadIDDataFork;
|
||||
pDetails->storageName = livePathStr; /* point at temp buffer */
|
||||
pDetails->origName = nil;
|
||||
pDetails->storageNameMOR = livePathStr; /* point at temp buffer */
|
||||
pDetails->origName = NULL;
|
||||
pDetails->fileSysID = kNuFileSysUnknown;
|
||||
pDetails->fileSysInfo = kStorageFssep;
|
||||
pDetails->fileType = 0;
|
||||
|
@ -497,11 +667,20 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
|
|||
}
|
||||
}
|
||||
|
||||
now = time(nil);
|
||||
now = time(NULL);
|
||||
UNIXTimeToDateTime(&now, &pDetails->archiveWhen);
|
||||
UNIXTimeToDateTime(&psb->st_mtime, &pDetails->modWhen);
|
||||
UNIXTimeToDateTime(&psb->st_mtime, &pDetails->createWhen);
|
||||
|
||||
#ifdef MAC_LIKE
|
||||
/*
|
||||
* Retrieve the file/aux type from the Finder info. We want the
|
||||
* type-preservation string to take priority, so get this first.
|
||||
*/
|
||||
(void) GetTypesFromFinder(livePathStr,
|
||||
&pDetails->fileType, &pDetails->extraType);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for file type preservation info in the filename. If present,
|
||||
* set the file type values and truncate the filename.
|
||||
|
@ -576,7 +755,7 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
|
|||
slashDotDotSlash[0] = NState_GetSystemPathSeparator(pState);
|
||||
slashDotDotSlash[3] = NState_GetSystemPathSeparator(pState);
|
||||
if ((livePathStr[0] == '.' && livePathStr[1] == '.') ||
|
||||
(strstr(livePathStr, slashDotDotSlash) != nil))
|
||||
(strstr(livePathStr, slashDotDotSlash) != NULL))
|
||||
{
|
||||
DBUG(("Found dot dot in '%s', keeping only filename\n", livePathStr));
|
||||
doJunk = true;
|
||||
|
@ -595,7 +774,7 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
|
|||
if (NState_GetModJunkPaths(pState) || doJunk) {
|
||||
char* lastFssep;
|
||||
lastFssep = strrchr(livePathStr, NState_GetSystemPathSeparator(pState));
|
||||
if (lastFssep != nil) {
|
||||
if (lastFssep != NULL) {
|
||||
Assert(*(lastFssep+1) != '\0'); /* should already have been caught*/
|
||||
memmove(livePathStr, lastFssep+1, strlen(lastFssep+1)+1);
|
||||
}
|
||||
|
@ -621,9 +800,8 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
|
|||
* Do the system-independent part of the file add, including things like
|
||||
* adding comments.
|
||||
*/
|
||||
NuError
|
||||
DoAddFile(NulibState* pState, NuArchive* pArchive, const char* pathname,
|
||||
const NuFileDetails* pDetails)
|
||||
static NuError DoAddFile(NulibState* pState, NuArchive* pArchive,
|
||||
const char* pathname, const NuFileDetails* pDetails)
|
||||
{
|
||||
NuError err;
|
||||
NuRecordIdx recordIdx = 0;
|
||||
|
@ -665,26 +843,26 @@ DoAddFile(NulibState* pState, NuArchive* pArchive, const char* pathname,
|
|||
DBUG(("Preparing comment for recordIdx=%ld\n", recordIdx));
|
||||
Assert(recordIdx != 0);
|
||||
comment = GetSimpleComment(pState, pathname, kDefaultCommentLen);
|
||||
if (comment != nil) {
|
||||
if (comment != NULL) {
|
||||
NuDataSource* pDataSource;
|
||||
|
||||
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
|
||||
kDefaultCommentLen, (unsigned char*)comment, 0,
|
||||
kDefaultCommentLen, (uint8_t*)comment, 0,
|
||||
strlen(comment), FreeCallback, &pDataSource);
|
||||
if (err != kNuErrNone) {
|
||||
ReportError(err, "comment buffer create failed");
|
||||
Free(comment);
|
||||
err = kNuErrNone; /* oh well */
|
||||
} else {
|
||||
comment = nil; /* now owned by the data source */
|
||||
comment = NULL; /* now owned by the data source */
|
||||
err = NuAddThread(pArchive, recordIdx, kNuThreadIDComment,
|
||||
pDataSource, nil);
|
||||
pDataSource, NULL);
|
||||
if (err != kNuErrNone) {
|
||||
ReportError(err, "comment thread add failed");
|
||||
NuFreeDataSource(pDataSource);
|
||||
err = kNuErrNone; /* oh well */
|
||||
} else {
|
||||
pDataSource = nil; /* now owned by NufxLib */
|
||||
pDataSource = NULL; /* now owned by NufxLib */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -707,24 +885,24 @@ static NuError UNIXAddFile(NulibState* pState, NuArchive* pArchive,
|
|||
* If a subdirectory is found, follow it; otherwise, call UNIXAddFile to
|
||||
* add the file.
|
||||
*/
|
||||
static NuError
|
||||
UNIXAddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
|
||||
static NuError UNIXAddDirectory(NulibState* pState, NuArchive* pArchive,
|
||||
const char* dirName)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
DIR* dirp = nil;
|
||||
DIR* dirp = NULL;
|
||||
DIR_TYPE* entry;
|
||||
char nbuf[MAX_PATH_LEN]; /* malloc might be better; this soaks stack */
|
||||
char fssep;
|
||||
int len;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pArchive != nil);
|
||||
Assert(dirName != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(dirName != NULL);
|
||||
|
||||
DBUG(("+++ DESCEND: '%s'\n", dirName));
|
||||
|
||||
dirp = opendir(dirName);
|
||||
if (dirp == nil) {
|
||||
if (dirp == NULL) {
|
||||
if (errno == ENOTDIR)
|
||||
err = kNuErrNotDir;
|
||||
else
|
||||
|
@ -736,7 +914,7 @@ UNIXAddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
|
|||
fssep = NState_GetSystemPathSeparator(pState);
|
||||
|
||||
/* could use readdir_r, but we don't care about reentrancy here */
|
||||
while ((entry = readdir(dirp)) != nil) {
|
||||
while ((entry = readdir(dirp)) != NULL) {
|
||||
/* skip the dotsies */
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
@ -761,7 +939,7 @@ UNIXAddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
|
|||
}
|
||||
|
||||
bail:
|
||||
if (dirp != nil)
|
||||
if (dirp != NULL)
|
||||
(void)closedir(dirp);
|
||||
return err;
|
||||
}
|
||||
|
@ -775,17 +953,17 @@ bail:
|
|||
*
|
||||
* Returns with an error if the file doesn't exist or isn't readable.
|
||||
*/
|
||||
static NuError
|
||||
UNIXAddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
|
||||
static NuError UNIXAddFile(NulibState* pState, NuArchive* pArchive,
|
||||
const char* pathname)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Boolean exists, isDir, isReadable;
|
||||
NuFileDetails details;
|
||||
struct stat sb;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pathname != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pathname != NULL);
|
||||
|
||||
err = CheckFileStatus(pathname, &sb, &exists, &isReadable, &isDir);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -848,17 +1026,16 @@ static const char* kWildMatchAll = "*.*";
|
|||
/*
|
||||
* Prepare a directory for reading.
|
||||
*/
|
||||
static Win32dirent*
|
||||
OpenDir(const char* name)
|
||||
static Win32dirent* OpenDir(const char* name)
|
||||
{
|
||||
Win32dirent* dir = nil;
|
||||
char* tmpStr = nil;
|
||||
Win32dirent* dir = NULL;
|
||||
char* tmpStr = NULL;
|
||||
char* cp;
|
||||
WIN32_FIND_DATA fnd;
|
||||
|
||||
dir = Malloc(sizeof(*dir));
|
||||
tmpStr = Malloc(strlen(name) + (2 + sizeof(kWildMatchAll)));
|
||||
if (dir == nil || tmpStr == nil)
|
||||
if (dir == NULL || tmpStr == NULL)
|
||||
goto failed;
|
||||
|
||||
strcpy(tmpStr, name);
|
||||
|
@ -878,7 +1055,7 @@ OpenDir(const char* name)
|
|||
goto failed;
|
||||
|
||||
strcpy(dir->d_name, fnd.cFileName);
|
||||
dir->d_attr = (uchar) fnd.dwFileAttributes;
|
||||
dir->d_attr = (uint8_t) fnd.dwFileAttributes;
|
||||
dir->d_first = 1;
|
||||
|
||||
bail:
|
||||
|
@ -887,17 +1064,16 @@ bail:
|
|||
|
||||
failed:
|
||||
Free(dir);
|
||||
dir = nil;
|
||||
dir = NULL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get an entry from an open directory.
|
||||
*
|
||||
* Returns a nil pointer after the last entry has been read.
|
||||
* Returns a NULL pointer after the last entry has been read.
|
||||
*/
|
||||
static Win32dirent*
|
||||
ReadDir(Win32dirent* dir)
|
||||
static Win32dirent* ReadDir(Win32dirent* dir)
|
||||
{
|
||||
if (dir->d_first)
|
||||
dir->d_first = 0;
|
||||
|
@ -905,9 +1081,9 @@ ReadDir(Win32dirent* dir)
|
|||
WIN32_FIND_DATA fnd;
|
||||
|
||||
if (!FindNextFile(dir->d_hFindFile, &fnd))
|
||||
return nil;
|
||||
return NULL;
|
||||
strcpy(dir->d_name, fnd.cFileName);
|
||||
dir->d_attr = (uchar) fnd.dwFileAttributes;
|
||||
dir->d_attr = (uint8_t) fnd.dwFileAttributes;
|
||||
}
|
||||
|
||||
return dir;
|
||||
|
@ -916,10 +1092,9 @@ ReadDir(Win32dirent* dir)
|
|||
/*
|
||||
* Close a directory.
|
||||
*/
|
||||
static void
|
||||
CloseDir(Win32dirent* dir)
|
||||
static void CloseDir(Win32dirent* dir)
|
||||
{
|
||||
if (dir == nil)
|
||||
if (dir == NULL)
|
||||
return;
|
||||
|
||||
FindClose(dir->d_hFindFile);
|
||||
|
@ -939,24 +1114,24 @@ static NuError Win32AddFile(NulibState* pState, NuArchive* pArchive,
|
|||
* If a subdirectory is found, follow it; otherwise, call Win32AddFile to
|
||||
* add the file.
|
||||
*/
|
||||
static NuError
|
||||
Win32AddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
|
||||
static NuError Win32AddDirectory(NulibState* pState, NuArchive* pArchive,
|
||||
const char* dirName)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Win32dirent* dirp = nil;
|
||||
Win32dirent* dirp = NULL;
|
||||
Win32dirent* entry;
|
||||
char nbuf[MAX_PATH_LEN]; /* malloc might be better; this soaks stack */
|
||||
char fssep;
|
||||
int len;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pArchive != nil);
|
||||
Assert(dirName != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(dirName != NULL);
|
||||
|
||||
DBUG(("+++ DESCEND: '%s'\n", dirName));
|
||||
|
||||
dirp = OpenDir(dirName);
|
||||
if (dirp == nil) {
|
||||
if (dirp == NULL) {
|
||||
if (errno == ENOTDIR)
|
||||
err = kNuErrNotDir;
|
||||
else
|
||||
|
@ -968,7 +1143,7 @@ Win32AddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
|
|||
fssep = NState_GetSystemPathSeparator(pState);
|
||||
|
||||
/* could use readdir_r, but we don't care about reentrancy here */
|
||||
while ((entry = ReadDir(dirp)) != nil) {
|
||||
while ((entry = ReadDir(dirp)) != NULL) {
|
||||
/* skip the dotsies */
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
@ -993,7 +1168,7 @@ Win32AddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
|
|||
}
|
||||
|
||||
bail:
|
||||
if (dirp != nil)
|
||||
if (dirp != NULL)
|
||||
(void)CloseDir(dirp);
|
||||
return err;
|
||||
}
|
||||
|
@ -1005,17 +1180,17 @@ bail:
|
|||
*
|
||||
* Returns with an error if the file doesn't exist or isn't readable.
|
||||
*/
|
||||
static NuError
|
||||
Win32AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
|
||||
static NuError Win32AddFile(NulibState* pState, NuArchive* pArchive,
|
||||
const char* pathname)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Boolean exists, isDir, isReadable;
|
||||
NuFileDetails details;
|
||||
struct stat sb;
|
||||
|
||||
Assert(pState != nil);
|
||||
Assert(pArchive != nil);
|
||||
Assert(pathname != nil);
|
||||
Assert(pState != NULL);
|
||||
Assert(pArchive != NULL);
|
||||
Assert(pathname != NULL);
|
||||
|
||||
err = CheckFileStatus(pathname, &sb, &exists, &isReadable, &isDir);
|
||||
if (err != kNuErrNone) {
|
||||
|
@ -1071,13 +1246,12 @@ bail_quiet:
|
|||
*
|
||||
* [ I figure the GS/OS version will want to pass a copy of the file
|
||||
* info from the GSOSAddDirectory function back into GSOSAddFile, so we'd
|
||||
* want to call it from here with a nil pointer indicating that we
|
||||
* want to call it from here with a NULL pointer indicating that we
|
||||
* don't yet have the file info. That way we can get the file info
|
||||
* from the directory read call and won't have to check it again in
|
||||
* GSOSAddFile. ]
|
||||
*/
|
||||
NuError
|
||||
AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
|
||||
NuError AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
|
||||
{
|
||||
#if defined(UNIX_LIKE)
|
||||
return UNIXAddFile(pState, pArchive, pathname);
|
||||
|
@ -1094,12 +1268,11 @@ AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
|
|||
*
|
||||
* Currently only used by Binary2.c.
|
||||
*/
|
||||
NuError
|
||||
Mkdir(const char* dir)
|
||||
NuError Mkdir(const char* dir)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
|
||||
Assert(dir != nil);
|
||||
Assert(dir != NULL);
|
||||
|
||||
#if defined(UNIX_LIKE)
|
||||
if (mkdir(dir, S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH) < 0) {
|
||||
|
@ -1126,12 +1299,11 @@ bail:
|
|||
*
|
||||
* Currently only used by Binary2.c.
|
||||
*/
|
||||
NuError
|
||||
TestFileExistence(const char* fileName, Boolean* pIsDir)
|
||||
NuError TestFileExistence(const char* fileName, Boolean* pIsDir)
|
||||
{
|
||||
NuError err = kNuErrNone;
|
||||
Assert(fileName != nil);
|
||||
Assert(pIsDir != nil);
|
||||
Assert(fileName != NULL);
|
||||
Assert(pIsDir != NULL);
|
||||
|
||||
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
|
||||
{
|
||||
|
@ -1160,4 +1332,3 @@ bail:
|
|||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
1456
nulib2/config.guess
vendored
1456
nulib2/config.guess
vendored
File diff suppressed because it is too large
Load Diff
|
@ -33,18 +33,6 @@
|
|||
/* Define if your <sys/time.h> declares struct tm. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define to `unsigned char' if <sys/types.h> doesn't define. */
|
||||
#undef uchar
|
||||
|
||||
/* Define to `unsigned short' if <sys/types.h> doesn't define. */
|
||||
#undef ushort
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> doesn't define. */
|
||||
#undef uint
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
|
||||
#undef ulong
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef mode_t
|
||||
|
||||
|
|
2785
nulib2/config.sub
vendored
2785
nulib2/config.sub
vendored
File diff suppressed because it is too large
Load Diff
50
nulib2/configure
vendored
50
nulib2/configure
vendored
|
@ -4001,50 +4001,6 @@ $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "uchar" "ac_cv_type_uchar" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_uchar" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define uchar unsigned char
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "ushort" "ac_cv_type_ushort" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_ushort" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ushort unsigned short
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "uint" "ac_cv_type_uint" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_uint" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define uint unsigned int
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "ulong" "ac_cv_type_ulong" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_ulong" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ulong unsigned long
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4156,12 +4112,6 @@ if test "$host_os" = "beos"; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
|
||||
echo "checking for Mac OS X... yes, adding -framework Carbon"
|
||||
LIBS="$LIBS -framework Carbon"
|
||||
fi
|
||||
|
||||
|
||||
if test "$host_cpu" = "powerpc" -a "$host_os" = "beos"; then
|
||||
CC=cc
|
||||
GCC=
|
||||
|
|
|
@ -47,7 +47,7 @@ if test $enable_deflate = "yes"; then
|
|||
fi
|
||||
if $got_zlibh; then
|
||||
echo " (found libz and zlib.h, enabling deflate)"
|
||||
AC_DEFINE(ENABLE_DEFLATE)
|
||||
AC_DEFINE(ENABLE_DEFLATE, [], [Define to include deflate (zlib) compresion (also need -l in Makefile).])
|
||||
else
|
||||
echo " (couldn't find libz and zlib.h, not enabling deflate)"
|
||||
fi
|
||||
|
@ -67,7 +67,7 @@ if test $enable_bzip2 = "yes"; then
|
|||
fi
|
||||
if $got_bzlibh; then
|
||||
echo " (found libbz2 and bzlib.h, enabling bzip2)"
|
||||
AC_DEFINE(ENABLE_BZIP2)
|
||||
AC_DEFINE(ENABLE_BZIP2, [], [Define to include bzip2 (libbz2) compression (also need -l in Makefile).])
|
||||
else
|
||||
echo " (couldn't find libbz2 and bzlib.h, not enabling bzip2)"
|
||||
fi
|
||||
|
@ -79,10 +79,6 @@ AC_TYPE_MODE_T
|
|||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_STRUCT_TM
|
||||
AC_CHECK_TYPE(uchar, unsigned char)
|
||||
AC_CHECK_TYPE(ushort, unsigned short)
|
||||
AC_CHECK_TYPE(uint, unsigned int)
|
||||
AC_CHECK_TYPE(ulong, unsigned long)
|
||||
|
||||
dnl Checks for library functions.
|
||||
dnl AC_FUNC_SETVBUF_REVERSED
|
||||
|
@ -129,13 +125,6 @@ if test "$host_os" = "beos"; then
|
|||
fi
|
||||
fi
|
||||
|
||||
dnl Mac OS X (powerpc-apple-darwin6.6) needs an extra flag.
|
||||
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
|
||||
echo "checking for Mac OS X... yes, adding -framework Carbon"
|
||||
LIBS="$LIBS -framework Carbon"
|
||||
fi
|
||||
|
||||
|
||||
dnl Figure out what the build and link flags should be
|
||||
if test "$host_cpu" = "powerpc" -a "$host_os" = "beos"; then
|
||||
dnl BeOS/PPC with Metrowerks compiler
|
||||
|
@ -149,6 +138,6 @@ AC_SUBST(BUILD_FLAGS)
|
|||
|
||||
AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc do dmalloc stuff], \
|
||||
[ echo "--- enabling dmalloc";
|
||||
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC) ])
|
||||
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC, [], [Define if we want to use the dmalloc library (also need -l in Makefile).]) ])
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
|
Loading…
Reference in New Issue
Block a user