first commit
This commit is contained in:
217
chexed.c
Normal file
217
chexed.c
Normal file
@@ -0,0 +1,217 @@
|
||||
#include <ncurses.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define ROW_SIZE 16
|
||||
#define CTRL_KEY(k) ((k) & 0x1f)
|
||||
|
||||
unsigned char* buffer;
|
||||
long file_size;
|
||||
char* filename;
|
||||
int cursor_pos = 0;
|
||||
int scroll_offset = 0;
|
||||
|
||||
void load_file(const char* fname) {
|
||||
FILE* f = fopen(fname, "rb");
|
||||
if (!f) {
|
||||
perror("Nie można otworzyć pliku");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
file_size = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
buffer = malloc(file_size);
|
||||
fread(buffer, 1, file_size, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void save_file() {
|
||||
FILE* f = fopen(filename, "wb");
|
||||
if (f) {
|
||||
fwrite(buffer, 1, file_size, f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
void draw_interface() {
|
||||
clear();
|
||||
int max_y, max_x;
|
||||
getmaxyx(stdscr, max_y, max_x);
|
||||
|
||||
attron(COLOR_PAIR(1));
|
||||
mvprintw(0, 0, "HEXED: %s (ROZMIAR: %ld bajtow)", filename, file_size);
|
||||
mvprintw(
|
||||
1, 0,
|
||||
"^S: Zapisz | ^Q: Wyjscie | Strzalki: Nawigacja | +/-: Zmien wartosc");
|
||||
mvhline(2, 0, ACS_HLINE, max_x);
|
||||
attroff(COLOR_PAIR(1));
|
||||
|
||||
int rows_to_draw = max_y - 4;
|
||||
|
||||
for (int i = 0; i < rows_to_draw; i++) {
|
||||
int offset = scroll_offset + (i * ROW_SIZE);
|
||||
if (offset >= file_size) break;
|
||||
|
||||
attron(COLOR_PAIR(1));
|
||||
mvprintw(3 + i, 0, "%08X: ", offset);
|
||||
attroff(COLOR_PAIR(1));
|
||||
|
||||
for (int j = 0; j < ROW_SIZE; j++) {
|
||||
if (offset + j < file_size) {
|
||||
unsigned char val = buffer[offset + j];
|
||||
int color_pair = (val == 0x00) ? 3 : 2;
|
||||
|
||||
if (offset + j == cursor_pos) {
|
||||
attron(COLOR_PAIR(4));
|
||||
printw("%02X ", val);
|
||||
attroff(COLOR_PAIR(4));
|
||||
} else {
|
||||
attron(COLOR_PAIR(color_pair));
|
||||
printw("%02X ", val);
|
||||
attroff(COLOR_PAIR(color_pair));
|
||||
}
|
||||
} else {
|
||||
printw(" ");
|
||||
}
|
||||
}
|
||||
|
||||
printw("| ");
|
||||
|
||||
for (int j = 0; j < ROW_SIZE; j++) {
|
||||
if (offset + j < file_size) {
|
||||
unsigned char c = buffer[offset + j];
|
||||
char ch = (isprint(c)) ? c : '.';
|
||||
int color_pair = (c == 0x00) ? 3 : 2;
|
||||
|
||||
if (offset + j == cursor_pos) {
|
||||
attron(COLOR_PAIR(4));
|
||||
printw("%c", ch);
|
||||
attroff(COLOR_PAIR(4));
|
||||
} else {
|
||||
attron(COLOR_PAIR(color_pair));
|
||||
printw("%c", ch);
|
||||
attroff(COLOR_PAIR(color_pair));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
void update_byte(int ch) {
|
||||
int val = -1;
|
||||
if (ch >= '0' && ch <= '9') val = ch - '0';
|
||||
if (ch >= 'a' && ch <= 'f') val = ch - 'a' + 10;
|
||||
if (ch >= 'A' && ch <= 'F') val = ch - 'A' + 10;
|
||||
|
||||
if (val != -1) {
|
||||
buffer[cursor_pos] = (buffer[cursor_pos] << 4) | val;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Uzycie: %s <plik>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
load_file(filename);
|
||||
|
||||
initscr();
|
||||
start_color();
|
||||
use_default_colors();
|
||||
|
||||
init_pair(1, COLOR_CYAN, -1);
|
||||
init_pair(2, COLOR_WHITE, -1);
|
||||
init_pair(3, COLOR_BLUE, -1);
|
||||
init_pair(4, COLOR_BLACK, COLOR_WHITE);
|
||||
|
||||
raw();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
curs_set(0);
|
||||
|
||||
int ch;
|
||||
|
||||
int max_y, max_x;
|
||||
draw_interface();
|
||||
int running = 1;
|
||||
while (running) {
|
||||
ch = getch();
|
||||
|
||||
getmaxyx(stdscr, max_y, max_x);
|
||||
|
||||
switch (ch) {
|
||||
case CTRL_KEY('q'):
|
||||
running = 0;
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (cursor_pos >= ROW_SIZE) cursor_pos -= ROW_SIZE;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (cursor_pos + ROW_SIZE < file_size) cursor_pos += ROW_SIZE;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (cursor_pos > 0) cursor_pos--;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if (cursor_pos < file_size - 1) cursor_pos++;
|
||||
break;
|
||||
case '+':
|
||||
buffer[cursor_pos]++;
|
||||
break;
|
||||
case '-':
|
||||
buffer[cursor_pos]--;
|
||||
break;
|
||||
case CTRL_KEY('s'):
|
||||
save_file();
|
||||
mvprintw(max_y - 1, 0, "ZAPISANO!");
|
||||
break;
|
||||
case KEY_NPAGE: {
|
||||
int rows = max_y - 4;
|
||||
int jump = rows * ROW_SIZE;
|
||||
|
||||
if (cursor_pos + jump < file_size) {
|
||||
cursor_pos += jump;
|
||||
} else {
|
||||
cursor_pos = file_size - 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case KEY_PPAGE: {
|
||||
int rows = max_y - 4;
|
||||
int jump = rows * ROW_SIZE;
|
||||
|
||||
if (cursor_pos - jump >= 0) {
|
||||
cursor_pos -= jump;
|
||||
} else {
|
||||
cursor_pos = 0;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
update_byte(ch);
|
||||
break;
|
||||
}
|
||||
|
||||
int rows_on_screen = max_y - 4;
|
||||
int cursor_row_start = (cursor_pos / ROW_SIZE) * ROW_SIZE;
|
||||
|
||||
if (cursor_pos < scroll_offset) {
|
||||
scroll_offset = cursor_row_start;
|
||||
}
|
||||
|
||||
else if (cursor_pos >= scroll_offset + (rows_on_screen * ROW_SIZE)) {
|
||||
scroll_offset = cursor_row_start - ((rows_on_screen - 1) * ROW_SIZE);
|
||||
|
||||
if (scroll_offset < 0) scroll_offset = 0;
|
||||
}
|
||||
|
||||
draw_interface();
|
||||
}
|
||||
|
||||
endwin();
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user