bool AcuArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet) { // TODO: this is essentially copy & paste from NufxArchive::TestSelection(). // We can move the implementation to GenericArchive and just have an // archive-specific TestEntry() function. NuError nerr; AcuEntry* pEntry; CString errMsg; bool retVal = false; ASSERT(fFp != NULL); LOGI("Testing %d entries", pSelSet->GetNumEntries()); SelectionEntry* pSelEntry = pSelSet->IterNext(); while (pSelEntry != NULL) { pEntry = (AcuEntry*) pSelEntry->GetEntry(); LOGD(" Testing '%ls' (offset=%ld)", (LPCWSTR) pEntry->GetDisplayName(), pEntry->GetOffset()); SET_PROGRESS_UPDATE2(0, pEntry->GetDisplayName(), NULL); nerr = pEntry->TestEntry(pMsgWnd); if (nerr != kNuErrNone) { if (nerr == kNuErrAborted) { CString title; CheckedLoadString(&title, IDS_MB_APP_NAME); errMsg = L"Cancelled."; pMsgWnd->MessageBox(errMsg, title, MB_OK); } else { errMsg.Format(L"Failed while testing '%ls': %hs.", (LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr)); ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED); } goto bail; } pSelEntry = pSelSet->IterNext(); } /* show success message */ errMsg.Format(L"Tested %d file%ls, no errors found.", pSelSet->GetNumEntries(), pSelSet->GetNumEntries() == 1 ? L"" : L"s"); pMsgWnd->MessageBox(errMsg); retVal = true; bail: SET_PROGRESS_END(); return retVal; }
NuError AcuEntry::CopyData(FILE* outfp, ConvertEOL conv, ConvertHighASCII convHA, CString* pMsg) const { NuError nerr = kNuErrNone; const int kChunkSize = 8192; char buf[kChunkSize]; bool lastCR = false; long srcLen, dataRem; srcLen = (long) GetUncompressedLen(); ASSERT(srcLen > 0); // empty files should've been caught earlier /* * Loop until all data copied. */ dataRem = srcLen; while (dataRem) { int chunkLen; if (dataRem > kChunkSize) chunkLen = kChunkSize; else chunkLen = dataRem; /* read a chunk from the source file */ nerr = fpArchive->AcuRead(buf, chunkLen); if (nerr != kNuErrNone) { pMsg->Format(L"File read failed: %hs.", NuStrError(nerr)); goto bail; } /* write chunk to destination file */ int err = GenericEntry::WriteConvert(outfp, buf, chunkLen, &conv, &convHA, &lastCR); if (err != 0) { pMsg->Format(L"File write failed: %hs.", strerror(err)); nerr = kNuErrGeneric; goto bail; } dataRem -= chunkLen; SET_PROGRESS_UPDATE(ComputePercent(srcLen - dataRem, srcLen)); } bail: return nerr; }
NuError AcuEntry::TestEntry(CWnd* pMsgWnd) { NuError nerr = kNuErrNone; CString errMsg; long len; int result = -1; len = (long) GetUncompressedLen(); if (len == 0) goto bail; errno = 0; if (fseek(fpArchive->fFp, fOffset, SEEK_SET) < 0) { nerr = kNuErrGeneric; errMsg.Format(L"Unable to seek to offset %ld: %hs\n", fOffset, strerror(errno)); ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED); goto bail; } if (GetSqueezed()) { nerr = UnSqueeze(fpArchive->fFp, (unsigned long) GetCompressedLen(), NULL, false, 0); if (nerr != kNuErrNone) { errMsg.Format(L"Unsqueeze failed: %hs.", NuStrError(nerr)); ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED); goto bail; } } else { errno = 0; if (fseek(fpArchive->fFp, fOffset + len, SEEK_SET) < 0) { nerr = kNuErrGeneric; errMsg.Format(L"Unable to seek to offset %ld (file truncated?): %hs\n", fOffset, strerror(errno)); ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED); goto bail; } } if (SET_PROGRESS_UPDATE(100) == IDCANCEL) nerr = kNuErrAborted; bail: return nerr; }
/* * Interpret commands, do clever things. */ static NuError CommandLoop(void) { NuError err = kNuErrNone; ExerciserState* pState = ExerciserState_New(); CommandFunc func; char lineBuf[128]; int argc; char** argv = nil; while (1) { printf("\nEnter command (%s)> ", ExerciserState_GetArchiveFile(pState)); fflush(stdout); if (fgets(lineBuf, sizeof(lineBuf), stdin) == nil) { printf("\n"); break; } if (argv != nil) { free(argv); argv = nil; } func = nil; /* sanity check */ err = ParseLine(lineBuf, pState, &func, &argc, &argv); if (err != kNuErrNone) continue; assert(func != nil); if (func == QuitFunc) break; err = (*func)(pState, argc, argv); if (err < 0) printf("Exerciser: received error %d (%s)\n", err, NuStrError(err)); else if (err > 0) printf("Exerciser: received error %d\n", err); if (argv != nil) { free(argv); argv = nil; } } if (ExerciserState_GetNuArchive(pState) != nil) { /* ought to query the archive before saying something like this... */ printf("Exerciser: aborting any un-flushed changes in archive %s\n", ExerciserState_GetArchivePath(pState)); (void) NuAbort(ExerciserState_GetNuArchive(pState)); err = NuClose(ExerciserState_GetNuArchive(pState)); if (err != kNuErrNone) printf("Exerciser: got error %d closing archive\n", err); ExerciserState_SetNuArchive(pState, nil); } if (pState != nil) ExerciserState_Free(pState); if (argv != nil) free(argv); return kNuErrNone; }
int AcuEntry::ExtractThreadToBuffer(int which, char** ppText, long* pLength, CString* pErrMsg) const { NuError nerr; ExpandBuffer expBuf; char* dataBuf = NULL; long len; bool needAlloc = true; int result = -1; ASSERT(fpArchive != NULL); ASSERT(fpArchive->fFp != NULL); if (*ppText != NULL) needAlloc = false; if (which != kDataThread) { *pErrMsg = "No such fork"; goto bail; } len = (long) GetUncompressedLen(); if (len == 0) { if (needAlloc) { *ppText = new char[1]; **ppText = '\0'; } *pLength = 0; result = IDOK; goto bail; } SET_PROGRESS_BEGIN(); errno = 0; if (fseek(fpArchive->fFp, fOffset, SEEK_SET) < 0) { pErrMsg->Format(L"Unable to seek to offset %ld: %hs", fOffset, strerror(errno)); goto bail; } if (GetSqueezed()) { nerr = UnSqueeze(fpArchive->fFp, (unsigned long) GetCompressedLen(), &expBuf, false, 0); if (nerr != kNuErrNone) { pErrMsg->Format(L"File read failed: %hs", NuStrError(nerr)); goto bail; } char* unsqBuf = NULL; long unsqLen = 0; expBuf.SeizeBuffer(&unsqBuf, &unsqLen); LOGI("Unsqueezed %ld bytes to %d", (unsigned long) GetCompressedLen(), unsqLen); if (unsqLen == 0) { // some bonehead squeezed a zero-length file delete[] unsqBuf; ASSERT(*ppText == NULL); LOGI("Handling zero-length squeezed file!"); if (needAlloc) { *ppText = new char[1]; **ppText = '\0'; } *pLength = 0; } else { if (needAlloc) { /* just use the seized buffer */ *ppText = unsqBuf; *pLength = unsqLen; } else { if (*pLength < unsqLen) { pErrMsg->Format(L"buf size %ld too short (%ld)", *pLength, unsqLen); delete[] unsqBuf; goto bail; } memcpy(*ppText, unsqBuf, unsqLen); delete[] unsqBuf; *pLength = unsqLen; } } } else { if (needAlloc) { dataBuf = new char[len]; if (dataBuf == NULL) { pErrMsg->Format(L"allocation of %ld bytes failed", len); goto bail; } } else { if (*pLength < (long) len) { pErrMsg->Format(L"buf size %ld too short (%ld)", *pLength, len); goto bail; } dataBuf = *ppText; } if (fread(dataBuf, len, 1, fpArchive->fFp) != 1) { pErrMsg->Format(L"File read failed: %hs", strerror(errno)); goto bail; } if (needAlloc) *ppText = dataBuf; *pLength = len; } result = IDOK; bail: if (result == IDOK) { SET_PROGRESS_END(); ASSERT(pErrMsg->IsEmpty()); } else { ASSERT(result == IDCANCEL || !pErrMsg->IsEmpty()); if (needAlloc) { delete[] dataBuf; ASSERT(*ppText == NULL); } } return result; }
int AcuEntry::ExtractThreadToFile(int which, FILE* outfp, ConvertEOL conv, ConvertHighASCII convHA, CString* pErrMsg) const { NuError nerr; long len; int result = -1; ASSERT(IDOK != -1 && IDCANCEL != -1); if (which != kDataThread) { *pErrMsg = L"No such fork"; goto bail; } len = (long) GetUncompressedLen(); if (len == 0) { LOGI("Empty fork"); result = IDOK; goto bail; } errno = 0; if (fseek(fpArchive->fFp, fOffset, SEEK_SET) < 0) { pErrMsg->Format(L"Unable to seek to offset %ld: %hs", fOffset, strerror(errno)); goto bail; } SET_PROGRESS_BEGIN(); /* * Generally speaking, anything in an ACU file is going to be small. * * To make life easy, we either unsqueeze the entire thing into a buffer * and then write that, or we do a file-to-file copy of the specified * number of bytes. */ if (GetSqueezed()) { ExpandBuffer expBuf; bool lastCR = false; char* buf; long uncLen; nerr = UnSqueeze(fpArchive->fFp, (unsigned long) GetCompressedLen(), &expBuf, false, 0); if (nerr != kNuErrNone) { pErrMsg->Format(L"File read failed: %hs", NuStrError(nerr)); goto bail; } expBuf.SeizeBuffer(&buf, &uncLen); LOGI("Unsqueezed %ld bytes to %d", len, uncLen); // some bonehead squeezed a zero-length file if (uncLen == 0) { ASSERT(buf == NULL); LOGI("Handling zero-length squeezed file!"); result = IDOK; goto bail; } int err = GenericEntry::WriteConvert(outfp, buf, uncLen, &conv, &convHA, &lastCR); if (err != 0) { pErrMsg->Format(L"File write failed: %hs", strerror(err)); delete[] buf; goto bail; } delete[] buf; } else { nerr = CopyData(outfp, conv, convHA, pErrMsg); if (nerr != kNuErrNone) { if (pErrMsg->IsEmpty()) { pErrMsg->Format(L"Failed while copying data: %hs\n", NuStrError(nerr)); } goto bail; } } result = IDOK; bail: SET_PROGRESS_END(); return result; }