📄 htformat.cc
字号:
bool ht_format_viewer::goto_offset(FileOfs ofs, bool save_vstate){ return false;}bool ht_format_viewer::goto_pos(viewer_pos pos, bool save_vstate){ return false;}static bool format_viewer_func_handler(eval_scalar *result, char *name, eval_scalarlist *params){ ht_format_viewer *viewer = (ht_format_viewer*)eval_get_context(); return viewer->func_handler(result, name, params);}static bool format_viewer_symbol_handler(eval_scalar *result, char *name){ ht_format_viewer *viewer = (ht_format_viewer*)eval_get_context(); return viewer->symbol_handler(result, name);}void ht_format_viewer::handlemsg(htmsg *msg){ switch (msg->msg) { case cmd_popup_dialog_eval: eval_dialog(format_viewer_func_handler, format_viewer_symbol_handler, this); clearmsg(msg); return; case msg_goto_offset: { FileOfs o = (FileOfs)msg->data1.q; if (goto_offset(o, false)) { clearmsg(msg); return; } break; } case msg_vstate_restore: vstate_restore((Object*)msg->data1.ptr); clearmsg(msg); return; case cmd_file_truncate: { File *f = (File*)msg->data1.ptr; FileOfs o = (FileOfs)msg->data2.q; if (file == f) { ht_format_loc loc; loc_enum_start(); while (loc_enum_next(&loc)) { if (o < loc.start+loc.length) { if (confirmbox("truncating at %08qx will destroy format '%s', continue ? \n(format ranges from %08qx to %08qx)", o, loc.name, loc.start, loc.start+loc.length) != button_yes) { clearmsg(msg); return; } break; } } } break; } case cmd_edit_mode_i: { if (file/* && (file==msg->data1.ptr)*/) { try { file->setAccessModex(IOAM_READ | IOAM_WRITE); htmsg m; m.msg = cmd_edit_mode; m.type = mt_broadcast; sendmsg(&m); } catch (const IOException &e) { String fn; errorbox("can't open file %y in write mode! (%y)", &file->getFilename(fn), &e); } } clearmsg(msg); return; } case cmd_view_mode_i: if (file /*&& (file==msg->data1.ptr)*/) { FileOfs size = file->getSize(); file->cntl(FCNTL_MODS_INVD); try { file->setAccessModex(IOAM_READ); htmsg m; m.msg = cmd_view_mode; m.type = mt_broadcast; sendmsg(&m); } catch (const IOException &e) { String fn; errorbox("can't (re)open file %y in read mode! (%y)", &file->getFilename(fn), &e); } if (size != file->getSize()) { htmsg m; m.msg = msg_filesize_changed; m.type = mt_broadcast; sendmsg(&m); } } clearmsg(msg); return; } ht_viewer::handlemsg(msg);}void ht_format_viewer::loc_enum_start(){}bool ht_format_viewer::loc_enum_next(ht_format_loc *loc){ return false;}bool ht_format_viewer::next_logical_pos(viewer_pos pos, viewer_pos *npos){ return false;}bool ht_format_viewer::next_logical_offset(FileOfs ofs, FileOfs *nofs){ return false;}bool ht_format_viewer::offset_to_pos(FileOfs ofs, viewer_pos *pos){ return false;}bool ht_format_viewer::vstate_save(){ Object *vs = vstate_create(); if (vs) { htmsg m; m.msg = msg_vstate_save; m.type = mt_empty; m.data1.ptr = vs; m.data2.ptr = this; app->sendmsg(&m); return true; } return false;}uint ht_format_viewer::pread(FileOfs ofs, void *buf, uint size){ try { file->seek(ofs); return file->read(buf, size); } catch (const IOException &e) { return 0; }}ht_search_result *ht_format_viewer::psearch(ht_search_request *search, FileOfs start, FileOfs end){ return 0;}void ht_format_viewer::pselect_add(FileOfs start, FileOfs end){}void ht_format_viewer::pselect_get(FileOfs *start, FileOfs *end){}void ht_format_viewer::pselect_set(FileOfs start, FileOfs end){}uint ht_format_viewer::pwrite(FileOfs ofs, void *buf, uint size){ sendmsg(msg_file_changed); file->seek(ofs); return file->write(buf, size);}bool ht_format_viewer::qword_to_offset(uint64 q, FileOfs *ofs){ return false;}bool ht_format_viewer::qword_to_pos(uint64 q, viewer_pos *pos){ return false;}bool ht_format_viewer::show_search_result(ht_search_result *r){ switch (r->search_class) { case SC_PHYSICAL: { ht_physical_search_result *s = (ht_physical_search_result*)r; if (!goto_offset(s->offset, this)) return false; pselect_set(s->offset, s->offset + s->size); return true; } case SC_VISUAL: { ht_visual_search_result *s = (ht_visual_search_result*)r; return goto_pos(s->pos, this); } } return false;}bool ht_format_viewer::string_to_qword(const char *string, uint64 *q){ eval_scalar r; if (eval(&r, string, format_viewer_func_handler, format_viewer_symbol_handler, this)) { eval_int i; scalar_context_int(&r, &i); scalar_destroy(&r); *q = i.value; return true; } else { const char *s; int p; get_eval_error(&s, &p); ht_snprintf(globalerror, GLOBAL_ERROR_SIZE, "%s at pos %d", s, p); } return false;}bool ht_format_viewer::string_to_pos(const char *string, viewer_pos *pos){ uint64 q; if (!string_to_qword(string, &q)) return false; return qword_to_pos(q, pos);}bool ht_format_viewer::string_to_offset(char *string, FileOfs *ofs){ uint64 q; if (!string_to_qword(string, &q)) return false; return qword_to_offset(q, ofs);}Object *ht_format_viewer::vstate_create(){ return NULL;}void ht_format_viewer::vstate_restore(Object *view_state){}uint ht_format_viewer::vread(viewer_pos pos, void *buf, uint size){ FileOfs o; if (pos_to_offset(pos, &o)) { return pread(o, buf, size); } return 0;}ht_search_result *ht_format_viewer::vsearch(ht_search_request *search, viewer_pos start, viewer_pos end){ return NULL;}void ht_format_viewer::vselect_add(viewer_pos start, viewer_pos end){ FileOfs so, eo; if (pos_to_offset(start, &so) && pos_to_offset(end, &eo)) { return pselect_add(so, eo); }}void ht_format_viewer::vselect_get(viewer_pos *start, viewer_pos *end){ HT_ERROR("NYI!");}void ht_format_viewer::vselect_set(viewer_pos start, viewer_pos end){ FileOfs so, eo; if (pos_to_offset(start, &so) && pos_to_offset(end, &eo)) { return pselect_set(so, eo); }}uint ht_format_viewer::vwrite(viewer_pos pos, void *buf, uint size){ FileOfs o; if (pos_to_offset(pos, &o)) { return pwrite(o, buf, size); } return 0;}/* * CLASS ht_uformat_view */class ht_uformat_viewer_vstate: public Object {public: int edit; ht_sub *first_sub, *last_sub; /* top line position */ uformat_viewer_pos top; /* cursor line and tag position */ uformat_viewer_pos cursor; int cursor_state; int cursor_ypos; /* selection*/ FileOfs sel_start; FileOfs sel_end;};void ht_uformat_viewer::init(Bounds *b, const char *desc, int caps, File *file, ht_format_group *format_group){ tagpal.data = NULL; tagpal.size = 0; ht_format_viewer::init(b, desc, caps, file, format_group); VIEW_DEBUG_NAME("ht_uformat_view"); first_sub = 0; last_sub = 0; clear_viewer_pos(&top); clear_viewer_pos(&cursor); xscroll = 0; cursor_ypos = 0; cursor_visual_length = 0; cursor_visual_xpos = 0; cursor_select = 0; cursor_select_start = -1ULL; sel_start = 0; sel_end = 0; isdirty_cursor_line = 0; search_caps = SEARCHMODE_VREGEX; uf_initialized = false;}void ht_uformat_viewer::done(){ edit_end(); clear_subs(); free(tagpal.data); ht_format_viewer::done();}int ht_uformat_viewer::address_input(const char *title, char *result, int limit, uint32 histid){ Bounds b; app->getbounds(&b); b.x = (b.w - 60) / 2, b.y = (b.h - 8) / 2; b.w = 60; b.h = 8; ht_dialog *dialog = new ht_dialog(); dialog->init(&b, title, FS_KILLER | FS_TITLE | FS_MOVE | FS_RESIZE); ht_strinputfield *input; const char *label = "~Address"; Bounds b2; b2.x = 3 + strlen(label); b2.y = 1; b2.w = b.w - 3 - b2.x; b2.h = 1; List *hist = NULL; if (histid) hist = (List*)getAtomValue(histid); input = new ht_strinputfield(); input->init(&b2, limit, hist); ht_inputfield_data d; d.text = (byte*)result; d.textlen = strlen((char*)d.text); input->databuf_set(&d, sizeof d); dialog->insert(input); if (label) { b2.x = 1; b2.y = 1; b2.w = 3 + strlen(label) - b2.x; b2.h = 1; ht_label *lab = new ht_label(); lab->init(&b2, label, input); dialog->insert(lab); } b2.x = b.w - 45; b2.y = b.h - 5; b2.w = 10; b2.h = 2; ht_button *bok = new ht_button(); bok->init(&b2, "O~k", button_ok); dialog->insert(bok); b2.x += 12; ht_button *bcancel = new ht_button(); bcancel->init(&b2, "~Cancel", button_cancel); dialog->insert(bcancel); b2.x += 12; b2.w = 14; ht_button *bhelp = new ht_button(); bhelp->init(&b2, "~Functions", 100); dialog->insert(bhelp); int r; bool run = true; int retval = button_cancel; while (run && (r = dialog->run(0)) != button_cancel) { switch (r) { case 100: { dialog_eval_help(format_viewer_func_handler, format_viewer_symbol_handler, this); break; } case button_ok: { int dsize = input->datasize(); ht_inputfield_data *data = ht_malloc(dsize); ViewDataBuf vdb(input, data, dsize); bin2str(result, data->text, data->textlen); free(data); if (hist) insert_history_entry(hist, result, 0); run = false; retval = button_ok; break; } } } dialog->done(); delete dialog; return retval;}void ht_uformat_viewer::adjust_cursor_group(){ cursorline_get(); int g=tag_count_groups(cursor_line); if (cursor.tag_group>=g) cursor.tag_group=0;}void ht_uformat_viewer::adjust_cursor_idx(){ cursorline_get(); int c = tag_count_selectable_tags_in_group(cursor_line, cursor.tag_group); if (cursor.tag_idx > c-1) cursor.tag_idx = c-1;}int ht_uformat_viewer::center_view(viewer_pos p){ top = p.u; int r = prev_line(&top, size.h/2); cursorline_dirty(); return r;}void ht_uformat_viewer::check_cursor_visibility(){ if (cursor_state != cursor_state_disabled) { if ((cursor_ypos < 0) || (cursor_ypos >= size.h)) { cursor_state=cursor_state_invisible; } else { cursor_state=cursor_state_visible; } }}void ht_uformat_viewer::complete_init(){ if (uf_initialized) return; cursor_state=cursor_state_disabled; if (!first_sub) { uf_initialized = true; return; } /* initialize top_* */ clear_viewer_pos(&top); top.sub = first_sub; top.sub->first_line_id(&top.line_id); cursor_tag_micropos = 0; uformat_viewer_pos p; clear_viewer_pos(&p); p.sub = first_sub; p.sub->first_line_id(&p.line_id); char line[1024]; cursor_ypos--; do { cursor_ypos++; if (!p.sub->getline(line, sizeof line, p.line_id)) break; if (tag_count_selectable_tags(line)) { if (cursor_ypos < size.h) { cursor_state = cursor_state_visible; } else { cursor_state = cursor_state_invisible; cursor_ypos = -1; } break; } } while (next_line(&p, 1) && cursor_ypos < size.h); p.tag_idx = 0; p.tag_group = 0; if (cursor_state == cursor_state_disabled) { p.sub = first_sub; p.sub->first_line_id(&p.line_id); if (p.sub->getline(line, sizeof line, p.line_id)) { cursor_ypos = -1; cursor_state = cursor_state_invisible; } } cursor = p; /* get cursorline */ cursorline_dirty(); cursorline_get(); /* initialize visual */ update_visual_info(); /* initialize misc */ update_misc_info(); uf_initialized = true;}int ht_uformat_viewer::cursor_left(){ if (cursor.tag_idx) { cursor.tag_idx--; update_visual_info(); update_misc_info(); return 1; } else { if (cursor_up(1)) { cursor_end(); return 1; } } return 0;}int ht_uformat_viewer::cursor_right(){ cursorline_get(); if (cursor.tag_idx < tag_count_selectable_tags_in_group(cursor_line, cursor.tag_group)-1) { cursor.tag_idx++; update_visual_info(); update_misc_info(); return 1; } else { if (cursor_down(1)) { cursor_home(); return 1; } } return 0;}int ht_uformat_viewer::cursor_up(int n){ switch (cursor_state) { case cursor_state_invisible: case cursor_state_visible: { if (n == 1 && cursor_state == cursor_state_visible) { int r = 0; uformat_viewer_pos c; clear_viewer_pos(&c); c = cursor; char c_line[1024]; int c_ypos = cursor_ypos; int c_tag_idx = cursor.tag_idx; int c_tag_group = cursor.tag_group; int d_tag_group = cursor.tag_group; while (prev_line(&c, 1) && c_ypos >= 0) { c_ypos--; c.sub->getline(c_line, sizeof c_line, c.line_id); int g = tag_count_groups(c_line); if (d_tag_group < g) c_tag_group = d_tag_group; int s; if (c_tag_group >= g) { c_tag_group = g-1; s = tag_count_selectable_tags_in_group(c_line, c_tag_group); if (s) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -