📄 heme.c
字号:
cur_offset = offset; cur_line = (cur_offset - beg_offset) / bpl; mvwprintw(w_main, cur_line, 3 * (cur_offset % bpl), "%02X", b); printable(&b); mvwprintw(w_ascii, cur_line, cur_offset % bpl, "%c", b); hilite(); } } else { undo_t fu; off_t t; fu = undo_list[undo_count]; for(t = 0; t <= fu.offset2 - fu.offset1; t++) put_byte(fu.offset1 + t, fu.fill_bytes[t]); offset = undo_list[undo_count].offset1; /* update the view */ if(offset >= beg_offset && offset < beg_offset + bpl * max_lines) { unhilite(); t = 0; while(offset < beg_offset + bpl * max_lines && offset <= fu.offset2) { b = fu.fill_bytes[t]; cur_offset = offset; cur_line = (cur_offset - beg_offset) / bpl; mvwprintw(w_main, cur_line, 3 * (cur_offset % bpl), "%02X", b); printable(&b); mvwprintw(w_ascii, cur_line, cur_offset % bpl, "%c", b); offset++; t++; } /* back to the last position */ cur_offset -= t - 1; cur_line = (cur_offset - beg_offset) / bpl; hilite(); } free(fu.fill_bytes); } undo_list = xrealloc(undo_list, sizeof(undo_t) * undo_count);}static int get_user_input(const char *prompt){ mvprintw(LINES - 1, 1, "%s", prompt); clrtoeol(); if(use_colors) mvchgat(LINES - 1, 0, -1, A_NORMAL, 3, NULL); else mvchgat(LINES - 1, 0, -1, A_STANDOUT, 0, NULL); wmove(stdscr, LINES - 1, strlen(prompt) + 1); wrefresh(stdscr); return tolower(getch());}static int ask_user_offset(const char *prompt, off_t *uoff){ char tmp[30], *p; int base, t; off_t ret; mvprintw(LINES - 1, 1, "%s", prompt); clrtoeol(); if(use_colors) mvchgat(LINES - 1, 0, -1, A_NORMAL, 3, NULL); else { mvchgat(LINES - 1, 0, -1, A_STANDOUT, 0, NULL); attron(A_STANDOUT); } wmove(stdscr, LINES - 1, strlen(prompt) + 1); wrefresh(stdscr); echo(); getnstr(tmp, sizeof(tmp)); noecho(); if(use_colors == 0) attroff(A_STANDOUT); p = tmp; while(isspace(*p)) p++; base = 10; if(*p == '0') { if(*(p + 1) == 'x' || *(p + 1) == 'X') { base = 16; p += 2; } else base = 8; } ret = 0; /* calc value */ while(*p) { if(isdigit(*p)) t = *p - '0'; else if(isxdigit(*p) && base == 16) t = 10 + tolower(*p) - 'a'; else return -1; ret *= base; ret += t; p++; } *uoff = ret; return 0;}static int ask_user_byte(const char *prompt, byte *bv){ off_t ret; if(ask_user_offset(prompt, &ret) < 0 || ret > 255) return -1; *bv = (byte) ret; return 0;}static const char *ask_user_string(const char *prompt){ static char buf[1024]; mvprintw(LINES - 1, 1, "%s", prompt); clrtoeol(); if(use_colors) mvchgat(LINES - 1, 0, -1, A_NORMAL, 3, NULL); else { mvchgat(LINES - 1, 0, -1, A_STANDOUT, 0, NULL); attron(A_STANDOUT); } wmove(stdscr, LINES - 1, strlen(prompt) + 1); wrefresh(stdscr); echo(); getnstr(buf, sizeof(buf)); noecho(); if(use_colors == 0) attroff(A_STANDOUT); return buf;}static void print_message(const char *msg){ mvprintw(LINES - 1, 1, "%s", msg); clrtoeol(); if(use_colors) mvchgat(LINES - 1, 0, -1, A_NORMAL, 3, NULL); else mvchgat(LINES - 1, 0, -1, A_STANDOUT, 0, NULL); wmove(stdscr, LINES - 1, strlen(msg) + 1); wrefresh(stdscr);}static void string_search(const char *p){ static off_t last_string_search_pos = -1; off_t tmp_offset; int i, len; char *s; len = strlen(p); s = xmalloc(len); tmp_offset = cur_offset; if(tmp_offset == last_string_search_pos) tmp_offset++; for(i = 0; i < len; i++) s[i] = get_byte(tmp_offset + i); while(tmp_offset + len < file_size) { if(memcmp(p, s, len) == 0) { unhilite(); last_string_search_pos = cur_offset = tmp_offset; for(beg_offset = cur_offset; beg_offset % bpl != 0; beg_offset--) ; if(beg_offset > end_offset) beg_offset = end_offset; cur_line = (cur_offset - beg_offset) / bpl; for(i = 0; i < max_lines; i++) put_line(i, beg_offset + i * bpl); hilite(); break; } for(i = 0; i < len - 1; i++) s[i] = s[i + 1]; s[i] = get_byte(tmp_offset + len); tmp_offset++; } free(s);}static void byte_search(byte b){ off_t tmp_offset; int i; unhilite(); tmp_offset = cur_offset; while(++cur_offset < file_size && get_byte(cur_offset) != b) ; if(cur_offset == file_size) { /* not found */ cur_offset = tmp_offset; hilite(); return; } if(cur_offset >= beg_offset && cur_offset < beg_offset + bpl * max_lines) { /* byte is in the current view */ cur_line = (cur_offset - beg_offset) / bpl; } else { /* refresh all lines */ for(beg_offset = cur_offset; beg_offset % bpl != 0; beg_offset--) ; cur_line = (cur_offset - beg_offset) / bpl; for(i = 0; i < max_lines; i++) put_line(i, beg_offset + i * bpl); } hilite();}static void show_helpwin(){ WINDOW *w_help; char format[] = "%-14s %s"; w_help = newwin(LINES - 2, COLS, 1, 0); werase(w_help); mvwprintw(w_help, 1, COLS / 2 - 2, "Help"); mvwprintw(w_help, 3, 1, format, "left (right)", "move to previous (next) byte"); mvwprintw(w_help, 4, 1, format, "up (down)", "move to previous (next) line"); mvwprintw(w_help, 5, 1, format, "<", "move to beginning of line"); mvwprintw(w_help, 6, 1, format, ">", "move to end of line"); mvwprintw(w_help, 7, 1, format, "page up", "move 1 page up"); mvwprintw(w_help, 8, 1, format, "page down", "move 1 page down"); mvwprintw(w_help, 9, 1, format, "home", "move to beginning of file"); mvwprintw(w_help, 10, 1, format, "end", "move to end of file"); mvwprintw(w_help, 11, 1, format, "h", "display this help screen"); mvwprintw(w_help, 12, 1, format, "j", "jump to offset"); mvwprintw(w_help, 13, 1, format, "n (w)", "search for byte (string)"); mvwprintw(w_help, 14, 1, format, "r", "repeat last search"); mvwprintw(w_help, 15, 1, format, "l", "fill range with byte"); mvwprintw(w_help, 16, 1, format, "tab", "toggle between hex and ascii editing modes"); mvwprintw(w_help, 17, 1, format, "u", "undo"); mvwprintw(w_help, 18, 1, format, "s", "save file"); mvwprintw(w_help, 19, 1, format, "q", "quit"); mvwprintw(w_help, 22, 1,"Press any key to exit this help screen."); wrefresh(w_help); getch(); delwin(w_help); redrawwin(w_offset); redrawwin(w_main); redrawwin(w_ascii);}static void main_loop(){ int running = 1; int ch, lastch = EOF; int i, ret = 0; off_t tmp_offset; /* determine number of bytes per line (always an even number) */ bpl = (COLS - 14) / 4; if(bpl % 2 != 0) bpl--; /* lines 0 and (LINES - 1) are reserved for status info */ max_lines = LINES - 2; w_offset = newwin(max_lines, 13, 1, 0); w_main = newwin(max_lines, COLS - (bpl + 1) - 13, 1, 13); w_ascii = newwin(max_lines, bpl + 1, 1, COLS - bpl - 1); scrollok(w_offset, TRUE); scrollok(w_main, TRUE); scrollok(w_ascii, TRUE); current_nibble = cur_offset = cur_line = beg_offset = 0; for(end_offset = file_size; end_offset % bpl != 0; end_offset--) ; end_offset -= bpl * (max_lines - 1); if(end_offset < 0) end_offset = 0; if(use_colors) { wattrset(w_offset, COLOR_PAIR(1)); wattrset(w_main, COLOR_PAIR(1)); wattrset(w_ascii, COLOR_PAIR(1)); wattrset(stdscr, COLOR_PAIR(3)); for(i = 0; i < LINES; i++) mvchgat(i, COLS - bpl - 2, 1, A_NORMAL, 1, NULL); } for(i = 0; i < max_lines; i++) put_line(i, i * bpl); hilite(); do { put_status(); wnoutrefresh(stdscr); wnoutrefresh(w_offset); wnoutrefresh(w_main); wnoutrefresh(w_ascii); if(!mode_ascii) { wmove(w_main, cur_line, (3 * (cur_offset % bpl)) + current_nibble); wnoutrefresh(w_main); } if(mode_ascii) { wmove(w_ascii, cur_line, cur_offset % bpl); wnoutrefresh(w_ascii); } doupdate(); ch = getch(); if(ch == '\t') { mode_ascii = !mode_ascii; continue; } if(mode_ascii && isprint(ch) && (0xFF00 & ch) == 0) { set_byte(ch); ch = KEY_RIGHT; /* nice hack for incrementing current_offset ... */ } switch(ch) { case KEY_LEFT: if(cur_line == 0 && beg_offset == 0 && cur_offset == 0 && (current_nibble == 0 || mode_ascii)) break; unhilite(); if(cur_line == 0 && beg_offset > 0 && cur_offset % bpl == 0) { /* move one line up */ wscrl(w_offset, -1); wscrl(w_main, -1); wscrl(w_ascii, -1); beg_offset -= bpl; cur_offset--; put_line(0, beg_offset); } else { if(mode_ascii || current_nibble == 0) { cur_offset--; if(mode_ascii) { current_nibble=0; } else { current_nibble=1; } } else { current_nibble--; } if((cur_offset + 1) % bpl == 0 && (current_nibble == 1 || mode_ascii)) cur_line--; } hilite(); break; case KEY_RIGHT: advance_right(); break; case KEY_UP: if(cur_line == 0 && beg_offset == 0) break; unhilite(); if(cur_line == 0) { /* move one line up */ wscrl(w_offset, -1); wscrl(w_main, -1); wscrl(w_ascii, -1); beg_offset -= bpl; cur_offset -= bpl; put_line(0, beg_offset); } else { cur_offset -= bpl; cur_line--; } hilite(); break; case KEY_DOWN: /* move one line down, but only if allowed */ if(cur_offset + bpl >= file_size && beg_offset == end_offset) break; unhilite(); if(cur_line == max_lines - 1) { scroll(w_offset); scroll(w_main); scroll(w_ascii); beg_offset += bpl; if(cur_offset + bpl >= file_size && beg_offset <= end_offset) cur_line--; else cur_offset += bpl; put_line(max_lines - 1, beg_offset + bpl * (max_lines - 1)); } else { cur_offset += bpl; cur_line++; } hilite(); break; case KEY_HOME: if(cur_offset == 0) break; unhilite(); if(beg_offset == 0) { /* we just need to move to the beginning of the line */ cur_offset = 0; cur_line = 0; hilite(); break; } for(i = 0; i < max_lines; i++) put_line(i, i * bpl); cur_offset = 0; cur_line = 0; beg_offset = 0; hilite(); break; case KEY_END: if(cur_offset == file_size - 1) break; unhilite(); if(beg_offset == end_offset) { /* we just need to move to EOF */ cur_offset = file_size - 1; cur_line = (cur_offset - beg_offset) / bpl; hilite(); break; } beg_offset = end_offset; for(i = 0; i < max_lines; i++) put_line(i, beg_offset + i * bpl); cur_offset = file_size - 1; cur_line = (cur_offset - beg_offset) / bpl; hilite(); break; case KEY_NPAGE: if(beg_offset == end_offset && cur_offset == file_size - 1) break; beg_offset += bpl * max_lines; if(beg_offset >= end_offset) { beg_offset = end_offset; cur_offset = file_size - 1; cur_line = (cur_offset - beg_offset) / bpl; } else cur_offset += bpl * max_lines; for(i = 0; i < max_lines; i++) put_line(i, beg_offset + i * bpl); hilite(); break; case KEY_PPAGE: if(beg_offset == 0 && cur_offset == 0) break; beg_offset -= bpl * max_lines; if(beg_offset < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -