1 /* hexedit -- Hexadecimal Editor for Binary Files
2 Copyright (C) 1998 Pixel (Pascal Rigaux)
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/
21 int move_cursor(off_t delta
)
23 return set_cursor(base
+ cursor
+ delta
);
26 int set_cursor(off_t loc
)
28 if (loc
< 0 && base
% lineLength
)
35 if (loc
- base
% lineLength
< 0)
37 else if (!move_base(myfloor(loc
- base
% lineLength
, lineLength
) + base
% lineLength
- base
))
40 } else if (loc
>= base
+ page
) {
41 if (!move_base(myfloor(loc
- base
% lineLength
, lineLength
) + base
% lineLength
- page
+ lineLength
- base
))
44 } else if (loc
> base
+ nbBytes
) {
55 int move_base(off_t delta
)
57 if (mode
== bySector
) {
58 if (delta
> 0 && delta
< page
)
60 else if (delta
< 0 && delta
> -page
)
63 return set_base(base
+ delta
);
66 int set_base(off_t loc
)
70 if (!tryloc(loc
)) return FALSE
;
74 if (mode
!= bySector
&& nbBytes
< page
- lineLength
&& base
!= 0) {
75 base
-= myfloor(page
- nbBytes
- lineLength
, lineLength
);
76 if (base
< 0) base
= 0;
80 if (cursor
> nbBytes
) cursor
= nbBytes
;
85 int computeLineSize(void) { return computeCursorXPos(lineLength
- 1, 0) + 1; }
86 int computeCursorXCurrentPos(void) { return computeCursorXPos(cursor
, hexOrAscii
); }
87 int computeCursorXPos(int cursor
, int hexOrAscii
)
90 int x
= cursor
% lineLength
;
91 int h
= (hexOrAscii
? x
: lineLength
- 1);
93 r
+= normalSpaces
* (h
% blocSize
) + (h
/ blocSize
) * (normalSpaces
* blocSize
+ 1) + (hexOrAscii
&& cursorOffset
);
95 if (!hexOrAscii
) r
+= x
+ normalSpaces
+ 1;
102 /*******************************************************************************/
103 /* Curses functions */
104 /*******************************************************************************/
105 void initCurses(void)
108 have_colors
= has_colors();
109 if (have_colors
&& colored
) {
111 use_default_colors();
112 init_pair(1, COLOR_RED
, -1); /* null zeros */
113 init_pair(2, COLOR_GREEN
, -1); /* control chars */
114 init_pair(3, COLOR_BLUE
, -1); /* extended chars */
120 keypad(stdscr
, TRUE
);
122 if (mode
== bySector
) {
123 lineLength
= modes
[bySector
].lineLength
;
124 page
= modes
[bySector
].page
;
125 page
= myfloor((LINES
- 1) * lineLength
, page
);
126 blocSize
= modes
[bySector
].blocSize
;
127 if (computeLineSize() > COLS
) DIE("%s: term is too small for sectored view (width)\n");
128 if (page
== 0) DIE("%s: term is too small for sectored view (height)\n");
129 } else { /* mode == maximized */
130 if (LINES
<= 4) DIE("%s: term is too small (height)\n");
132 blocSize
= modes
[maximized
].blocSize
;
133 for (lineLength
= blocSize
; computeLineSize() <= COLS
; lineLength
+= blocSize
);
134 lineLength
-= blocSize
;
135 if (lineLength
== 0) DIE("%s: term is too small (width)\n");
137 page
= lineLength
* (LINES
- 1);
139 colsUsed
= computeLineSize();
140 buffer
= malloc(page
);
141 bufferAttr
= malloc(page
* sizeof(*bufferAttr
));
144 void exitCurses(void)
156 for (i
= 0; i
< nbBytes
; i
+= lineLength
) {
157 move(i
/ lineLength
, 0);
158 displayLine(i
, nbBytes
);
160 for (; i
< page
; i
+= lineLength
) {
162 move(i
/ lineLength
, 0);
163 for (j
= 0; j
< colsUsed
; j
++) printw(" "); /* cleanup the line */
164 move(i
/ lineLength
, 0);
165 PRINTW(("%08lX", (int) (base
+ i
)));
170 for (i
= 0; i
< colsUsed
; i
++) printw("-");
172 if (isReadOnly
) i
= '%';
173 else if (edited
) i
= '*';
175 printw("-%c%c %s --0x%llX", i
, i
, baseName
, (long long) base
+ cursor
);
176 if (MAX(fileSize
, lastEditedLoc
)) printw("/0x%llX", (long long) getfilesize());
177 if (mode
== bySector
) printw("--sector %lld", (long long) (base
+ cursor
) / SECTOR_SIZE
);
179 move(cursor
/ lineLength
, computeCursorXCurrentPos());
182 void displayLine(int offset
, int max
)
186 PRINTW(("%08lX ", (int) (base
+ offset
)));
187 for (i
= offset
; i
< offset
+ lineLength
; i
++) {
188 if (i
> offset
) MAXATTRPRINTW(bufferAttr
[i
] & MARKED
, (((i
- offset
) % blocSize
) ? " " : " "));
191 (!(have_colors
&& colored
) ? 0 :
192 buffer
[i
] == 0 ? COLOR_PAIR(1) :
193 buffer
[i
] < ' ' ? COLOR_PAIR(2) :
194 buffer
[i
] >= 127 ? COLOR_PAIR(3) : 0) |
195 bufferAttr
[i
], ("%02X", buffer
[i
]));
200 for (i
= offset
; i
< offset
+ lineLength
; i
++) {
201 if (i
>= max
) PRINTW((" "));
202 else if (buffer
[i
] >= ' ' && buffer
[i
] < 127) ATTRPRINTW(bufferAttr
[i
], ("%c", buffer
[i
]));
203 else ATTRPRINTW(bufferAttr
[i
], ("."));
207 void clr_line(int line
) { move(line
, 0); clrtoeol(); }
209 void displayCentered(char *msg
, int line
)
212 move(line
, (COLS
- strlen(msg
)) / 2);
216 void displayOneLineMessage(char *msg
)
218 int center
= page
/ lineLength
/ 2;
219 clr_line(center
- 1);
220 clr_line(center
+ 1);
221 displayCentered(msg
, center
);
224 void displayTwoLineMessage(char *msg1
, char *msg2
)
226 int center
= page
/ lineLength
/ 2;
227 clr_line(center
- 2);
228 clr_line(center
+ 1);
229 displayCentered(msg1
, center
- 1);
230 displayCentered(msg2
, center
);
233 void displayMessageAndWaitForKey(char *msg
)
235 displayTwoLineMessage(msg
, pressAnyKey
);
239 int displayMessageAndGetString(char *msg
, char **last
, char *p
, int p_size
)
243 displayOneLineMessage(msg
);
246 getnstr(p
, p_size
- 1);
249 if (*last
) strcpy(p
, *last
); else ret
= FALSE
;
257 void ungetstr(char *s
)
261 for (p
= s
+ strlen(s
) - 1; p
>= s
; p
--) ungetch(*p
);
264 int get_number(off_t
*i
)
266 char tmp
[BLOCK_SEARCH_SIZE
];
268 getnstr(tmp
, BLOCK_SEARCH_SIZE
- 1);
270 int base
= ((tmp
[0] == '0' && tmp
[1] == 'x') ? 16 : 10);
272 unsigned long long val
= strtoull(tmp
, &endptr
, base
);
274 return (base
== 16 && (size_t) endptr
> ((size_t) tmp
) + 2) ||
275 (base
== 10 && endptr
!= tmp
);