void Directory::scan_dir(const ACE_TString& relative, DDS_Dirent& dir, unsigned int overflow_index) { ACE_TString path = physical_dirname_ + relative; add_slash(path); while (DDS_DIRENT* ent = dir.read()) { if (ent->d_name[0] == ACE_TEXT('.') && (!ent->d_name[1] || (ent->d_name[1] == ACE_TEXT('.') && !ent->d_name[2]))) { continue; // skip '.' and '..' } ACE_TString file = path + ent->d_name; if (is_dir(file.c_str())) { ACE_TString phys(relative); add_slash(phys); phys += ent->d_name; if (ACE_OS::strncmp(ent->d_name, ACE_TEXT("_overflow."), 10) == 0) { unsigned int n = ACE_OS::atoi(ent->d_name + 10); DDS_Dirent overflow(file.c_str()); scan_dir(ent->d_name, overflow, n); } else if (ACE_OS::strlen(ent->d_name) <= FSS_MAX_FILE_NAME_ENCODED) { dirs_[b32h_decode(ent->d_name)] = phys; ++overflow_[overflow_index]; } else { CwdGuard cg(file); std::ifstream fn("_fullname"); std::string fullname; if (!std::getline(fn, fullname)) { throw std::runtime_error("Can't read .../_fullname"); } ACE_TString full_t(ACE_TEXT_CHAR_TO_TCHAR(fullname.c_str())); dirs_[full_t] = phys; ++overflow_[overflow_index]; String_Index_t idx = phys.rfind(ACE_TEXT('.')); if (idx == ACE_TString::npos) { throw std::runtime_error("Badly formatted long dir name"); } ACE_TString prefix(phys.c_str(), idx); unsigned int serial = ACE_OS::atoi(&phys[idx + 1]); unsigned int& counter = long_names_[prefix]; if (serial >= counter) counter = serial + 1; } } else { // regular file if (ent->d_name[0] != ACE_TEXT('_')) { files_[b32h_decode(ent->d_name)] = ent->d_name; ++overflow_[overflow_index]; } } } }
void main() { printf("fn(5, 3) value is %d\n", fn(5, 3)); // 输出结果? }
// Dirichlet boundary condition values scalar bc_values(int marker, double x, double y) { return fn(x, y); }
void SjKaraokeModule::OnMenuOption(int i) { switch( i ) { case IDC_BG_BLACK: m_bgType = SJ_KARAOKE_BG_BLACK; WriteKarConfig(); UpdateBg(); break; case IDC_BG_USERDEF_DIR_USE: case IDC_BG_DEFAULT_IMAGES: m_bgType = (i==IDC_BG_USERDEF_DIR_USE)? SJ_KARAOKE_BG_USERDEF_DIR : SJ_KARAOKE_BG_DEFAULT_IMAGES; WriteKarConfig(); InitBgFiles(); UpdateBg(); break; case IDC_BG_USERDEF_DIR_CHANGE: g_visModule->SetModal(true); { SJ_WINDOW_DISABLER(m_impl); ::wxBeginBusyCursor(wxHOURGLASS_CURSOR); wxDirDialog dirDialog(m_impl, _("Please select a directory with images"), m_bgUserDefDir); ::wxEndBusyCursor(); if( dirDialog.ShowModal() == wxID_OK ) { wxFileName fn(dirDialog.GetPath()); fn.Normalize(); m_bgUserDefDir = SjLittleDirSel::NormalizeDir(fn.GetFullPath()); m_bgType = SJ_KARAOKE_BG_USERDEF_DIR; WriteKarConfig(); InitBgFiles(); UpdateBg(); } } g_visModule->SetModal(false); break; case IDC_BG_SMOOTH: SjTools::ToggleFlag(m_karFlags, SJ_KAR_SMOOTH); WriteKarConfig(); UpdateBg(true/*keepImage*/); break; case IDC_BG_KEEPASPECT: SjTools::ToggleFlag(m_karFlags, SJ_KAR_KEEPASPECT); WriteKarConfig(); UpdateBg(true/*keepImage*/); break; case IDC_BG_GRAYSCALE: SjTools::ToggleFlag(m_karFlags, SJ_KAR_GRAYSCALE); WriteKarConfig(); UpdateBg(true/*keepImage*/); break; case IDC_BG_USEBGJPG: SjTools::ToggleFlag(m_karFlags, SJ_KAR_USEBGJPG); WriteKarConfig(); UpdateBg(); break; } }
/********************************************************************** * %FUNCTION: set_option * %ARGUMENTS: * es -- event selector * desc -- option descriptor * value -- value string parsed from config file * %RETURNS: * -1 on error, 0 if all is OK * %DESCRIPTION: * Sets an option value. ***********************************************************************/ static int set_option(EventSelector *es, l2tp_opt_descriptor *desc, char const *value) { long x; char *end; struct hostent *he; int (*fn)(EventSelector *, l2tp_opt_descriptor *, char const *); switch(desc->type) { case OPT_TYPE_BOOL: if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on") || !strcasecmp(value, "1")) { * (int *) (desc->addr) = 1; return 0; } if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off") || !strcasecmp(value, "0")) { * (int *) (desc->addr) = 0; return 0; } l2tp_set_errmsg("Expecting boolean value, found '%s'", value); return -1; case OPT_TYPE_INT: case OPT_TYPE_PORT: x = strtol(value, &end, 0); if (*end) { l2tp_set_errmsg("Expecting integer value, found '%s'", value); return -1; } if (desc->type == OPT_TYPE_PORT) { if (x < 1 || x > 65535) { l2tp_set_errmsg("Port values must range from 1 to 65535"); return -1; } } * (int *) desc->addr = (int) x; return 0; case OPT_TYPE_IPADDR: he = gethostbyname(value); if (!he) { l2tp_set_errmsg("Could not resolve %s as IP address: %s", value, strerror(errno)); return -1; } memcpy(desc->addr, he->h_addr, sizeof(he->h_addr)); return 0; case OPT_TYPE_STRING: if (desc->addr) { free(desc->addr); } desc->addr = strdup(value); if (!desc->addr) { l2tp_set_errmsg("Out of memory"); return -1; } return 0; case OPT_TYPE_CALLFUNC: fn = (int (*)(EventSelector *, l2tp_opt_descriptor *, char const *)) desc->addr; return fn(es, desc, value); } l2tp_set_errmsg("Unknown value type %d", desc->type); return -1; }
void fork_thunk(void (*fn)(void*) /*NORETURN*/, void *arg, long sigmask) { sigsetmask(sigmask); fn(arg); }
/* LfdArchive::write * Writes the lfd archive to a MemChunk * Returns true if successful, false otherwise *******************************************************************/ bool LfdArchive::write(MemChunk& mc, bool update) { // Determine total size uint32_t dir_size = (numEntries() + 1)<<4; uint32_t total_size = dir_size; ArchiveEntry* entry = NULL; for (uint32_t l = 0; l < numEntries(); l++) { entry = getEntry(l); total_size += 16; setEntryOffset(entry, total_size); if (update) { entry->setState(0); entry->exProp("Offset") = (int)total_size; } total_size += entry->getSize(); } // Clear/init MemChunk mc.clear(); mc.seek(0, SEEK_SET); mc.reSize(total_size); // Variables char type[5] = "RMAP"; char name[9] = "resource"; size_t size = wxINT32_SWAP_ON_BE(numEntries()<<4); // Write the resource map first mc.write(type, 4); mc.write(name, 8); mc.write(&size,4); for (uint32_t l = 0; l < numEntries(); l++) { entry = getEntry(l); for (int t = 0; t < 5; ++t) type[t] = 0; for (int n = 0; n < 9; ++n) name[n] = 0; size = wxINT32_SWAP_ON_BE(entry->getSize()); wxFileName fn(entry->getName()); for (size_t c = 0; c < fn.GetName().length() && c < 9; c++) name[c] = fn.GetName()[c]; for (size_t c = 0; c < fn.GetExt().length() && c < 5; c++) type[c] = fn.GetExt()[c]; mc.write(type, 4); mc.write(name, 8); mc.write(&size,4); } // Write the lumps for (uint32_t l = 0; l < numEntries(); l++) { entry = getEntry(l); for (int t = 0; t < 5; ++t) type[t] = 0; for (int n = 0; n < 9; ++n) name[n] = 0; size = wxINT32_SWAP_ON_BE(entry->getSize()); wxFileName fn(entry->getName()); for (size_t c = 0; c < fn.GetName().length() && c < 9; c++) name[c] = fn.GetName()[c]; for (size_t c = 0; c < fn.GetExt().length() && c < 5; c++) type[c] = fn.GetExt()[c]; mc.write(type, 4); mc.write(name, 8); mc.write(&size,4); mc.write(entry->getData(), entry->getSize()); } return true; }
int qt_wince_open( const char *filename, int oflag, int pmode ) { QString fn( QString::fromLatin1(filename) ); return _wopen( (wchar_t*)fn.utf16(), oflag, pmode ); }
nsresult WrapperPromiseCallback::Call(JSContext* aCx, JS::Handle<JS::Value> aValue) { JS::ExposeObjectToActiveJS(mGlobal); JS::ExposeValueToActiveJS(aValue); JSAutoCompartment ac(aCx, mGlobal); JS::Rooted<JS::Value> value(aCx, aValue); if (!JS_WrapValue(aCx, &value)) { NS_WARNING("Failed to wrap value into the right compartment."); return NS_ERROR_FAILURE; } ErrorResult rv; // PromiseReactionTask step 6 JS::Rooted<JS::Value> retValue(aCx); JSCompartment* compartment; if (mNextPromise) { compartment = mNextPromise->Compartment(); } else { MOZ_ASSERT(mNextPromiseObj); compartment = js::GetObjectCompartment(mNextPromiseObj); } mCallback->Call(value, &retValue, rv, "promise callback", CallbackObject::eRethrowExceptions, compartment); rv.WouldReportJSException(); // PromiseReactionTask step 7 if (rv.Failed()) { JS::Rooted<JS::Value> value(aCx); { // Scope for JSAutoCompartment // Convert the ErrorResult to a JS exception object that we can reject // ourselves with. This will be exactly the exception that would get // thrown from a binding method whose ErrorResult ended up with whatever // is on "rv" right now. Do this in the promise reflector compartment. Maybe<JSAutoCompartment> ac; if (mNextPromise) { ac.emplace(aCx, mNextPromise->GlobalJSObject()); } else { ac.emplace(aCx, mNextPromiseObj); } DebugOnly<bool> conversionResult = ToJSValue(aCx, rv, &value); MOZ_ASSERT(conversionResult); } if (mNextPromise) { mNextPromise->RejectInternal(aCx, value); } else { JS::Rooted<JS::Value> ignored(aCx); ErrorResult rejectRv; mRejectFunc->Call(value, &ignored, rejectRv); // This reported any JS exceptions; we just have a pointless exception on // there now. rejectRv.SuppressException(); } return NS_OK; } // If the return value is the same as the promise itself, throw TypeError. if (retValue.isObject()) { JS::Rooted<JSObject*> valueObj(aCx, &retValue.toObject()); valueObj = js::CheckedUnwrap(valueObj); JS::Rooted<JSObject*> nextPromiseObj(aCx); if (mNextPromise) { nextPromiseObj = mNextPromise->GetWrapper(); } else { MOZ_ASSERT(mNextPromiseObj); nextPromiseObj = mNextPromiseObj; } // XXXbz shouldn't this check be over in ResolveInternal anyway? if (valueObj == nextPromiseObj) { const char* fileName = nullptr; uint32_t lineNumber = 0; // Try to get some information about the callback to report a sane error, // but don't try too hard (only deals with scripted functions). JS::Rooted<JSObject*> unwrapped(aCx, js::CheckedUnwrap(mCallback->Callback())); if (unwrapped) { JSAutoCompartment ac(aCx, unwrapped); if (JS_ObjectIsFunction(aCx, unwrapped)) { JS::Rooted<JS::Value> asValue(aCx, JS::ObjectValue(*unwrapped)); JS::Rooted<JSFunction*> func(aCx, JS_ValueToFunction(aCx, asValue)); MOZ_ASSERT(func); JSScript* script = JS_GetFunctionScript(aCx, func); if (script) { fileName = JS_GetScriptFilename(script); lineNumber = JS_GetScriptBaseLineNumber(aCx, script); } } } // We're back in aValue's compartment here. JS::Rooted<JSString*> fn(aCx, JS_NewStringCopyZ(aCx, fileName)); if (!fn) { // Out of memory. Promise will stay unresolved. JS_ClearPendingException(aCx); return NS_ERROR_OUT_OF_MEMORY; } JS::Rooted<JSString*> message(aCx, JS_NewStringCopyZ(aCx, "then() cannot return same Promise that it resolves.")); if (!message) { // Out of memory. Promise will stay unresolved. JS_ClearPendingException(aCx); return NS_ERROR_OUT_OF_MEMORY; } JS::Rooted<JS::Value> typeError(aCx); if (!JS::CreateError(aCx, JSEXN_TYPEERR, nullptr, fn, lineNumber, 0, nullptr, message, &typeError)) { // Out of memory. Promise will stay unresolved. JS_ClearPendingException(aCx); return NS_ERROR_OUT_OF_MEMORY; } if (mNextPromise) { mNextPromise->RejectInternal(aCx, typeError); } else { JS::Rooted<JS::Value> ignored(aCx); ErrorResult rejectRv; mRejectFunc->Call(typeError, &ignored, rejectRv); // This reported any JS exceptions; we just have a pointless exception // on there now. rejectRv.SuppressException(); } return NS_OK; } } // Otherwise, run resolver's resolve with value. if (!JS_WrapValue(aCx, &retValue)) { NS_WARNING("Failed to wrap value into the right compartment."); return NS_ERROR_FAILURE; } if (mNextPromise) { mNextPromise->ResolveInternal(aCx, retValue); } else { JS::Rooted<JS::Value> ignored(aCx); ErrorResult resolveRv; mResolveFunc->Call(retValue, &ignored, resolveRv); // This reported any JS exceptions; we just have a pointless exception // on there now. resolveRv.SuppressException(); } return NS_OK; }
/* EntryOperations::optimizePNG * Attempts to optimize [entry] using external PNG optimizers. *******************************************************************/ bool EntryOperations::optimizePNG(ArchiveEntry* entry) { // Check entry was given if (!entry) return false; // Check entry has a parent (this is useless otherwise) if (!entry->getParent()) return false; // Check entry is PNG if (!EntryDataFormat::getFormat("img_png")->isThisFormat(entry->getMCData())) { wxMessageBox("Error: Entry does not appear to be PNG", "Error", wxOK|wxCENTRE|wxICON_ERROR); return false; } // Check if the PNG tools path are set up, at least one of them should be string pngpathc = path_pngcrush; string pngpatho = path_pngout; string pngpathd = path_deflopt; if ((pngpathc.IsEmpty() || !wxFileExists(pngpathc)) && (pngpatho.IsEmpty() || !wxFileExists(pngpatho)) && (pngpathd.IsEmpty() || !wxFileExists(pngpathd))) { wxLogMessage("PNG tool paths not defined or invalid, no optimization done."); return false; } // Save special chunks point2_t offsets; bool alphchunk = getalPhChunk(entry); bool grabchunk = readgrAbChunk(entry, offsets); string errormessages = ""; wxArrayString output; wxArrayString errors; size_t oldsize = entry->getSize(); size_t crushsize = 0, outsize = 0, deflsize = 0; bool crushed = false, outed = false; // Run PNGCrush if (!pngpathc.IsEmpty() && wxFileExists(pngpathc)) { wxFileName fn(pngpathc); fn.SetExt("opt"); string pngfile = fn.GetFullPath(); fn.SetExt("png"); string optfile = fn.GetFullPath(); entry->exportFile(pngfile); string command = path_pngcrush + " -brute \"" + pngfile + "\" \"" + optfile + "\""; output.Empty(); errors.Empty(); wxExecute(command, output, errors, wxEXEC_SYNC); if (wxFileExists(optfile)) { if (optfile.size() < oldsize) { entry->importFile(optfile); wxRemoveFile(optfile); wxRemoveFile(pngfile); } else errormessages += "PNGCrush failed to reduce file size further.\n"; crushed = true; } else errormessages += "PNGCrush failed to create optimized file.\n"; crushsize = entry->getSize(); // send app output to console if wanted if (0) { string crushlog = ""; if (errors.GetCount()) { crushlog += "PNGCrush error messages:\n"; for (size_t i = 0; i < errors.GetCount(); ++i) crushlog += errors[i] + "\n"; errormessages += crushlog; } if (output.GetCount()) { crushlog += "PNGCrush output messages:\n"; for (size_t i = 0; i < output.GetCount(); ++i) crushlog += output[i] + "\n"; } wxLogMessage(crushlog); } } // Run PNGOut if (!pngpatho.IsEmpty() && wxFileExists(pngpatho)) { wxFileName fn(pngpatho); fn.SetExt("opt"); string pngfile = fn.GetFullPath(); fn.SetExt("png"); string optfile = fn.GetFullPath(); entry->exportFile(pngfile); string command = path_pngout + " /y \"" + pngfile + "\" \"" + optfile + "\""; output.Empty(); errors.Empty(); wxExecute(command, output, errors, wxEXEC_SYNC); if (wxFileExists(optfile)) { if (optfile.size() < oldsize) { entry->importFile(optfile); wxRemoveFile(optfile); wxRemoveFile(pngfile); } else errormessages += "PNGout failed to reduce file size further.\n"; outed = true; } else if (!crushed) // Don't treat it as an error if PNGout couldn't create a smaller file than PNGCrush errormessages += "PNGout failed to create optimized file.\n"; outsize = entry->getSize(); // send app output to console if wanted if (0) { string pngoutlog = ""; if (errors.GetCount()) { pngoutlog += "PNGOut error messages:\n"; for (size_t i = 0; i < errors.GetCount(); ++i) pngoutlog += errors[i] + "\n"; errormessages += pngoutlog; } if (output.GetCount()) { pngoutlog += "PNGOut output messages:\n"; for (size_t i = 0; i < output.GetCount(); ++i) pngoutlog += output[i] + "\n"; } wxLogMessage(pngoutlog); } } // Run deflopt if (!pngpathd.IsEmpty() && wxFileExists(pngpathd)) { wxFileName fn(pngpathd); fn.SetExt("png"); string pngfile = fn.GetFullPath(); entry->exportFile(pngfile); string command = path_deflopt + " /sf \"" + pngfile + "\""; output.Empty(); errors.Empty(); wxExecute(command, output, errors, wxEXEC_SYNC); entry->importFile(pngfile); wxRemoveFile(pngfile); deflsize = entry->getSize(); // send app output to console if wanted if (0) { string defloptlog = ""; if (errors.GetCount()) { defloptlog += "DeflOpt error messages:\n"; for (size_t i = 0; i < errors.GetCount(); ++i) defloptlog += errors[i] + "\n"; errormessages += defloptlog; } if (output.GetCount()) { defloptlog += "DeflOpt output messages:\n"; for (size_t i = 0; i < output.GetCount(); ++i) defloptlog += output[i] + "\n"; } wxLogMessage(defloptlog); } } output.Clear(); errors.Clear(); // Rewrite special chunks if (alphchunk) modifyalPhChunk(entry, true); if (grabchunk) setGfxOffsets(entry, offsets.x, offsets.y); wxLogMessage("PNG %s size %i =PNGCrush=> %i =PNGout=> %i =DeflOpt=> %i =+grAb/alPh=> %i", entry->getName(), oldsize, crushsize, outsize, deflsize, entry->getSize()); if (!crushed && !outed && !errormessages.IsEmpty()) { ExtMessageDialog dlg(NULL, "Optimizing Report"); dlg.setMessage("The following issues were encountered while optimizing:"); dlg.setExt(errormessages); dlg.ShowModal(); return false; } return true; }
static void fn(const arma::Cube<eT>& x, arma::Cube<eT>& y) { y = x; for (size_t s = 0; s < x.n_slices; s++) fn(x.slice(s), y.slice(s)); }
static void kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg) { fn(arg); do_exit(-1); /* Should never be called, return bad exit value */ }
void br_call_ioctl_atomic(void (*fn)(void)) { down(&ioctl_mutex); fn(); up(&ioctl_mutex); }
scalar rhs(scalar x, scalar y) { if (x < 0) return fn(x, y)*K*K; else return fn(x, y)*K*K-ALPHA*(ALPHA-1)*pow(x, ALPHA - 2.) - K*K*pow(x, ALPHA); }
virtual void go() { std::for_each(std::begin(state.data), std::end(state.data), [&](const str_fixture_state::array_t & r) { state.res.emplace_back(fn(r)); }); }
static bool get_rpc_shares(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state) { NTSTATUS status; struct rpc_pipe_client *pipe_hnd = NULL; TALLOC_CTX *mem_ctx; WERROR werr; struct srvsvc_NetShareInfoCtr info_ctr; struct srvsvc_NetShareCtr1 ctr1; int i; uint32_t resume_handle = 0; uint32_t total_entries = 0; struct dcerpc_binding_handle *b; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { DEBUG(0, ("talloc_new failed\n")); return False; } status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc, &pipe_hnd); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Could not connect to srvsvc pipe: %s\n", nt_errstr(status))); TALLOC_FREE(mem_ctx); return False; } b = pipe_hnd->binding_handle; ZERO_STRUCT(info_ctr); ZERO_STRUCT(ctr1); info_ctr.level = 1; info_ctr.ctr.ctr1 = &ctr1; status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx, pipe_hnd->desthost, &info_ctr, 0xffffffff, &total_entries, &resume_handle, &werr); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) { TALLOC_FREE(mem_ctx); TALLOC_FREE(pipe_hnd); return False; } for (i=0; i < info_ctr.ctr.ctr1->count; i++) { struct srvsvc_NetShareInfo1 info = info_ctr.ctr.ctr1->array[i]; fn(info.name, info.type, info.comment, state); } TALLOC_FREE(mem_ctx); TALLOC_FREE(pipe_hnd); return True; }
NO_INLINE static int do_test (void) { fn (2, SIGACTION_FLAGS); return ret; }
int main() { void (*fn)(void *) = polyglot_import("foo"); fn(polyglot_from_string("bar", "ascii")); return 14; }
void exconf_expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) { if (!e) { fn(data, NULL, "y"); return; } if (expr_compare_type(prevtoken, e->type) > 0) fn(data, NULL, "("); switch (e->type) { case E_SYMBOL: if (e->left.sym->name) fn(data, e->left.sym, e->left.sym->name); else fn(data, NULL, "<choice>"); break; case E_NOT: fn(data, NULL, "!"); exconf_expr_print(e->left.expr, fn, data, E_NOT); break; case E_EQUAL: if (e->left.sym->name) fn(data, e->left.sym, e->left.sym->name); else fn(data, NULL, "<choice>"); fn(data, NULL, "=\""); fn(data, e->right.sym, e->right.sym->name); fn(data, NULL, "\""); break; case E_UNEQUAL: if (e->left.sym->name) fn(data, e->left.sym, e->left.sym->name); else fn(data, NULL, "<choice>"); fn(data, NULL, "!=\""); fn(data, e->right.sym, e->right.sym->name); fn(data, NULL, "\""); break; case E_OR: exconf_expr_print(e->left.expr, fn, data, E_OR); fn(data, NULL, " || "); exconf_expr_print(e->right.expr, fn, data, E_OR); break; case E_AND: exconf_expr_print(e->left.expr, fn, data, E_AND); fn(data, NULL, " && "); exconf_expr_print(e->right.expr, fn, data, E_AND); break; case E_RANGE: fn(data, NULL, "["); fn(data, e->left.sym, e->left.sym->name); fn(data, NULL, " "); fn(data, e->right.sym, e->right.sym->name); fn(data, NULL, "]"); break; default: { char buf[32]; sprintf(buf, "<unknown type %d>", e->type); fn(data, NULL, buf); break; } } if (expr_compare_type(prevtoken, e->type) > 0) fn(data, NULL, ")"); }
/* LfdArchive::open * Reads lfd format data from a MemChunk * Returns true if successful, false otherwise *******************************************************************/ bool LfdArchive::open(MemChunk& mc) { // Check data was given if (!mc.hasData()) return false; // Check size if (mc.getSize() < 16) return false; // Check magic header if (mc[0] != 'R' || mc[1] != 'M' || mc[2] != 'A' || mc[3] != 'P') return false; // Get directory length uint32_t dir_len = 0; mc.seek(12, SEEK_SET); mc.read(&dir_len, 4); dir_len = wxINT32_SWAP_ON_BE(dir_len); // Check size if ((unsigned)mc.getSize() < (dir_len) || dir_len % 16) return false; // Guess number of lumps uint32_t num_lumps = dir_len / 16; // Stop announcements (don't want to be announcing modification due to entries being added etc) setMuted(true); // Read each entry theSplashWindow->setProgressMessage("Reading lfd archive data"); size_t offset = dir_len + 16; size_t size = mc.getSize(); for (uint32_t d = 0; offset < size; d++) { // Update splash window progress theSplashWindow->setProgress(((float)d / (float)num_lumps)); // Read lump info uint32_t length = 0; char type[5] = ""; char name[9] = ""; mc.read(type, 4); // Type mc.read(name, 8); // Name mc.read(&length, 4); // Size name[8] = '\0'; type[4] = 0; // Move past the header offset += 16; // Byteswap values for big endian if needed length = wxINT32_SWAP_ON_BE(length); // If the lump data goes past the end of the file, // the gobfile is invalid if (offset + length > size) { wxLogMessage("LfdArchive::open: lfd archive is invalid or corrupt"); Global::error = "Archive is invalid and/or corrupt"; setMuted(false); return false; } // Create & setup lump wxFileName fn(name); fn.SetExt(type); ArchiveEntry* nlump = new ArchiveEntry(fn.GetFullName(), length); nlump->setLoaded(false); nlump->exProp("Offset") = (int)offset; nlump->setState(0); // Add to entry list getRoot()->addEntry(nlump); // Move to next entry offset += length; mc.seek(offset, SEEK_SET); } if (num_lumps != numEntries()) wxLogMessage("Warning: computed %i lumps, but actually %i entries", num_lumps, numEntries()); // Detect all entry types MemChunk edata; theSplashWindow->setProgressMessage("Detecting entry types"); for (size_t a = 0; a < numEntries(); a++) { // Update splash window progress theSplashWindow->setProgress((((float)a / (float)num_lumps))); // Get entry ArchiveEntry* entry = getEntry(a); // Read entry data if it isn't zero-sized if (entry->getSize() > 0) { // Read the entry data mc.exportMemChunk(edata, getEntryOffset(entry), entry->getSize()); entry->importMemChunk(edata); } // Detect entry type EntryType::detectEntryType(entry); // Unload entry data if needed if (!archive_load_data) entry->unloadData(); // Set entry to unchanged entry->setState(0); } // Setup variables setMuted(false); setModified(false); announce("opened"); theSplashWindow->setProgressMessage(""); return true; }