📄 htsearch.cc
字号:
throw MsgfException("Internal error: can't convert offset to viewer_pos"); } if (!format->pos_to_offset(*end, &send.offset)) { send.offset = -1; } break; case SC_VISUAL: *start = sstart.pos; *end = send.pos; break; } } catch (const Exception &e) { errorbox("error: %y", &e); } } dialog->done(); delete dialog; return result;}static ht_replace_method replace_methods[] ={ { "bin: hex/ascii", 0, create_form_replace_hexascii, create_replace_hexascii_context, replace_bin_process }, { NULL }};uint replace_dialog(ht_format_viewer *format, uint searchmodes, bool *cancelled){ *cancelled = false; Bounds b; b.w = 50; b.h = 22; b.x = (screen->w - b.w)/2; b.y = (screen->h - b.h)/2; ht_replace_dialog *dialog = new ht_replace_dialog(); dialog->init(&b); Bounds k; dialog->search_mode_xgroup->getbounds(&k); k.x = 0; k.y = 0; int i; i = 0; ht_search_method *q = search_methods; while (q->name) { if ((q->search_mode_mask & searchmodes) && (q->search_class == SC_PHYSICAL)) { Bounds v = k; ht_view *form = q->create_form(&v, q->histid); dialog->insert_search_mode(i, q->name, form); } q++; i++; } dialog->replace_mode_xgroup->getbounds(&k); k.x = 0; k.y = 0; i = 0; ht_replace_method *w = replace_methods; while (w->name) { Bounds v = k; ht_view *form = w->create_form(&v, w->histid); dialog->insert_replace_mode(i, w->name, form); w++; i++; } dialog->select_search_mode(lastsearchmodeid); dialog->select_replace_mode(lastreplacemodeid); uint repl_count = 0; if (dialog->run(false)) { int smodeid = dialog->get_search_modeid(); int rmodeid = dialog->get_replace_modeid(); lastsearchmodeid = smodeid; lastreplacemodeid = rmodeid; ht_search_method *s = &search_methods[smodeid]; ht_replace_method *r = &replace_methods[rmodeid]; ht_view *sform = dialog->get_search_modeform(); ht_view *rform = dialog->get_replace_modeform(); search_pos start, end; ht_search_request *request = NULL; try { /* create history entry */ if (s->create_desc) { char hist_desc[1024]; s->create_desc(hist_desc, sizeof hist_desc, sform); insert_history_entry((List*)getAtomValue(s->histid), hist_desc, sform); } /* search */ start.offset=0; end.offset=0xffffffff; format->get_current_offset(&start.offset); request = s->create_request(&start, &end, sform, format, s->search_class); } catch (const Exception &e) { errorbox("error: %y", &e); } if (request) { FileOfs so = start.offset, eo = end.offset; ht_physical_search_result *result; format->vstate_save(); try { bool replace_all = false; while ((result = (ht_physical_search_result*)format->psearch(request, so, eo))) { FileOfs irepllen = 0; bool do_replace = false; if (!replace_all) { bool showed = format->show_search_result(result); int r = msgbox(btmask_yes+btmask_no+btmask_all+btmask_cancel, "confirmation", 0, align_center, "replace?"); if (showed) app->sendmsg(cmd_vstate_restore); switch (r) { case button_yes: do_replace = true; break; case button_no: break; case button_all: replace_all = true; break; } if (r == button_cancel) { *cancelled = true; delete result; break; } } if (replace_all || do_replace) { Object *rctx = r->create_replace_context(format->get_file(), result->offset, result->size, rform, &irepllen); bool p = execute_process(r->replace_process, rctx); delete rctx; if (!p) { delete result; break; } if (irepllen != result->size) { format->sendmsg(msg_filesize_changed); } so = result->offset + irepllen; repl_count++; } else { so = result->offset + result->size; } delete result; } } catch (const Exception &e) { errorbox("error: %y", &e); } app->sendmsg(cmd_vstate_restore); } delete request; } dialog->done(); delete dialog; return repl_count;}#define REPLACE_COPY_BUF_SIZE 64*1024Object* create_replace_bin_context(File *file, FileOfs ofs, FileOfs len, byte *repl, FileOfs repllen, FileOfs *return_repllen){ ht_replace_bin_context *ctx = new ht_replace_bin_context(); ctx->file = file; ctx->ofs = ofs; ctx->len = len; ctx->repl = ht_malloc(repllen); memcpy(ctx->repl, repl, repllen); ctx->repllen = repllen; if (repllen > len) { ctx->o = file->getSize(); } else if (len > repllen) { ctx->o = ofs + len; } ctx->z = REPLACE_COPY_BUF_SIZE; if (len != repllen) ctx->buf = ht_malloc(REPLACE_COPY_BUF_SIZE); ctx->return_repllen = return_repllen; return ctx;}bool replace_bin_process(Object *context, ht_text *progress_indicator){ progress_indicator->settext("replacing...\n"); ht_replace_bin_context *c = (ht_replace_bin_context*)context; if (c->repllen > c->len) { /* grow */ uint size = c->file->getSize(); c->file->extend(size + c->repllen - c->len); if (c->o > c->z) { c->o -= c->z; } else { c->z = c->o; c->o = 0; } if (c->o < c->ofs+c->len) { c->z -= c->ofs + c->len - c->o; c->o = c->ofs + c->len; } c->file->seek(c->o); c->file->readx(c->buf, c->z); c->file->seek(c->o + c->repllen - c->len); c->file->writex(c->buf, c->z); if (c->o > c->ofs + c->len) return true; c->file->seek(c->ofs); c->file->writex(c->repl, c->repllen); free(c->buf); } else if (c->repllen < c->len) { /* shrink */ uint size = c->file->getSize(); if (c->o == c->ofs + c->len) { c->file->seek(c->ofs); c->file->writex(c->repl, c->repllen); } if (c->z > size - c->o) { c->z = size - c->o; } c->file->seek(c->o); c->file->readx(c->buf, c->z); c->file->seek(c->o - (c->len - c->repllen)); c->file->writex(c->buf, c->z); c->o += REPLACE_COPY_BUF_SIZE; if (c->z == REPLACE_COPY_BUF_SIZE) return true; c->file->truncate(size - (c->len - c->repllen)); free(c->buf); } else { c->file->seek(c->ofs); c->file->writex(c->repl, c->repllen); } if (c->return_repllen) *c->return_repllen = c->repllen; return false;}/* * CLASS ht_search_dialog */void ht_search_dialog::init(Bounds *b, const char *title){ ht_dialog::init(b, title, FS_KILLER | FS_TITLE | FS_MOVE); VIEW_DEBUG_NAME("ht_search_dialog"); smodecount = 0; smodeidx = -1; Bounds c; c.x=1; c.y=1; c.w=20; c.h=1; search_mode_popup = new ht_listpopup(); search_mode_popup->init(&c); insert(search_mode_popup); c.x=1; c.y=0; c.w=4; c.h=1; ht_label *mlabel=new ht_label(); mlabel->init(&c, "~mode", search_mode_popup); insert(mlabel); c.x = 1; c.y = 3; c.w = size.w-4; c.h = MIN(10, size.h-4); search_mode_xgroup = new ht_xgroup(); search_mode_xgroup->init(&c, VO_SELECTABLE, "modes"); insert(search_mode_xgroup);}void ht_search_dialog::done(){ ht_dialog::done();}int ht_search_dialog::find_search_mode(int id){ for (int i=0; i<smodecount; i++) { if (smodes[i].id==id) { return i; } } return -1;}void ht_search_dialog::handlemsg(htmsg *msg){ if (msg->msg==msg_keypressed) { ht_dialog::handlemsg(msg); ht_listpopup_data data; ViewDataBuf vdb(search_mode_popup, &data, sizeof data); if ((int)data.cursor_pos != smodeidx) { smodeidx = data.cursor_pos; select_search_mode_bymodeidx(); } } else ht_dialog::handlemsg(msg);}int ht_search_dialog::get_search_modeid(){ return smodes[smodeidx].id;}ht_view *ht_search_dialog::get_search_modeform(){ return smodes[smodeidx].view;}void ht_search_dialog::insert_search_mode(int id, const char *desc, ht_view *v){ if (smodecount < MAX_SEARCH_DIALOG_MODES) { search_mode_xgroup->insert(v); search_mode_popup->insertstring(desc); smodes[smodecount].id=id; smodes[smodecount].view=v; smodecount++; focus(search_mode_xgroup); }}void ht_search_dialog::select_search_mode(int id){ int i=find_search_mode(id); if (i!=-1) { smodeidx=i; select_search_mode_bymodeidx(); }}void ht_search_dialog::select_search_mode_bymodeidx(){ ht_listpopup_data d; d.cursor_pos = smodeidx; d.cursor_string = NULL; search_mode_popup->databuf_set(&d, sizeof d); focus(smodes[smodeidx].view); sendmsg(msg_dirtyview, 0);}/* * CLASS ht_replace_dialog */void ht_replace_dialog::init(Bounds *b){ ht_search_dialog::init(b, "replace"); rmodecount=0; Bounds c; c.x=1; c.y=15; c.w=20; c.h=1; replace_mode_popup = new ht_listpopup(); replace_mode_popup->init(&c); insert(replace_mode_popup); c.x=0; c.y=13; c.w=size.w-2; c.h=1; ht_hbar *hbar=new ht_hbar(); hbar->init(&c, 0, NULL); insert(hbar); c.x=1; c.y=14; c.w=4; c.h=1; ht_label *mlabel=new ht_label(); mlabel->init(&c, "~replace mode", replace_mode_popup); insert(mlabel); c.x=1; c.y=17; c.w=size.w-4; c.h=size.h-c.y; replace_mode_xgroup = new ht_xgroup(); replace_mode_xgroup->init(&c, VO_SELECTABLE, "replace modes"); insert(replace_mode_xgroup);}void ht_replace_dialog::done(){ ht_dialog::done();}int ht_replace_dialog::find_replace_mode(int id){ for (int i=0; i<rmodecount; i++) { if (rmodes[i].id==id) { return i; } } return -1;}void ht_replace_dialog::handlemsg(htmsg *msg){ if (msg->msg == msg_keypressed) { ht_search_dialog::handlemsg(msg); ht_listpopup_data data; ViewDataBuf vdb(replace_mode_popup, &data, sizeof data); if ((int)data.cursor_pos != rmodeidx) { rmodeidx=data.cursor_pos; select_replace_mode_bymodeidx(); } } else ht_search_dialog::handlemsg(msg);}int ht_replace_dialog::get_replace_modeid(){ return rmodes[rmodeidx].id;}ht_view *ht_replace_dialog::get_replace_modeform(){ return rmodes[rmodeidx].view;}void ht_replace_dialog::insert_replace_mode(int id, const char *desc, ht_view *v){ if (rmodecount < MAX_REPLACE_DIALOG_MODES) { replace_mode_xgroup->insert(v); replace_mode_popup->insertstring(desc); rmodes[rmodecount].id=id; rmodes[rmodecount].view=v; rmodecount++;// focus(replace_mode_xgroup); }}void ht_replace_dialog::select_replace_mode(int id){ int i=find_replace_mode(id); if (i!=-1) { rmodeidx=i; select_replace_mode_bymodeidx(); }}void ht_replace_dialog::select_replace_mode_bymodeidx(){ ht_listpopup_data d; d.cursor_pos = rmodeidx; d.cursor_string = NULL; replace_mode_popup->databuf_set(&d, sizeof d);// focus(rmodes[rmodeidx].view); sendmsg(msg_dirtyview, 0);}/* * */ ht_search_result *linear_bin_search(ht_search_request *search, FileOfs start, FileOfs end, File *file, FileOfs fofs, FileOfs fsize){ ht_fxbin_search_request *s = (ht_fxbin_search_request*)search; int fl = (search->flags & SFBIN_CASEINSENSITIVE) ? SFBIN_CASEINSENSITIVE : 0; if (start < fofs) start = fofs; if (end > fofs+fsize) end = fofs+fsize; if (fsize && start < end) { /* create result */ bool search_success = false; FileOfs search_ofs; Object *ctx = create_search_bin_context(file, start, end-start, s->data, s->data_size, fl, &search_ofs, &search_success); if (execute_process(search_bin_process, ctx)) { delete ctx; if (search_success) { ht_physical_search_result *r=new ht_physical_search_result(); r->offset = search_ofs; r->size = s->data_size; return r; } } else delete ctx; } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -