Exemple #1
0
/*
 * 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)
{
    if (NuThreadIDGetClass(threadID) == kNuThreadClassData)
        return true;
    else
        return false;
}
Exemple #2
0
/*
 * Determine if it's okay to add a thread of the type specified by
 * "threadID" into "pRecord".
 *
 * Returns with an error (kNuErrThreadAdd) if it's not okay.
 */
NuError Nu_OkayToAddThread(NuArchive* pArchive, const NuRecord* pRecord,
    NuThreadID threadID)
{
    NuError err = kNuErrNone;

    /*
     * Check for class conflicts (can't mix data and control threads).
     */
    if (NuThreadIDGetClass(threadID) == kNuThreadClassData) {
        err = Nu_FindNoFutureThreadClass(pArchive, pRecord,
                kNuThreadClassControl);
        BailError(err);
    } else if (NuThreadIDGetClass(threadID) == kNuThreadClassControl) {
        err = Nu_FindNoFutureThreadClass(pArchive, pRecord,
                kNuThreadClassData);
        BailError(err);
    }

    /*
     * Check for specific type conflicts.
     */
    if (threadID == kNuThreadIDDataFork) {
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDDataFork);
        BailError(err);
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDDiskImage);
        BailError(err);
    } else if (threadID == kNuThreadIDRsrcFork) {
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDRsrcFork);
        BailError(err);
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDDiskImage);
        BailError(err);
    } else if (threadID == kNuThreadIDDiskImage) {
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDDataFork);
        BailError(err);
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDRsrcFork);
        BailError(err);
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDDiskImage);
        BailError(err);
    } else if (threadID == kNuThreadIDFilename) {
        err = Nu_FindNoFutureThread(pArchive, pRecord, kNuThreadIDFilename);
        BailError(err);
    }

bail:
    return err;
}
Exemple #3
0
/*
 * Like Nu_FindNoFutureThread, but tests against a whole class.
 */
static NuError Nu_FindNoFutureThreadClass(NuArchive* pArchive,
    const NuRecord* pRecord, long threadClass)
{
    NuError err = kNuErrNone;
    const NuThread* pThread;
    const NuThreadMod* pThreadMod;
    int idx;

    /*
     * Start by scanning the existing threads (if any).
     */
    for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
        pThread = Nu_GetThread(pRecord, idx);
        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 != NULL &&
                pThreadMod->entry.kind == kNuThreadModDelete)
            {
                /* it's deleted, ignore it */
                continue;
            }
            DBUG(("--- Found existing thread matching 0x%04lx\n", threadClass));
            err = kNuErrThreadAdd;
            goto bail;
        }
    }

    /*
     * Now look for "add" threadMods with a matching threadClass.
     */
    pThreadMod = pRecord->pThreadMods;
    while (pThreadMod != NULL) {
        if (pThreadMod->entry.kind == kNuThreadModAdd &&
            NuThreadIDGetClass(pThreadMod->entry.add.threadID) == threadClass)
        {
            DBUG(("--- Found 'add' threadMod matching 0x%04lx\n", threadClass));
            err = kNuErrThreadAdd;
            goto bail;
        }

        pThreadMod = pThreadMod->pNext;
    }

bail:
    return err;
}
Exemple #4
0
/*
 * at - add thread to record
 */
static NuError
AddThreadFunc(ExerciserState* pState, int argc, char** argv)
{
    NuError err;
    NuDataSource* pDataSource = nil;
    char* lineBuf = nil;
    long ourLen, maxLen;
    NuThreadID threadID;
    NuThreadIdx threadIdx;

    (void) pState, (void) argc, (void) argv;    /* shut up, gcc */
    assert(ExerciserState_GetNuArchive(pState) != nil);
    assert(argc == 3);

    lineBuf = (char*)malloc(kNiceLineLen);
    assert(lineBuf != nil);

    threadID = strtol(argv[2], nil, 0);
    if (NuThreadIDGetClass(threadID) == kNuThreadClassData) {
        /* load data from a file on disk */
        maxLen = 0;
        err = GetLine("Enter filename", lineBuf, kNiceLineLen);
        if (err != kNuErrNone)
            goto bail;
        if (!lineBuf[0]) {
            fprintf(stderr, "Invalid filename\n");
            err = kNuErrInvalidArg;
            goto bail;
        }

        err = NuCreateDataSourceForFile(kNuThreadFormatUncompressed,
                0, lineBuf, false, &pDataSource);
        if (err != kNuErrNone) {
            fprintf(stderr,
                "Exerciser: file data source create failed (err=%d)\n", err);
            goto bail;
        }
    } else {
        if (threadID == kNuThreadIDFilename || threadID == kNuThreadIDComment) {
            /* select the buffer pre-size */
            err = GetLine("Enter max buffer size", lineBuf, kNiceLineLen);
            if (err != kNuErrNone)
                goto bail;
            maxLen = strtol(lineBuf, nil, 0);
            if (maxLen <= 0) {
                fprintf(stderr, "Bad length\n");
                err = kNuErrInvalidArg;
                goto bail;
            }
        } else {
            maxLen = 0;
        }

        err = GetLine("Enter the thread contents", lineBuf, kNiceLineLen);
        if (err != kNuErrNone)
            goto bail;
        ourLen = strlen(lineBuf);

        /* create a data source from the buffer */
        err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
                maxLen, (unsigned char*)lineBuf, 0, ourLen, FreeCallback,
                &pDataSource);
        if (err != kNuErrNone) {
            fprintf(stderr,
                "Exerciser: buffer data source create failed (err=%d)\n", err);
            goto bail;
        }
        lineBuf = nil;  /* now owned by the library */
    }


    err = NuAddThread(ExerciserState_GetNuArchive(pState),
            strtol(argv[1], nil, 0), threadID, pDataSource, &threadIdx);
    if (err == kNuErrNone) {
        pDataSource = nil;  /* library owns it now */
        printf("Exerciser: success; function returned threadIdx=%ld\n",
            threadIdx);
    }

bail:
    NuFreeDataSource(pDataSource);
    if (lineBuf != nil)
        free(lineBuf);
    return err;
}
Exemple #5
0
/*
 * NuContents callback function.  Print the contents of an individual record.
 */
NuResult
PrintEntry(NuArchive* pArchive, void* vpRecord)
{
    const NuRecord* pRecord = (const NuRecord*) vpRecord;
    int idx;

    (void)pArchive; /* shut up, gcc */

    printf("RecordIdx %ld: '%s'\n",
        pRecord->recordIdx, pRecord->filename);

    for (idx = 0; idx < (int) pRecord->recTotalThreads; idx++) {
        const NuThread* pThread;
        NuThreadID threadID;
        const char* threadLabel;

        pThread = NuGetThread(pRecord, idx);
        assert(pThread != nil);

        threadID = NuGetThreadID(pThread);
        switch (NuThreadIDGetClass(threadID)) {
        case kNuThreadClassMessage:
            threadLabel = "message class";
            break;
        case kNuThreadClassControl:
            threadLabel = "control class";
            break;
        case kNuThreadClassData:
            threadLabel = "data class";
            break;
        case kNuThreadClassFilename:
            threadLabel = "filename class";
            break;
        default:
            threadLabel = "(unknown class)";
            break;
        }

        switch (threadID) {
        case kNuThreadIDComment:
            threadLabel = "comment";
            break;
        case kNuThreadIDIcon:
            threadLabel = "icon";
            break;
        case kNuThreadIDMkdir:
            threadLabel = "mkdir";
            break;
        case kNuThreadIDDataFork:
            threadLabel = "data fork";
            break;
        case kNuThreadIDDiskImage:
            threadLabel = "disk image";
            break;
        case kNuThreadIDRsrcFork:
            threadLabel = "rsrc fork";
            break;
        case kNuThreadIDFilename:
            threadLabel = "filename";
            break;
        default:
            break;
        }

        printf("  ThreadIdx %ld - 0x%08lx (%s)\n", pThread->threadIdx,
            threadID, threadLabel);
    }

    return kNuOK;
}
Exemple #6
0
/*
 * Decide if the thread has a CRC, based on the record version and the
 * threadID.
 */
Boolean Nu_ThreadHasCRC(uint16_t recordVersion, NuThreadID threadID)
{
    return recordVersion >= 3 &&
            NuThreadIDGetClass(threadID) == kNuThreadClassData;
}