diff options
-rw-r--r-- | Makefile | 45 | ||||
-rw-r--r-- | README.txt | 247 | ||||
-rw-r--r-- | buffers.c | 100 | ||||
-rw-r--r-- | buffers.h | 22 | ||||
-rw-r--r-- | config.h | 10 | ||||
-rw-r--r-- | configfile.c | 194 | ||||
-rw-r--r-- | configfile.h | 10 | ||||
-rw-r--r-- | correlation.c | 272 | ||||
-rw-r--r-- | correlation.h | 11 | ||||
-rw-r--r-- | datatypes.h | 120 | ||||
-rw-r--r-- | dhex.1 | 252 | ||||
-rw-r--r-- | dhex_markers.5 | 66 | ||||
-rw-r--r-- | dhex_searchlog.5 | 53 | ||||
-rw-r--r-- | dhexrc.5 | 212 | ||||
-rw-r--r-- | gpl.c | 571 | ||||
-rw-r--r-- | gpl.h | 6 | ||||
-rw-r--r-- | gpl.txt | 335 | ||||
-rw-r--r-- | hexcalc.c | 185 | ||||
-rw-r--r-- | hexcalc.h | 17 | ||||
-rw-r--r-- | input.c | 481 | ||||
-rw-r--r-- | input.h | 46 | ||||
-rw-r--r-- | machine_type.c | 23 | ||||
-rw-r--r-- | machine_type.h | 29 | ||||
-rw-r--r-- | main.c | 704 | ||||
-rw-r--r-- | markers.c | 213 | ||||
-rw-r--r-- | markers.h | 13 | ||||
-rw-r--r-- | menu.c | 255 | ||||
-rw-r--r-- | menu.h | 19 | ||||
-rw-r--r-- | mkrelease.sh | 47 | ||||
-rw-r--r-- | output.c | 476 | ||||
-rw-r--r-- | output.h | 21 | ||||
-rw-r--r-- | search.c | 139 | ||||
-rw-r--r-- | search.h | 10 | ||||
-rw-r--r-- | todo.txt | 6 | ||||
-rw-r--r-- | ui.c | 207 | ||||
-rw-r--r-- | ui.h | 11 |
36 files changed, 5428 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d72dde1 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +CC= gcc +LDFLAGS= -L/usr/lib -L/usr/local/lib -L/usr/lib/ncurses -L/usr/local/lib/ncurses +CPPFLAGS= -I/usr/include -I/usr/local/include -I/usr/include/ncurses -I/usr/local/include/ncurses +CFLAGS= -O3 -Wall -std=c99 +#CFLAGS+= -ffunction-sections -fdata-sections +#LDFLAGS+= --gc-sections +LIBS= -lncurses +DESTDIR= /usr/local/ + +OFILES=buffers.o \ + configfile.o \ + correlation.o \ + gpl.o \ + hexcalc.o \ + input.o \ + machine_type.o \ + main.o \ + markers.o \ + menu.o \ + output.o \ + search.o \ + ui.o + +all: dhex + +dhex: $(OFILES) + $(CC) $(LDFLAGS) -o $@ $(OFILES) $(LIBS) + +install:all + strip dhex + cp dhex $(DESTDIR)/bin + cp dhex.1 $(DESTDIR)/share/man/man1 + cp dhexrc.5 $(DESTDIR)/share/man/man5 + cp dhex_markers.5 $(DESTDIR)/share/man/man5 + cp dhex_searchlog.5 $(DESTDIR)/share/man/man5 + + + +.c.o: + $(CC) $< -c -I. $(CPPFLAGS) $(CFLAGS) $(OPTIONS) + +clean: + rm -f dhex $(OFILES) + + diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..4c61f21 --- /dev/null +++ b/README.txt @@ -0,0 +1,247 @@ +-----------------------------------------------------------------[ 0. Welcome ]- + +Thank you for downloading dhex 0.63. It is a hex editor with a diff mode. +Since it is based on ncurses, it runs in any console. +It makes heavy use of colors, but it is themeable to run on monochrome-displays +as well. + +If you have any questions, or found any bugs, please do not hesitate to contact +me under dettus@dettus.net. Be sure to include "DHEX" somewhere in the subject. + + +Thomas Dettbarn, 30-Dec-2010 + +0.60: Initial release +0.61: Some code cleanup, rudementary manual correlation is possible through + commandline parameters +0.62: Code cleanup, bug fixes, and as new features: bookmarks and ascii-search. +0.63: Man pages were written, searching is possible from the command line. +0.64: Naive correlation, a new default theme +0.65: dhex 0.64 crashed at startup on some systems. + +---------------------------------------------------------[ 1. Getting started ]- + +Download the latest version from http://www.dettus.net/dhex/dhex_latest.tar.gz. +Unpack it, + +% tar xvfz dhex_latest.tar.gz + +then compile it + +% make + +This should produce an executable. It requires a file as a paramter to start + +% ./dhex gpl.txt + +When starting for the first time, dhex will attempt to create a .dhexrc file +in your $HOME-directory. If you already have a .dhexrc from an older version of +dhex, it will convert it. + + +The first screen you'll see will be the keyboard setup. (I was not satisfied +with the way ncurses handled the function keys, so i created something new) +The keyboard setup will be written into the .dhexrc file. + + +You can edit the file, search for short strings in it, and scroll through it. +After pressing F10 (or whichever key you pressed instead of F10 during the +keyboard setup), dhex will ask you whether or not to save the changes. + + +To invode the keyboard setup manually, just start dhex with the parameter -k + +% ./dhex -k gpl.txt + + + +---------------------------------------------------------------[ 2. Diff mode ]- + + +When you run dhex with two files, + +% ./dhex gpl.txt dhex + +it will start in the diff mode. This is useful for file comparison. Any +difference in the files will be highlighted. To jump from one difference to +the next, press F3. To go to the previous one, press F4. + + +--------------------------------------------------------------------[ 3. Goto ]- + +Pressing F1 will open up the "Goto" dialog. Here you have three possibilities: +Pressing = will set the cursor to the absolute address you're about to type in, +Pressing + will advance the cursors those many bytes, +Pressing - will go back those many bytes. + +Press "Go" to set the cursor, or "Cancel" to quit the dialog. + + +Moreover, you can set up to ten bookmarks here. And save them for later use. + + + +---------------------------------------------------------------[ 4. Searching ]- + +When not in diff mode, pressing F2 will invoke the "Search" dialog. You can +search forward or backward. When selecting the "Writelog" option, you'll have +to provide a filename to write the search results to. +Later, when you select the "Readlog" option, it'll read the cursor positions +where to search from this file. Otherwise dhex will search the whole file. + +When not selecting the "Writelog" option, the search dialog will immediately +close upon finding the first occuracnce, and set the cursor there. + +Press F3 to go to the next occurace, or F4 to the previous one. + +Searching is also possible from the command line: Simply apply the -sa, -sab, +-sh, -shb parameters. To write into a searchlog, -w is the parameter to go. To +read from it, -r can be used. For example + +% ./dhex -oh affe -shb d00f dhex + +sets the cursor to 0xaffe, and searches for the hex string "d0 0f" backwards +from there. + +% ./dhex -oh affe -shb d00f -w occurances.log dhex + +writes the results into a logfile called "occurances.log" and exits. + +-----------------------------------------------------------------[ 5. Hexcalc ]- + +Pressing F5 will open up the hexcalc dialog. This is a small 64-bit calculator. +Simply type in a value in one of the formats "decimal", "hexadecimal" or +"binary", chose an operation, press ENTER and see the results. +You can select any former result by going up a few lines with the cursor keys. + + + +------------------------------------------------------------[ 6. config-files ]- + +The default config file is $HOME/.dhexrc. Another config file can be chosen +with the -f option: + +% ./dhex -f /etc/globaldhexrc gpl.txt + +Basically, a config file is broken down into two sections: Colors and keyboard +conversion tab. The default config file on a MacBook looks like this: + +DHEXCOLORSCHEME +#VERSION 0 +#possible colors are: BLACK,GREEN,GREEN,YELLOW,BLUE,MAGENTA,CYAN,BLACK +#possible extra flags are: UNDERLINE,REVERSE,BLINK,DIM,BOLD + +BRACKETS: FG=BLACK,BG=BLACK,BOLD +HEXFIELD: FG=WHITE,BG=BLACK +INPUT: FG=BLACK,BG=WHITE +CURSOR: FG=WHITE,BG=BLACK +TEXT: FG=WHITE,BG=BLACK,BOLD +MENU_NORMAL: FG=CYAN,BG=BLACK +MENU_HIGHLIGHT: FG=BLACK,BG=CYAN +MENU_HOTKEY: FG=YELLOW,BG=BLACK,BOLD +MENU_HOTKEY_HI: FG=YELLOW,BG=CYAN,BOLD +FRAME: FG=BLUE,BG=BLACK,BOLD +NORMAL_DIFF: FG=YELLOW,BG=BLACK +CURSOR_DIFF: FG=YELLOW,BG=WHITE,BOLD +HEADLINE: FG=BLUE,BG=BLACK,BOLD + +KEYF1:c2 a1 +KEYF2:e2 84 a2 +KEYF3:c2 a3 +KEYF4:c2 a2 +KEYF5:e2 88 9e +KEYF6:c2 a7 +KEYF7:c2 b6 +KEYF8:e2 80 a2 +KEYF9:c2 aa +KEYF10:c2 ba +KEYESC:1b +KEYBACKSPACE:08 +KEYDEL:1b +KEYENTER:0a +KEYTAB:09 +KEYUP:1b 5b 41 +KEYDOWN:1b 5b 42 +KEYRIGHT:1b 5b 43 +KEYLEFT:1b 5b 44 +KEYPGUP:02 +KEYPGDOWN:06 +KEYHOME:5e +KEYEND:24 + +(Actually, in this example ALT+1, ALT+2, ALT+3,... ALT+0 were used instead of +F1..F10) You can edit it with any texteditor you like. + + + +--------------------------------------[ 7. Correlating two files in diff mode ]- + +Lets assume you would like to compare two files. One of those files starts with +garbage at the beginning: + + file1: GARBAGE0123456789ABCDEF + file2: 0123456789ABCDEF + +GARBAGE has 7 letters, so to skip over the first 7 bytes in the first file, just +apply the following paramters: + +% dhex -o1d 7 file1 file2 + +-o sets the cursor offset. -o1 means that the first buffer is affected. -o1d +gives the radix for the offset. it can either be -o1d for decimal, -o1b for +binary, -o1h for hexadecimal or -o1o for octal. + +If the garbage is in the second file, just use + +% dhex -o2d 7 file1 file2 + +Since version 0.64 there is also a way of doing this automatically: Pressing +F6 in the GUI will open up a dialog where you can select one of three +correlation algorithms. They are painfully slow, but they'll do the job. +Those three algorithms are: + +- best match + move the two files in such a way that as many bytes match as possible +- longest match + move the two files in such a way that as many consecutive bytes match as + possible +- minimum diff + move the two files in such a way that as little bytes differ as possible. This + algorithm requires an upper limit to improve its speed. + +To invoke correlation from the command line, use one of these + +% dhex -cb file1 file2 # best match +% dhex -cl file1 file2 # longest match +% dhex -cd 1000 file1 file2 # minimum difference, with the upper limit of 1000. + + + +--------------------------------------------------------------[ 8. Disclaimer ]- + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +--------------------------------------------------------------[ 9. Known bugs ]- + +- Searching has not been thourughly tested. +- Code is not clean (yet) +- Searching is only possible in normal mode, not diff mode +- Searching ignores unsaved changes. +- Some features are missing +- -k expects a file to be opened +- -f might overwrite ANY file. +- GOTO can jump way behind the end of the file +- some ways of exiting won't free all the allocated buffers diff --git a/buffers.c b/buffers.c new file mode 100644 index 0000000..5f196ea --- /dev/null +++ b/buffers.c @@ -0,0 +1,100 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include "machine_type.h" +#include "config.h" +#include "buffers.h" + + + + +// retval: OK +// +tUInt32 openbuf(tBuffer* hBuf,tUInt8 bufnum,char* filename) +{ + hBuf->changesnum=0; + hBuf->valid=0; + hBuf->fresh=1; + hBuf->file=fopen(filename,"rb"); + memcpy(hBuf->filename,filename,512); + hBuf->filename[511]=0; + if (hBuf->file) + { + hBuf->valid=1; + hBuf->filesize=getfilesize(hBuf->file); + hBuf->bufsize=hBuf->filesize; + hBuf->bufferpos=-1; + return RETOK; + } else return RETNOK; +} + +tUInt32 readbuf(tBuffer* hBuf,tInt64 pos) +{ + tBool havetoread=0; + tInt32 bytesread; + if (hBuf->fresh || pos<hBuf->bufferpos || pos>(hBuf->bufferpos+BUFFERSIZE)) + { + havetoread=1; + hBuf->bufferpos=pos&(~(BUFFERSIZE-1)); // floor + } + else if ((hBuf->bufferpos+BUFFERMARGIN)>pos && hBuf->bufferpos>=(BUFFERSIZE/2)) + { + havetoread=1; + hBuf->bufferpos-=(BUFFERSIZE/2); + } + else if ((hBuf->bufferpos+BUFFERSIZE-BUFFERMARGIN)<pos && (hBuf->bufferpos+(BUFFERSIZE/2))<hBuf->bufsize && hBuf->bufsize>BUFFERSIZE) + { + havetoread=1; + hBuf->bufferpos+=(BUFFERSIZE/2); + } + if (havetoread) + { + hBuf->fresh=0; + if (hBuf->filesize>hBuf->bufferpos) + { + setfilepos(hBuf->file,hBuf->bufferpos); + bytesread=fread(hBuf->data,sizeof(tUInt8),BUFFERSIZE,hBuf->file); + if (bytesread!=BUFFERSIZE) + { + memset(&hBuf->data[bytesread],0,sizeof(tUInt8)*(BUFFERSIZE-bytesread)); // fill the rest with 0 + } + } else { + memset(hBuf->data,0,sizeof(tUInt8)*BUFFERSIZE); + } + } + + return RETOK; +} + +tInt32 getbufferidx(tBuffer* hBuf,tInt64 pos) +{ + tInt32 retval=OK; + if ((pos<(hBuf->bufferpos+BUFFERMARGIN)) || (pos>(hBuf->bufferpos+BUFFERSIZE-BUFFERMARGIN))) + { + retval=readbuf(hBuf,pos); + } + if (retval==OK) + { + retval=pos-(hBuf->bufferpos); + } + return retval; +} +tInt8 savechanges(tBuffer* hBuf) +{ + int i; + fclose(hBuf->file); + if (hBuf->changesnum) + { + hBuf->file=fopen(hBuf->filename,"r+b"); + if (hBuf->file==NULL) return RETNOK; + for (i=0;i<hBuf->changesnum;i++) + { + setfilepos(hBuf->file,hBuf->changes[i].pos); + fwrite(&(hBuf->changes[i].after),sizeof(tUInt8),1,hBuf->file); + } + fclose(hBuf->file); + } + return RETOK; +} + diff --git a/buffers.h b/buffers.h new file mode 100644 index 0000000..7bcdd1d --- /dev/null +++ b/buffers.h @@ -0,0 +1,22 @@ +#ifndef BUFFERS_H +#define BUFFERS_H + +#include <stdio.h> +#include <stdlib.h> +#include "machine_type.h" +#include "config.h" +#include "datatypes.h" + +// opens a buffer, bufnum has to be either 1 or 2 +tUInt32 openbuf(tBuffer* hBuf,tUInt8 bufnum,char* filename); + +// reads into the buffer, if the need arises +tUInt32 readbuf(tBuffer* hBuf,tInt64 pos); + +// get the index of the file position within the buffer +tInt32 getbufferidx(tBuffer* hBuf,tInt64 pos); + + +tInt8 savechanges(tBuffer* hBuf); + +#endif diff --git a/config.h b/config.h new file mode 100644 index 0000000..a5fbbc9 --- /dev/null +++ b/config.h @@ -0,0 +1,10 @@ + +// size for the hex buffer +#define BUFFERSIZE (1<<20) +#define BUFFERMARGIN (BUFFERSIZE/4) + +#define CHANGEBUFSIZE (1<<16) + + +// size for text strings, like from the config-file +#define TEXTSTRINGSIZE 128 diff --git a/configfile.c b/configfile.c new file mode 100644 index 0000000..85beaec --- /dev/null +++ b/configfile.c @@ -0,0 +1,194 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include "configfile.h" +#include "machine_type.h" +#include "ncurses.h" +#include "output.h" +#include "input.h" + +typedef struct _tColorName +{ + char name[16]; + short len; + short val; + int attrs; +} tColorName; + +typedef struct _tColorGroup +{ + char configname[16]; + short len; + uicolors uicol; +} tColorGroup; + +const tColorGroup colorGroups[13]={ + {"BRACKETS:", 9,COLOR_BRACKETS}, + {"HEXFIELD:", 9,COLOR_HEXFIELD}, + {"INPUT:", 6,COLOR_INPUT}, + {"CURSOR:", 7,COLOR_CURSOR}, + {"TEXT:", 5,COLOR_TEXT}, + {"MENU_NORMAL:", 12,COLOR_MENUNORMAL}, + {"MENU_HIGHLIGHT:", 15,COLOR_MENUACTIVE}, + {"MENU_HOTKEY:", 12,COLOR_MENUHOTKEY}, + {"MENU_HOTKEY_HI:", 15,COLOR_MENUHOTKEYACTIVE}, + {"NORMAL_DIFF:", 12,COLOR_DIFF}, + {"CURSOR_DIFF:", 12,COLOR_CURSORDIFF}, + {"HEADLINE:", 9,COLOR_HEADLINE}, + {"FRAME:", 6,COLOR_FRAME}}; +const tColorName colorNames[20]={ {"BLACK", 5,COLOR_BLACK,0}, + {"RED", 3,COLOR_RED,0}, + {"GREEN", 5,COLOR_GREEN,0}, + {"BLUE", 4,COLOR_BLUE,0}, + {"PURPLE", 6,COLOR_MAGENTA,0}, + {"MAGENTA", 7,COLOR_MAGENTA,0}, + {"CYAN", 4,COLOR_CYAN,0}, + {"WHITE", 5,COLOR_WHITE,0}, + {"YELLOW", 6,COLOR_YELLOW,A_BOLD}, + {"BROWN", 5,COLOR_YELLOW,0}, + + {"LIGHTBLACK", 10,COLOR_BLACK,A_BOLD}, + {"LIGHTRED", 8,COLOR_RED,A_BOLD}, + {"LIGHTGREEN", 10,COLOR_GREEN,A_BOLD}, + {"LIGHTBLUE", 9,COLOR_BLUE,A_BOLD}, + {"LIGHTPURPLE", 11,COLOR_MAGENTA,A_BOLD}, + {"LIGHTMAGENTA",12,COLOR_MAGENTA,A_BOLD}, + {"LIGHTCYAN", 9,COLOR_CYAN,A_BOLD}, + {"LIGHTWHITE", 10,COLOR_WHITE,A_BOLD}, + {"LIGHTYELLOW", 11,COLOR_YELLOW,A_BOLD}, + {"LIGHTBROWN", 10,COLOR_YELLOW,A_BOLD}}; + +const tColorName attrNames[5]={ {"UNDERLINE", 9,0,A_UNDERLINE}, + {"REVERSE", 7,0,A_REVERSE}, + {"BLINK", 5,0,A_BLINK}, + {"DIM", 3,0,A_DIM}, + {"BOLD", 4,0,A_BOLD}}; + +int getcolors(tOutput* output,char* line) +{ + int i; + int l; + int state=0; // 0: find :, 1=find FG=, 2=find, , 3=find BG=, 4=find , ,5=find END, 6=nothing + char token[6][64]; + int tokenidx=0; + char c; + short col1; + short col2; + int attrs1; + int attrs2; + int attrsret; + short fg=7,bg=0; + + l=strlen(line); + memset(token,0,sizeof(token)); + for (i=0;i<l;i++) + { + c=line[i]; + if (c=='#') state=6; + if (c==' ' || c==9) c=0; // ignore all the white spaces + else { + if (c>='a' && c<='z') c-=32; // make the letters lower case + if (state==0 && c==':') { + token[state][tokenidx++]=c; //apend the last char + token[state][tokenidx]=0; + state=1; + tokenidx=0; + } + else if (state==1 && c=='=') {state=2;tokenidx=0;} + else if (state==2 && c==',') {state=3;tokenidx=0;} + else if (state==3 && c=='=') {state=4;tokenidx=0;} + else if (state==4 && c==',') {state=5;tokenidx=0;} + else if (state==5 && c<32) {state=6;tokenidx=0;} + else if (state!=6 && tokenidx<63) + { + token[state][tokenidx++]=c; + token[state][tokenidx]=0; + } + } + } + //printf("%s;%s;%s;%s;%s;%s\n",token[0],token[1],token[2],token[3],token[4],token[5]); + // token0: contains the color group + // token1: contains fg or bg + // token2: contains the color + // token3: contains fg or bg + // token4: contains the color black, red, green, blue, purple, cyan, brown, yellow, white, lightblack, lightred, lightgreen, lightblue, lightpurple,lightcyan, lightbrown, lightyellow + // token5: contains something light BOLD, reverse, blink, underline, dim + + col1=0;col2=0; + attrs1=0;attrs2=0; + attrsret=0; + for (i=0;i<20;i++) + { + if (strncmp(token[2],colorNames[i].name,colorNames[i].len)==0) {col1=colorNames[i].val;attrs1=colorNames[i].attrs;} + if (strncmp(token[4],colorNames[i].name,colorNames[i].len)==0) {col2=colorNames[i].val;attrs2=colorNames[i].attrs;} + } + if (strncmp(token[1],"FG",2)==0) + { + fg=col1; + attrsret|=attrs1; + } + if (strncmp(token[1],"BG",2)==0) + { + bg=col1; + attrsret|=(attrs1==A_BOLD)?A_BLINK:attrs1; + } + + if (strncmp(token[3],"FG",2)==0) + { + fg=col2; + attrsret|=attrs2; + } + if (strncmp(token[3],"BG",2)==0) + { + bg=col2; + attrsret|=(attrs2==A_BOLD)?A_BLINK:attrs2; + } + for (i=0;i<5;i++) + { + if (strncmp(attrNames[i].name,token[5],attrNames[i].len)==0) attrsret|=attrNames[i].attrs; + } + + for (i=0;i<13;i++) + { + if (strncmp(colorGroups[i].configname,token[0],colorGroups[i].len)==0) + { + colorpair(output,colorGroups[i].uicol,fg,bg,attrsret); + } + } + return RETOK; +} +int readconfigfile(tOutput* output,char* filename) +{ + tFptr f=fopen(filename,"rb"); + unsigned char line[512]; + unsigned char c; + int lineidx=0; + int keyboardcnt; + if (!f) return 1; + keyboardcnt=0; + while (!feof(f)) + { + fread(&c,sizeof(char),1,f); + if (!feof(f)) + { + if (c>='a' && c<='z') c-=32; // make everything uppercase + if (c==9) c=32; // and whitespaces are all the same + if (lineidx<511 && c!=32) + { + line[lineidx++]=c; + line[lineidx]=0; + if (c<32) + { + getcolors(output,line); + keyboardcnt+=(configkeytab((tKeyTab*)output->pKeyTab,line)==0); + lineidx=0; + line[0]=0; + } + } + } + } + fclose(f); + if (keyboardcnt!=NUM_SPECIALKEYS) return 2; // not every spcial key was configured in the config file + return 0; +} diff --git a/configfile.h b/configfile.h new file mode 100644 index 0000000..eef3a97 --- /dev/null +++ b/configfile.h @@ -0,0 +1,10 @@ +#ifndef CONFIGFILE_H +#define CONFIGFILE_H +#include <stdio.h> +#include <stdlib.h> +#include "machine_type.h" +#include "output.h" + +int readconfigfile(tOutput* output,char* filename); +#endif + diff --git a/correlation.c b/correlation.c new file mode 100644 index 0000000..2c0e68e --- /dev/null +++ b/correlation.c @@ -0,0 +1,272 @@ +#include "correlation.h" +#include "buffers.h" +#include <strings.h> +#include <string.h> +void find_longestmatch(tOutput* output,tCorrelation* correlation,tBuffer* buf1,tBuffer* buf2,tInt64* cursorpos1,tInt64* cursorpos2) +{ + tInt64 idx1; + tInt64 idx2; + tInt64 match; + tInt64 sumpos; + tInt64 pos1; + tInt64 pos2; + tInt16 offsx; + tInt16 offsy; + WINDOW* smallwin=NULL; + tInt64 diff; + tBool found=0; + + + if (output) + { + offsx=COLS/2-22; + offsy=LINES/2-3; + drawcenterframe(output,6,44,"correlating..."); + setcolor(output,COLOR_TEXT); + smallwin=subwin(output->win,6,19,offsy,offsx+24); + mvwprintw(output->win,offsy+1,offsx+1,"pos1:"); + mvwprintw(output->win,offsy+4,offsx+1,"longest match:"); + mvwprintw(output->win,offsy+5,offsx+1,"at"); + if (smallwin) mvwprintw(smallwin,4,1,"%18lli",0); + wrefresh(output->win); + } + + correlation->bestmatch=0; + correlation->mindiff=MAX(buf1->bufsize,buf2->bufsize); + for (pos1=-(tInt64)buf2->bufsize;pos1<(tInt64)buf1->bufsize;pos1++) + { + match=0; + diff=0; + if (smallwin) mvwprintw(smallwin,1,3,"%16lli",((tInt64)buf1->bufsize-pos1)); + else fprintf(stderr,"%16lli\r",((tInt64)buf1->bufsize-pos1)); + if (smallwin) wrefresh(smallwin); + for (pos2=0;pos2<buf2->bufsize;pos2++) + { + sumpos=pos1+pos2; + if (sumpos>=0 && sumpos<buf1->bufsize) + { + idx1=getbufferidx(buf1,sumpos); + idx2=getbufferidx(buf2,pos2); + + if (buf1->data[idx1]==buf2->data[idx2]) match++; + else { + diff++; + if (match>correlation->bestmatch) + { + correlation->bestmatch=match; + correlation->bestmatchpos=pos1; + correlation->mindiff=diff; + if (smallwin) mvwprintw(smallwin,4,1,"%18lli",match); + if (smallwin) mvwprintw(smallwin,5,3,"%16llx",pos1); + if (smallwin) wrefresh(smallwin); + found=1; + } + match=0; + } + if (match>correlation->bestmatch) + { + correlation->bestmatch=match; + correlation->bestmatchpos=pos1; + correlation->mindiff=diff; + if (smallwin) mvwprintw(smallwin,4,1,"%18lli",match); + if (smallwin) mvwprintw(smallwin,5,3,"%16llx",pos1); + if (smallwin) wrefresh(smallwin); + found=1; + } + } + } + if (smallwin) wrefresh(smallwin); + } + if (found) + { + if (correlation->bestmatch>=0) + { + *cursorpos1=correlation->bestmatchpos; + *cursorpos2=0; + } else { + *cursorpos1=0; + *cursorpos2=-correlation->bestmatchpos; + } + } + if (smallwin) delwin(smallwin); +} +void find_bestmatch(tOutput* output,tCorrelation* correlation,tBuffer* buf1,tBuffer* buf2,tInt64* cursorpos1,tInt64* cursorpos2) +{ + tInt64 idx1; + tInt64 idx2; + tInt64 match; + tInt64 sumpos; + tInt64 pos1; + tInt64 pos2; + tInt16 offsx; + tInt16 offsy; + WINDOW* smallwin=NULL; + tInt64 diff; + tBool found=0; + + + if (output) + { + offsx=COLS/2-22; + offsy=LINES/2-3; + drawcenterframe(output,6,44,"correlating..."); + setcolor(output,COLOR_TEXT); + smallwin=subwin(output->win,6,19,offsy,offsx+24); + mvwprintw(output->win,offsy+1,offsx+1,"pos1:"); + mvwprintw(output->win,offsy+4,offsx+1,"best match:"); + mvwprintw(output->win,offsy+5,offsx+1,"at"); + if (smallwin) mvwprintw(smallwin,4,1,"%18lli",0); + wrefresh(output->win); + } + + correlation->bestmatch=0; + correlation->mindiff=MAX(buf1->bufsize,buf2->bufsize); + for (pos1=-(tInt64)buf2->bufsize;pos1<(tInt64)buf1->bufsize;pos1++) + { + match=0; + diff=0; + if (output) mvwprintw(smallwin,1,3,"%16lli",((tInt64)buf1->bufsize-pos1)); + else fprintf(stderr,"%16lli\r",((tInt64)buf1->bufsize-pos1)); + for (pos2=0;pos2<buf2->bufsize;pos2++) + { + sumpos=pos1+pos2; + if (sumpos>=0 && sumpos<buf1->bufsize) + { + idx1=getbufferidx(buf1,sumpos); + idx2=getbufferidx(buf2,pos2); + + match+=(buf1->data[idx1]==buf2->data[idx2]); + diff+=(buf1->data[idx1]!=buf2->data[idx2]); + } else { + diff++; + } + } + if (match>correlation->bestmatch) + { + correlation->bestmatch=match; + correlation->bestmatchpos=pos1; + correlation->mindiff=diff; + if (smallwin) mvwprintw(smallwin,4,1,"%18lli",match); + if (smallwin) mvwprintw(smallwin,5,3,"%16llx",pos1); + found=1; + } + if (output) wrefresh(smallwin); + } + if (found) + { + if (correlation->bestmatch>=0) + { + *cursorpos1=correlation->bestmatchpos; + *cursorpos2=0; + } else { + *cursorpos1=0; + *cursorpos2=-correlation->bestmatchpos; + } + } + if (smallwin) delwin(smallwin); +} +void find_mindiff(tOutput* output,tCorrelation* correlation,tBuffer* buf1,tBuffer* buf2,tInt64* cursorpos1,tInt64* cursorpos2) +{ + tInt64 idx1; + tInt64 idx2; + tInt64 diff; + tInt64 sumpos; + tInt64 pos1; + tInt64 pos2; + tInt16 offsx; + tInt16 offsy; + WINDOW* smallwin=NULL; + tBuffer* smallbuf; + tBuffer* bigbuf; + tInt64 match; + tBool found; + + + + if (output) + { + offsx=COLS/2-22; + offsy=LINES/2-3; + drawcenterframe(output,6,44,"correlating..."); + setcolor(output,COLOR_TEXT); + smallwin=subwin(output->win,6,19,offsy,offsx+24); + mvwprintw(output->win,offsy+1,offsx+1,"pos1:"); + mvwprintw(output->win,offsy+4,offsx+1,"mindiff:"); + mvwprintw(output->win,offsy+5,offsx+1,"at"); + mvwprintw(smallwin,4,1,"%18lli",correlation->start_mindiff); + wrefresh(output->win); + } + + smallbuf=(buf1->bufsize<buf2->bufsize)?buf1:buf2; + bigbuf =(buf1->bufsize<buf2->bufsize)?buf2:buf1; + + correlation->mindiff=correlation->start_mindiff; + correlation->bestmatch=0; + if (!correlation->mindiff) correlation->mindiff=bigbuf->bufsize; + + for (pos1=-(tInt64)smallbuf->bufsize;pos1<(tInt64)bigbuf->bufsize && correlation->mindiff;pos1++) + { + diff=0; + match=0; + if (smallwin) mvwprintw(smallwin,1,3,"%16lli",((tInt64)bigbuf->bufsize-pos1)); + else fprintf(stderr,"%16lli\r",((tInt64)buf1->bufsize-pos1)); + + for (pos2=0;pos2<smallbuf->bufsize && diff<correlation->mindiff;pos2++) + { + sumpos=pos1+pos2; + if (sumpos>=0 && sumpos<bigbuf->bufsize) + { + idx1=getbufferidx(bigbuf,sumpos); + idx2=getbufferidx(smallbuf,pos2); + + diff+=(bigbuf->data[idx1]!=smallbuf->data[idx2]); + } else { + diff++; + } + } + if (diff<correlation->mindiff) + { + correlation->mindiffpos=pos1; + correlation->mindiff=diff; + if (smallwin) mvwprintw(smallwin,4,1,"%18lli",diff); + if (smallwin) mvwprintw(smallwin,5,3,"%16llx",pos1); + found=1; + } + if (smallwin) wrefresh(smallwin); + } + if (found) + { + if (correlation->mindiffpos>=0) + { + *cursorpos1=(bigbuf==buf1)?correlation->mindiffpos:0; + *cursorpos2=(bigbuf==buf1)?0:correlation->mindiffpos; + } else { + *cursorpos1=(bigbuf==buf1)?0:-correlation->mindiffpos; + *cursorpos2=(bigbuf==buf1)?-correlation->mindiffpos:0; + } + } + if (smallwin) delwin(smallwin); +} +void find_correlation(tOutput* output,tCorrelation* correlation,tBuffer* buf1,tBuffer* buf2,tInt64* cursorpos1,tInt64* cursorpos2) +{ + tInt16 ch=0; + correlation->correlated=1; + switch(correlation->algorithm) + { + case CORR_BEST_MATCH: find_bestmatch(output,correlation,buf1,buf2,cursorpos1,cursorpos2);break; + case CORR_LONGEST_MATCH: find_longestmatch(output,correlation,buf1,buf2,cursorpos1,cursorpos2);break; + case CORR_MIN_DIFF: find_mindiff(output,correlation,buf1,buf2,cursorpos1,cursorpos2);break; + } + if (output) + { + while (ch!=ERR) + { + ch=getch(); // remove all the keys which have been pressed from the buffer + } + } +} +void clear_correlation(tCorrelation* correlation) +{ + memset(correlation,0,sizeof(tCorrelation)); + correlation->algorithm=CORR_BEST_MATCH; +} diff --git a/correlation.h b/correlation.h new file mode 100644 index 0000000..c7e51b5 --- /dev/null +++ b/correlation.h @@ -0,0 +1,11 @@ +#ifndef CORRELATION_H +#define CORRELATION_H +#include "machine_type.h" +#include "buffers.h" +#include "output.h" +#include "datatypes.h" + +void find_correlation(tOutput* output,tCorrelation* correlation,tBuffer* buf1,tBuffer* buf2,tInt64* cursorpos1,tInt64* cursorpos2); +void clear_correlation(tCorrelation* correlation); + +#endif diff --git a/datatypes.h b/datatypes.h new file mode 100644 index 0000000..ced6166 --- /dev/null +++ b/datatypes.h @@ -0,0 +1,120 @@ +#ifndef DATATYPES_H +#define DATATYPES_H +#include <ncurses.h> +#include "machine_type.h" + +/* INPUT DATATYPES */ +// this is for the special keys +// i was not satisfied with how ncurses handled the function keys +typedef struct _tKeyTab +{ + tInt16 retval; + tBool allowed_in_inputfield; + tUInt8 seqlen; + char seq[8]; // which sequence will be returned when this key is pressed + char config[16]; // what string is written in the config-file + char desc[64]; +} tKeyTab; + + +/* OUTPUT DATATYPES */ + +typedef enum {COLOR_NONE,COLOR_BRACKETS,COLOR_INPUT,COLOR_CURSOR,COLOR_TEXT,COLOR_HEXFIELD,COLOR_DIFF,COLOR_HEADLINE,COLOR_HEADER,COLOR_MENUHOTKEY,COLOR_MENUNORMAL,COLOR_FRAME,COLOR_MENUACTIVE,COLOR_MENUHOTKEYACTIVE,COLOR_CURSORDIFF,UICOLORNUM} uicolors; +typedef struct _tColors +{ + short fg; + short bg; + int attrs; +} tColors; +typedef struct _tOutput +{ + WINDOW* win; + tColors colors[UICOLORNUM]; + int attrs[UICOLORNUM]; + void* pKeyTab; +} tOutput; + + +/* BUFFER DATATYPES */ +typedef struct _tChange +{ + tUInt64 pos; + tUInt8 before; + tUInt8 after; +} tChange; + +typedef struct _tBuffer +{ + tBool valid; + tUInt8 data[BUFFERSIZE]; + tUInt64 filesize; // the size of the actual file + tUInt64 bufsize; // the size of the buffer, in case some bytes are added at the end + tUInt64 bufferpos; // the offset from where this chunk has been read + tBool fresh; // =1 if there is no data in this buffer + tFptr file; // the file pointer + char filename[512]; // the file name + tChange changes[CHANGEBUFSIZE]; + tUInt32 changesnum; // number of changes + tBool nibble; + tUInt8 nexthex; + tUInt64 changepos; +} tBuffer; + + +/* CORRELATION DATATYPES */ +typedef enum {CORR_BEST_MATCH,CORR_LONGEST_MATCH,CORR_MIN_DIFF} corr_algorithms; +typedef struct _tCorrelation +{ + tBool correlated; + corr_algorithms algorithm; + tInt64 start_mindiff; + tInt64 mindiff; + tInt64 mindiffpos; + tInt64 bestmatch; + tInt64 bestmatchpos; +} tCorrelation; + +/* MENU DATATYPES */ +typedef struct _tMenuItem +{ + char menutext[64]; + tUInt16 x; + tUInt16 y; + char hotkey; +} tMenuItem; + +typedef struct _tMenu +{ + tMenuItem MenuItems[64]; + int menuitemnum; + int menuitemactive; +} tMenu; + +/* SEARCH DATATYPES */ +typedef struct _tSearch +{ + char writelogfilename[64]; + char readlogfilename[64]; + tBool writesearchlog; + tBool readsearchlog; + tBool forwardnotbackward; + char searchstring[32]; + tInt16 searchlen; + tInt64 occurancesfound; + tInt64 lastoccurance; + tInt64 lastsearchlogpos; +} tSearch; + + +/* MARKER DATATYPES */ +#define NUMMARKERS 10 + +typedef struct _tMarkers +{ + char relative[NUMMARKERS]; + tUInt64 cursorpos[NUMMARKERS]; +} tMarkers; + + + +#endif @@ -0,0 +1,252 @@ +.\" Process this file with +.\" groff -man -Tascii dhex.1 +.\" +. +.Dd February 12, 2011 +.Os +.Dt DHEX 1 +. +. +.Sh NAME +.Nm dhex +.Nd hex editor with a diff mode +. +. +.Sh SYNOPSIS +. +.Nm +.Op Fl h +.Op Fl v +.Op Fl g +.Op Fl k +.Bk -words +.Op Fl f Ar config-file +.Ek +.Bk -words +.Op Fl m Ar marker-file +.Ek +.Bk -words +.Op Fl ob od oh oo Ar offset +.Ek +.Bk -words +.Op Fl r Ar searchlog +.Ek +.Bk -words +.Op Fl sa sab Ar string (ascii) +.Ek +.Bk -words +.Op Fl sh shb Ar string (hex) +.Ek +.Bk -words +.Op Fl w Ar searchlog +.Ek +.Op Ar file +.Nm +.Op Fl h +.Op Fl v +.Op Fl g +.Op Fl k +.Bk -words +.Op Fl cb +.Ek +.Bk -words +.Op Fl cd Ar upper-limit +.Ek +.Bk -words +.Op Fl cl +.Ek +.Bk -words +.Op Fl f Ar config-file +.Ek +.Bk -words +.Op Fl m Ar marker-file +.Ek +.Bk -words +.Op Fl o1b o1d o1h o1o Ar offset1 +.Ek +.Bk -words +.Op Fl o2b o2d o2h o2o Ar offset2 +.Ek +.Bk -words +.Op Fl r1 Ar searchlog1 +.Ek +.Bk -words +.Op Fl r2 Ar searchlog2 +.Ek +.Bk -words +.Op Fl s1a s1ab s1h s1hb Ar string (ascii/hex) +.Ek +.Bk -words +.Op Fl s2a s2ab s2h s2hb Ar string (ascii/hex) +.Ek +.Bk -words +.Op Fl w1 Ar searchlog1 +.Ek +.Bk -words +.Op Fl w2 Ar searchlog2 +.Ek +.Bk -words +.Op Ar file1 file2 +.Ek +.Sh DESCRIPTION +.Nm +is a hex editor. It can be used to alter individual bytes in large files. Since it is a text-mode programm based on ncurses, it can run in numerous scenarios. +. +Its special feature is the diff mode: With it, the user has a visual tool for file comparison. This mode is invoked when +.Nm +is called with two instead of one file as parameters. +.Sh OPTIONS +All the options are case-insensitive and can be given as either upper- or lowercase characters. +.Bl -tag -width 10n +.It Fl cb cl +Diff mode only: The input files can be correlated from the command line with the best +.Fl cb +or longest +.Fl cl +match. This is very slow. +.It Fl cd Ar upper-limit +Diff mode only: The input files can be correlated from the command line with the minimum difference. To improve the correlation speed, an upper limit can be provided. +.It Fl f Ar configfile +Usually, .dhexrc is being read from the invoker's home directory. With this parameter, any other config file can be loaded. See +.Xr dhexrc 5 +for a description of its file format. +.It Fl g +Shows the license +.It Fl h +Shows the help screen +.It Fl k +Starts the keyboard setup manually before any file is being loaded. This is very helpful when calling +.Nm +from an exotic terminal. +.It Fl m Ar markerfile +It is possible in +.Nm +to set bookmarks and store them in a markerfile for later use. With this parameter, the markerfile is being read at start time, making it unnecesarry to read them later through the gui. Their file format is described in +.Xr dhex_markers 5 . +.It Fl ob od oh oo Ar offset +After loading a file, the cursor is set to 0, and the first page of bytes is being shown on the screen. With one of those parameters it is possible to start at any other location in the file. The cursorposition could be given as a binary number with +.Op Fl ob +, as a decimal one with +.Op Fl od +, as a hexadecimal one with +.Op Fl oh +or an octal with +.Op Fl oo . +.It Fl o1b o1d o1h o1o Ar offset1 +.It Fl o2b o2d o2h o2o Ar offset2 +For the diff mode, it is possible to set two different cursorpositions at start time. Again, the cursorpositions can be given as a binary number with +.Op Fl o1b o2b +, as decimal one with +.Op Fl o1d o2d +, as hexadecimal one with +.Op Fl o1h o2h +or an octal one with +.Op Fl o1o o2o . +.Pp +This way, the first few bytes in a file can be skipped, and just the rest can be compared. +.It Fl r Ar searchlog +When searching from the command line, the offsets are being read from this searchlog. Its format is being decribed in +.Xr dhex_searchlog 5 . +.It Fl r1 Ar searchlog1 +.It Fl r2 Ar searchlog2 +When searching in two files simultanously, the offsets can be read from two different searchlogs. +.It Fl sa sab sh shb Ar string +Instead of setting the cursor offset to an absolute value, it is possible to search for a specific string from the command line. If there is an additional +.Op Fl ob od oh oo Ar offset +present, the search will start there. It is possible to read and write search logs with +.Op Fl r Ar searchlog +and +.Op Fl w Ar searchlog +respectively. With +.Op Fl sa Ar string +is being interpreted as ASCII. +.Op Fl sh Ar string +interprets it as hex. For backwards search, +.Op Fl sab Ar string +or +.Op Fl shb Ar string +can be applied. +.It Fl s1a s1ab s1h s1hb Ar string1 +.It Fl s2a s2ab s2h s2hb Ar string2 +In the diff mode, it is possible to search for two strings in two files simultanously. +.It Fl v +Prints out the version of +.Nm . +.It Fl w Ar searchlog +When searching from the command line, write the results into this searchlog and quit. It is being written in the format described in +.Xr dhex_searchlog 5. +.Pp +.It Fl \&w1 Ar searchlog1 +.It Fl w2 Ar searchlog2 +When searching in two files simultanously, write the results from both searches into those log files. +.El +.Sh USER INTERFACE +.Ss General +Menus have hotkeys, they are being presented in a different color. To jump from one menu item to the next, the cursor keys or the TAB key can be used. +.Pp +Input fields can be closed by pressing ESC, ENTER, or any cursor key. Only pressing ESC will not save the changes made in there. +.Pp +.Ss The keyboard setup +When running +.Nm +for the first time, without any configfile present, or with the parameter -k, the first screen shown is that of the keyboard setup. In this screen, the program asks the user to press certain keys. Which are (in order) ESCAPE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, BACKSPACE, DEL, ENTER, TAB, UP, DOWN, RIGHT, LEFT, PG UP, PG DOWN, HOME, END. It also tells the user what it intends to do with those keys later. So the user can decide on any alternative he chooses. +If he does not want to bind a specific function to a certain key, he can simply press ESCAPE and skip to the next question. +.Pp +After pressing all the keys, the user can chose whether or not to write those keys into the config file. +.Ss The main screen +The main screen is broken down into three columns: The first column contains the offset within the file for the current line. The second column contains the bytes in the file in hex format. Finally, the third coumn contains the same bytes, but this time in ascii format. If a byte is not printable, it is being substituted with a '.'. +How many bytes are are being shown in a line depends on the width of the terminal. For example, if the terminal is 80 characters wide, 16 bytes are being shown in each line. +.Pp +If no other +.Op Fl o +parameter was given at start time, the cursor is being set to offset 0. It is also being shown in the hex column. Here, it can be moved with the cursor keys. When entering a hexadecimal number, the file is being edited. The file can be edited in the ascii column as well, simply by pressing the TAB key (or whichever key was substituted for it in the keyboard setup). Pressing TAB again will return the cursor to the hex column. Pressing F9 (or its substitute) will undo the last of the changes. Changes are being shown in a differnt color. +.Pp +Editing is not possible in the diff mode. Here, pressing the cursor keys will move both files synchronously. +.Ss The goto screen +Pressing F1 (or its substitute) will open the Goto... screen. Here, it is possible to jump to a specific address directly, without the need of scrolling there with the cursor keys. The address can be entered in the 'To' field, either absolute or relative (to leap over a specified amount of bytes). An absolute address is being chosen by pressing '=', and a relative one by pressing '+' or '-', for a positive or negative leap respectively. Regardless of the adressing mode, it has to be entered as a hexadecimal number. +.Pp +It is also possible to set up to ten bookmarks in this screen: Pressing '0'...'9' will select one of them. Moving the cursor to "Set" and pressing ENTER will alter one of those book marks. The "Diff:" fields are showing the difference between the actual cursor position and the bookmark. +.Pp +Bookmarks can be stored and loaded, for this there are the "Save Markers" and "Load Markers" items on the bottom. Upon selecting one of them, the user is being prompted for a filename. It is possible to load a marker file at start time, by providing the +.Op Fl m Ar markerfile +parameter. +.Xr dhex_markers 5 +describes the format of the marker files. +.Ss Searching +Pressing F2 (or its subsitute) will open the Search... screen. Here, a short string can be entered (either in hex, or in ascii). If no logfiles are being selected, the cursor will jump to the next occurance of this search string upon selection of "Go". It can be chosen if the search is supposed to be conducted forward of backwards. +.Pp +To jump to the next occurance, F3 (or its substitute) has to be pressed. To jump to the previous one, F4 has to be pressed. The search itself wraps at the edges of the file, meaning that when it reaches the end, it will start from the beginning and vice versa. +.Pp +Searchlogs are an advanced way of searching: Writing to the searchlog does not jump the cursor from one occurance to the next. Instead, it will write the offsets of all of them into the logfile. Their format is described in +.Xr dhex_searchlog 5 . +.Pp +Reading from this searchlog means that the search does not cover the whole file: Only the addresses which have been provided in this file are being searched. Thus it is possible to search for specific changes. Like for example the number of lives stored in the save file of a game. +.Xr dhex_searchlog 5 +describes the format of the searchlog. +.Ss HexCal +Pressing F5 (or its substitute) will open a small 64 bit calculator. This calculator is capable of not only performing arithmetic operations (+, -, *, /, modulo), but also logic ones. (and, or, xor, shift). There are three columns to enter numbers as hexadecimals, decimals or in binary format. Pressing 'x' will close this screen. +.Ss Correlation +When +.Xr dhex 1 +is running in diff mode, pressing F6 (or its substitute) will open the dialog for file correlation. This will try to find the optimal offset between the two files. There are three algorithms available for finding this offset: Searching for the best match (as many bytes as possible are the same), the longest match (as many consecutive bytes match as possible), or the minimum difference (as little differences between the bytes as possible). +.Pp +Even though it seems like the same at first, looking for the minimum difference is in fact faster. This can be improved even more, if the user sets an upper difference limit. +.Pp +Upon selecting Go, the program will search for the optimal offset. This will take some time. +.Ss Saving and quitting +Pressing F10 (or its substitute) will close +.Nm . +In case there have been changes made to the file, a save dialog opens up. Here, it is possible to select whether or not to write the changes back into the file. +.Sh FILES +$HOME/.dhexrc: The default location of the config file. If the $HOME-variable is not set, its location has to be provided manually. +.Sh BUGS +Report bugs to +.An Aq dettus@dettus.net . +Make sure to include DHEX somewhere in the subject. +.Sh AUTHOR +Written by +.An Thomas Dettbarn +.Sh SEE ALSO +.Xr dhexrc 5 , +.Xr dhex_markers 5 , +.Xr dhex_searchlog 5 diff --git a/dhex_markers.5 b/dhex_markers.5 new file mode 100644 index 0000000..64815e3 --- /dev/null +++ b/dhex_markers.5 @@ -0,0 +1,66 @@ +.\" Process this file with +.\" groff -man -Tascii dhex.1 +.\" +.Dd January 28, 2011 +.Os +.Dt DHEX_MARKERS 5 +.Sh NAME +.Nm dhex_markers +.Nd marker file for dhex +.Sh DESCRIPTION +Bookmarks for +.Xr dhex 1 +are stored in marker files. This manpage describes the format of those marker files. +.Ss EXAMPLE +A typical marker file looks like this: +. +.br +.Ql #DHEX MARKERS +.br +.Ql #VERSION 0 +.br +.Ql #lines are all in hex +.br +.Ql #relative positions are =, +, - +.br +.br +.Ql =0000000000000000 +.br +.Ql =0000000000001000 +.br +.Ql =0000000000002000 +.br +.Ql +0000000000001000 +.br +.Ql +0000000000002000 +.br +.Ql -0000000000001000 +.br +.Ql -0000000000002000 +.br +.Ql =00000005334ffeba +.br +.Ql =00000000DEADBEEF +.br +.Ql +000000000000BABE +.br +. +.Sh OPTIONS +In the example above, the file has two sections: A comment section, and a bookmark section. +.Ss Comments +Comments are indicated with a '#' character. Everything afterwards in a line is being ignored when parsing the file +.Ss Bookmark section +Bookmarks can be either absolute or relative. Lines with absolute bookmarks are starting with '=', the relative ones with '+' or '-'. The value is a 64 bit hexadecimal one. +.Pp +There should always be 10 bookmarks per file. +.Sh BUGS +Report bugs to +.An Aq dettus@dettus.net . +Make sure to include DHEX somewhere in the subject. +.Sh AUTHOR +Written by +.An Thomas Dettbarn +.Sh SEE ALSO +.Xr dhex 1 , +.Xr dhexrc 5 , +.Xr dhex_searchlog 5 . diff --git a/dhex_searchlog.5 b/dhex_searchlog.5 new file mode 100644 index 0000000..81e23cc --- /dev/null +++ b/dhex_searchlog.5 @@ -0,0 +1,53 @@ +.\" Process this file with +.\" groff -man -Tascii dhex.1 +.\" +.Dd January 28, 2011 +.Os +.Dt DHEX_SEARCHLOG 5 +.Sh NAME +.Nm dhex_searchlog +.Nd search log file for dhex +.Sh DESCRIPTION +Searchlogs for +.Xr dhex 1 +are stored in searchlog files. This manpage describes the format of those files. +.Ss EXAMPLE +A typical searchlog file looks like this: +.br +.Ql #DHEX SEARCHLOG +.br +.Ql #VERSION 0 +.br +.Ql #Search was for d0 0f af fe +.br +.Ql #lines are all in hex +.br +.br +.Ql 0000000000002385 +.br +.Ql 0000000000002e21 +.br +.Ql 0000000000006acb +.br +.Ql 0000000000006b8b +.br +.Ql 000000000000cd27 +.br +.Sh OPTIONS +In the example above, the file has two sections: A comment section, and an offset section. +.Ss Comments +Comments are indicated with a '#' character. Everything afterwards in a line is being ignored when parsing the file +.Ss Offset section +Offsets are 64 bit addresses presented as hexadecimal values. It is the offset where the searchstring occurred as result when the searchlog was written. +And it is also where the next search is being conducted when reading the searchlog. +.Sh BUGS +Report bugs to +.An Aq dettus@dettus.net . +Make sure to include DHEX somewhere in the subject. +.Sh AUTHOR +Written by +.An Thomas Dettbarn +.Sh SEE ALSO +.Xr dhex 1 , +.Xr dhexrc 5 , +.Xr dhex_markers 5 . diff --git a/dhexrc.5 b/dhexrc.5 new file mode 100644 index 0000000..69e5344 --- /dev/null +++ b/dhexrc.5 @@ -0,0 +1,212 @@ +.\" Process this file with +.\" groff -man -Tascii dhex.1 +.\" +.Dd January 28, 2011 +.Os +.Dt DHEXRC 5 +. +. +.Sh NAME +.Nm dhexrc +.Nd Configuration File for dhex +.Sh DESCRIPTION +dhexrc is the configuration file that specifies the colorscheme and the key translation tab for +.Xr dhex 1 , +Upon starting the program, it is being read and parsed. It is being written and/or created after invoking the keyboard setup. +.Ss EXAMPLE +A typical .dhexrc file looks like this: +. +.br +.Ql #DHEXCOLORSCHEME +.br +.Ql #VERSION 0 +.br +.Ql #possible colors are: BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITE +.br +.Ql #possible extra flags are: UNDERLINE,REVERSE,BLINK,DIM,BOLD +.br +.br +.Ql BRACKETS: FG=BLACK,BG=BLACK,BOLD +.br +.Ql HEXFIELD: FG=WHITE,BG=BLACK +.br +.Ql INPUT: FG=BLACK,BG=WHITE +.br +.Ql CURSOR: FG=WHITE,BG=BLACK +.br +.Ql TEXT: FG=WHITE,BG=BLACK,BOLD +.br +.Ql MENU_NORMAL: FG=CYAN,BG=BLACK +.br +.Ql MENU_HIGHLIGHT: FG=BLACK,BG=CYAN +.br +.Ql MENU_HOTKEY: FG=YELLOW,BG=BLACK,BOLD +.br +.Ql MENU_HOTKEY_HI: FG=YELLOW,BG=CYAN,BOLD +.br +.Ql FRAME: FG=BLUE,BG=BLACK,BOLD +.br +.Ql NORMAL_DIFF: FG=YELLOW,BG=BLACK +.br +.Ql CURSOR_DIFF: FG=YELLOW,BG=WHITE,BOLD +.br +.Ql HEADLINE: FG=BLUE,BG=BLACK,BOLD +.br +.br +.Ql KEYF1:1b 5b 31 31 7e +.br +.Ql KEYF2:1b 5b 31 32 7e +.br +.Ql KEYF3:1b 5b 31 33 7e +.br +.Ql KEYF4:1b 5b 31 34 7e +.br +.Ql KEYF5:1b 5b 31 35 7e +.br +.Ql KEYF6:1b 5b 31 37 7e +.br +.Ql KEYF7:1b 5b 31 38 7e +.br +.Ql KEYF8:1b 5b 31 39 7e +.br +.Ql KEYF9:1b 5b 32 30 7e +.br +.Ql KEYF10:1b 5b 32 31 7e +.br +.Ql KEYESC:1b +.br +.Ql KEYBACKSPACE:08 +.br +.Ql KEYDEL:7f +.br +.Ql KEYENTER:0a +.br +.Ql KEYTAB:09 +.br +.Ql KEYUP:1b 5b 41 +.br +.Ql KEYDOWN:1b 5b 42 +.br +.Ql KEYRIGHT:1b 5b 43 +.br +.Ql KEYLEFT:1b 5b 44 +.br +.Ql KEYPGUP:1b 5b 35 7e +.br +.Ql KEYPGDOWN:1b 5b 36 7e +.br +.Ql KEYHOME:1b 5b 37 7e +.br +.Ql KEYEND:1b 5b 38 7e +.br +.Sh OPTIONS +In the example above, the dhexrc file has three distinct sections: A comment section, a color section and a key conversion tab section. +.Ss Comments +Comments are indicated with a '#' character. Everything afterwards in a line is being ignored when parsing the file +.Ss Color section +There are 13 color groups. Each of the color group has a foreground color, a background color and some extra flags, coming from ncurses. The foreground color is being defined by +.Nm FG= +while the background color is being defined by +.Nm BG=. +They and the extra flags are being separated by ','. Possible colors are +.Nm BLACK , +.Nm GREEN , +.Nm RED , +.Nm YELLOW , +.Nm BROWN , +.Nm BLUE , +.Nm MAGENTA , +.Nm WHITE , +and exclusively as foreground colors +.Nm LIGHTBLACK , +.Nm LIGHTGREEN , +.Nm LIGHTRED , +.Nm LIGHTYELLOW , +.Nm LIGHTBROWN , +.Nm LIGHTBLUE , +.Nm LIGHTMAGENTA +and +.Nm LIGHTWHITE. +Valid extra flags are +.Nm UNDERLINE , +.Nm REVERSE , +.Nm BLINK , +.Nm DIM +and +.Nm BOLD . +.Pp +The color pairs are as followed: +.Bl -tag -width 10 +.It BRACKETS: +This specifies the color for the brackets around text fields. +.It HEXFIELD: +This specifies the color in which the file's content is being shown. +.It INPUT: +When entering text, it is in this color. +.It CURSOR: +The cursor in the hex field has this color. +.It TEXT: +This color is for informative text as well as for text fields which are not taking input yet. +.It MENU_NORMAL: +Menu items which are not selected belong into this color group. +.It MENU_HIGHLIGHT: +The selected menu item gets this special color. +.It MENU_HOTKEY: +Hotkeys for menu items are visually distinct from the rest of the text because they have this color. +.It MENU_HOTKEY_HI: +If the actual menu item has a hotkey, it is shown in this color. +.It FRAME: +Some screens have frames. Those frames have this color. +.It NORMAL_DIFF: +Differences in the file's content (either because of changes or because dhex is running in diff mode) are indicated by this color. +.It CURSOR_DIFF: +If the cursor is on one of those differences, it will have this color. +.It HEADLINE: +On top of the screen, there is a headline. Which is shown in this color. +.El +.Ss Key conversion tab section +When pressing a "standard" key, something which can be mapped directly to an ascii character, only this character will end up in ncurses' buffer. However, pressing special keys like (for example) +.Nm F1 +or +.Nm ALT+6 +will produce longer sequences. Mapping those sequences back to a specific key is the job of the key conversion tab. (I was dissatisfied how ncurses handled this on its own). The sequences are called (in order) +.Nm KEYF1 , +.Nm KEYF2 , +.Nm KEYF3 , +.Nm KEYF4 , +.Nm KEYF5 , +.Nm KEYF6 , +.Nm KEYF7 , +.Nm KEYF8 , +.Nm KEYF9 , +.Nm KEYF10 , +.Nm KEYESC , +.Nm KEYBACKSPACE , +.Nm KEYDEL , +.Nm KEYENTER , +.Nm KEYTAB , +.Nm KEYUP , +.Nm KEYDOWN , +.Nm KEYRIGHT , +.Nm KEYLEFT , +.Nm KEYPGUP , +.Nm KEYPGDOWN , +.Nm KEYHOME +and +.Nm KEYEND . +.Pp +Sequences itself are a string of lower case hex-values, each two nibbles long. Currently, there is no way of adding an alternativ sequence to the same key. +.Pp +It is possible that the sequence made up of hex values does not REALLY belong to the key. (For example if F2 was pressed in the setup program when F1 was prompted). +However, when this sequence ends up in the ncurses buffer, it is being interpreted as if that key was pressed. +.Sh BUGS +Report bugs to +.An Aq dettus@dettus.net . +Make sure to include DHEX somewhere in the subject. +.Sh AUTHOR +Written by +.An Thomas Dettbarn +.Sh SEE ALSO +.Xr dhex 1 , +.Xr dhex_markers 5 , +.Xr dhex_searchlog 5 @@ -0,0 +1,571 @@ +#include <stdio.h> +#include <stdlib.h> +void warte() +{ + char b[2]; + fprintf(stderr,"...Please press <Enter> to read on..."); + fgets(b,sizeof(b),stdin); +} + +void print_gpl() +{ + // this is a simple lz-coded version of the gpl. + // i had a little fun with this. +const unsigned short packbits=62833; +const unsigned char packedgpl[7855]={ + 0x12,0x03,0x08,0xa8,0xe8,0xc8,0xa9,0x5a,0x4a,0x91,0x53,0x91,0x54,0x10,0x13,0x08, + 0x54,0x95,0x10,0x53,0xd2,0x10,0xe8,0xd4,0xb2,0x4c,0x15,0x29,0x1a,0x70,0x48,0x56, + 0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x32,0x2c,0x20,0x4a,0x75,0x6e,0x65,0x20,0x31, + 0x39,0x39,0x31,0x0a,0x0a,0x20,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20, + 0x28,0x43,0xa9,0x93,0x83,0x93,0x2b,0xb3,0xa4,0x03,0x62,0x24,0x57,0x2e,0x38,0x53, + 0x6f,0x66,0x74,0x77,0xe1,0xb2,0x2d,0x59,0xef,0x62,0x43,0x16,0x46,0x3f,0xae,0x32, + 0x95,0xe4,0x36,0xe6,0x2a,0xbf,0x37,0x8a,0x79,0x4f,0x50,0x4d,0x0e,0x08,0x55,0x59, + 0x1b,0x1c,0xbb,0x98,0x81,0x62,0x0b,0x1b,0x2b,0x17,0x39,0x53,0x75,0x69,0xf4,0x82, + 0x69,0x66,0x06,0x56,0x3e,0x09,0xbd,0xcd,0xd1,0x13,0x9c,0xa6,0x60,0x71,0x04,0x23, + 0x13,0x13,0x13,0xd3,0x12,0x2b,0xa8,0x6e,0xc5,0x56,0xd5,0x54,0xb0,0xe0,0x29,0xb2, + 0x97,0x15,0xf9,0x02,0x5b,0x4a,0xa5,0xcd,0x81,0xc0,0xcb,0xb2,0x76,0x19,0x2d,0xa4, + 0xc8,0x40,0xe5,0x15,0xc8,0xf8,0x08,0x01,0x09,0x97,0x35,0x20,0xe4,0x22,0x8d,0x5e, + 0x8a,0x88,0xd5,0x0f,0xe9,0x51,0x26,0x3e,0x6d,0xda,0x29,0x5c,0x5a,0xd9,0x9c,0x02, + 0xc8,0x9b,0x19,0x08,0x1d,0xfa,0x48,0xc3,0x96,0x36,0x56,0xe6,0x36,0x57,0x06,0x42, + 0xf6,0x36,0x56,0xd7,0x56,0xe6,0x46,0xc7,0x02,0x3a,0xf1,0x80,0x8c,0xa1,0x85,0xb9, + 0x9d,0xa5,0xb9,0x9d,0x81,0xa4,0xd1,0x53,0x34,0x6e,0x6f,0x74,0x20,0x61,0x6c,0x6c, + 0x6f,0x77,0x65,0x64,0x2e,0x8a,0x03,0x62,0x89,0x00,0x25,0x57,0x16,0xd6,0x26,0xc6, + 0x56,0x3e,0x3e,0x80,0x50,0xa1,0x95,0xa3,0x43,0x73,0x20,0x66,0x6f,0x72,0x20,0xed, + 0xd3,0x0a,0xc8,0x3c,0x82,0x49,0x70,0x91,0x95,0xcd,0xa5,0x9d,0xb9,0x1b,0x37,0x74, + 0x61,0xeb,0x23,0xd7,0x5d,0x58,0x1e,0x48,0xde,0x5b,0x9d,0x9c,0x82,0xf9,0x6c,0x41, + 0xf6,0xd6,0x4e,0x80,0xcd,0xa1,0x17,0xdc,0x83,0x6e,0x95,0x3c,0xd0,0xd0,0xb9,0x80, + 0x80,0x08,0xe5,0x8f,0x3f,0x6e,0x74,0x72,0x61,0xf3,0xe3,0x11,0xfd,0x58,0x5d,0x06, + 0x94,0xb9,0x95,0xc9,0x85,0xb1,0x81,0x40,0xd5,0x89,0x4f,0x56,0x0a,0xcc,0x07,0xf1, + 0xc4,0x94,0xe6,0x46,0x57,0xe6,0x46,0x6e,0x7e,0x9d,0xd5,0x85,0xc9,0x85,0x0f,0x79, + 0xe5,0xd5,0x18,0xe8,0x4f,0xde,0xa2,0x25,0xff,0x28,0xe2,0x5a,0x5a,0x5a,0xc7,0x40, + 0xed,0x54,0x98,0xb9,0xfa,0x61,0x30,0x05,0x37,0xd7,0x3a,0xe0,0x25,0x0d,0x57,0x58, + 0x07,0xa7,0xe3,0x9a,0x39,0x90,0xba,0xf9,0x59,0xe1,0xc4,0x86,0x7a,0x16,0xa2,0xe8, + 0xc9,0x01,0x45,0xec,0x84,0xc1,0xc1,0xb1,0x8f,0x40,0xa9,0xc0,0x65,0xd6,0x3a,0xe8, + 0x98,0x91,0xb7,0xa0,0xa8,0x68,0x38,0x99,0x5f,0xb5,0x0e,0x84,0x67,0x50,0x61,0x6e, + 0x79,0x20,0xef,0xe3,0x28,0x39,0x10,0x38,0xb9,0xb7,0x33,0xb9,0xb0,0x36,0x90,0x3b, + 0xb4,0x77,0xc2,0x53,0x1d,0x1d,0xda,0x9b,0xdc,0xfc,0xd8,0xa6,0x7d,0xb0,0x39,0xb9, + 0x52,0xa8,0x9b,0x37,0x95,0x0e,0x97,0x50,0xa6,0xde,0xda,0xca,0x0f,0xd8,0xaf,0xc5, + 0x0c,0x75,0xe7,0x68,0xec,0x7d,0xec,0x39,0xe9,0x11,0xcb,0x53,0xc4,0xe0,0x30,0xa5, + 0x89,0xc9,0x85,0xc9,0xe5,0x3f,0x72,0x53,0x4e,0x69,0x6e,0x73,0x74,0x65,0x61,0x64, + 0x2e,0x29,0x20,0x20,0x59,0x6f,0x75,0x20,0x63,0x61,0xee,0xa5,0xa7,0x7c,0x6a,0xe9, + 0x90,0xbb,0xf2,0x7b,0xc7,0x9a,0x9f,0xdf,0xbc,0xbd,0xcf,0x4f,0x40,0x40,0xae,0xd0, + 0xca,0xdc,0x40,0xee,0x07,0x47,0x70,0x65,0x61,0xeb,0xa4,0xe8,0x32,0x32,0x5e,0x8c, + 0x95,0x1e,0x4f,0x1c,0x93,0x2b,0x33,0x2b,0x93,0x93,0xa7,0x74,0x8f,0xae,0xcf,0x3f, + 0xac,0x34,0x13,0x05,0x38,0xf9,0x71,0xfa,0xbc,0xeb,0x79,0xec,0xfe,0x3e,0xbf,0xa6, + 0xcd,0xff,0x5c,0x5d,0x45,0x61,0xf4,0x84,0x1f,0x0a,0x68,0x61,0xf6,0x46,0xa3,0xeb, + 0x9f,0xbb,0x8e,0xf6,0x8f,0x8f,0xb9,0x73,0x40,0xa8,0xf7,0x20,0xf2,0x74,0x21,0x6f, + 0xf2,0xd3,0xb2,0x03,0xb2,0x83,0x25,0xf6,0x83,0x3e,0x20,0x69,0xe6,0xe4,0x40,0x20, + 0x77,0x69,0x73,0x68,0xa9,0xf4,0x9b,0xc6,0xc0,0x13,0x3b,0x63,0x65,0xe9,0x53,0x41, + 0xf3,0x53,0xb7,0x43,0x46,0x63,0x6f,0xe4,0x63,0x2f,0xf2,0x35,0x36,0x67,0xe5,0xf3, + 0x12,0x74,0x8a,0x78,0xc6,0x33,0x9f,0xc3,0xc9,0x3b,0xc7,0x54,0xc9,0x37,0xa1,0x6d, + 0xa3,0x23,0xc9,0x73,0x25,0xa0,0x43,0x43,0xe3,0x66,0xc3,0xd4,0x49,0x6e,0x20,0x6e, + 0x65,0xf7,0xb6,0xc3,0x98,0x37,0xbb,0x56,0xab,0x18,0x4b,0x6b,0x6e,0x6f,0xf7,0x49, + 0x4b,0xe4,0x23,0x18,0x68,0xe5,0x53,0xcd,0xa3,0x45,0x6e,0x67,0xf3,0x65,0x38,0x54, + 0xef,0x04,0x4f,0x74,0x65,0xe3,0x25,0x50,0x72,0xa0,0x55,0x84,0x03,0xb8,0xb3,0x3a, + 0xee,0xe3,0xc1,0xc9,0x3f,0x72,0xe5,0x94,0x42,0xe3,0x24,0xb1,0x13,0xa8,0x04,0xd0, + 0x63,0x45,0x62,0x69,0x64,0x8a,0xd3,0xab,0xe4,0x8c,0x44,0x42,0xe5,0xe3,0xab,0xd4, + 0xd0,0x86,0xd1,0x96,0xd3,0x04,0xcd,0xa4,0x2b,0x73,0xeb,0x86,0xd7,0x73,0x20,0x75, + 0x72,0xf2,0x64,0x9e,0xb3,0xd8,0x53,0xcc,0x36,0x58,0x2e,0x8a,0x53,0x95,0x04,0xd8, + 0x2d,0xd5,0x23,0x1f,0x73,0x6c,0xe1,0xf3,0xc2,0xf4,0x0d,0x65,0x72,0x74,0xe1,0x53, + 0xce,0x73,0x5b,0xf0,0x03,0x5c,0x69,0x62,0x69,0x6c,0x69,0xf4,0x54,0xc3,0xb4,0xa4, + 0x44,0xd9,0x06,0x4a,0x8a,0x7f,0xc2,0xc6,0xcd,0x4c,0x4c,0xac,0x94,0xd8,0x07,0x4a, + 0x6d,0x6f,0x64,0x69,0xe6,0xc4,0xb6,0x45,0x52,0xc6,0xc3,0x61,0x65,0x78,0xe1,0x54, + 0x09,0xac,0xe8,0xe1,0x9f,0xdf,0x86,0x60,0x73,0x75,0x63,0x68,0x20,0xe1,0x08,0xcf, + 0xf3,0x53,0x68,0xe5,0x94,0x2f,0x8a,0x73,0x66,0xf4,0xc3,0xc5,0x53,0xe3,0xb5,0x24, + 0x20,0x66,0xe5,0xe3,0xe3,0x25,0x62,0xf5,0x83,0x28,0xe7,0x24,0xc8,0x55,0x5a,0x65, + 0x63,0xe9,0x53,0x65,0xee,0x73,0xd8,0xf4,0xa4,0x5a,0xda,0xd5,0xd5,0x34,0x37,0xa0, + 0x34,0xc1,0x13,0xbd,0x04,0xb6,0xe5,0xe8,0x0f,0xc0,0xb3,0x6a,0xf9,0x15,0x38,0xac, + 0xd9,0xc7,0x2b,0xc9,0xe3,0xed,0xe3,0xa1,0x89,0xc8,0x33,0x6c,0xc1,0xc3,0xcf,0xa9, + 0x68,0x73,0xe8,0xa3,0xd0,0xc3,0xef,0x23,0xc2,0x96,0xd1,0x63,0x8d,0xb4,0xaa,0xd5, + 0xed,0x76,0xd0,0x43,0x73,0x69,0x72,0x8a,0x98,0xda,0x84,0xb8,0xf5,0xce,0xff,0x52, + 0xf3,0xd3,0x46,0x74,0x68,0x20,0x74,0xf7,0x93,0x59,0x74,0x65,0x70,0x73,0x3a,0x20, + 0x28,0x31,0xa9,0x15,0x8e,0x56,0x84,0xee,0xe0,0xb3,0x4f,0x0a,0x28,0x32,0xa9,0x93, + 0xe5,0x43,0xbb,0x87,0xd7,0xcb,0x10,0x77,0x68,0xe9,0xf3,0xe5,0x34,0x69,0xf3,0xf5, + 0x79,0x6c,0x65,0xe7,0xd3,0xbd,0x55,0x0d,0xf3,0xd5,0x82,0xf7,0x0d,0xac,0x8c,0xdf, + 0x23,0x79,0xaf,0x35,0x96,0x85,0xe2,0x4c,0xf8,0xa5,0x74,0x41,0x6c,0xf3,0x63,0x6e, + 0xe9,0xcf,0x94,0x85,0xd3,0x97,0x2d,0x6b,0x39,0xaa,0xf2,0xa4,0x2e,0x39,0x5f,0xda, + 0xa7,0xb3,0x75,0xcd,0xa7,0xd6,0x29,0xc5,0xa4,0x7a,0xd1,0x75,0xb2,0xe8,0x6c,0x9b, + 0x72,0x54,0x86,0xe3,0x30,0x27,0x4b,0xd0,0x0f,0x0a,0x3e,0xae,0x4a,0x70,0xb6,0x3c, + 0x86,0xdb,0xfb,0xd0,0x20,0x79,0x92,0x0f,0xf9,0xa5,0x80,0x8b,0xf4,0xb6,0x86,0x9c, + 0x85,0x93,0xec,0x0c,0x96,0xdc,0x70,0xb5,0x9f,0xf4,0x42,0x99,0xd3,0x89,0xda,0xca, + 0x89,0x0a,0x95,0xb1,0x93,0xb4,0x9c,0x14,0x04,0x17,0x36,0x37,0x3f,0xb0,0x98,0x60, + 0xc1,0x5d,0x99,0xe2,0x9d,0x92,0x79,0xde,0xb4,0xa3,0x83,0x2f,0xe7,0x8e,0x19,0xba, + 0x47,0x6d,0x5b,0xbe,0x16,0x61,0x22,0x69,0xa2,0xf7,0xf1,0x3b,0x69,0x6e,0x61,0x6c, + 0xac,0x53,0x8b,0x2d,0x09,0x53,0xaf,0x9c,0x0e,0x3c,0x4e,0x71,0x5c,0xee,0x8c,0x07, + 0xb9,0x37,0xb2,0xba,0x71,0x83,0xc5,0x85,0x2f,0x89,0xec,0x0e,0xaa,0x25,0x84,0x3c, + 0xb2,0x83,0x9d,0xac,0x2e,0x3d,0xdf,0x6d,0x48,0x8a,0x57,0x2d,0x4e,0x87,0x29,0xc1, + 0xd5,0xd1,0x57,0xc4,0xb4,0xa4,0x63,0x4c,0x60,0x89,0x7d,0xc2,0x2d,0x89,0x64,0x66, + 0xa7,0x44,0x90,0xe8,0xd0,0x47,0x29,0x4e,0x79,0x9c,0x9b,0x3c,0xb7,0x91,0xba,0x10, + 0xfd,0xac,0xcd,0x9a,0xc5,0x97,0x29,0xe0,0xe9,0x33,0x0f,0xd2,0xad,0xa6,0x4b,0x6e, + 0xb4,0x18,0x8b,0xdd,0x5b,0x3a,0xf5,0xd3,0x91,0x9f,0xf4,0x4b,0x09,0x10,0xcf,0x47, + 0x9e,0x93,0x89,0xdc,0x97,0xb2,0xe5,0x68,0xd9,0x19,0xb4,0x84,0x88,0xf3,0x58,0x52, + 0x51,0x4a,0x73,0x23,0x4b,0xb3,0x4b,0x23,0xab,0xa7,0xc0,0x04,0xf2,0x26,0x5e,0xd4, + 0xd5,0x7a,0x73,0x62,0xc5,0xf9,0x31,0x6e,0x20,0xe5,0xb3,0x79,0x47,0x2a,0x4f,0x0f, + 0x2e,0xdc,0x39,0xfd,0x16,0x03,0xf4,0x20,0xe9,0x61,0x1e,0x65,0xf4,0xa3,0x33,0x89, + 0x4b,0x92,0x4a,0x9d,0x27,0x4c,0x37,0x78,0x06,0x71,0xc1,0xe0,0x02,0x48,0x6d,0xe1, + 0xf3,0x48,0xc7,0x6d,0x8c,0xb1,0x95,0x85,0x5f,0x78,0x9e,0xc3,0x7c,0xbc,0xd9,0x2a, + 0x8e,0x78,0x5e,0x05,0x72,0x53,0xc0,0x07,0x85,0x47,0x03,0xd7,0x62,0x26,0x6a,0x3a, + 0xa7,0x9a,0x92,0x72,0x76,0x6a,0x3a,0x54,0x6c,0xec,0x46,0x52,0x27,0x3b,0x4f,0x98, + 0x1a,0x4b,0x4f,0x94,0x5b,0x4b,0xe4,0x7d,0x1e,0xb4,0xf9,0x56,0x32,0xd5,0x54,0x7d, + 0x07,0x48,0xb1,0xea,0x91,0x3d,0x12,0xa4,0x68,0xaa,0x68,0xdc,0x22,0x86,0xd9,0x3b, + 0xe5,0x04,0xd7,0x03,0x81,0x6f,0x00,0xb9,0x02,0x0e,0xcc,0xa2,0x2a,0x92,0x6a,0x9a, + 0x02,0x09,0x72,0x22,0x02,0x19,0x7a,0x72,0x22,0x4a,0xa2,0x4a,0x7a,0x72,0x9a,0x02, + 0x31,0x7a,0x92,0x1e,0xad,0x05,0x95,0x95,0xe4,0x74,0xc4,0x02,0x42,0x94,0x34,0x45, + 0x25,0x95,0x24,0x54,0x4d,0x60,0xbb,0xac,0x56,0xd3,0x13,0x51,0x92,0x51,0xd2,0x50, + 0x30,0xed,0x6d,0xaa,0x56,0x30,0xae,0xe5,0x25,0x5f,0x4e,0xd6,0x39,0x3e,0x91,0x5c, + 0x4b,0x7a,0xf6,0xb5,0xe1,0x8b,0xbb,0x37,0xb9,0xf5,0x83,0xbd,0x74,0x1b,0xc7,0x43, + 0xcd,0x29,0x84,0x13,0xb0,0xa6,0x31,0x02,0x4f,0x9b,0xb0,0x70,0x32,0x61,0x67,0xd5, + 0x3b,0x68,0x6f,0xec,0x14,0x5a,0xe6,0xc2,0x29,0x60,0xd3,0x9e,0x6a,0x9f,0xc5,0x38, + 0x9a,0x5a,0xb7,0x0f,0x99,0x62,0x61,0xe1,0x52,0xdf,0x56,0xae,0xf1,0x20,0x3e,0xf6, + 0x3c,0xce,0x5d,0x5c,0xa2,0x0c,0x44,0x04,0xda,0x68,0x97,0xe8,0x7c,0x84,0xf2,0x41, + 0x59,0x2c,0x8a,0x25,0x3b,0x53,0x75,0x57,0x97,0xdd,0xd9,0x4d,0xc4,0xbb,0x20,0xef, + 0xe4,0x27,0xd1,0x22,0x5e,0x62,0xe1,0xa6,0x8c,0x4b,0x84,0xe3,0x14,0x53,0x68,0x2b, + 0x1f,0xe3,0x02,0x52,0x3e,0x67,0xf7,0x40,0xf8,0x85,0x72,0xf2,0xe3,0xe4,0xc6,0xe7, + 0x83,0xa5,0xd9,0xcf,0xc7,0x1e,0x3a,0x5d,0x8f,0xdc,0x3a,0xb8,0xbe,0x2f,0xb6,0xb0, + 0x3b,0x5d,0xe3,0xc8,0x84,0x99,0xa7,0xed,0x84,0x13,0x61,0x36,0x6a,0x7e,0xcf,0xfb, + 0x80,0x74,0xeb,0x32,0x10,0xb8,0x37,0xf9,0x02,0xd9,0xf5,0x4d,0x58,0x14,0x0f,0x96, + 0xa7,0x3d,0xa4,0x3f,0x4e,0x67,0x97,0x31,0x76,0xa5,0x6b,0x4a,0xbf,0x49,0x5c,0xc8, + 0xc9,0x25,0x13,0x1b,0x2f,0xdf,0xa5,0xc0,0x3e,0xdd,0xa9,0x2e,0xec,0x9c,0x94,0x18, + 0x0a,0xf2,0xac,0xe1,0xf9,0x4b,0xe6,0x73,0xc2,0x47,0xdc,0xde,0x57,0x27,0x93,0x5e, + 0xe0,0x61,0x8c,0xad,0x9e,0xd0,0x23,0x11,0xb5,0xf7,0x11,0x09,0x6c,0xe9,0x03,0x2e, + 0xaf,0xb2,0x13,0x12,0xb6,0x12,0x06,0x22,0xca,0x49,0x4d,0x94,0xb8,0x46,0x31,0x41, + 0xe0,0x2b,0xd6,0x35,0x90,0xc2,0xc8,0xc8,0x27,0xbb,0x96,0xb2,0x9a,0x03,0x11,0x9d, + 0xde,0x23,0x3a,0xd4,0x2a,0x78,0x44,0x90,0xbd,0x91,0x57,0xf3,0xdd,0xf3,0xce,0x67, + 0x97,0xfe,0xbf,0x4e,0x87,0xdd,0x48,0xbd,0xde,0x27,0x21,0x4f,0x1d,0x99,0xf6,0xc2, + 0x8f,0x88,0xed,0x9a,0x3e,0xae,0x66,0x52,0x47,0x37,0x97,0x5e,0x79,0x7a,0x5e,0xee, + 0x50,0x78,0x54,0x62,0xe1,0x24,0x95,0xcc,0x14,0xe4,0xea,0xdc,0x9f,0xa1,0x97,0x65, + 0xb6,0xa4,0x6c,0xb9,0xa5,0x8c,0xdc,0x0c,0x79,0x61,0xa5,0x3a,0xfa,0x81,0xcb,0x43, + 0xab,0x29,0x84,0x6a,0xa3,0x53,0x5c,0x90,0xf1,0xe6,0x4e,0x6b,0x93,0x56,0x3a,0x31, + 0x7b,0x22,0x8f,0xf6,0xed,0xe6,0xe8,0xd2,0xe8,0x4b,0xfc,0x1a,0x40,0x67,0x4a,0xa6, + 0x88,0x90,0x0e,0x75,0x1c,0x54,0x19,0x3c,0x7d,0xd6,0x91,0xd4,0xa3,0xd2,0x47,0x4e, + 0x13,0xa2,0x13,0x2b,0x9f,0xc6,0x59,0x77,0x7a,0x96,0xfc,0x13,0x7a,0x6a,0x78,0x29, + 0x2e,0x8a,0xb3,0x38,0x51,0xc1,0x9b,0x3c,0x93,0xab,0x27,0xf9,0x49,0x17,0x7f,0x0e, + 0xfc,0x38,0xce,0xbb,0xc7,0xf9,0xe8,0xc8,0xde,0xca,0x0d,0x2f,0xc5,0xb8,0x5a,0xb1, + 0x9d,0x05,0xfe,0xe2,0xf0,0xe3,0x61,0x17,0xd8,0xab,0x7b,0x27,0xf3,0xfc,0x6f,0x49, + 0xbe,0xb3,0x1e,0x25,0x56,0x3a,0x33,0x9a,0x8c,0x59,0xfb,0xa4,0xa7,0xfa,0x51,0xb3, + 0x73,0xc7,0x47,0x42,0x93,0x51,0xc5,0x05,0x4a,0xeb,0x0e,0x5c,0xda,0x58,0xdd,0x5b, + 0xdd,0xfc,0x60,0xbb,0x85,0xc8,0xc0,0x1b,0x94,0x3a,0x64,0xed,0x44,0x40,0xf0,0xe4, + 0xc3,0x0e,0x73,0x3a,0x69,0x6f,0x3d,0xa0,0x17,0xf9,0xf2,0x05,0x3c,0x05,0x30,0x8a, + 0xb3,0xa7,0xbd,0x9e,0xe5,0x33,0xc6,0x16,0x96,0xd6,0x3e,0x51,0xef,0xd4,0xbe,0x58, + 0x87,0xec,0x80,0xac,0x95,0x95,0xc1,0x13,0x5a,0x4b,0x7d,0xee,0x9d,0x1a,0x8a,0x46, + 0x05,0x9f,0x18,0x5a,0x64,0x6c,0x01,0x86,0x8d,0xb9,0xda,0xad,0x48,0xb8,0x4f,0x98, + 0xd8,0x5c,0x99,0xfb,0x60,0xc1,0x74,0x9f,0x4e,0xfa,0x9b,0x6d,0xf0,0xa4,0x15,0xe4, + 0x26,0x69,0x6a,0xaf,0xb8,0xde,0xa8,0xd7,0xbe,0x53,0xef,0x96,0x0d,0x8c,0x2d,0xec, + 0x99,0x42,0x0a,0x61,0x6c,0xef,0xb3,0xf3,0x9a,0xd9,0xa9,0xf4,0xf0,0x04,0xbe,0x99, + 0xf8,0x1a,0x14,0x59,0x83,0xe6,0xf5,0xa1,0xf3,0xbd,0xa0,0xe5,0xcd,0xcf,0x8c,0xc3, + 0x7e,0x7c,0xae,0x39,0xb6,0x48,0x3b,0xda,0x3f,0x6c,0x90,0x67,0x49,0x9c,0x43,0x13, + 0xdb,0xff,0x3b,0x68,0x10,0xfc,0x95,0xb4,0xa4,0x09,0x67,0x1d,0xba,0x1d,0x28,0xcd, + 0x28,0xf8,0x38,0x21,0x22,0xa0,0x59,0x81,0x8f,0xac,0x1e,0xbe,0xd7,0x7e,0x16,0x60, + 0x6c,0x01,0x71,0x55,0xc7,0x1f,0xfb,0xee,0x2f,0x7b,0x22,0x8d,0xa2,0xa9,0xb4,0x83, + 0x1e,0xd5,0x17,0xbe,0xd2,0x6e,0x65,0xf1,0xe3,0xbb,0xaa,0x1e,0x5b,0xaa,0x8b,0x91, + 0x2f,0x6b,0x9f,0x25,0xc7,0x7a,0x52,0x7b,0x7f,0xec,0x65,0xb3,0x3d,0xc2,0x4c,0xdf, + 0x67,0x14,0xa3,0x10,0x26,0x3e,0xcf,0xee,0xcb,0xbf,0x45,0xfd,0x84,0x8f,0x01,0x3a, + 0xeb,0xef,0xe4,0x9b,0x34,0x08,0x9b,0x79,0x3c,0xab,0xb0,0xbe,0x2b,0xba,0xc4,0x1b, + 0x81,0x80,0x84,0xa5,0x6a,0xb1,0x31,0x16,0x4e,0xba,0x2a,0xb9,0xc9,0xa9,0x8a,0x98, + 0xa5,0xb1,0x5b,0xea,0x32,0x3e,0x93,0x71,0x65,0xc6,0x33,0x21,0xd3,0xc6,0x7b,0x8b, + 0x70,0x05,0xcb,0x93,0x9a,0xd0,0x9b,0xce,0x8b,0xb2,0x64,0xb1,0xc6,0xd6,0xea,0x5a, + 0xb9,0x8c,0xab,0xee,0x40,0x8c,0xf9,0x0b,0xdb,0xc6,0x5c,0xbb,0x11,0x08,0x88,0xf8, + 0x1f,0xcb,0x96,0x0d,0xd7,0x98,0x9c,0x12,0xf3,0x0a,0xc9,0x03,0x26,0x9f,0x09,0x7c, + 0xae,0xe4,0xe8,0xb6,0xa4,0x34,0xcf,0xb3,0x38,0x97,0x20,0x71,0x98,0x04,0xa2,0xc8, + 0x0f,0xd6,0x7c,0xd0,0x6b,0x69,0x4e,0xf3,0x96,0xcc,0x92,0xb8,0xfc,0xbb,0xee,0xd1, + 0xc7,0x05,0x39,0x57,0xe8,0x5c,0x69,0xc8,0x9b,0x39,0x89,0x9b,0x9d,0xa9,0x8e,0xf4, + 0x3b,0x18,0x72,0x59,0xce,0xb3,0x38,0x8f,0x1c,0x7a,0x37,0x31,0xad,0xb5,0x45,0x08, + 0xa5,0xc9,0x91,0x27,0xf5,0x4c,0xe2,0xf1,0xa3,0xc9,0x5f,0x10,0xa3,0xd1,0x34,0x96, + 0x8a,0x96,0x68,0x72,0xcb,0x78,0xc7,0xb8,0x4f,0x84,0x5c,0x16,0xea,0x74,0xa6,0x63, + 0xf6,0x52,0xb7,0x58,0x5f,0x28,0x8d,0x07,0xf2,0x53,0x15,0x0f,0xee,0xc4,0x6e,0xd3, + 0xf3,0xb4,0x99,0x73,0x5d,0xd4,0xcf,0x33,0x9a,0x12,0xa7,0x69,0xcd,0x74,0x20,0x97, + 0x24,0x3d,0x0a,0x93,0x3c,0x95,0xb5,0x68,0xf3,0x92,0x6c,0x4c,0x4d,0x72,0x35,0xd2, + 0x0b,0x48,0x57,0xae,0x3a,0x9e,0xb3,0x4d,0xd1,0x84,0x28,0xc8,0x91,0x8f,0x61,0x3b, + 0xf1,0xf2,0x28,0x86,0x55,0x3e,0xcf,0x10,0x4c,0x1c,0x8f,0x3c,0xc5,0xcd,0x13,0xbe, + 0x12,0x8f,0x6c,0xc1,0x92,0x9b,0xfb,0x34,0x0c,0x63,0xe5,0xb4,0x11,0x5e,0x67,0x5b, + 0x14,0x72,0xf3,0xc0,0xfb,0xcd,0x2e,0x15,0x14,0x5e,0x11,0xf5,0x19,0xd5,0x4f,0x86, + 0xee,0x1c,0x82,0x4a,0xa7,0xea,0xfc,0xa2,0x83,0x91,0x5a,0x00,0x9b,0x69,0xf3,0x31, + 0xca,0x16,0x51,0xa7,0x5b,0x95,0xaa,0xfa,0x64,0x5d,0x89,0x65,0x1c,0x2f,0x7a,0x6a, + 0xd6,0x32,0x82,0xd1,0x75,0x42,0x57,0x66,0xfd,0xaf,0xf2,0xb0,0xa9,0xa5,0x5a,0x95, + 0xb1,0xb1,0xa3,0xce,0x4b,0xb3,0xf5,0xe0,0xaf,0xf3,0x8e,0xbc,0x81,0xd8,0xa5,0x4f, + 0x3a,0xe9,0xff,0x70,0x6d,0xd7,0x4a,0xc4,0xa0,0x14,0xe1,0x8d,0x95,0x97,0x61,0xa4, + 0x4b,0xda,0x6e,0x33,0x3a,0x74,0x73,0x65,0xec,0x53,0x20,0xb7,0x1f,0x4d,0x20,0x61, + 0x85,0xd8,0xd4,0xf7,0x96,0xa6,0x9b,0x68,0xb4,0xf9,0xd3,0xd6,0x65,0x92,0xf9,0xab, + 0x18,0x75,0x69,0xd2,0x17,0x26,0xe3,0x87,0x8c,0xdb,0xf5,0x3f,0xba,0xc3,0x5b,0xc5, + 0xd5,0xa5,0x93,0xb4,0x9b,0xfb,0xf4,0x1b,0x5a,0x2e,0xa9,0x09,0x5b,0xd6,0xb0,0x4d, + 0xde,0xf6,0xdc,0xcf,0x95,0x36,0x9e,0x2c,0x9c,0x57,0x74,0x71,0xda,0x6a,0x3f,0x17, + 0x25,0xa2,0x38,0x96,0x95,0x1b,0xfd,0x20,0x5c,0xe1,0x93,0x92,0x8e,0x17,0x79,0xbd, + 0x65,0x69,0xd8,0x34,0x8f,0xd6,0xc3,0x6d,0x3c,0xee,0xd3,0xce,0x9b,0x22,0x57,0x34, + 0x4c,0xf4,0xe6,0xa8,0xcf,0x13,0x47,0xcd,0xbd,0xb9,0xcf,0xca,0x5d,0xb5,0x21,0xa1, + 0xb9,0x64,0x6c,0xf3,0xc4,0x4b,0x68,0xd7,0x5c,0xf9,0x7c,0xd0,0x84,0x53,0x53,0xd0, + 0x4d,0x53,0x36,0xf1,0x36,0xed,0xd3,0x64,0x4f,0xee,0x59,0xbf,0x21,0x89,0xd3,0xca, + 0x43,0x1b,0x7c,0x4d,0xde,0x6e,0xc5,0xd0,0xb3,0xe1,0xbc,0xdb,0x4c,0xa8,0xf9,0xf6, + 0x44,0x0b,0x8a,0x09,0x73,0xd7,0x2b,0xfd,0x6e,0x73,0x81,0x9c,0x33,0x71,0x7b,0xe6, + 0x4d,0xb1,0xe1,0xdc,0xba,0x88,0x7f,0x73,0x90,0x5c,0x9a,0x48,0xf8,0xd4,0x8b,0xf9, + 0x7e,0x4f,0x04,0x5e,0xd9,0x73,0xdd,0xa7,0xb6,0x3f,0x5b,0xf2,0x4a,0xe6,0xed,0x6e, + 0x5a,0x8a,0x5f,0x22,0x1b,0xcc,0xcc,0x1e,0xee,0x99,0xc7,0xc6,0x85,0x63,0xa5,0x7a, + 0x78,0x38,0xc6,0xd0,0x96,0x45,0x66,0xf0,0x6d,0xcf,0xa2,0x1e,0x9f,0x86,0xaf,0xda, + 0x37,0x8c,0xdd,0xed,0xb8,0x32,0xf8,0x54,0x1e,0x5e,0xbf,0xa5,0x48,0x25,0xf7,0x1c, + 0xdd,0x05,0x8a,0x63,0xaa,0x3b,0x0d,0xf2,0xe4,0xe3,0xf6,0x80,0xce,0x43,0x5e,0xaa, + 0xaa,0x45,0x61,0xf2,0x23,0x7c,0xc8,0x91,0x4f,0xca,0x5c,0x37,0xf7,0x1c,0x64,0x20, + 0xf7,0xc4,0x19,0x1b,0x8b,0x41,0x3d,0x13,0xf9,0x8c,0xbf,0xf9,0x12,0x52,0x2c,0x5e, + 0xe3,0xe1,0x25,0x8a,0xc5,0x45,0x5a,0x9f,0x4c,0xeb,0x32,0x8d,0xc1,0x2b,0x58,0x96, + 0xb8,0x33,0x5f,0xb9,0x66,0x76,0x9d,0x63,0x97,0x1b,0xf1,0x22,0x4f,0xd9,0xe0,0x9c, + 0xc6,0x15,0x90,0x9b,0x6b,0x3a,0x91,0xd9,0x0e,0xe8,0x60,0xe0,0x43,0x8e,0x9b,0x21, + 0x7e,0x5f,0x79,0xd1,0x33,0x0a,0x65,0x78,0x65,0xf2,0x06,0xae,0x22,0xab,0x69,0xd1, + 0x27,0xc1,0xa4,0x96,0x6a,0x3e,0x23,0xce,0xc9,0xec,0x5c,0x11,0xe3,0x63,0xb2,0xd2, + 0x5b,0x7e,0xd2,0xcc,0xfc,0x7b,0xc8,0x69,0x12,0x25,0x0f,0xb5,0x45,0x6e,0xe9,0x15, + 0xeb,0x88,0xca,0x34,0x2b,0x9c,0x9d,0x93,0x4b,0x8e,0x01,0xfa,0xb9,0xb5,0xf6,0x99, + 0xd3,0x55,0xfe,0x28,0xba,0x15,0xbb,0xcf,0x11,0x0f,0xc4,0x8b,0x41,0xed,0x63,0xc8, + 0xdd,0xf3,0x12,0xab,0x16,0x06,0x62,0xf7,0xc6,0x3e,0x1a,0x21,0xe9,0x62,0xe1,0x33, + 0x4b,0xbd,0xc9,0xcf,0x5e,0x7b,0x03,0xb5,0xf2,0xe7,0xc6,0xfe,0x2a,0x9a,0x25,0x6e, + 0xb7,0x23,0xc1,0xba,0x3a,0xa6,0x9b,0x75,0x5d,0x3d,0x38,0xc9,0xb9,0x6f,0x43,0x5b, + 0x11,0x35,0xfb,0x87,0xef,0x5b,0xbe,0xbf,0xa8,0xff,0xa7,0x3e,0xa4,0xf1,0xb8,0xb4, + 0x76,0x42,0xe3,0x9e,0x3c,0x97,0xe7,0x84,0x53,0x6f,0x62,0xea,0x94,0xa3,0x62,0x23, + 0x39,0xd7,0xd9,0xf8,0xc4,0xa5,0xc4,0x72,0x13,0x84,0xfc,0x26,0x74,0xe5,0xe2,0x87, + 0xb7,0xcd,0x81,0xc4,0x96,0xcf,0x26,0x3b,0xb8,0xf0,0x1c,0xca,0xbf,0x28,0xa7,0xa6, + 0x3c,0xd9,0x37,0xe9,0xa2,0x97,0x89,0x5b,0xc9,0x3a,0xf8,0xba,0xfe,0x4a,0x41,0xe3, + 0x73,0x47,0xc1,0x13,0xd8,0x3c,0x51,0x79,0x1a,0xea,0x94,0xc0,0xb1,0x95,0x57,0x4e, + 0x3d,0x9d,0x25,0x6d,0x97,0x85,0x52,0xb5,0xcf,0x46,0x3e,0xf8,0x52,0x2b,0xc5,0xd1, + 0xb4,0xb9,0x5b,0xc1,0xac,0xc7,0x2f,0x29,0xe3,0x44,0x86,0xa3,0x29,0xbe,0x11,0xec, + 0x93,0xee,0x6c,0x27,0x1b,0x88,0xed,0xc1,0x7b,0xf5,0xea,0x67,0xae,0x8d,0x4f,0x17, + 0xf7,0xd6,0x16,0x26,0x97,0x3e,0xb3,0xf9,0x08,0xd8,0x46,0xaa,0xaa,0x27,0x4a,0x56, + 0xb6,0x05,0x4d,0xbb,0x13,0xb9,0xb1,0x26,0xd2,0xfc,0x07,0xbc,0x75,0xea,0x67,0x9a, + 0x17,0x63,0xc4,0x02,0x62,0x17,0xc6,0x3e,0xd5,0x69,0xc9,0xc6,0xd3,0xda,0x0e,0xdd, + 0x4d,0x59,0x39,0xf5,0xa7,0xa4,0xcd,0xe5,0x4f,0xa0,0x5a,0x80,0xa3,0x56,0xc3,0x55, + 0x41,0x17,0x4a,0x3e,0xf8,0xb4,0xc9,0xc6,0x77,0x40,0x0f,0x5b,0xd5,0xf6,0x6e,0xd6, + 0x66,0xb1,0xe0,0xa6,0x5d,0x8d,0xdf,0xa1,0x88,0x4c,0x31,0xe1,0x59,0x65,0xf2,0x08, + 0x21,0x5f,0x12,0xcf,0xd9,0x3a,0xf5,0xb3,0xd8,0xc1,0xd7,0x57,0xff,0x34,0xbc,0xe9, + 0xd4,0xc8,0xbe,0xbb,0x09,0xdf,0x49,0x7c,0x9d,0xcf,0x46,0x66,0x7f,0x19,0xff,0x74, + 0xfc,0xe3,0xee,0x6f,0xc9,0x53,0x29,0x6f,0x5f,0xfd,0xaf,0xf2,0xaf,0xcb,0x7f,0x32, + 0x9f,0x47,0xf4,0x87,0xf3,0x67,0xc1,0xa5,0xb9,0x93,0x5e,0x6f,0x57,0xfa,0x56,0xbf, + 0x45,0x3f,0x9f,0xbf,0x5d,0xfd,0xbc,0xa5,0xda,0x5f,0x42,0x7e,0x71,0xbf,0x03,0x07, + 0x6a,0x5d,0x2e,0x61,0xec,0xe3,0xe4,0xb9,0x9b,0x83,0x7e,0x1f,0xf6,0xe1,0x84,0x56, + 0xed,0xd2,0x8f,0xe7,0xf6,0xe6,0x4e,0x77,0x34,0x65,0xe7,0x23,0x15,0x7f,0x87,0xab, + 0xd4,0x2e,0xb9,0xe0,0x74,0xee,0xe7,0xa2,0xcf,0xca,0xf5,0x0f,0xee,0x2f,0xb9,0x53, + 0xe8,0x5e,0x72,0x7e,0x22,0xd3,0x83,0xd5,0x5f,0x3f,0x4f,0xe5,0xef,0x98,0xf9,0x73, + 0xd3,0x97,0xd8,0x37,0x55,0x3f,0xba,0xb0,0xe9,0x6d,0xe2,0x76,0xe1,0x8f,0xb8,0x4d, + 0xe4,0x76,0x17,0x92,0x16,0xd4,0x17,0xd8,0x6e,0xaa,0xac,0xd1,0xfc,0x35,0x3b,0x1a, + 0x8f,0x3f,0xcc,0xf3,0x69,0xe2,0x64,0xfb,0x93,0x15,0x79,0x3d,0xaa,0x4b,0xc9,0x83, + 0xea,0x57,0xbb,0x48,0x34,0xe6,0xc0,0x7d,0x57,0xea,0x6b,0x82,0xcc,0xec,0xe0,0xda, + 0xe8,0x77,0x2c,0xb4,0xc3,0xfa,0x35,0xdd,0x2f,0x9e,0x1a,0x7f,0xf4,0x5b,0x32,0xe0, + 0x51,0xff,0xd4,0x53,0xca,0x94,0xf8,0x94,0x77,0x3a,0x1d,0x45,0x09,0xfb,0x50,0x64, + 0x29,0x7a,0x3a,0xc8,0x88,0xf7,0x29,0xf8,0x5e,0x59,0x73,0xf0,0xba,0x33,0xbe,0x1c, + 0x04,0x8d,0xf9,0x2c,0x34,0x0d,0x64,0x49,0x28,0xd3,0x13,0x03,0x5b,0xc4,0x46,0x2e, + 0x0d,0xde,0xa8,0x84,0x74,0x8f,0xa5,0x02,0x68,0xc1,0x67,0x09,0x03,0x94,0x7e,0x94, + 0xcd,0x52,0xbe,0x12,0x6a,0x82,0xfd,0x74,0xc1,0x37,0xfd,0xd5,0x03,0xf0,0xf4,0x7f, + 0x90,0xc7,0xdd,0x3b,0x24,0xd9,0xa9,0xec,0xce,0x19,0x48,0x71,0x26,0x87,0x55,0xf0, + 0x9d,0xd4,0xa8,0xd1,0x58,0x8d,0x38,0xcb,0x3b,0x60,0x46,0xef,0x16,0x51,0x91,0xe4, + 0xb5,0xe7,0xd9,0xa4,0xb4,0x62,0x79,0x14,0x73,0xea,0x99,0x72,0x56,0xbe,0x08,0x8f, + 0xc4,0x13,0x5f,0x99,0xb7,0x10,0x1e,0x24,0x90,0x78,0xc1,0x53,0x14,0xc9,0xf9,0x93, + 0xaa,0x71,0x9e,0xb6,0x30,0xf5,0x32,0xcc,0xb4,0x0f,0xaf,0xb7,0xe6,0x2d,0xa8,0x56, + 0x0b,0xa6,0x75,0xd0,0xfa,0x6c,0x7b,0xca,0xe7,0x22,0x59,0x95,0x57,0x3a,0xdf,0x12, + 0xe6,0xb1,0xf6,0xb1,0x73,0xb1,0x25,0x3b,0x23,0x05,0x7b,0xf2,0xe7,0xed,0x38,0xd1, + 0x5f,0x52,0x7b,0x12,0x16,0xd7,0xab,0xc1,0xb4,0x4b,0x9d,0x48,0x50,0x9d,0x7b,0xd1, + 0x64,0xab,0x27,0x9c,0x8b,0x21,0xc5,0x5b,0xb2,0x52,0xdf,0x97,0xd2,0xbc,0x85,0xba, + 0x74,0x6b,0xf0,0xf4,0x68,0xe7,0x40,0xfb,0xfa,0xd9,0xcd,0x0e,0xd3,0x37,0x76,0x89, + 0xbe,0x74,0x8a,0xbc,0x97,0x67,0xcd,0x7d,0x27,0x38,0xa4,0x38,0x07,0xe2,0x6a,0x0f, + 0x1f,0x38,0xb0,0xac,0x2e,0xe1,0x37,0x3f,0xac,0x39,0x70,0x85,0x2f,0xaf,0xf6,0x8a, + 0x5c,0x22,0x50,0x62,0xb7,0x0e,0x41,0x97,0xf8,0xc3,0x5f,0x26,0xfe,0x83,0xb0,0x56, + 0x5d,0x2b,0x08,0x5b,0x86,0xe2,0xf9,0x15,0xd5,0x17,0xbd,0x65,0x5e,0x63,0xb0,0xeb, + 0x0c,0xee,0xe8,0x2e,0x8d,0x29,0x09,0xfd,0x52,0x77,0x4e,0xd3,0x61,0xb4,0xe9,0xd2, + 0x83,0x58,0x77,0x1c,0x6d,0xf0,0x73,0x5f,0x5d,0x6e,0xe0,0xce,0x8b,0xdf,0x22,0xba, + 0x45,0x62,0xba,0x03,0xd0,0x2a,0xcc,0x96,0x50,0xc2,0xb6,0x16,0xb5,0xe5,0xe8,0x00, + 0x56,0xcb,0x87,0x69,0xc6,0x58,0xb6,0xd6,0x36,0xd3,0x76,0xac,0xb3,0xe4,0x0f,0x26, + 0x77,0x50,0x19,0xfe,0x10,0x7f,0xe6,0x09,0x02,0x9a,0xcf,0x5b,0xa4,0xef,0x2e,0xc8, + 0x96,0x18,0x8e,0xb4,0x17,0x1d,0xe4,0x10,0x1c,0x9d,0x62,0x01,0x6c,0x47,0x39,0x69, + 0xcc,0xc5,0x8f,0x1b,0x23,0xe0,0xf8,0x13,0xc7,0xee,0x6a,0x51,0xa4,0xe9,0xa4,0x9d, + 0x86,0x2b,0x41,0x39,0x65,0xc9,0x91,0xf1,0x4e,0x56,0xb5,0x92,0xc2,0xe4,0xdf,0x1d, + 0xb8,0xf0,0x4c,0x90,0x39,0x32,0xfb,0xc1,0xe3,0x3a,0xd9,0xa6,0x39,0x18,0x2d,0xc6, + 0xc4,0x93,0x2d,0x39,0x65,0xae,0x7c,0xed,0x3b,0x5a,0x88,0x63,0xcc,0x29,0x56,0xb1, + 0x98,0x0e,0xbd,0xb8,0xb0,0xdd,0x51,0x68,0x12,0x25,0x71,0x82,0x90,0x9e,0xe6,0x58, + 0x83,0xbe,0x96,0x11,0xb9,0x56,0xc3,0x45,0x34,0xa6,0x08,0x2c,0xa1,0x7d,0xb1,0x8e, + 0x3c,0xf0,0x56,0xf2,0x50,0x8e,0x40,0xc9,0xac,0x7e,0x80,0xc9,0x85,0x01,0x4a,0x0b, + 0x9f,0x6d,0x6b,0xa9,0x6c,0x6a,0x4d,0x6c,0x8c,0x46,0x57,0x0e,0xb6,0x92,0xa9,0x78, + 0x50,0xc7,0xee,0x8b,0x1d,0x74,0xe1,0x00,0x8d,0x71,0xd7,0x58,0x21,0xe3,0xb3,0x1f, + 0xd6,0xfe,0x37,0xd9,0xc8,0x14,0xa6,0xad,0x4b,0x31,0xfd,0x22,0xa7,0x83,0x4c,0xdc, + 0xe2,0x72,0xac,0x36,0xf2,0xf1,0x96,0xa3,0x03,0xfe,0xfd,0x05,0xf2,0x1a,0x4f,0xc9, + 0xf9,0xfa,0xca,0x4c,0xdb,0x12,0xd2,0xb9,0x95,0xb4,0xac,0xb5,0x84,0x25,0xdd,0x84, + 0xdc,0x1b,0xfa,0x80,0x17,0x49,0x9c,0x3c,0x59,0xe2,0x51,0x67,0x26,0x90,0xf1,0xb4, + 0xaf,0x8f,0x53,0x4e,0x24,0xe6,0x14,0x7f,0x47,0xaa,0x3b,0x5b,0x8c,0x7c,0xbb,0x58, + 0x16,0x61,0xb5,0xad,0xb5,0x9f,0xe8,0x2c,0xad,0x2d,0x86,0x4d,0xbf,0xdf,0x69,0xb6, + 0x5a,0xd3,0xa4,0x92,0x83,0x72,0xe0,0xbf,0xa7,0x44,0xb6,0x03,0x33,0x4d,0x94,0x5f, + 0x63,0x6b,0x6f,0xc5,0xc1,0x67,0x0e,0x02,0x92,0x7c,0xa4,0xf8,0x24,0xfc,0x72,0xe5, + 0xd3,0x2b,0x3d,0xc3,0x69,0x32,0xe6,0x5c,0x31,0x17,0xc4,0x76,0x67,0xcb,0x2f,0xa2, + 0xbd,0x16,0x83,0x8d,0xab,0x5d,0x37,0x47,0xf5,0x69,0x50,0xe5,0xef,0xad,0xfe,0x91, + 0xf9,0xad,0xcc,0x5f,0x66,0xf6,0x4b,0xe3,0xcf,0x90,0xcf,0x90,0x4c,0x69,0x58,0x04, + 0x20,0x63,0xb1,0x48,0x11,0xb9,0x92,0xd7,0x78,0x36,0xc5,0xa2,0xbd,0x8f,0x5d,0x6e, + 0xba,0xed,0x47,0xdc,0x39,0x4f,0xff,0xb8,0xa8,0xc6,0xa3,0x0a,0xe6,0x92,0xa3,0xfb, + 0x9a,0x71,0xd8,0x78,0x69,0xa3,0xf4,0xc1,0x0f,0x5f,0xd7,0xc4,0xac,0x4e,0xbe,0xe2, + 0x9a,0x7d,0x5b,0xbc,0x56,0xad,0x96,0x43,0x4e,0xc9,0x46,0x6c,0xda,0xd9,0x83,0x17, + 0x5f,0x14,0xb9,0x02,0xcb,0x33,0x75,0x26,0x0f,0x53,0x9a,0x9b,0x6b,0xb9,0x44,0x75, + 0xa4,0x7c,0xdb,0x45,0xd3,0xfa,0x0e,0x6b,0x76,0x02,0x51,0xe3,0x34,0x6e,0xd6,0x86, + 0xf2,0x29,0x39,0x77,0x62,0x5c,0xe3,0xe7,0x07,0xd9,0xdc,0xb8,0xce,0xc7,0xd5,0xda, + 0xc1,0xd5,0x77,0x1d,0x96,0x72,0xf2,0x42,0x09,0x5b,0x3c,0x2b,0x19,0xb5,0x3a,0xb2, + 0xf3,0xf2,0xa8,0x1a,0x12,0x78,0xab,0xb4,0xe6,0xa8,0x1c,0x72,0x82,0x39,0x59,0x8a, + 0xad,0xa3,0x8a,0x7c,0xc6,0xe5,0x86,0x52,0xdd,0x05,0x04,0xd5,0x82,0x95,0x13,0xdb, + 0xbc,0x63,0xab,0x3d,0x2a,0x07,0xb2,0x54,0x57,0x36,0x97,0xc2,0x4a,0xac,0x60,0x2c, + 0x36,0x17,0x92,0xb7,0x20,0xd0,0x45,0x75,0x26,0x93,0x13,0xea,0xb5,0x19,0x29,0x13, + 0x6d,0xdc,0xe8,0x01,0xfc,0xd6,0x3a,0x78,0xa6,0xb4,0xa8,0x90,0xd6,0xf0,0x51,0x2a, + 0xc2,0x87,0x29,0x37,0x38,0x7b,0x66,0xcb,0xca,0x2e,0x52,0xfa,0x25,0xcd,0x55,0x76, + 0x1e,0xa6,0x70,0x05,0x98,0x69,0x74,0x4c,0xdd,0x54,0x12,0x4b,0x67,0xb1,0xf8,0x57, + 0xd3,0xfe,0x60,0x1e,0x12,0xf1,0x35,0x14,0xe9,0x39,0xcd,0x42,0x52,0x72,0x2c,0x9a, + 0x3d,0x73,0xf0,0x8c,0xc3,0x7c,0x9a,0x4b,0x6b,0xab,0x63,0x1f,0x46,0x53,0xb9,0x39, + 0x40,0x0d,0x30,0x3a,0xff,0x63,0x93,0x47,0xb3,0x15,0x39,0xaf,0x83,0xd5,0x54,0x55, + 0x5f,0xe1,0x0c,0x21,0x0d,0x5f,0xba,0x42,0xea,0x5b,0x14,0xbf,0x31,0xba,0xb0,0xd3, + 0x23,0xfe,0xb5,0x04,0xf4,0xb3,0x9c,0xf3,0x1e,0x6a,0xcf,0xca,0x97,0x31,0x4e,0x7e, + 0x79,0x40,0x9a,0xd6,0x8f,0xce,0xd4,0xc3,0x5b,0x1d,0xbb,0x99,0x84,0xad,0x1a,0x00, + 0x22,0xf7,0x96,0x3f,0xd8,0x9e,0xbc,0xd6,0xaa,0x55,0xae,0xca,0x79,0xd9,0xc5,0x78, + 0xab,0x1e,0x14,0xb3,0xcd,0x80,0x49,0x02,0x4d,0x7d,0x64,0xcc,0x7e,0xde,0x77,0x84, + 0x7c,0x5e,0x4a,0xe3,0xd4,0x9a,0xac,0xcd,0x69,0x16,0xad,0xe7,0xa2,0x5b,0x0b,0xe3, + 0xe1,0x54,0x1b,0xa1,0xba,0xe6,0xcd,0xb5,0xf1,0x3d,0xc5,0x20,0xc5,0xa5,0x87,0x5d, + 0x8d,0x26,0x2a,0xf1,0x49,0x53,0x93,0x15,0xd8,0x1c,0xb2,0x3c,0x4b,0x2e,0xc0,0xf5, + 0x84,0x71,0x67,0x15,0x3d,0x20,0x26,0x79,0x0a,0x28,0x67,0x6b,0xb6,0xbc,0xd3,0x9f, + 0xb0,0x7e,0x18,0xed,0x10,0xa8,0x17,0x3f,0xfa,0x65,0xd9,0xca,0x6c,0xa0,0x95,0x4f, + 0xea,0x2a,0xcd,0xdd,0x08,0xba,0x14,0x4d,0x1c,0x3a,0x35,0x1d,0xa2,0xca,0xab,0x47, + 0x6c,0xab,0xe4,0x4a,0x5f,0x13,0x29,0x6a,0xac,0x8e,0x7d,0x04,0x15,0x63,0x69,0xf2, + 0x93,0x11,0xa4,0xd4,0xe4,0x25,0x8a,0xe7,0xe9,0x3c,0x76,0x4d,0x7c,0x34,0x27,0x11, + 0xf6,0xbf,0x03,0x8a,0x06,0x7e,0xc5,0x96,0x29,0x72,0xb1,0xd7,0x7e,0xfa,0xe0,0xc1, + 0x43,0x1b,0xce,0xfc,0xba,0x3a,0xd0,0xbc,0xc3,0x26,0xc0,0x47,0x72,0x4b,0x65,0xe0, + 0xea,0xe4,0x2b,0x02,0xfd,0xf5,0xeb,0xba,0xff,0xb8,0x13,0x4d,0x12,0x27,0x8b,0x38, + 0x90,0xde,0x44,0x65,0x11,0x66,0x33,0x58,0x48,0x6f,0xea,0x09,0x3c,0x57,0x79,0xb6, + 0xf2,0xb2,0x88,0x58,0xbc,0xc4,0xac,0x0d,0x74,0xd2,0xa7,0xa3,0x6d,0x3a,0x13,0xc5, + 0x0a,0xb4,0x9a,0x49,0x9b,0xb4,0x9c,0xdb,0xcd,0x42,0x27,0x10,0x75,0xe5,0x8c,0x27, + 0x92,0xbd,0xd0,0x6c,0xdc,0x8c,0x5e,0x90,0x92,0x2e,0x59,0xe7,0x63,0xcf,0x4d,0xdd, + 0xae,0xf3,0x10,0x1b,0x79,0x6d,0xc5,0x61,0xa4,0xe2,0x8e,0x95,0x7a,0xae,0xd2,0xa3, + 0x92,0x9c,0x84,0xb6,0xbd,0x97,0x0b,0x70,0x32,0x9e,0x8d,0x27,0xf8,0xca,0xb2,0x12, + 0x2f,0x0b,0x04,0xa4,0xb9,0x58,0x58,0x65,0xef,0x64,0x09,0x4c,0x39,0x85,0xc2,0x39, + 0xd9,0x30,0xe7,0x46,0x6d,0x9b,0xe9,0x83,0x6d,0x67,0xa5,0xe7,0x9e,0xd2,0x9c,0xa3, + 0x85,0xa6,0x69,0xed,0x6c,0x19,0x7f,0xb4,0x5d,0x18,0x4c,0xe4,0x5a,0xd7,0x65,0xfa, + 0x8a,0xc3,0x65,0x5d,0xbc,0x49,0xf4,0xd4,0xb6,0xcb,0xef,0x3a,0x59,0x6e,0x92,0x3b, + 0x53,0xe9,0xf2,0x68,0x9c,0x97,0x73,0x51,0xb4,0x2b,0xd7,0xee,0x41,0x65,0xea,0xe0, + 0x33,0x16,0x5a,0x66,0x89,0x17,0xb2,0xf7,0x29,0x0a,0x1b,0x5c,0x61,0xbc,0xd2,0x9c, + 0x03,0xf2,0xac,0xe1,0xd3,0x3c,0xe1,0x79,0x4d,0x28,0x59,0xf0,0xe6,0x4e,0xf5,0x66, + 0x8d,0x1b,0x95,0xdc,0x5a,0xa6,0xbe,0x2b,0xb7,0x21,0x32,0xb3,0xbb,0x79,0x0b,0xea, + 0x7b,0x40,0xdb,0x65,0x0a,0xed,0x9d,0x9c,0x87,0xd4,0xf9,0x75,0xfd,0x35,0x5f,0xb2, + 0xab,0x07,0x49,0xa6,0x6e,0x6a,0x77,0xd3,0xde,0xb5,0x00,0x95,0xc5,0xf6,0x9c,0x9d, + 0xf7,0x74,0x31,0xd2,0xc7,0xad,0x5c,0x6e,0xec,0x61,0x5d,0x7f,0x32,0xfa,0x98,0xd0, + 0x74,0xd3,0x7e,0xf9,0x34,0x75,0x8d,0x70,0x09,0x18,0xfd,0xf4,0x59,0xf3,0x05,0x93, + 0x56,0xb3,0x74,0x95,0xdf,0x63,0x25,0x7e,0x32,0x86,0x3a,0xe9,0xf4,0x8a,0xd1,0xc5, + 0xca,0x16,0x0f,0x95,0x32,0x5d,0x99,0x54,0xdd,0xd6,0x83,0x76,0xbd,0xa5,0xcf,0xa7, + 0xca,0x75,0x60,0x1b,0x54,0xab,0xe7,0xf9,0xdf,0x97,0xe4,0xf5,0x1e,0x9b,0x34,0x51, + 0x8b,0xed,0xac,0x8d,0xcd,0xef,0xc7,0x22,0x93,0x44,0xb4,0xf2,0x22,0xe4,0x34,0xa6, + 0xa6,0xd6,0xf1,0x24,0xbc,0x87,0xd2,0x75,0x56,0x4e,0x57,0x30,0xf8,0x09,0x6e,0xff, + 0xc1,0x97,0x5d,0x9b,0x33,0x9d,0x36,0x93,0xea,0x24,0xb9,0x89,0xe3,0x9d,0xee,0x6f, + 0xc2,0x48,0xda,0xc7,0xbb,0x23,0xe1,0x2d,0x0d,0xb4,0x8d,0xef,0x08,0xba,0xa7,0x22, + 0xd5,0x3e,0xea,0xe4,0x39,0x4a,0x23,0xfc,0xdb,0x90,0xd9,0xf3,0xe0,0xb6,0x54,0xf8, + 0xf4,0x04,0x47,0x40,0x3d,0xb6,0xed,0x62,0x6a,0x4f,0xd4,0x99,0x4c,0xe0,0xbb,0xb9, + 0x9e,0xa6,0xd2,0xfb,0xd0,0xb5,0x09,0x03,0x33,0x5f,0x6d,0xeb,0xf5,0x84,0x8f,0x59, + 0x7b,0x76,0xdd,0x58,0xcf,0xbd,0x70,0x8a,0xd8,0x1b,0xf9,0x13,0x44,0x0f,0x17,0x95, + 0x4b,0x95,0xcb,0x87,0x14,0xf2,0xc2,0x90,0xe0,0xe0,0x68,0x02,0x1d,0x31,0xe5,0x48, + 0xa6,0xc9,0x0e,0x5e,0xbd,0x6f,0x42,0x27,0xce,0x5b,0xb9,0xb0,0xb1,0x34,0x20,0x2d, + 0x97,0xe1,0xdb,0x30,0xfb,0xf1,0x4c,0x22,0x67,0xea,0x74,0x8f,0x79,0x7c,0x24,0x62, + 0xd3,0x94,0x11,0xe7,0xda,0x78,0x29,0xbb,0x69,0xee,0x3d,0x2e,0xea,0xc9,0x05,0x17, + 0xe7,0x74,0x12,0xa0,0x33,0x15,0x47,0x4e,0x37,0xc1,0x8e,0x89,0xce,0x7d,0xfd,0x71, + 0xfb,0x08,0x92,0x66,0x7c,0x94,0xcf,0xe4,0x18,0x1d,0x0b,0x19,0xf9,0x58,0x29,0xd2, + 0x47,0x65,0x3d,0x71,0x6c,0x53,0x6f,0x16,0x7e,0x3c,0x4d,0x92,0x66,0x98,0x1d,0xf3, + 0x77,0xdd,0x25,0x8b,0xe3,0x7c,0x2f,0x72,0xc2,0x86,0xd3,0x4a,0x97,0x3e,0xbc,0xc4, + 0x0c,0x9f,0x57,0x58,0xfd,0x88,0xc6,0x89,0xb0,0x8d,0x7c,0x32,0xb7,0xba,0x36,0xb1, + 0x32,0x79,0xa5,0x44,0x22,0xe7,0xb8,0xe8,0xc1,0x93,0x70,0x25,0x45,0xb6,0x7b,0xca, + 0xbf,0x2c,0x8e,0x60,0xd8,0x25,0x5d,0x9e,0xe4,0x4a,0x94,0x8e,0xda,0x34,0xd6,0x2c, + 0x9b,0x26,0x35,0xcb,0x47,0x8b,0x99,0x52,0xe5,0x72,0x5b,0xa3,0x61,0x54,0xe7,0xb7, + 0x9b,0xdf,0x75,0xf9,0x33,0xc2,0x34,0x31,0xe7,0x8a,0xca,0x72,0x72,0x68,0xdb,0xf9, + 0xba,0x0d,0xe6,0xd8,0x19,0xd7,0xf2,0x25,0x05,0xc6,0x14,0xdf,0x30,0x4e,0x4a,0xf3, + 0x67,0x95,0x9f,0xde,0xb3,0x00,0xe2,0xe6,0x2b,0x1f,0x39,0xf8,0x27,0xcb,0x5f,0x17, + 0x8b,0x87,0xc6,0xa2,0x89,0xbc,0xa3,0x04,0x1a,0x9b,0xe7,0xe4,0x56,0x7e,0xbf,0xf9, + 0xfb,0xc5,0xd9,0x53,0x68,0x81,0xcf,0xa1,0x5c,0x1e,0x81,0x1a,0x95,0x93,0x0b,0x13, + 0xaf,0x17,0xf6,0x93,0x47,0x89,0xcb,0x3d,0x4b,0x74,0xb3,0x77,0x33,0x7f,0xb2,0xf6, + 0xc8,0x44,0x11,0xe4,0x66,0xf8,0x23,0xa5,0x0d,0x48,0x5e,0x92,0x56,0x92,0x8a,0x1b, + 0x7a,0x3c,0x43,0xdd,0x24,0xed,0x26,0xc8,0x22,0x4d,0xa4,0x95,0xb1,0x7c,0xc5,0xea, + 0x0c,0x77,0xa7,0x18,0x96,0x21,0xe0,0x9f,0x38,0x7f,0xcc,0x39,0x3d,0x23,0xd9,0x96, + 0xfe,0x81,0xf1,0xcc,0xa8,0xed,0xd6,0xe3,0x70,0x6e,0x91,0xd4,0x1e,0x9b,0x27,0xf1, + 0x2f,0x55,0x88,0xcf,0x1f,0x6c,0xcb,0x66,0xfa,0x9e,0x5f,0xf4,0x90,0x68,0xdd,0x35, + 0x40,0x2f,0x5f,0xf2,0x2c,0xc8,0xa7,0x52,0x4e,0x43,0xef,0x1b,0xa8,0xd3,0xda,0xe1, + 0xec,0x7d,0xc2,0xb7,0x14,0x1c,0xaf,0x13,0xf9,0x84,0x11,0x8f,0x66,0x6e,0x9d,0xed, + 0x29,0x8a,0xcf,0x41,0x9c,0xd4,0xe6,0x23,0x58,0x57,0xe1,0x72,0xf1,0xd6,0x51,0x3f, + 0xd8,0xac,0x42,0xfb,0xac,0xbd,0xb5,0x0f,0x56,0xf5,0x56,0xeb,0x94,0x20,0xb4,0x94, + 0xea,0xe8,0x52,0xca,0x4f,0xf8,0x9d,0xdd,0xf5,0x4a,0x70,0x93,0xdf,0x59,0x7f,0x02, + 0x4e,0x4f,0x20,0x57,0x41,0x52,0x52,0x41,0x4e,0x54,0xd9,0x75,0x43,0x1f,0xc3,0x87, + 0x50,0xd1,0x50,0x50,0xd5,0x54,0x11,0x08,0x15,0x52,0x11,0x08,0x94,0xd4,0xd3,0x91, + 0x54,0x50,0x13,0x48,0xd2,0x34,0x16,0x2d,0x88,0x40,0x8c,0xa4,0x8a,0x8a,0x40,0x9e, + 0x8c,0x40,0x86,0x90,0x82,0xa4,0x8e,0x8a,0x58,0xc9,0xc8,0x26,0x55,0x4c,0x52,0x76, + 0x66,0xb1,0x93,0xd9,0x72,0x8f,0xec,0xd3,0x66,0x7b,0xae,0x43,0x5b,0x11,0x16,0x55, + 0x91,0x13,0x15,0x08,0xf4,0x48,0x2d,0x92,0xa8,0xa8,0x87,0xcb,0x26,0x94,0x05,0x12, + 0x04,0x05,0x3d,0x56,0xb6,0x20,0x21,0xa6,0x22,0x10,0xa6,0xa0,0xeb,0x81,0xab,0x15, + 0x61,0x0d,0x15,0x41,0x51,0x81,0x5c,0x21,0x15,0x39,0x29,0x3c,0xd3,0x9b,0xed,0x2a, + 0x79,0x88,0x6c,0x53,0x54,0xc1,0x94,0x6a,0x4b,0x72,0x02,0xb9,0x92,0x9e,0xaf,0x85, + 0xd3,0x71,0x5d,0xda,0x49,0x6d,0x21,0x95,0x74,0x84,0x44,0x05,0x82,0xf4,0xc4,0x44, + 0x54,0x24,0x5d,0x55,0x8b,0xd7,0x29,0xb4,0x57,0xb3,0x0d,0x04,0x2a,0x48,0x8a,0x2a, + 0xa9,0x68,0x4a,0x71,0x18,0x6d,0x56,0x49,0xc4,0x5e,0x64,0x13,0x09,0x9a,0x1e,0x3a, + 0x9b,0x08,0xc8,0x55,0x12,0x15,0xd2,0x53,0xf5,0x18,0xdb,0x8f,0xcf,0x4e,0x63,0xb6, + 0x20,0xa7,0x2c,0x90,0xa5,0x24,0x27,0x22,0x16,0x90,0xe2,0x89,0xb9,0x4f,0xc2,0xad, + 0x08,0x0b,0x4a,0xaa,0x68,0x7a,0xb6,0x6c,0x8a,0x33,0x70,0x4b,0x6a,0x1e,0x59,0x5b, + 0xf1,0x2c,0xdd,0x92,0x9c,0x86,0x98,0xaa,0x88,0xcb,0x6d,0x39,0x79,0xcb,0xb9,0xb3, + 0x51,0x4f,0x95,0x7d,0x4c,0xed,0xb3,0x6d,0xa3,0x7a,0xae,0x36,0x3b,0x86,0xdd,0xf1, + 0xe6,0x3e,0x10,0xf7,0x01,0xba,0x29,0x34,0x15,0x49,0xcf,0x99,0xcd,0x89,0x2a,0x48, + 0x28,0x89,0x29,0x79,0x7c,0xee,0x04,0xb8,0x30,0x4a,0xa2,0x72,0x9e,0xac,0x7b,0x95, + 0x2d,0x82,0x6d,0xe1,0x36,0x54,0xc5,0x14,0x3c,0x0a,0xb7,0x2a,0x29,0xa8,0xa7,0xa9, + 0x62,0xd2,0x30,0x53,0xa6,0x7d,0x36,0xef,0x23,0x67,0x93,0x4a,0x9a,0x5a,0x02,0x09, + 0x9a,0x52,0xbc,0x4a,0x5b,0x54,0x55,0x70,0xbe,0xde,0x67,0xd4,0x3e,0xc0,0xb7,0xa6, + 0x20,0xa7,0xe1,0x12,0xb3,0xff,0x91,0x9d,0x60,0x6e,0x20,0x59,0x4f,0xd5,0x14,0x1f, + 0x9f,0x99,0x1b,0xf3,0x10,0xde,0x90,0x8a,0x69,0xe2,0x5e,0x17,0x78,0xa2,0xb8,0x15, + 0x81,0x10,0x15,0x19,0x15,0x0d,0x51,0x25,0x59,0x0f,0x9b,0x7d,0x48,0xf0,0xa3,0x7e, + 0x9b,0xaa,0x6a,0x36,0x8d,0xdb,0xd0,0xd3,0x14,0x75,0x01,0xdd,0x98,0x98,0x40,0x9c, + 0x8a,0x86,0x87,0xf7,0x16,0x24,0x95,0x05,0x32,0x55,0x24,0x65,0x95,0x34,0x4c,0x71, + 0x37,0x05,0xa9,0x22,0xa8,0xa0,0xe4,0x21,0xb8,0x13,0xda,0x42,0x4a,0x9a,0x8c,0x70, + 0x4f,0xce,0x66,0x43,0x1f,0xe0,0xe8,0x78,0xdb,0x07,0xcf,0x56,0x64,0x4d,0x9f,0xb6, + 0x2a,0x27,0x66,0xe2,0xbd,0x49,0x15,0x45,0x55,0x8f,0xf8,0xfd,0x57,0xed,0xa4,0x6b, + 0x27,0x42,0x5c,0xd0,0xf1,0x80,0xd9,0x89,0xf0,0xbe,0xdd,0x36,0x85,0xab,0xe4,0x31, + 0xc3,0x13,0xd1,0xfd,0xdb,0x6d,0x52,0xac,0x85,0x8c,0x9f,0x73,0xbc,0x1a,0xdc,0xb2, + 0xe7,0xd8,0xf6,0x3c,0xb3,0x80,0x6c,0x1b,0x5c,0xd6,0xfe,0x7d,0x04,0xee,0xd3,0x87, + 0xcf,0xb9,0xa5,0x6b,0xdc,0x27,0xe5,0xae,0xa3,0xb6,0x20,0xe1,0xf9,0xc1,0x0f,0xdd, + 0x7d,0x86,0x71,0xc9,0x05,0x8c,0x9f,0x69,0x3c,0x39,0xe1,0x09,0xf8,0x46,0x14,0xd4, + 0x14,0x74,0x54,0x34,0xc5,0xa2,0x98,0x6b,0xf7,0xf2,0xc7,0xdf,0xcd,0x72,0x3e,0x01, + 0x50,0x45,0x43,0xc9,0x34,0x98,0x1f,0xb8,0xfc,0x60,0xdc,0x47,0xf5,0xc6,0x6c,0x84, + 0xf8,0xd1,0xb2,0x45,0x55,0xd3,0xf7,0x7d,0x30,0xf3,0x77,0x96,0x03,0x09,0x1e,0xf3, + 0x3b,0x75,0xe3,0x89,0xe6,0x7e,0x0d,0x78,0x1a,0xb2,0xd3,0xd7,0xcd,0x19,0x59,0xef, + 0xc3,0x95,0xff,0x21,0x1b,0x08,0xaa,0xc2,0xe5,0xdf,0xee,0x4e,0xed,0x37,0xa6,0xe7, + 0x59,0xc5,0x0f,0x70,0x8e,0x28,0x88,0x2a,0x98,0x94,0xf3,0x15,0xa1,0x13,0x2a,0x26, + 0xf9,0x9c,0x54,0x91,0xf3,0xdc,0xe3,0x6b,0xdb,0x16,0x34,0x34,0x54,0x25,0x3d,0xd9, + 0x76,0xaa,0xd0,0x53,0x82,0x7e,0x62,0x73,0x53,0xd5,0x73,0x6d,0x4b,0x72,0x2e,0x5a, + 0x9c,0x22,0x7d,0xe5,0xab,0xd0,0x96,0x24,0x3d,0xff,0x77,0x6b,0xb8,0xd7,0x3e,0x0e, + 0xc4,0x28,0x28,0x89,0xa9,0x7a,0xc6,0xef,0xdf,0x80,0x1f,0x03,0xdd,0xf3,0x04,0xe5, + 0x89,0x46,0x5f,0x1f,0xf8,0xfc,0xc7,0x23,0x0d,0x6e,0x7a,0xc8,0xce,0x14,0x8a,0x03, + 0x49,0x32,0x9e,0x20,0xdd,0x10,0xf2,0xcd,0xe3,0x69,0x4c,0xcf,0x03,0x39,0xe4,0xf1, + 0xc9,0x09,0x15,0xcf,0xa9,0x2e,0x88,0xc8,0x7a,0xa6,0x6d,0xc4,0x07,0xa7,0x53,0x1c, + 0xea,0xdb,0x54,0xf2,0x45,0xe7,0x27,0x5b,0x5f,0xad,0xfa,0x63,0xcd,0x97,0x88,0xbd, + 0x16,0x81,0x53,0xa2,0x2f,0x6c,0xfd,0x4b,0x2d,0x29,0x6c,0xa1,0x58,0xff,0xfa,0x59, + 0x2b,0x53,0x4a,0x2d,0xb8,0x48,0xd9,0x56,0x5d,0xa2,0x2e,0x9e,0xf9,0xa8,0xec,0x27, + 0x0d,0x25,0x07,0xe2,0x3c,0x5d,0xf2,0x3b,0xa3,0xcd,0xd3,0x24,0xfe,0x7e,0x68,0xe4, + 0x83,0x40,0x63,0x7b,0x83,0x1f,0xe5,0xf9,0x71,0xc9,0xf5,0x45,0xba,0xa3,0xc4,0x33, + 0x9f,0x1e,0x18,0x7d,0x00,0xd3,0x84,0x13,0x1f,0xe5,0xc1,0xfb,0x64,0xd3,0x4b,0x84, + 0x6d,0x9f,0x66,0x63,0x66,0xd3,0x74,0xfc,0x8e,0xd8,0xd4,0xf8,0xa6,0xbb,0x75,0xd1, + 0x94,0xd0,0x69,0xed,0x6d,0xdb,0x72,0xa3,0x67,0x16,0x56,0x7d,0xc4,0x89,0x8e,0x5d, + 0x37,0x77,0x7a,0x3e,0x21,0x89,0xed,0xda,0x2a,0xe7,0x7d,0x10,0x26,0x7d,0x17,0xd3, + 0xcf,0x48,0x52,0xc4,0x52,0x13,0xfd,0xf8,0x41,0x8d,0x69,0xac,0x2d,0xf3,0x5c,0x84, + 0x62,0x88,0xdc,0xbc,0xd7,0x53,0xb5,0xaf,0xb1,0xd7,0x5c,0x98,0x39,0x5d,0xee,0x89, + 0x78,0x9f,0x3c,0xfc,0x12,0x21,0xd6,0x7d,0x9d,0x6a,0xa9,0x35,0x23,0x26,0x3e,0xfe, + 0xf1,0x8c,0xa9,0x11,0x9c,0x82,0x42,0xb3,0x51,0x1a,0x22,0x75,0x36,0x69,0xf6,0x93, + 0x9c,0xb6,0x09,0xf1,0x30,0xc4,0x4d,0x6c,0xce,0x6b,0xd0,0xfa,0xc8,0x92,0x25,0xbf, + 0x42,0xf9,0xb3,0x71,0x24,0xd4,0x75,0x69,0xcc,0xd1,0xa1,0x5b,0x3c,0x31,0xd1,0xbc, + 0xa7,0x89,0x0e,0x50,0x7c,0xf8,0xf7,0x36,0xf0,0x82,0x7b,0x2f,0x0e,0x78,0x71,0x66, + 0x8b,0xac,0x5a,0x42,0x7c,0x4a,0x28,0xdf,0x55,0x95,0x08,0x91,0x04,0x54,0x3f,0x23, + 0x0a,0x2f,0xed,0xef,0xeb,0xa1,0x8f,0x28,0xdd,0xdd,0xe2,0x8f,0xac,0xc2,0x9d,0x9e, + 0xc5,0x46,0xd1,0x1f,0x7b,0x4d,0xf9,0x40,0x59,0xc8,0xca,0xc2,0x0d,0x27,0x4b,0x62, + 0xef,0x51,0x86,0x93,0xdf,0xc3,0xb7,0x8a,0xfa,0x1e,0x04,0xe0,0xa5,0x90,0x8e,0xef, + 0x20,0xf5,0x4b,0xad,0x4f,0xbe,0xf5,0x1a,0xa6,0xf9,0x1a,0x51,0xbf,0x5c,0xde,0x0b, + 0x99,0x6c,0xf1,0xdd,0x6e,0x32,0x14,0x7b,0x80,0x6f,0xfa,0x72,0x4d,0x3f,0x1a,0x33, + 0x75,0x62,0xab,0x5f,0xdf,0x45,0xe1,0xf8,0x1b,0x07,0x19,0x4e,0x38,0xc5,0xfd,0x75, + 0xa0,0x67,0xaa,0xf5,0x63,0xea,0x0b,0x54,0xd7,0x98,0xa6,0xb5,0x00,0xb1,0xc3,0x9f, + 0xe4,0xf3,0x31,0xa6,0x13,0x94,0x0f,0xd5,0xfb,0xa2,0x84,0x5a,0xfd,0xb7,0xf9,0x0d, + 0xf5,0x5f,0xb8,0xdf,0x4d,0xe1,0xd3,0x8a,0xa1,0xd3,0xc5,0xd6,0x7a,0xc2,0x04,0xe7, + 0x35,0xc1,0xfa,0x90,0xee,0xe7,0xa5,0xc7,0x6a,0xd9,0xdc,0xc9,0x91,0x23,0xcc,0x9d, + 0x20,0xf5,0x88,0x73,0x9f,0xa4,0xfa,0xa1,0x36,0x8f,0x60,0x5c,0x55,0xe9,0x91,0x97, + 0x4f,0x0b,0x19,0xe1,0xaa,0xc3,0x3d,0xa7,0x81,0xff,0x93,0xde,0xc9,0x6c,0xfe,0xb8, + 0xf7,0x3f,0xbe,0x97,0xf5,0x6d,0x7a,0xb4,0xfc,0x84,0x02,0xcf,0x97,0xe5,0xab,0xf8, + 0x31,0x3b,0x5e,0xfd,0xfd,0x8a,0x1f,0x12,0x93,0xdc,0x56,0xf8,0x16,0x80,0x66,0x75, + 0xbe,0x2e,0x7a,0xdb,0xb6,0xfb,0x8c,0xff,0xdd,0xfc,0x9f,0xb9,0x77,0x8b,0xc6,0x5a, + 0xec,0x1f,0x49,0x97,0x39,0xcd,0xf4,0x5f,0xa4,0xee,0x1e,0x74,0xd2,0xfd,0x3f,0x1a, + 0xc0,0x85,0xf5,0x1f,0x81,0xef,0x09,0xfc,0x56,0x20,0xf3,0x02,0x87,0xbf,0x49,0xe2, + 0x5b,0xa2,0x83,0xf3,0x9e,0x97,0xc4,0xda,0x76,0xb2,0x2f,0x2d,0xb0,0x5d,0x1d,0xc9, + 0xb1,0x56,0x4e,0x1a,0x1a,0xb9,0x37,0xf7,0xa9,0xff,0xdb,0x30,0x72,0xa8,0xe9,0x93, + 0xbd,0x4b,0xa7,0x69,0xe5,0xad,0xce,0x17,0xd9,0xbf,0x55,0xd6,0x99,0x1f,0xdb,0xf6, + 0x1e,0x65,0x9d,0xc3,0xac,0x1d,0xdc,0x7e,0x12,0x55,0xd8,0xd2,0x8b,0xe9,0x3d,0xc6, + 0xed,0x4a,0xc1,0x0e,0xbc,0xbf,0x18,0xf9,0xc4,0xf3,0xa6,0x3b,0x38,0x57,0x59,0x07, + 0xc0,0x57,0x7e,0xfd,0x9b,0x23,0xf7,0x79,0xaf,0x0f,0x6a,0x9c,0xfa,0xfc,0x98,0xe7, + 0xb3,0x1d,0x29,0xa0,0x5b,0xf6,0xa9,0xb4,0x6f,0x69,0xfd,0x94,0xed,0xdb,0xe1,0xcf, + 0x7d,0xde,0xeb,0x83,0x1a,0xb7,0x4b,0xfa,0x50,0xd5,0x0d,0x69,0x14,0x24,0x34,0xf5, + 0xc4,0x3c,0x2e,0x39,0xa6,0x6c,0xbe,0xb3,0xed,0x96,0xe9,0xff,0x60,0x7f,0x20,0x74, + 0xf9,0x83,0xee,0x03,0xaf,0x8d,0xc3,0xdd,0xa9,0xdd,0x01,0x6b,0xd8,0xff,0xcf,0xfd, + 0x5b,0xc8,0x56,0xf7,0x96,0xda,0x77,0x65,0xec,0xf3,0x88,0x2e,0xa9,0xfe,0xa7,0xf7, + 0xeb,0xff,0x7f,0xda,0xcc,0x3c,0x7f,0x63,0x27,0x7d,0xac,0x5a,0xf9,0x83,0xee,0x03, + 0xaf,0x8d,0xc3,0xd8,0x69,0x99,0xfe,0x15,0xf6,0x4f,0x7d,0x31,0xb4,0x3c,0x78,0xa2, + 0xa3,0xd7,0xde,0x59,0xed,0x28,0xe0,0xb5,0x71,0xb8,0x3b,0x2d,0xb7,0x1e,0x78,0x6d, + 0x1c,0xc6,0x4e,0x31,0xf8,0x8f,0x1b,0xc7,0xee,0x81,0xb6,0x16,0xfd,0xd3,0xff,0xaa, + 0x9f,0x7a,0x32,0xaf,0xb8,0xf4,0x0d,0xa7,0xd5,0x8e,0x5a,0xa7,0xe4,0x21,0xfd,0x4f, + 0xfc,0x9c,0x14,0xe4,0xd4,0x77,0xae,0x71,0xf2,0x40,0xd5,0x2b,0x53,0xbe,0x09,0x0e, + 0xf0,0xda,0x38,0xdc,0x9d,0x96,0x5b,0x0f,0xbc,0x36,0x0e,0x63,0xa7,0xa7,0xe5,0xb4, + 0xbf,0x75,0xa5,0xfc,0x27,0xbc,0xd3,0x3e,0x0e,0xae,0xb2,0x96,0xf1,0xa1,0xff,0x8f, + 0xc1,0x99,0x50,0x7f,0x65,0xee,0x73,0x67,0x9e,0x7f,0xd7,0x5c,0x4b,0x2b,0x0d,0xf6, + 0x0b,0x81,0x36,0x3f,0xa2,0xc0,0x32,0x2c,0xe7,0xdd,0xf0,0x58,0xa2,0x27,0xfc,0xaf, + 0xf0,0x2d,0xe1,0x1b,0xcb,0xd3,0x4f,0x94,0x80,0xb7,0xfc,0x91,0xf5,0xa1,0x22,0x28, + 0x31,0x1f,0xae,0x87,0xec,0x1f,0x81,0xef,0xc8,0x86,0xcb,0xf3,0x20,0xa7,0x30,0x4f, + 0xf5,0xf3,0x31,0x0d,0x53,0xb5,0xca,0xdd,0xf0,0xa9,0xf4,0x55,0xa6,0x45,0xa6,0xd6, + 0xc0,0xf5,0x0b,0x22,0xaa,0x43,0x51,0x6c,0xdb,0xa5,0x99,0x29,0xb8,0x93,0x36,0x61, + 0xde,0xb0,0x94,0x24,0xd8,0xb4,0x33,0xec,0x38,0x8b,0x67,0xbf,0x3d,0xda,0x7c,0xca, + 0xf6,0x16,0xf8,0x9f,0x5a,0xfb,0xe6,0x2b,0xc9,0x7a,0xcb,0x1f,0xb1,0x98,0xfb,0x40, + 0xfa,0x89,0x0e,0xc0,0x5a,0x60,0xe8,0x79,0xac,0xe3,0x17,0xd4,0x62,0xc0,0x5a,0x03, + 0x2f,0x8e,0x3e,0xf1,0xee,0xef,0xdb,0x7f,0xc8,0xfe,0xf9,0xff,0x81,0x1d,0xb9,0xcf, + 0x7b,0x7d,0x50,0xe3,0x74,0x2a,0xa4,0xb2,0x74,0x61,0x71,0x67,0x7b,0x4f,0x50,0xd8, + 0x71,0x6f,0x0e,0x29,0xdd,0xe8,0xc3,0xb4,0x19,0x9a,0x1f,0xbd,0xf0,0x4d,0xc5,0xe7, + 0xb1,0xa6,0x3c,0xae,0xbd,0x39,0x10,0xa4,0xb0,0xf1,0x09,0x0d,0xd7,0xed,0x8f,0xd7, + 0xfa,0xc4,0x54,0x6d,0x1c,0xef,0x1f,0x55,0xfe,0x54,0xf6,0xde,0xdc,0x7c,0x67,0x0a, + 0x38,0x2c,0xfb,0xa9,0xf1,0x96,0x13,0x90,0x5c,0x78,0xf9,0x53,0xd9,0x27,0x90,0xfa, + 0x24,0x05,0x29,0xf0,0x6a,0x63,0x19,0xeb,0xc9,0xff,0x1f,0xcb,0xfb,0xd3,0xff,0xf8, + 0xf9,0x4f,0xdd,0xf9,0xcd,0xab,0xd5,0x89,0x4e,0x4c,0x7c,0xa6,0x1b,0x96,0x1b,0x9d, + 0xfc,0xe8,0x38,0xa5,0x4c,0x78,0x62,0x06,0xa8,0xb5,0x58,0x58,0x68,0xd8,0xd9,0x3e, + 0x8f,0xd4,0x9b,0xe4,0xd4,0xe3,0xd4,0x2f,0x9c,0x61,0xae,0xcf,0xab,0x00,0x4a,0x82, + 0xd7,0x32,0x60,0x12,0xeb,0xdf,0xf6,0xfd,0x45,0x93,0x36,0x7a,0xf5,0x3c,0xf5,0xab, + 0xfc,0xbb,0x50,0x4a,0xbe,0x73,0x23,0xd9,0x71,0x0a,0x7f,0xec,0x76,0x33,0x44,0xd4, + 0xb9,0x45,0xef,0x6b,0xb0,0x9f,0x79,0xfb,0x12,0x35,0x0f,0x7a,0xf8,0xba,0xb3,0x2f, + 0x33,0x24,0xf6,0x9f,0xe2,0x63,0xfe,0xaf,0x6a,0xf8,0xd8,0xf2,0xa1,0x8b,0x01}; +#define GETBITS(x,buf,idx,bits) \ +x=0; \ +for (j=0;j<bits;j++) \ +{ \ + x|=((((buf[idx/8])>>(idx%8))&1)<<j); \ + (idx)++; \ +} + + unsigned char gplbuf[17999]; + int i,j; + int idx=0; + int widx=0; + char ptrnotcodebook; + unsigned char len; + unsigned char character; + unsigned short ptr; + unsigned char ptrlen; + int newlinecnt=0; + ptrlen=0; + while (idx<packbits) + { + GETBITS(ptrnotcodebook,packedgpl,idx,1); // get 1 bit from packedgpl + if (!ptrnotcodebook) // =0: a character + { + GETBITS(character,packedgpl,idx,7); // the character is packed in the next 7 bits + gplbuf[widx++]=character; + } else { // =1: a pointer to a portion which was unpacked before + GETBITS(len,packedgpl,idx,4); // 4 bits of the len + GETBITS(ptr,packedgpl,idx,ptrlen); // get ptrlen bits + + for (j=0;j<len;j++) gplbuf[widx++]=gplbuf[ptr+j]; + } + while (widx>(1<<ptrlen)) ptrlen++; + if (ptrlen>14) ptrlen=14; + } +#undef GETBITS + for (i=0;i<widx;i++) + { + printf("%c",gplbuf[i]); + if (gplbuf[i]==10) newlinecnt++; + if (newlinecnt>=24) + { + warte(); + newlinecnt=0; + } + } + printf("\n"); +} +void ende() +{ +fprintf(stderr,"This program is free software; you can redistribute it and/or modify\n"); +fprintf(stderr,"it under the terms of the GNU General Public License as published by\n"); +fprintf(stderr,"the Free Software Foundation; either version 2 of the License, or\n"); +fprintf(stderr,"(at your option) any later version.\n"); +fprintf(stderr,"\n"); +fprintf(stderr,"This program is distributed in the hope that it will be useful,\n"); +fprintf(stderr,"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); +fprintf(stderr,"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); +fprintf(stderr,"GNU General Public License for more details.\n"); +fprintf(stderr,"\n"); +fprintf(stderr,"You should have received a copy of the GNU General Public License\n"); +fprintf(stderr,"along with this program; if not, write to the Free Software\n"); +fprintf(stderr,"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"); +fprintf(stderr,"\n"); +} @@ -0,0 +1,6 @@ +#ifndef GPL_H +#define GPL_H +void warte(); +void print_gpl(); +#endif + @@ -0,0 +1,335 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/hexcalc.c b/hexcalc.c new file mode 100644 index 0000000..18bd2fd --- /dev/null +++ b/hexcalc.c @@ -0,0 +1,185 @@ +#include <stdio.h> +#include <stdlib.h> +#include "hexcalc.h" +#include <ncurses.h> +#include "output.h" +#include "input.h" +typedef enum {FIELDHEX,FIELDDEC,FIELDBIN} eFields; + +void hexcalc(tOutput* output,thHexCalc* hHexCalc) +{ + tInt16 offsx; + tInt16 offsy; + tInt64 akkumulator=0; + int i; + int j; + int cursorline=-1; + tInt16 ch=0; + tUInt64 x; + tUInt64 newval=0; + tUInt8 dig=0; + tUInt64 g=10; + tBool neg=0; + eFields field=FIELDHEX; + +// hHexCalc->valuenum=0; + if (hHexCalc->operators[0]==0) hHexCalc->operators[0]='='; + + offsx=COLS/2-40; + offsy=LINES/2-10; + drawframe(output,offsy,offsx,21,79,"HexCalc"); + + setcolor(output,COLOR_BRACKETS); + for (i=0;i<17;i++) + { + mvwprintw(output->win,offsy+2+i,offsx+2,"[ ] [ ] [ ]"); + } + setcolor(output,COLOR_MENUNORMAL); + mvwprintw(output->win,offsy+20,offsx+ 2,":Add"); + mvwprintw(output->win,offsy+20,offsx+ 8,":Sub"); + mvwprintw(output->win,offsy+20,offsx+14,":Mul"); + mvwprintw(output->win,offsy+20,offsx+20,":Div"); + mvwprintw(output->win,offsy+20,offsx+26,":Mod"); + mvwprintw(output->win,offsy+20,offsx+32,">:Right"); + mvwprintw(output->win,offsy+20,offsx+41,"<:Left"); + mvwprintw(output->win,offsy+20,offsx+49,":And"); + mvwprintw(output->win,offsy+20,offsx+55,":Or"); + mvwprintw(output->win,offsy+20,offsx+61,":Xor"); + + mvwprintw(output->win,offsy+20,offsx+74,"Exit"); + + setcolor(output,COLOR_MENUHOTKEY); + mvwprintw(output->win,offsy+20,offsx+ 1,"+"); + mvwprintw(output->win,offsy+20,offsx+ 7,"-"); + mvwprintw(output->win,offsy+20,offsx+13,"*"); + mvwprintw(output->win,offsy+20,offsx+19,"/"); + mvwprintw(output->win,offsy+20,offsx+25,"%%"); + mvwprintw(output->win,offsy+20,offsx+31,">"); + mvwprintw(output->win,offsy+20,offsx+40,"<"); + mvwprintw(output->win,offsy+20,offsx+48,"&"); + mvwprintw(output->win,offsy+20,offsx+54,"|"); + mvwprintw(output->win,offsy+20,offsx+60,"^"); + mvwprintw(output->win,offsy+20,offsx+75,"x"); + + + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+1,offsx+ 3,"Hex"); + mvwprintw(output->win,offsy+1,offsx+22,"Dec"); + mvwprintw(output->win,offsy+1,offsx+45,"Bin"); + while (ch!='x' && ch!='X') + { + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+19,offsx+ 1,"%c",hHexCalc->operators[0]); + for (i=0;i<17 && i<hHexCalc->valuenum;i++) + { + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+18-i,offsx+ 1,"%c",hHexCalc->operators[i+1]); + x=hHexCalc->values[i]; + setcolor(output,(field==FIELDHEX && cursorline==i)?COLOR_INPUT:COLOR_TEXT); + mvwprintw(output->win,offsy+18-i,offsx+ 3,"%16llx",x); + setcolor(output,(field==FIELDDEC && cursorline==i)?COLOR_INPUT:COLOR_TEXT); + mvwprintw(output->win,offsy+18-i,offsx+22,"%20lli",(tInt64)x); + setcolor(output,(field==FIELDBIN && cursorline==i)?COLOR_INPUT:COLOR_TEXT); + for (j=0;j<32;j++) + { + if (x || !j) mvwprintw(output->win,offsy+18-i,offsx+76-j,"%i",(x&1)); + else mvwprintw(output->win,offsy+18-i,offsx+76-j," "); + x>>=1; + } + } + if (cursorline==-1) x=newval; else x=hHexCalc->values[cursorline]; + setcolor(output,(field==FIELDHEX && cursorline==-1)?COLOR_INPUT:COLOR_TEXT); + mvwprintw(output->win,offsy+19,offsx+ 3,"%16llx",x); + setcolor(output,(field==FIELDDEC && cursorline==-1)?COLOR_INPUT:COLOR_TEXT); + if (x || !neg) mvwprintw(output->win,offsy+19,offsx+22,"%20lli",(tInt64)x); + else if (neg) mvwprintw(output->win,offsy+19,offsx+22," -"); + setcolor(output,(field==FIELDBIN && cursorline==-1)?COLOR_INPUT:COLOR_TEXT); + for (j=0;j<32;j++) + { + if (x || !j) mvwprintw(output->win,offsy+19,offsx+76-j,"%i",(x&1)); + else mvwprintw(output->win,offsy+19,offsx+76-j," "); + x>>=1; + } + ch=getkey((tKeyTab*)output->pKeyTab,1); + switch (ch) + { + case KEYUP: if (cursorline<(hHexCalc->valuenum-1)) cursorline++;break; + case KEYDOWN: if (cursorline>-1) cursorline--;break; + case KEYLEFT: if (field!=FIELDHEX) field--;break; + case KEYRIGHT: if (field!=FIELDBIN) field++;break; + case KEYTAB: field=(field!=FIELDBIN)?field+1:FIELDHEX;break; + case '+': + case '-': + case '*': + case '/': + case '%': + case '&': + case '|': + case '^': + case '>': + case '<': + case KEYENTER: + + if (cursorline!=-1) newval=hHexCalc->values[cursorline]; + cursorline=-1; + if (hHexCalc->valuenum) + { + switch(hHexCalc->operators[0]) + { + case '=': akkumulator=newval;break; + case '+': akkumulator=akkumulator+newval;break; + case '-': akkumulator=akkumulator-newval;break; + case '*': akkumulator=akkumulator*newval;break; + case '/': akkumulator=akkumulator/newval;break; + case '%': akkumulator=akkumulator%newval;break; + case '&': akkumulator=akkumulator&newval;break; + case '|': akkumulator=akkumulator|newval;break; + case '^': akkumulator=akkumulator^newval;break; + case '>': akkumulator=akkumulator>>newval;break; + case '<': akkumulator=akkumulator<<newval;break; + } + } + else + { + akkumulator=newval; + } + if (ch==KEYENTER) ch='='; + if (cursorline!=-1) newval=hHexCalc->values[cursorline]; + for (i=31;i>0;i--) + { + hHexCalc->values[i]=hHexCalc->values[i-1]; + hHexCalc->operators[i]=hHexCalc->operators[i-1]; + } + hHexCalc->operators[0]=ch; + hHexCalc->values[0]=newval; + if (ch=='=') newval=akkumulator; else newval=0; + hHexCalc->valuenum++; + break; + + + default: + if (cursorline!=-1) cursorline=-1; + dig=17; + if (field==FIELDBIN) g=2; + else if (field==FIELDDEC) g=10; + else if (field==FIELDHEX) g=16; + + if (ch>='a' && ch<='f') ch-=32; + if (field==FIELDBIN && ch>='0' && ch<='1') dig=(ch-'0'); + else if (field==FIELDDEC && ch>='0' && ch<='9') dig=(ch-'0'); + else if (field==FIELDHEX && ch>='0' && ch<='9') dig=(ch-'0'); + else if (field==FIELDHEX && ch>='A' && ch<='F') dig=(ch-'A'+10); + else if (field==FIELDDEC && ch=='-') neg=1; + if (ch==KEYBACKSPACE) + { + if (newval) newval=newval/g; + else neg=0; + } else if (dig!=17) { + newval=newval*g; + newval=newval+(neg?-dig:dig); + } + break; + } + } +} + diff --git a/hexcalc.h b/hexcalc.h new file mode 100644 index 0000000..4a935cd --- /dev/null +++ b/hexcalc.h @@ -0,0 +1,17 @@ +#ifndef HEXCALC_H +#define HEXCALC_H +#include <stdio.h> +#include <stdlib.h> +#include <ncurses.h> +#include "machine_type.h" +#include "output.h" + +typedef struct _thHexCalc +{ + tUInt64 values[32]; + char operators[32]; + tInt8 valuenum; +} thHexCalc; +void hexcalc(tOutput* output,thHexCalc* hHexCalc); + +#endif @@ -0,0 +1,481 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "machine_type.h" +#include "input.h" +#include "output.h" +#include "unistd.h" + +void initkeytab(tOutput* output) +{ + // those values are for mac os x + const tKeyTab KeyTab[NUM_SPECIALKEYS]={ + // key return value (retval),allowed_in_inputfield,seqlen,seq[8],config[16] + {KEYESC, 1,1,{0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYESC:","The standard cancel key"}, + {KEYF1, 0,2,{0xc2,0xa1,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF1:","This key opens the goto dialog"}, + {KEYF2, 0,3,{0xe2,0x84,0xa2,0x00,0x00,0x00,0x00,0x00},"KEYF2:","This key opens the search dialog"}, + {KEYF3, 0,2,{0xc2,0xa3,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF3:","This key jumps to the next search item"}, + {KEYF4, 0,2,{0xc2,0xa2,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF4:","This key jumps to the previous search item"}, + {KEYF5, 0,3,{0xe2,0x88,0x9e,0x00,0x00,0x00,0x00,0x00},"KEYF5:","This key openes the hexcalc tool"}, + {KEYF6, 0,2,{0xc2,0xa7,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF6:","This key is not used yet"}, + {KEYF7, 0,2,{0xc2,0xb6,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF7:","This key is not used yet"}, + {KEYF8, 0,3,{0xe2,0x80,0xa2,0x00,0x00,0x00,0x00,0x00},"KEYF8:","This key is not used yet"}, + {KEYF9, 0,2,{0xc2,0xaa,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF9:","This key is for undo"}, + {KEYF10, 0,2,{0xc2,0xba,0x00,0x00,0x00,0x00,0x00,0x00},"KEYF10:","This key is for saving and quitting"}, + {KEYBACKSPACE, 1,1,{0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYBACKSPACE:","Erases a character in input fields"}, + {KEYDEL, 1,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYDEL:","Erases a character in input fields"}, + {KEYENTER, 1,1,{0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYENTER:","The standard Enter key"}, + {KEYTAB, 1,1,{0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYTAB:","This key jumps trough windows and menu items"}, + {KEYUP, 0,3,{0x1b,0x5b,0x41,0x00,0x00,0x00,0x00,0x00},"KEYUP:","Standard scroll key"}, + {KEYDOWN, 0,3,{0x1b,0x5b,0x42,0x00,0x00,0x00,0x00,0x00},"KEYDOWN:","Standard scroll key"}, + {KEYRIGHT, 0,3,{0x1b,0x5b,0x43,0x00,0x00,0x00,0x00,0x00},"KEYRIGHT:","Standard scroll key"}, + {KEYLEFT, 0,3,{0x1b,0x5b,0x44,0x00,0x00,0x00,0x00,0x00},"KEYLEFT:","Standard scroll key"}, + {KEYPGUP, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYPGUP:","Scrolls up a full page"}, + {KEYPGDOWN, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYPGDOWN:","Scrolls down a full page"}, + {KEYHOME, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYHOME:","Jumps to beginning"}, + {KEYEND, 0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},"KEYEND:","Jumps to the end"} +}; + if (output->pKeyTab) free(output->pKeyTab); + output->pKeyTab=malloc(sizeof(tKeyTab)*NUM_SPECIALKEYS); + memcpy(output->pKeyTab,KeyTab,sizeof(tKeyTab)*NUM_SPECIALKEYS); +} +tInt16 getkey(tKeyTab* pKeyTab,tBool inputfield) // =1 this is an inputfield. which means that certain allowed_in_inputfields may not be used +{ + tInt16 ch; + unsigned char seq[8]; + tUInt8 seqlen=0; + tBool done; + tInt16 donecnt; + tInt16 lastch=ERR; + tBool partial; + tBool exact; + int i,j; + + donecnt=1000; + done=0; + partial=0; + exact=0; + while (!done) + { + while (!done) + { + ch=getch(); + + if ((lastch!=ERR && ch==ERR) || seqlen==8) done=1; + if (ch!=ERR) + { + if (seqlen<8) seq[seqlen++]=ch; + lastch=ch; + done=1; // a key was pressed + } else { + usleep(1); + donecnt=donecnt-partial; + done=!donecnt; + } + } + exact=0; + partial=0; + for (i=0;i<NUM_SPECIALKEYS;i++) // check if it was a special key + { + if (pKeyTab[i].seqlen==seqlen) + { + j=memcmp(pKeyTab[i].seq,seq,seqlen); + if (j==0) + { + lastch=pKeyTab[i].retval; // in an inputfield, certain special keys have to be disabled + exact=1; + } + } else if (pKeyTab[i].seqlen>seqlen) { + j=memcmp(pKeyTab[i].seq,seq,seqlen); + if (j==0) partial=1; + } + } + if (exact && (!partial || !donecnt)) done=1; + else if (partial && donecnt) done=0; + } + return lastch; +} + + +tInt16 decinput(tOutput* output,tInt16 y,tInt16 x,tUInt64* val,tInt16 len) +{ + tInt16 i; + tInt16 ch; + tInt16 done=0; + tUInt64 newval; + char tmpbuf[21]; + + newval=*val; + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,y,x,"["); + mvwprintw(output->win,y,x+len,"]"); + while (!done) + { + setcolor(output,COLOR_INPUT); + snprintf(tmpbuf,21,"%20lli",newval); + for (i=0;i<len && i<20;i++) mvwprintw(output->win,y,x+len-i,"%c",tmpbuf[20-i]); + wmove(output->win,y,x+len); + ch=getkey(output->pKeyTab,1); + if (ch==KEYENTER) done=1; + if (ch==KEYTAB) done=1; + if (ch==KEYESC) done=1; + if (ch>='0' && ch<='9') + { + newval=newval*10; + newval=newval+(ch-'0'); + } + if (ch==KEYBACKSPACE || ch==KEYDEL) + { + newval=newval/10; + } + } + if (ch!=KEYESC) { + *val=newval; + } + return ch; +} +tInt16 hexinput(tOutput* output,tInt16 y,tInt16 x,tUInt64* val,char* relative,tInt16 len) +{ + char e; + tInt16 i; + tInt16 ch; + tInt16 done=0; + tUInt64 newval; + tUInt64 t; + + newval=*val; + if (relative) e=*relative; else e='='; + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,y,x,"["); + mvwprintw(output->win,y,x+len+1,"]"); + while (!done) + { + setcolor(output,COLOR_BRACKETS); + for (i=0;i<len;i++) mvwprintw(output->win,y,x+i+1," "); + setcolor(output,COLOR_INPUT); + t=newval; + for (i=len-2;i>=0 && t;i--) + { + tUInt8 c=t&0xf; + t>>=4; + mvwprintw(output->win,y,x+i+2,"%1x",c); + } + mvwprintw(output->win,y,x+i+2,"%c",e); + refresh(); + ch=getkey(output->pKeyTab,1); + if (ch=='=' || ch=='-' || ch=='+') e=ch; + + if (ch>='a' && ch<='f') ch-=32; // make it uppercase + if (ch==KEYENTER) done=1; + if (ch==KEYTAB) done=1; + if (ch==KEYESC) done=1; + if (ch>='0' && ch<='9') + { + newval=newval*16; + newval=newval+(ch-'0'); + } + else if (ch>='A' && ch<='F') + { + newval=newval*16; + newval=newval+(ch-'A'+10); + } + if (ch==KEYBACKSPACE || ch==KEYDEL) + { + newval=newval/16; + } + } + if (ch!=KEYESC && relative==NULL) + { + if (e=='=') *val=newval; + if (e=='-') *val-=newval; + if (e=='+') *val+=newval; + } else if (ch!=KEYESC) { + *val=newval; + *relative=e; + } + return ch; +} +tInt16 hexinput2(tOutput* output,tInt16 y,tInt16 x,char* s,tInt16* usedlen,tInt16 len) +{ + char* buf; + tInt16 ch; + tBool done=0; + tInt16 newusedlen; + tBool nibble=0; + tUInt8 newchar=0; + int i; + + buf=malloc(len); + memcpy(buf,s,len); + newusedlen=*usedlen; + + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,y,x,"["); + mvwprintw(output->win,y,x+len*3,"]"); + while (!done) + { + setcolor(output,COLOR_INPUT); + for (i=0;i<len;i++) + { + if (i<newusedlen) mvwprintw(output->win,y,x+1+i*3,"%02x",((tUInt16)buf[i]&0xff)); + else if (i==newusedlen && nibble) mvwprintw(output->win,y,x+1+i*3,"%1x ",newchar&0xf); + else mvwprintw(output->win,y,x+1+i*3," "); + if (i!=(len-1)) mvwprintw(output->win,y,x+3+i*3," "); + } + wmove(output->win,y,x+1+newusedlen*3+nibble); + ch=getkey(output->pKeyTab,1); + if (ch>='a' && ch<='z') ch-=32; + if (newusedlen<len && ((ch>='0' && ch<='9') || (ch>='A' && ch<='F'))) + { + newchar<<=4; + newchar|=(ch>='A')?(ch-'A'+10):(ch-'0'); + if (nibble) buf[newusedlen++]=newchar; + nibble=!nibble; + } + if ((newusedlen>0 || nibble) && ch==KEYBACKSPACE) + { + if (!nibble && newusedlen) newchar=buf[--newusedlen]; + newchar>>=4; + nibble=!nibble; + } + if (ch==KEYENTER || ch==KEYTAB || ch==KEYUP || ch==KEYDOWN) done=1; + if (ch==KEYESC) done=1; + } + if (ch!=KEYESC) + { + memcpy(s,buf,len); + *usedlen=newusedlen; + } + setcolor(output,COLOR_TEXT); + newusedlen=*usedlen; + for (i=0;i<len;i++) + { + if (i<newusedlen) mvwprintw(output->win,y,x+1+i*3,"%02x",((tUInt16)buf[i]&0xff)); + else if (i==newusedlen && nibble) mvwprintw(output->win,y,x+1+i*3,"%1x ",newchar&0xf); + else mvwprintw(output->win,y,x+1+i*3," "); + if (i!=(len-1)) mvwprintw(output->win,y,x+3+i*3," "); + } + free(buf); + return ch; +} +tInt16 stringinput(tOutput* output,tInt16 y,tInt16 x,char* s,tInt16 len) +{ + tInt16 i; + tInt16 cursorpos; + tInt16 ch; + tInt16 done=0; + char* buf; + + buf=malloc(len); + memcpy(buf,s,len); + + + + cursorpos=strlen(s); + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,y,x,"["); + mvwprintw(output->win,y,x+len+1,"]"); + while (!done) + { + setcolor(output,COLOR_INPUT); + for (i=0;i<len;i++) + { + mvwprintw(output->win,y,x+i+1,"%c",(i<strlen(buf))?buf[i]:'_'); + } + + if (cursorpos<len) + { + setcolor(output,COLOR_CURSOR); + mvwprintw(output->win,y,x+cursorpos+1,"%c",(cursorpos<strlen(buf))?buf[cursorpos]:'_'); + } + move(y,x+cursorpos+1); + refresh(); + ch=getkey(output->pKeyTab,1); + if (ch==KEYENTER) + done=1; + if (ch==KEYTAB) done=1; + if (ch==KEYESC) done=1; + if (ch==KEYLEFT && cursorpos) cursorpos--; + if (ch==KEYRIGHT && cursorpos<strlen(buf)) cursorpos++; + if (ch>=' ' && ch<127 && cursorpos<len) + { + memmove(&buf[cursorpos+1],&buf[cursorpos],len-cursorpos); + buf[cursorpos++]=ch; + } else if (ch==KEYBACKSPACE && cursorpos>0) { + memmove(&buf[cursorpos-1],&buf[cursorpos],len-cursorpos); + cursorpos--; + } else if (ch==KEYDEL && cursorpos<(strlen(buf))) { + memmove(&buf[cursorpos],&buf[cursorpos+1],len-cursorpos); + } + } + if (ch!=KEYESC) memcpy(s,buf,len); + setcolor(output,COLOR_TEXT); + for (i=0;i<len;i++) + { + mvwprintw(output->win,y,x+i+1,"%c",(i<strlen(s))?s[i]:' '); + } + free(buf); + return ch; +} +int configkeytab(tKeyTab* pKeyTab,char* line) +{ + int i; + int j; + unsigned int x; + int retval=1; + + for (i=0;i<NUM_SPECIALKEYS;i++) + { + if (strncmp(pKeyTab[i].config,line,strlen(pKeyTab[i].config))==0) + { + retval=0; + x=1; + pKeyTab[i].seqlen=0; + for (j=strlen(pKeyTab[i].config);j<strlen(line);j++) + { + x<<=4; + if (line[j]>='0' && line[j]<='9') x|=(line[j]-'0'); + if (line[j]>='A' && line[j]<='F') x|=(line[j]-'A'+10); + if (x&0x100 && pKeyTab[i].seqlen<8) + { + pKeyTab[i].seq[pKeyTab[i].seqlen++]=(x&0xff); + x=1; + } + } + + } + } + return retval; +} +int writeconfigfile(tOutput* output,char* configfilename) +{ + tFptr f; + char tmpbuf[65536]; + char lineorig[512]; + char lineupcase[512]; + char c; + int lineorigidx; + int lineupcaseidx; + int i,j,size; + tBool found; + tKeyTab* pKeyTab=(tKeyTab*)output->pKeyTab; + + f=fopen(configfilename,"rb"); + if (!f) return RETNOK; + size=fread(tmpbuf,sizeof(char),65536,f); + fclose(f); + if (size>=65536) return RETNOK; + tmpbuf[size++]=0; + + lineorigidx=0; + lineupcaseidx=0; + f=fopen(configfilename,"w"); + for (i=0;i<size;i++) + { + c=tmpbuf[i]; + + lineorig[lineorigidx++]=c; + lineorig[lineorigidx]=0; + if (c>='a' && c<='z') c-=32; + if (c==9) c=32; + if (c!=32) + { + lineupcase[lineupcaseidx++]=c; + lineupcase[lineupcaseidx]=0; + } + + if (c<32) + { + found=0; + for (j=0;j<NUM_SPECIALKEYS;j++) + { + if (strncmp(pKeyTab[j].config,lineupcase,strlen(pKeyTab[j].config))==0) + { + found=1; + } + } + if (!found) + fprintf(f,"%s",lineorig); + lineorigidx=0; + lineupcaseidx=0; + } + } + for (i=0;i<NUM_SPECIALKEYS;i++) + { + fprintf(f,"%s",pKeyTab[i].config); + for (j=0;j<pKeyTab[i].seqlen;j++) + { + fprintf(f,"%02x ",((unsigned int)pKeyTab[i].seq[j])&0xff); + } + fprintf(f,"\n"); + } + fclose(f); + return RETOK; +} +void keyboardsetup(tOutput* output,char* configfilename) +{ + int i,j; + int ch=0; + int lastkey=0; + int keyesc=0; + unsigned char seq[8]; + unsigned int seqlen; + tBool done; + tKeyTab* pKeyTab=(tKeyTab*)output->pKeyTab; + + mvwprintw(output->win,0,0,"Please press the following keys"); + mvwprintw(output->win,1,0,"(Press ESC if your keyboard does not have them)"); + mvwprintw(output->win,3,0,"Config file:%s",configfilename); + + for (i=0;i<NUM_SPECIALKEYS;i++) + { + lastkey=-1; + done=0; + seqlen=0; + memset(seq,0,sizeof(seq)); + mvwprintw(output->win,21,0," "); + mvwprintw(output->win,21,0,"%s",pKeyTab[i].desc); + if (i<12) mvwprintw(output->win,5+i,0,"%s",pKeyTab[i].config); + else mvwprintw(output->win,i-7,40,"%s",pKeyTab[i].config); + memset(pKeyTab[i].seq,0,8); + while (!done) + { + ch=getch(); + if (ch==-1 && lastkey!=-1) done=1; + if (ch!=-1 && seqlen<8) seq[seqlen++]=ch; + lastkey=ch; + } + pKeyTab[i].seqlen=seqlen; + memcpy(pKeyTab[i].seq,seq,seqlen); + if (pKeyTab[i].retval==KEYESC) keyesc=i; + else + if (memcmp(pKeyTab[i].seq,pKeyTab[keyesc].seq,8)==0 && i!=keyesc) pKeyTab[i].seqlen=0; + for (j=0;j<pKeyTab[i].seqlen;j++) + { + if (i<12) mvwprintw(output->win,5+i,15+j*3,"%02x",seq[j]); + else mvwprintw(output->win,i-7,55+j*3,"%02x",seq[j]); + } + if (seqlen==1 && seq[0]>=32 && seq[0]<127) + { + mvwprintw(output->win,(i<12)?(5+i):(i-7),(i<12)?0:40,"%s(*)",pKeyTab[i].config); + mvwprintw(output->win,20,0,"WARNING: Keystrokes with (*) cannot be used in an input field\n"); + } + } + for (i=0;i<NUM_SPECIALKEYS;i++) + { + if (memcmp(pKeyTab[i].seq,pKeyTab[keyesc].seq,8)==0 && i!=keyesc) pKeyTab[i].seqlen=0; + } + mvwprintw(output->win,21,0,"Would you like me to write this into the config file? (Y/N)"); + done=0; + while (!done) + { + ch=getch(); + if (ch=='n' || ch=='N') done=1; + else if (ch=='y' || ch=='Y') + { + writeconfigfile(output,configfilename); + done=1; + } else usleep(1); + } +} @@ -0,0 +1,46 @@ +#ifndef INPUT_H +#define INPUT_H +#include <stdio.h> +#include <stdlib.h> +#include "machine_type.h" +#include "output.h" +#include <ncurses.h> +#include "datatypes.h" + +#define KEYF1 0x0100 +#define KEYF2 0x0101 +#define KEYF3 0x0102 +#define KEYF4 0x0103 +#define KEYF5 0x0104 +#define KEYF6 0x0105 +#define KEYF7 0x0106 +#define KEYF8 0x0107 +#define KEYF9 0x0108 +#define KEYF10 0x0109 +#define KEYESC 0x010a +#define KEYBACKSPACE 0x010b +#define KEYDEL 0x010c +#define KEYENTER 0x010d +#define KEYTAB 0x010e +#define KEYUP 0x010f +#define KEYDOWN 0x0110 +#define KEYLEFT 0x0111 +#define KEYRIGHT 0x0112 +#define KEYPGUP 0x0113 +#define KEYPGDOWN 0x0114 +#define KEYHOME 0x0115 +#define KEYEND 0x0116 + +#define NUM_SPECIALKEYS 0x17 + + +void initkeytab(tOutput* output); +tInt16 getkey(tKeyTab* pKeyTab,tBool inputfield); +tInt16 decinput(tOutput* output,tInt16 y,tInt16 x,tUInt64* val,tInt16 len); +tInt16 hexinput(tOutput* output,tInt16 y,tInt16 x,tUInt64* val,char* relative,tInt16 len); +tInt16 hexinput2(tOutput* output,tInt16 y,tInt16 x,char* s,tInt16* usedlen,tInt16 len); +tInt16 stringinput(tOutput* output,tInt16 y,tInt16 x,char* s,tInt16 len); +int configkeytab(tKeyTab* pKeyTab,char* line); +void keyboardsetup(tOutput* output,char* configfilename); + +#endif diff --git a/machine_type.c b/machine_type.c new file mode 100644 index 0000000..0aa1322 --- /dev/null +++ b/machine_type.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include "machine_type.h" + +tUInt64 getfilepos(tFptr f) +{ + tUInt64 x; + x=ftell(f); + return x; +} +tUInt64 getfilesize(tFptr f) +{ + tUInt64 x; + fseek(f,0,SEEK_END); + x=getfilepos(f); + + return x; + //return (tUInt64)ftell(f); +} +void setfilepos(tFptr f,tUInt64 pos) +{ + fseek(f,pos,SEEK_SET); +} + diff --git a/machine_type.h b/machine_type.h new file mode 100644 index 0000000..124650f --- /dev/null +++ b/machine_type.h @@ -0,0 +1,29 @@ +#ifndef MACHINE_TYPE_H +#define MACHINE_TYPE_H +#include <stdio.h> +#include <ncurses.h> +// number 1: datatypes + +typedef unsigned char tBool; +typedef unsigned char tUInt8; +typedef unsigned short tUInt16; +typedef unsigned int tUInt32; +typedef unsigned long long tUInt64; + +typedef signed char tInt8; +typedef signed short tInt16; +typedef signed int tInt32; +typedef signed long long tInt64; + +typedef FILE* tFptr; + +// number 2: file operations +tUInt64 getfilepos(tFptr f); +tUInt64 getfilesize(tFptr f); +void setfilepos(tFptr f,tUInt64 pos); + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define RETOK 0 +#define RETNOK -1 +#endif @@ -0,0 +1,704 @@ +#define MAJORVERSION 0 +#define MINORVERSION 6 +#define REVISION 5 +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include <ncurses.h> +#include "menu.h" +#include "configfile.h" +#include "machine_type.h" +#include "input.h" +#include "output.h" +#include "buffers.h" +#include "ui.h" +#include "hexcalc.h" +#include "search.h" +#include "gpl.h" +#include "markers.h" +#include "correlation.h" + +void welcomescreen(char* argv0) +{ + fprintf(stderr,"*** DHEX %i.%i%i\n",MAJORVERSION,MINORVERSION,REVISION); + fprintf(stderr,"*** (C)opyleft 2011 by Thomas Dettbarn\n"); + fprintf(stderr,"*** dettus@dettus.net (include DHEX somewhere in the subject)\n\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"(start it with %s -gpl to see the license)\n",argv0); + fprintf(stderr,"\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"This program is free software; you can redistribute it and/or modify\n"); + fprintf(stderr,"it under the terms of the GNU General Public License as published by\n"); + fprintf(stderr,"the Free Software Foundation; either version 2 of the License, or\n"); + fprintf(stderr,"(at your option) any later version.\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"This program is distributed in the hope that it will be useful,\n"); + fprintf(stderr,"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); + fprintf(stderr,"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); + fprintf(stderr,"GNU General Public License for more details.\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"You should have received a copy of the GNU General Public License\n"); + fprintf(stderr,"along with this program; if not, write to the Free Software\n"); + fprintf(stderr,"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"); + fprintf(stderr," \n\n"); +} +void helpscreen(char* argv0,int exitval) +{ + welcomescreen(argv0); + fprintf(stderr,"%s [Parameters]: General parameters\n",argv0); + fprintf(stderr," -h, -H, -? show this help\n"); + fprintf(stderr," -v, -V show the version number %i.%i%i\n",MAJORVERSION,MINORVERSION,REVISION); + fprintf(stderr," -k, -K start the keyboard setup manually\n"); + //fprintf(stderr," -x, -X start the hexcalc program (TODO)\n"); + fprintf(stderr," -g, -G show the license\n"); + fprintf(stderr," -f, -F [configfile] read the config from [configfile]\n"); + fprintf(stderr," -m, -M [markerfile] read the bookmarks from [markerfile]\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"%s [Parameters] [Filename]: Edit a single file\n",argv0); + fprintf(stderr," -ob, -OB [x] set the cursor to [x] (binary)\n"); + fprintf(stderr," -od, -OD [x] set the cursor to [x] (decimal)\n"); + fprintf(stderr," -oh, -OH [x] set the cursor to [x] (hexadecimal)\n"); + fprintf(stderr," -oo, -OO [x] set the cursor to [x] (octal)\n"); + fprintf(stderr," -sa, -SA, -sab, -SAB [x] find the ascii string x in file (b=backwards)\n"); + fprintf(stderr," -sh, -SH, -shb, -SHB [x] find the hex string x in file (b=backwards)\n"); + fprintf(stderr," -r, -R [read searchlog] read the search positions from this searchlog\n"); + fprintf(stderr," -w, -W [write searchlog] write the location of the occurances to this log\n"); + fprintf(stderr,"\n"); + fprintf(stderr,"%s [Parameters] [Filename1] [Filename2]: Diff mode\n",argv0); + fprintf(stderr," -cd, -CD [x] correlate with the minimum difference\n"); + fprintf(stderr," -cb, -CB, -cl, -CL correlate with the best/longest match\n"); + fprintf(stderr," -o1b, -O1B [x] -o2b, -O2B [y] set the cursors to [x] and [y] (binary)\n"); + fprintf(stderr," -o1d, -O1D [x] -o2d, -O2D [y] set the cursors to [x] and [y] (decimal)\n"); + fprintf(stderr," -o1h, -O1H [x] -o2h, -O2H [y] set the cursors to [x] and [y] (hexadecimal)\n"); + fprintf(stderr," -o1o, -O1O [x] -o2o, -O2O [y] set the cursors to [x] and [y] (octal)\n"); + fprintf(stderr," -s1a, -s1ab [x] -s2a, -s2ab [y] find the ascii strings [x] and [y]\n"); + fprintf(stderr," -s1h, -s1hb [x] -s2h, -s2hb [y] find the hex strings [x] and [y]\n"); + fprintf(stderr," -r1 [searchlog1] -r2 [searchlog2] read the search positions from searchlogs\n"); + fprintf(stderr," -w1 [searchlog1] -w2 [searchlog2] write the search positions to searchlogs\n"); + //fprintf(stderr," -c, -C [corrlen] find the best correlation between the files (TODO)\n"); + exit(exitval); +} +int parsecursorpos(tInt64* cursorpos1,tInt64* cursorpos2,char* lastopt,char* argv) +{ + int i; + int g; + int d; + char c; + tInt64 x=0; + + g=16; // default: hex + if (lastopt[1]=='D' || lastopt[2]=='D') g=10; // -od: decimal + if (lastopt[1]=='d' || lastopt[2]=='d') g=10; // -od: decimal + if (lastopt[1]=='H' || lastopt[2]=='H') g=16; // -oh: hexadecimal + if (lastopt[1]=='h' || lastopt[2]=='h') g=16; // -oh: hexadecimal + if (lastopt[1]=='B' || lastopt[2]=='B') g=2; // -ob: binary + if (lastopt[1]=='b' || lastopt[2]=='b') g=2; // -ob: binary + if (lastopt[1]=='O' || lastopt[2]=='O') g=8; // -oo: octal + if (lastopt[1]=='o' || lastopt[2]=='o') g=8; // -oo: octal + + + for (i=0;i<strlen(argv);i++) + { + c=argv[i]; + if (c>32) + { + x=x*g; + d=g; + if (c>='0' && c<='9') d=c-'0'; + if (c>='a' && c<='f') d=c-'a'+10; + if (c>='A' && c<='F') d=c-'A'+10; + + if (d>=g) return RETNOK; + x=x+d; + } + } + if (lastopt[1]=='1' || lastopt[2]=='1') *cursorpos1=x; // -o1: cursorpos1 + else if (lastopt[1]=='2' || lastopt[2]=='2') *cursorpos2=x; // -o2: cursorpos2 + else { + *cursorpos1=x; // -o: both + *cursorpos2=x; // -o: both + } + return RETOK; + +} +int parsecommandlineoptions(int argc,char** argv,tInt64* cursorpos1,tInt64* cursorpos2,tBool* diffmode,int* filename1,int* filename2,tBool* keyboardsetupreq,char* markerfilename,char* configfile,tSearch* search1,tBool* gosearch1,tSearch* search2,tBool* gosearch2,tCorrelation* correlation,tBool* gocorr) +{ + int filenamecnt=0; + int i; + int retval=RETOK; + char lastopt[8]; + tBool moreopts=1; + + *gosearch1=0; + *gosearch2=0; + *gocorr=0; + memset(lastopt,0,8); + for (i=1;i<argc;i++) + { + if (argv[i][0]=='-' && moreopts) + { + memcpy(lastopt,&argv[i][1],8); + switch (lastopt[0]) // this is for parameters with just one part + { + case '-': lastopt[0]=0; // -- means: no more options + if (argv[i][2]) retval=RETNOK; + moreopts=0; + break; + case 'c': // searching for a correlation could be a two-parted search. + case 'C': + *gocorr=1; + if (lastopt[1]=='d' || lastopt[1]=='D') correlation->algorithm=CORR_MIN_DIFF; // min diff, this is two parted + else if (lastopt[1]=='b' || lastopt[1]=='B') {correlation->algorithm=CORR_BEST_MATCH;lastopt[0]=0;} // best match + else if (lastopt[1]=='l' || lastopt[1]=='L') {correlation->algorithm=CORR_LONGEST_MATCH;lastopt[0]=0;} // longest match + else { + fprintf(stderr,"unknown correlation algorithm. please provide -cb, -cd or -cl\n"); + exit(1); + } + + break; + case '?': + case 'H': + case 'h': helpscreen(argv[0],0); // print the helpscreen and be done with it + lastopt[0]=0; + break; + case 'g': + case 'G': + print_gpl(); // print the gpl and be done with it + exit(0); + lastopt[0]=0; + break; + case 'X': + case 'x': printf("TODO:hexcalc\n"); + break; + case 'K': + case 'k': + *keyboardsetupreq=1; + lastopt[0]=0; + break; + case 'v': + case 'V': + printf("%i.%i%i\n",MAJORVERSION,MINORVERSION,REVISION); + exit(0); + break; + default: + break; + + } + } + else if (lastopt[0]) // two-parted parameters + { + switch (lastopt[0]) + { + case 'C': + case 'c': + correlation->start_mindiff=atoi(argv[i]); + break; + case 'F': + case 'f': + snprintf(configfile,512,"%s",argv[i]); + break; + case 'S': + case 's': + { + tInt8 stringtype=0; // 0=unknown, 1=ascii, 2=hex + tBool forward=1; + tSearch* search; + tBool* gosearch; + int j; + + search=search1; + gosearch=gosearch1; + for (j=1;j<8 && lastopt[j];j++) + { + if (lastopt[j]=='a' || lastopt[j]=='A') stringtype=1; + if (lastopt[j]=='h' || lastopt[j]=='H') stringtype=2; + if (lastopt[j]=='b' || lastopt[j]=='B') forward=0; + if (lastopt[j]=='1') + { + search=search1; + gosearch=gosearch1; + } + if (lastopt[j]=='2') + { + search=search2; + gosearch=gosearch2; + } + + } + + *gosearch=1; + search->forwardnotbackward=!(lastopt[2]=='b' || lastopt[2]=='B'); + if (stringtype==1) + { + memcpy(search->searchstring,argv[i],19); + search->searchlen=strlen(argv[i]); + if (search->searchlen>19) search->searchlen=19; + } else if (stringtype==2) { + int k=0; + int x=0; + search->searchlen=0; + for (j=0;j<strlen(argv[i]) && search->searchlen<19;j++) + { + int y; + y=-1; + x<<=4; + y=(argv[i][j]>='0' && argv[i][j]<='9')?argv[i][j]-'0':y; + y=(argv[i][j]>='a' && argv[i][j]<='f')?argv[i][j]-'a'+10:y; + y=(argv[i][j]>='A' && argv[i][j]<='F')?argv[i][j]-'A'+10:y; + if (y>=0) + { + x|=y; + if (k&1) + { + search->searchstring[search->searchlen++]=(x&0xff); + } + k++; + } + else if (argv[i][j]!=' ') + { + fprintf(stderr,"illegal character in hex searchstring.\n"); + retval=RETNOK; + } + } + } else { + fprintf(stderr,"please select one of -sa or -sh\n"); + retval=RETNOK; + } + } + break; + case 'r': + case 'R': + { + tSearch* search; + if (lastopt[1]=='2') search=search2; else search=search1; + memcpy(search->readlogfilename,argv[i],64); + search->readsearchlog=1; + } + break; + case 'w': + case 'W': + { + tSearch* search; + if (lastopt[1]=='2') search=search2; else search=search1; + memcpy(search->writelogfilename,argv[i],64); + search->writesearchlog=1; + } + break; + case 'O': + case 'o': + retval=parsecursorpos(cursorpos1,cursorpos2,lastopt,argv[i]); + break; + case 'm': + case 'M': + if (markerfilename) memcpy(markerfilename,argv[i],64); + break; + default: + retval=RETNOK; + break; + } + lastopt[0]=0; + } + else // no parameters, must be a filename + { + if (filenamecnt==0) + { + *filename1=i; + } + if (filenamecnt==1) + { + *filename2=i; + *diffmode=1; + } + filenamecnt++; + if (filenamecnt>2) retval=RETNOK; + } + } + return retval; +} +int main(int argc,char** argv) +{ +// tBuffer buf1; +// tBuffer buf2; + thHexCalc* hHexCalc=NULL; + tBuffer* buf1=NULL; + tBuffer* buf2=NULL; + tOutput* output=NULL; + tInt64 cursorpos1; + tInt64 firstpos1; + tInt64 cursorpos2; + tInt64 firstpos2; + tInt64 oldcursorpos1; + tInt64 oldfirstpos1; + tInt64 oldcursorpos2; + tInt64 oldfirstpos2; + tSearch search1; + tSearch search2; + tMarkers* markers; + tBool gosearch1=0; + tBool gosearch2=0; + tCorrelation correlation; + char markerfilename[64]; + + tUInt8 windowfield=0; // 0=hex field buffer 1, 1=ascii field buffer 1, 2=hex field buffer 2, 3=ascii field buffer 2 + tBool diffmode=0; + tBool keyboardsetupreq; + tBool gocorr=0; + int retval; + + int ch; + int filename1=-1; + int filename2=-1; + char* homedir; + char configfile[512]; + + memset(configfile,0,512); + memset(markerfilename,0,64); + markers=initmarkers(); + output=malloc(sizeof(tOutput)); + memset(output,0,sizeof(tOutput)); + initcolors(output); + initkeytab(output); + + keyboardsetupreq=0; + cursorpos1=0; + cursorpos2=0; + clearsearch(&search1); + clearsearch(&search2); + clear_correlation(&correlation); + if (parsecommandlineoptions(argc,argv,&cursorpos1,&cursorpos2,&diffmode,&filename1,&filename2,&keyboardsetupreq,markerfilename,configfile,&search1,&gosearch1,&search2,&gosearch2,&correlation,&gocorr)!=RETOK) + { + if (output) + { + if (output->pKeyTab) free(output->pKeyTab); + free(output); + } + if (markers) free(markers); + helpscreen(argv[0],0); + } + if (configfile[0]==0) + { + homedir=getenv("HOME"); + if (homedir==NULL) + { + fprintf(stderr,"$HOME-variable not set. \n\n"); + fprintf(stderr,"I'm sorry, but you'll have to provide a config-file by using\n"); + fprintf(stderr,"%s -f /PATHTOCONFIGFILE/.dhexrc\n",argv[0]); + exit(1); + } else { + snprintf(configfile,512,"%s/.dhexrc",homedir); + } + } + + if (markerfilename[0]) if (parsemarkerfile(markers,markerfilename)!=RETOK) + { + if (output) + { + if (output->pKeyTab) free(output->pKeyTab); + free(output); + } + if (markers) free(markers); + helpscreen(argv[0],0); + + } + + if (filename1==-1 || (filename2==-1 && diffmode)) helpscreen(argv[0],0); + retval=readconfigfile(output,configfile); + if (retval==1) // config file did not exists. creating one + { + tFptr f=fopen(configfile,"w"); + if (!f) + { + welcomescreen(argv[0]); + fprintf(stderr,"config file %s did not exists, and i couldn't create it\n",configfile); + exit(1); + } + fprintf(f,"#DHEXCOLORSCHEME\n"); + fprintf(f,"#VERSION 0\n"); + fprintf(f,"#possible colors are: BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITE\n"); + fprintf(f,"#possible extra flags are: UNDERLINE,REVERSE,BLINK,DIM,BOLD\n"); + fprintf(f,"\n"); + fprintf(f,"BRACKETS: FG=BLACK,BG=BLACK,BOLD\n"); + fprintf(f,"HEXFIELD: FG=WHITE,BG=BLACK\n"); + fprintf(f,"INPUT: FG=BLACK,BG=WHITE\n"); + fprintf(f,"CURSOR: FG=WHITE,BG=BLACK\n"); + fprintf(f,"TEXT: FG=LIGHTCYAN,BG=BLACK,BOLD\n"); + fprintf(f,"MENU_NORMAL: FG=LIGHTBLUE,BG=BLACK\n"); + fprintf(f,"MENU_HIGHLIGHT: FG=LIGHTBLUE,BG=BLUE\n"); + fprintf(f,"MENU_HOTKEY: FG=CYAN,BG=BLACK\n"); + fprintf(f,"MENU_HOTKEY_HI: FG=CYAN,BG=BLUE\n"); + fprintf(f,"FRAME: FG=BLUE,BG=BLACK\n"); + fprintf(f,"NORMAL_DIFF: FG=YELLOW,BG=BLACK,BOLD\n"); + fprintf(f,"CURSOR_DIFF: FG=YELLOW,BG=WHITE,BOLD\n"); + fprintf(f,"HEADLINE: FG=BLUE,BG=BLACK\n"); + fprintf(f," \n"); + fclose(f); + retval=2; + } + if (retval==2) keyboardsetupreq=1; + + hHexCalc=malloc(sizeof(thHexCalc)); + memset(hHexCalc,0,sizeof(thHexCalc)); + buf1=malloc(sizeof(tBuffer)); + memset(buf1,0,sizeof(tBuffer)); + if (diffmode) + { + buf2=malloc(sizeof(tBuffer)); + memset(buf2,0,sizeof(tBuffer)); + } + + if (openbuf(buf1,1,argv[filename1])!=RETOK) + { + fprintf(stderr,"error opening inputfile %s\n",argv[filename1]); + exit(1); + } + if (diffmode) if (openbuf(buf2,2,argv[filename2])!=RETOK) + { + fprintf(stderr,"error opening second inputfile %s\n",argv[filename2]); + exit(1); + } + if (gosearch1) searchfor(&search1,buf1,&cursorpos1,1); + if (gosearch2 && diffmode) searchfor(&search2,buf2,&cursorpos2,1); + if (gocorr && diffmode) + { + fprintf(stderr,"correlating...\n"); + find_correlation(NULL,&correlation,buf1,buf2,&cursorpos1,&cursorpos2); + } + if (!(gosearch1 && search1.writesearchlog) || (diffmode && !(gosearch2 && search2.writesearchlog))) + { + output->win=initscr(); + pairsinit(output); + noecho(); + nodelay(output->win,1); + if (keyboardsetupreq) keyboardsetup(output,configfile); + readbuf(buf1,0); + firstpos1=cursorpos1; + firstpos2=cursorpos2; + ch=0; + while (ch!=KEYF10) + { + printmainmenu(output,diffmode); + if (diffmode) + printbufferdiff(output,buf1,buf2,cursorpos1,cursorpos2); + else + printbuffersingle(output,buf1,cursorpos1,firstpos1,windowfield); + ch=getkey((tKeyTab*)output->pKeyTab,1); + +#define MOVEMENTDEFINE(KEY,VIKEY,mvchar,mvline,mvpage) \ + if (ch==KEY || (VIKEY && ch==VIKEY && windowfield==0)) \ + { \ + tInt32 err; \ + oldfirstpos1=firstpos1; \ + oldcursorpos1=cursorpos1; \ + oldfirstpos2=firstpos2; \ + oldcursorpos2=cursorpos2; \ + \ + err=movepositions(&cursorpos1,&firstpos1,buf1->bufsize,mvchar,mvline,mvpage,diffmode); \ + \ + if (diffmode) \ + { \ + movepositions(&cursorpos2,&firstpos2,buf2->bufsize,mvchar,mvline,mvpage,diffmode); \ + err=((cursorpos1<0 && cursorpos2<0) || (cursorpos1>buf1->bufsize && cursorpos2>buf2->bufsize)); \ + } \ + if (err) \ + { \ + firstpos1=oldfirstpos1; \ + cursorpos1=oldcursorpos1; \ + firstpos2=oldfirstpos2; \ + cursorpos2=oldcursorpos2; \ + } \ + } + MOVEMENTDEFINE(KEYRIGHT,'l' , 1, 0, 0); + MOVEMENTDEFINE(KEYLEFT,'h' ,-1, 0, 0); + MOVEMENTDEFINE(KEYDOWN,'j' , 0, 1, 0); + MOVEMENTDEFINE(KEYUP,'k' , 0,-1, 0); + MOVEMENTDEFINE(KEYPGDOWN,' ' , 0, 0, 1); + MOVEMENTDEFINE(KEYPGUP,0 , 0, 0,-1); + +#undef MOVEMENTDEFINE + if (ch==KEYHOME || (ch=='^' && windowfield==0)) + { + if (diffmode) + { + tInt64 dmin,dmax; + + dmin=MIN(cursorpos1,cursorpos2); + dmax=MAX(cursorpos1,cursorpos2); + if (dmin==0) + { + cursorpos1-=dmax; + cursorpos2-=dmax; + } else { + cursorpos1-=dmin; + cursorpos2-=dmin; + } + firstpos1=cursorpos1; + firstpos2=cursorpos2; + + } else { + firstpos1=cursorpos1=0; + } + } + if (ch==KEYEND || (ch=='$' && windowfield==0)) + { + if (diffmode) + { + tInt64 dmin,dmax; + dmin=MIN(buf1->bufsize-cursorpos1,buf2->bufsize-cursorpos2); + dmax=MAX(buf1->bufsize-cursorpos1,buf2->bufsize-cursorpos2); + + if (dmin==0) + { + + cursorpos2+=dmax; + cursorpos1+=dmax; + } else { + cursorpos1+=dmin; + cursorpos2+=dmin; + } + } else { + firstpos1=cursorpos1=buf1->bufsize; + } + } + if (ch==KEYTAB) {windowfield=(windowfield+1)&1;} + if ((ch==KEYF1 || (ch==':' && windowfield==0))&& !diffmode) { + if (gotomask(output,markers,&cursorpos1)==RETOK) + { + firstpos1=cursorpos1; + } + } + if ((ch==KEYF2 || ((ch=='/' || ch=='?') && (windowfield==0))) && !diffmode) + { + if (ch=='/') search1.forwardnotbackward=1; // / means forward + if (ch=='?') search1.forwardnotbackward=0; // ? means backward + searchmask(output,&search1,buf1,&cursorpos1); + firstpos1=cursorpos1; + } + if (ch==KEYF3 || ch==KEYF4 || (windowfield==0 && (ch=='n' || ch=='N'))) + { + if (ch=='n') ch=KEYF3; // n=next + if (ch=='N') ch=KEYF4; // N=previous + if (diffmode) + { + tInt64 actcursorpos1=cursorpos1; + tInt64 actcursorpos2=cursorpos2; + tInt32 idx1,idx2; + tBool found; + tBool diffnotdiff; + tUInt64 minbufsize=(buf1->bufsize<buf2->bufsize)?buf1->bufsize:buf2->bufsize; // get the minimum of the filesizes + tUInt64 searchcnt=minbufsize; + + oldcursorpos1=cursorpos1; + oldcursorpos2=cursorpos2; + actcursorpos1=actcursorpos1+((ch==KEYF3)?1:-1); // F3: next, F4:prev + actcursorpos2=actcursorpos2+((ch==KEYF3)?1:-1); // F3: next, F4:prev + found=(!minbufsize); + idx1=getbufferidx(buf1,actcursorpos1); + idx2=getbufferidx(buf2,actcursorpos2); + diffnotdiff=(buf1->data[idx1]!=buf2->data[idx2]); // if the cursor is on something which is a diff, look for the next time the values are the same + while (actcursorpos1!=oldcursorpos1 && actcursorpos2!=oldcursorpos2 && searchcnt && !found) + { + idx1=getbufferidx(buf1,actcursorpos1); + idx2=getbufferidx(buf2,actcursorpos2); + if ((buf1->data[idx1]!=buf2->data[idx2]) != diffnotdiff) found=1; + else { + actcursorpos1=actcursorpos1+((ch==KEYF3)?1:-1); // F3: next, F4:prev + actcursorpos2=actcursorpos2+((ch==KEYF3)?1:-1); // F3: next, F4:prev + } + if (actcursorpos1<0 || actcursorpos2<0) + { + actcursorpos1+=minbufsize; // start at the end of the smallest file + actcursorpos2+=minbufsize; // start at the end of the smallest file + } + if (actcursorpos1>=minbufsize && actcursorpos2>=minbufsize) + { + actcursorpos1-=minbufsize; // if you are at the end of the smallest file, start at the beginning + actcursorpos2-=minbufsize; // if you are at the end of the smallest file, start at the beginning + } + searchcnt--; + } + if (found) + { + cursorpos1=actcursorpos1; + cursorpos2=actcursorpos2; + } + } + else if (search1.occurancesfound) + { + searchfor(&search1,buf1,&cursorpos1,(ch==KEYF3)); // f3: next + firstpos1=cursorpos1; + } + } + if (ch==KEYF5) hexcalc(output,hHexCalc); + if (ch==KEYF6 && diffmode) + { + correlation.start_mindiff=MIN(buf1->bufsize,buf2->bufsize); + if (correlationmask(output,&correlation)==RETOK) + { + find_correlation(output,&correlation,buf1,buf2,&cursorpos1,&cursorpos2); + } + } + if ((ch==KEYF9 || (ch=='u' && windowfield==0)) && !diffmode) + { + if (buf1->changesnum) + { + if ((buf1->changes[buf1->changesnum].pos==(buf1->bufsize-1) && (buf1->filesize<=buf1->changes[buf1->changesnum].pos))) buf1->bufsize--; // if this was the last byte in the buffer, decrease its size + cursorpos1=buf1->changes[--buf1->changesnum].pos; + if (cursorpos1<firstpos1) firstpos1=cursorpos1; + if ((firstpos1+100)>cursorpos1) firstpos1=cursorpos1; // TODO: 100 depends on the size of the window + } + + } + if (buf1->changesnum<CHANGEBUFSIZE-1 && !diffmode) + { + if (((ch>='0' && ch<='9') || (ch>='a' && ch<='f') || (ch>='A' && ch<='F')) && windowfield==0) + { + buf1->nexthex<<=4; + if (ch>='a') ch-=32; + buf1->nexthex|=((ch>='A')?(ch-'A'+10):(ch-'0')); + if (buf1->nibble) + { + if (cursorpos1==buf1->bufsize) buf1->bufsize++; // append the byte at the end + buf1->changes[buf1->changesnum].pos=cursorpos1; + buf1->changes[buf1->changesnum].after=buf1->nexthex; + buf1->changesnum++; + movepositions(&cursorpos1,&firstpos1,buf1->bufsize,1,0,0,diffmode); + } + buf1->nibble=!buf1->nibble; + buf1->changepos=cursorpos1; + } else buf1->nibble=0; + if (ch>=32 && ch<127 && windowfield==1) + { + if (cursorpos1==buf1->bufsize) buf1->bufsize++; // append the byte at the end + buf1->changes[buf1->changesnum].pos=cursorpos1; + buf1->changes[buf1->changesnum].after=ch; + buf1->changesnum++; + movepositions(&cursorpos1,&firstpos1,buf1->bufsize,1,0,0,diffmode); + } + } + if (ch==KEYF10) + { + if (buf1->changesnum) if (savedialog(output,buf1)!=RETOK) + { + ch=0; + } + } + } + if (output) + { + if (output->pKeyTab) free(output->pKeyTab); + free(output); + } + if (buf1) free(buf1); + if (buf2) free(buf2); + if (hHexCalc) free(hHexCalc); + if (markers) free(markers); + if (output->win) endwin(); + welcomescreen(argv[0]); + } else { + if (gosearch1) fprintf(stderr,"%lli occurances found in %s\n",search1.occurancesfound,buf1->filename); + if (gosearch2) fprintf(stderr,"%lli occurances found in %s\n",search2.occurancesfound,buf2->filename); + } + return 0; +} + diff --git a/markers.c b/markers.c new file mode 100644 index 0000000..6731e24 --- /dev/null +++ b/markers.c @@ -0,0 +1,213 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include "machine_type.h" +#include "menu.h" +#include "output.h" +#include "input.h" +#include "markers.h" + +void* initmarkers() +{ + tMarkers* p; + int i; + p=malloc(sizeof(tMarkers)); + for (i=0;i<NUMMARKERS;i++) + { + p->relative[i]='='; + p->cursorpos[i]=0; + } + return p; +} + +int parsemarkerfile(tMarkers* markers,char* filename) +{ + tFptr f; + char c; + tMarkers* tmp; + int markersnum=0; + tInt8 state=0; // 0=start of the line, waiting for the relativ tokens, or a number + // 1=got relative + // 2=reading in number + // 3=end of line + tBool hadnumber=0; + tmp=initmarkers(); + f=fopen(filename,"r"); + if (!f) return RETNOK; + while (!feof(f) && markersnum<10) + { + fread(&c,sizeof(char),1,f); + if (c>='a' && c<='z') c=c-32; // make the letters uppercase + if (!feof(f) && c!=' ' && c!=9) // ignore the spaces + { + if (c=='#') state=3; // the rest of this line is just a comment + if (c<32) // newline + { + if (hadnumber) + { + markersnum++; + tmp->relative[markersnum]='='; + tmp->cursorpos[markersnum]=0; + } + hadnumber=0; + state=0; + } + if (state==1) state=2; // the last character was the relative, now for the number + if (state==0 && (c=='=' || c=='+' || c=='-')) + { + tmp->relative[markersnum]=c; + state=1; + } + if (state==0 && ((c>='A' && c<='F') || (c>='0' && c<='9'))) state=2; // the number starts right here + if (state==2) + { + tmp->cursorpos[markersnum]<<=4; + hadnumber=1; + if (c>='0' && c<='9') tmp->cursorpos[markersnum]+=(c-'0'); + else if (c>='A' && c<='F') tmp->cursorpos[markersnum]+=(c-'A'+10); + else return RETNOK; // illegal value + } + } + } + fclose(f); + memcpy(markers,tmp,sizeof(tMarkers)); + free(tmp); + return RETOK; +} + +int writemarkerfile(tMarkers* markers,char* filename) +{ + tFptr f; + int i; + + f=fopen(filename,"w"); + if (!f) return RETNOK; + fprintf(f,"#DHEX MARKERS\n"); + fprintf(f,"#VERSION 0\n"); + fprintf(f,"#lines are all in hex\n"); + fprintf(f,"#relative positions are =, +, -\n"); + fprintf(f,"\n"); + for (i=0;i<NUMMARKERS;i++) + { + fprintf(f,"%c%016llX\n",markers->relative[i],markers->cursorpos[i]); + } + fclose(f); + return RETOK; +} +tInt8 gotomask(tOutput* output,tMarkers* markers,tUInt64* cursorpos) +{ + tUInt64 actcursorpos=*cursorpos; + tUInt64 newcursorpos=*cursorpos; + tInt8 itemnums[25]; + tInt8 selected; + tMenu Menu1; + tInt16 offsx; + tInt16 offsy; + tInt8 retval=RETOK; + char buf[17]; + char filename[64]; + + + int i; + tInt16 ch; + + memset(filename,0,64); + + offsx=COLS/2-30; + offsy=LINES/2-10; + + drawcenterframe(output,17,60,"Goto..."); + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,offsy+3,offsx+8,"[ ]"); + clearMenu(&Menu1); + newMenuItem(&Menu1,"To",3,1,'T',0,&itemnums[0]); + newMenuItem(&Menu1,"Go",3,48,'G',0,&itemnums[1]); + newMenuItem(&Menu1,"Cancel",3,53,'C',1,&itemnums[2]); + + newMenuItem(&Menu1,"Set", 5,1,0,0,&itemnums[ 3]); + newMenuItem(&Menu1,"Set", 6,1,0,0,&itemnums[ 4]); + newMenuItem(&Menu1,"Set", 7,1,0,0,&itemnums[ 5]); + newMenuItem(&Menu1,"Set", 8,1,0,0,&itemnums[ 6]); + newMenuItem(&Menu1,"Set", 9,1,0,0,&itemnums[ 7]); + newMenuItem(&Menu1,"Set",10,1,0,0,&itemnums[ 8]); + newMenuItem(&Menu1,"Set",11,1,0,0,&itemnums[ 9]); + newMenuItem(&Menu1,"Set",12,1,0,0,&itemnums[10]); + newMenuItem(&Menu1,"Set",13,1,0,0,&itemnums[11]); + newMenuItem(&Menu1,"Set",14,1,0,0,&itemnums[12]); + + newMenuItem(&Menu1,"Mark 1", 5,7,'1',0,&itemnums[13]); + newMenuItem(&Menu1,"Mark 2", 6,7,'2',0,&itemnums[14]); + newMenuItem(&Menu1,"Mark 3", 7,7,'3',0,&itemnums[15]); + newMenuItem(&Menu1,"Mark 4", 8,7,'4',0,&itemnums[16]); + newMenuItem(&Menu1,"Mark 5", 9,7,'5',0,&itemnums[17]); + newMenuItem(&Menu1,"Mark 6",10,7,'6',0,&itemnums[18]); + newMenuItem(&Menu1,"Mark 7",11,7,'7',0,&itemnums[19]); + newMenuItem(&Menu1,"Mark 8",12,7,'8',0,&itemnums[20]); + newMenuItem(&Menu1,"Mark 9",13,7,'9',0,&itemnums[21]); + newMenuItem(&Menu1,"Mark 0",14,7,'0',0,&itemnums[22]); + + + newMenuItem(&Menu1,"Load Markers",16, 1,'L',0,&itemnums[23]); + newMenuItem(&Menu1,"Save Markers",16,17,'S',0,&itemnums[24]); + selected=-1; + + while (1) + { + setcolor(output,COLOR_FRAME); + for (i=0;i<58;i++) mvwprintw(output->win,offsy+17,offsx+1+i," "); + setcolor(output,COLOR_TEXT); + if (retval!=RETOK) mvwprintw(output->win,offsy+17,offsx+1,"error opening file"); + for (i=0;i<NUMMARKERS;i++) + { + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,offsy+5+i,offsx+14,"[ ]"); + mvwprintw(output->win,offsy+5+i,offsx+41,"[ ]"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+5+i,offsx+36,"Diff:"); + + snprintf(buf,17,"%c%llx",markers->relative[i],markers->cursorpos[i]); + mvwprintw(output->win,offsy+5+i,offsx+32-strlen(buf),"%s",buf); + mvwprintw(output->win,offsy+5+i,offsx+42,"%16llx",abs(markers->cursorpos[i]-actcursorpos)); + } + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+3,offsx+9,"%17llx",newcursorpos); + selected=MenuInteract(output,&Menu1,offsy,offsx); + if (selected==itemnums[0]) { + newcursorpos=actcursorpos; + hexinput(output,offsy+3,offsx+8,&newcursorpos,NULL,17); + } + if (selected==itemnums[1]) {*cursorpos=newcursorpos;return RETOK;} + if (selected==itemnums[2]) return RETNOK; + + for (i=0;i<NUMMARKERS;i++) + { + if (selected==itemnums[3+i]) + { + if (markers->relative[i]=='=' && markers->cursorpos[i]==0) markers->cursorpos[i]=actcursorpos; + hexinput(output,offsy+ 5+i,offsx+14,&markers->cursorpos[i],&markers->relative[i],17); + } + if (selected==itemnums[13+i]) + { + if (markers->relative[i]=='=') newcursorpos =markers->cursorpos[i]; + if (markers->relative[i]=='-') newcursorpos=actcursorpos-markers->cursorpos[i]; + if (markers->relative[i]=='+') newcursorpos=actcursorpos+markers->cursorpos[i]; + } + } + if (selected==itemnums[23] || selected==itemnums[24]) + { + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+17,offsx+1,"Filename:"); + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,offsy+17,offsx+10,"[ ]"); + ch=stringinput(output,offsy+17,offsx+10,filename,32); + if (ch==KEYENTER) + { + if (selected==itemnums[23]) retval=parsemarkerfile(markers,filename); + if (selected==itemnums[24]) retval=writemarkerfile(markers,filename); + } + } + } + return RETOK; +} + diff --git a/markers.h b/markers.h new file mode 100644 index 0000000..908bb5a --- /dev/null +++ b/markers.h @@ -0,0 +1,13 @@ +#ifndef MARKERS_H +#define MARKERS_H +#include "machine_type.h" +#include "output.h" +#include "datatypes.h" + +void* initmarkers(); +int parsemarkerfile(tMarkers* markers,char* filename); +tInt8 gotomask(tOutput* output,tMarkers* markers,tUInt64* cursorpos); + + +#endif + @@ -0,0 +1,255 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include "machine_type.h" +#include "menu.h" +#include "output.h" +#include "input.h" + +void clearMenu(tMenu* Menu) +{ + Menu->menuitemnum=0; + Menu->menuitemactive=0; +} +void newMenuItem(tMenu* Menu,char* text,tUInt16 y,tUInt16 x,char hotkey,tBool active,tInt8* itemnum) +{ + memcpy(Menu->MenuItems[Menu->menuitemnum].menutext,text,64); + Menu->MenuItems[Menu->menuitemnum].x=x; + Menu->MenuItems[Menu->menuitemnum].y=y; + if (hotkey>='a' && hotkey<='z') hotkey-=32; // make the hotkey uppercase + Menu->MenuItems[Menu->menuitemnum].hotkey=hotkey; + + if (active) Menu->menuitemactive=Menu->menuitemnum; + *itemnum=Menu->menuitemnum; + Menu->menuitemnum++; +} +void printMenu(tOutput* output,tMenu* Menu,tUInt16 offsy,tUInt16 offsx) +{ + int i; + int j; + for (i=0;i<Menu->menuitemnum;i++) + { + setcolor(output,(i==Menu->menuitemactive)?COLOR_MENUACTIVE:COLOR_MENUNORMAL); + mvwprintw(output->win,offsy+Menu->MenuItems[i].y,offsx+Menu->MenuItems[i].x,"%s",Menu->MenuItems[i].menutext); + if (Menu->MenuItems[i].hotkey) + { + for (j=0;j<strlen(Menu->MenuItems[i].menutext);j++) + { + if (Menu->MenuItems[i].menutext[j]==Menu->MenuItems[i].hotkey || (Menu->MenuItems[i].hotkey>='A' && Menu->MenuItems[i].hotkey<='Z' && Menu->MenuItems[i].menutext[j]-32==Menu->MenuItems[i].hotkey)) + { + setcolor(output,(i==Menu->menuitemactive)?COLOR_MENUHOTKEYACTIVE:COLOR_MENUHOTKEY); + mvwprintw(output->win,offsy+Menu->MenuItems[i].y,offsx+Menu->MenuItems[i].x+j,"%c",Menu->MenuItems[i].menutext[j]); + j=65; + } + } + } + } +} +void MenuMoveLeft(tMenu* Menu) +{ + tUInt16 actx; + tUInt16 acty; + tInt16 diffx; + tInt16 diffy; + tInt16 mindiffx; + tInt16 mindiffy; + tUInt16 minact; + int i; + + actx=Menu->MenuItems[Menu->menuitemactive].x; + acty=Menu->MenuItems[Menu->menuitemactive].y; + + + mindiffx=COLS; + mindiffy=LINES; + minact=Menu->menuitemactive; + + for (i=0;i<Menu->menuitemnum;i++) + if (i!=Menu->menuitemactive) + { + diffx=actx-Menu->MenuItems[i].x; + diffy=acty-Menu->MenuItems[i].y; + if (diffy<0) diffy=-diffy; + if (mindiffy>diffy) + { + mindiffy=diffy; + mindiffx=COLS; + } + if (mindiffy==diffy) + { + if (mindiffx>=diffx && diffx>0) + { + mindiffx=diffx; + minact=i; + } + } + } + Menu->menuitemactive=minact; +} +void MenuMoveRight(tMenu* Menu) +{ + tUInt16 actx; + tUInt16 acty; + tInt16 diffx; + tInt16 diffy; + tInt16 mindiffx; + tInt16 mindiffy; + tUInt16 minact; + int i; + + actx=Menu->MenuItems[Menu->menuitemactive].x; + acty=Menu->MenuItems[Menu->menuitemactive].y; + + + mindiffx=COLS; + mindiffy=LINES; + minact=Menu->menuitemactive; + + for (i=0;i<Menu->menuitemnum;i++) + if (i!=Menu->menuitemactive) + { + diffx=Menu->MenuItems[i].x-actx; + diffy=acty-Menu->MenuItems[i].y; + if (diffy<0) diffy=-diffy; + if (mindiffy>diffy) + { + mindiffy=diffy; + mindiffx=COLS; + } + if (mindiffy==diffy) + { + if (mindiffx>=diffx && diffx>0) + { + mindiffx=diffx; + minact=i; + } + } + } + Menu->menuitemactive=minact; +} +void MenuMoveUp(tMenu* Menu) +{ + tUInt16 actx; + tUInt16 acty; + tInt16 diffx; + tInt16 diffy; + tInt16 mindiffx; + tInt16 mindiffy; + tUInt16 minact; + int i; + + actx=Menu->MenuItems[Menu->menuitemactive].x; + acty=Menu->MenuItems[Menu->menuitemactive].y; + + + mindiffx=COLS; + mindiffy=LINES; + minact=Menu->menuitemactive; + + for (i=0;i<Menu->menuitemnum;i++) + if (i!=Menu->menuitemactive) + { + diffx=Menu->MenuItems[i].x-actx; + diffy=acty-Menu->MenuItems[i].y; + if (diffx<0) diffx=-diffx; + if (mindiffx>diffx) + { + mindiffx=diffx; + mindiffy=LINES; + } + if (mindiffx==diffx) + { + if (mindiffy>=diffy && diffy>0) + { + mindiffy=diffy; + minact=i; + } + } + } + Menu->menuitemactive=minact; +} +void MenuMoveDown(tMenu* Menu) +{ + tUInt16 actx; + tUInt16 acty; + tInt16 diffx; + tInt16 diffy; + tInt16 mindiffx; + tInt16 mindiffy; + tUInt16 minact; + int i; + + actx=Menu->MenuItems[Menu->menuitemactive].x; + acty=Menu->MenuItems[Menu->menuitemactive].y; + + + mindiffx=COLS; + mindiffy=LINES; + minact=Menu->menuitemactive; + + for (i=0;i<Menu->menuitemnum;i++) + if (i!=Menu->menuitemactive) + { + diffx=Menu->MenuItems[i].x-actx; + diffy=Menu->MenuItems[i].y-acty; + if (diffx<0) diffx=-diffx; + + if (mindiffx>diffx) + { + mindiffx=diffx; + mindiffy=LINES; + } + if (mindiffx==diffx) + { + if (mindiffy>=diffy && diffy>0) + { + mindiffy=diffy; + minact=i; + } + } + } + Menu->menuitemactive=minact; +} +void MenuSetActiveItem(tMenu* Menu,tInt8 itemnum) +{ + Menu->menuitemactive=itemnum; +} +tInt8 MenuInteract(tOutput* output,tMenu* Menu,tInt16 offsy,tInt16 offsx) +{ + tInt16 ch; + int i; + tInt8 retval; + + ch=0; + printMenu(output,Menu,offsy,offsx); + while (ch!=KEYENTER) + { + ch=getkey((tKeyTab*)output->pKeyTab,0); + switch(ch) + { + case KEYLEFT: MenuMoveLeft(Menu); break; + case KEYRIGHT: MenuMoveRight(Menu); break; + case KEYUP: MenuMoveUp(Menu); break; + case KEYDOWN: MenuMoveDown(Menu); break; + case KEYTAB: Menu->menuitemactive=(Menu->menuitemactive+1)%Menu->menuitemnum;break; + case KEYENTER: retval=Menu->menuitemactive; break; + default: + if (ch>=' ' && ch<127) + { + if (ch>='a' && ch<='z') ch-=32; + for (i=0;i<Menu->menuitemnum;i++) + { + if (Menu->MenuItems[i].hotkey==ch) + { + Menu->menuitemactive=i; + ch=KEYENTER; + } + } + } + break; + } + printMenu(output,Menu,offsy,offsx); + } + return Menu->menuitemactive; +} @@ -0,0 +1,19 @@ +#ifndef MENU_H +#define MENU_H +#include <stdio.h> +#include "machine_type.h" +#include "config.h" +#include "output.h" +#include "datatypes.h" + + +void clearMenu(tMenu* Menu); +void newMenuItem(tMenu* Menu,char* text,tUInt16 y,tUInt16 x,char hotkey,tBool active,tInt8* itemnum); +void printMenu(tOutput* output,tMenu* Menu,tUInt16 offsy,tUInt16 offsx); +void MenuMoveLeft(tMenu* Menu); +void MenuMoveRight(tMenu* Menu); +void MenuMoveUp(tMenu* Menu); +void MenuMoveDown(tMenu* Menu); +void MenuSetActiveItem(tMenu* Menu,tInt8 itemnum); +tInt8 MenuInteract(tOutput* output,tMenu* Menu,tInt16 offsy,tInt16 offsx); +#endif diff --git a/mkrelease.sh b/mkrelease.sh new file mode 100644 index 0000000..e740d80 --- /dev/null +++ b/mkrelease.sh @@ -0,0 +1,47 @@ +mkdir dhex_0.65 +for I in `echo " +Makefile +buffers.c +buffers.h +config.h +configfile.c +configfile.h +correlation.c +correlation.h +datatypes.h +gpl.c +gpl.h +gpl.txt +hexcalc.c +hexcalc.h +input.c +input.h +machine_type.c +machine_type.h +main.c +markers.c +markers.h +menu.c +menu.h +output.c +output.h +search.c +search.h +ui.c +ui.h +README.txt +todo.txt +dhex.1 +dhexrc.5 +dhex_markers.5 +dhex_searchlog.5 +mkrelease.sh" | sort -f` +do + cp $I dhex_0.65/ +done +( cd dhex_0.65/ && make && make clean && cd .. && \ +tar cvfz dhex_0.65.tar.gz dhex_0.65/ ) +cp dhex_0.65.tar.gz dhex_latest.tar.gz +md5 dhex_0.65.tar.gz +md5 dhex_latest.tar.gz + diff --git a/output.c b/output.c new file mode 100644 index 0000000..6e7cda0 --- /dev/null +++ b/output.c @@ -0,0 +1,476 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include <ncurses.h> +#include "machine_type.h" +#include "output.h" +#include "buffers.h" +void initcolors(tOutput* output) +{ + + output->colors[COLOR_BRACKETS].fg =COLOR_WHITE; output->colors[COLOR_BRACKETS].bg =COLOR_BLACK; output->colors[COLOR_BRACKETS].attrs =0; + output->colors[COLOR_INPUT].fg =COLOR_BLACK; output->colors[COLOR_INPUT].bg =COLOR_WHITE; output->colors[COLOR_INPUT].attrs =0; + output->colors[COLOR_CURSOR].fg =COLOR_WHITE; output->colors[COLOR_CURSOR].bg =COLOR_BLACK; output->colors[COLOR_CURSOR].attrs =0; + output->colors[COLOR_TEXT].fg =COLOR_WHITE; output->colors[COLOR_TEXT].bg =COLOR_BLACK; output->colors[COLOR_TEXT].attrs =A_BOLD; + output->colors[COLOR_HEXFIELD].fg =COLOR_WHITE; output->colors[COLOR_HEXFIELD].bg =COLOR_BLACK; output->colors[COLOR_HEXFIELD].attrs =0; + output->colors[COLOR_DIFF].fg =COLOR_YELLOW; output->colors[COLOR_DIFF].bg =COLOR_BLACK; output->colors[COLOR_DIFF].attrs =A_BOLD; + output->colors[COLOR_HEADLINE].fg =COLOR_BLUE; output->colors[COLOR_HEADLINE].bg =COLOR_BLACK; output->colors[COLOR_HEADLINE].attrs =A_BOLD; +// output->colors[COLOR_INFO].fg =COLOR_WHITE; output->colors[COLOR_INFO].bg =COLOR_BLACK; output->colors[COLOR_INFO].attrs =A_BOLD; + output->colors[COLOR_HEADER].fg =COLOR_BLACK; output->colors[COLOR_HEADER].bg =COLOR_CYAN; output->colors[COLOR_HEADER].attrs =0; + output->colors[COLOR_MENUHOTKEY].fg =COLOR_YELLOW; output->colors[COLOR_MENUHOTKEY].bg =COLOR_BLACK; output->colors[COLOR_MENUHOTKEY].attrs =A_BOLD; + output->colors[COLOR_MENUNORMAL].fg =COLOR_CYAN; output->colors[COLOR_MENUNORMAL].bg =COLOR_BLACK; output->colors[COLOR_MENUNORMAL].attrs =A_BOLD; + output->colors[COLOR_FRAME].fg =COLOR_BLUE; output->colors[COLOR_FRAME].bg =COLOR_BLACK; output->colors[COLOR_FRAME].attrs =A_BOLD; + output->colors[COLOR_MENUACTIVE].fg =COLOR_BLACK; output->colors[COLOR_MENUACTIVE].bg =COLOR_CYAN; output->colors[COLOR_MENUACTIVE].attrs =0; + output->colors[COLOR_MENUHOTKEYACTIVE].fg=COLOR_YELLOW; output->colors[COLOR_MENUHOTKEYACTIVE].bg=COLOR_CYAN; output->colors[COLOR_MENUHOTKEYACTIVE].attrs=A_BOLD; +} +void colorpair(tOutput* output,uicolors uicol,short fg,short bg,int attr) +{ + //init_pair(uicol,fg,bg);attrs[uicol]=COLOR_PAIR(uicol)+attr; + output->colors[uicol].fg=fg; + output->colors[uicol].bg=bg; + output->colors[uicol].attrs=attr; +} +void pairsinit(tOutput* output) +{ + int i; + start_color(); + for (i=0;i<UICOLORNUM;i++) + { + init_pair(i,output->colors[i].fg,output->colors[i].bg);output->attrs[i]=COLOR_PAIR(i)+output->colors[i].attrs; + } +} +void setcolor(tOutput* output,uicolors col) +{ + wattrset(output->win,output->attrs[col]); +} + +void drawframe(tOutput* output,tInt16 y,tInt16 x,tInt8 h,tInt8 w,char* header) +{ + int i; + int j; + + setcolor(output,COLOR_FRAME); + wmove(output->win,y,x); + waddch(output->win,ACS_ULCORNER); + for (i=0;i<w-2;i++) waddch(output->win,ACS_HLINE); + waddch(output->win,ACS_URCORNER); + for (j=1;j<h;j++) + { + wmove(output->win,y+j,x); + waddch(output->win,ACS_VLINE); + for (i=0;i<w-2;i++) waddch(output->win,' '); + waddch(output->win,ACS_VLINE); + } + wmove(output->win,y+h,x); + waddch(output->win,ACS_LLCORNER); + for (i=0;i<w-2;i++) waddch(output->win,ACS_HLINE); + waddch(output->win,ACS_LRCORNER); + if (header) + { + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,y,x+1,"["); + mvwprintw(output->win,y,x+1+strlen(header)+1,"]"); + setcolor(output,COLOR_HEADER); + mvwprintw(output->win,y,x+2,"%s",header); + } +} +void drawcenterframe(tOutput* output,tInt8 h,tInt8 w,char* header) +{ + drawframe(output,LINES/2-h/2,COLS/2-w/2,h,w,header); +} +void printbuffersingle(tOutput* output,tBuffer* hBuf1,tInt64 cursorpos1,tUInt64 firstpos1,tUInt8 windowfield) +{ + int i; + int j; + int k; + int addrwidth; + int bytesperline; + tInt32 intpos1; + tInt32 charcnt; + + + + addrwidth=(hBuf1->bufsize>0xffffffffull)?16:8; + bytesperline=(COLS-(addrwidth+3+3))*8/(8*3+8+1); // this many bytes can be printed in one line. every 8 bytes there is an extra space in the hex field. + + setcolor(output,COLOR_HEADLINE); + wmove(output->win,0,0); + for (i=0;i<COLS;i++) + { + waddch(output->win,ACS_HLINE); + } + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,0,COLS-3-strlen(hBuf1->filename),"["); + mvwprintw(output->win,0,COLS-2,"]"); + if (addrwidth==16) + { + mvwprintw(output->win,0,1,"[ / ]"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,0,2,"%16llX",cursorpos1); + mvwprintw(output->win,0,19,"%16llX",hBuf1->bufsize); + } else { + mvwprintw(output->win,0,1,"[ / ]"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,0,2,"%8X",(tUInt32)cursorpos1); + mvwprintw(output->win,0,11,"%8X",(tUInt32)hBuf1->bufsize); + } + setcolor(output,COLOR_HEADER); + mvwprintw(output->win,0,COLS-2-strlen(hBuf1->filename),"%s",hBuf1->filename); + intpos1=getbufferidx(hBuf1,firstpos1); + if (intpos1>=0) + { + charcnt=0; + for (i=0;i<LINES-2;i++) + { + tBool colhex; + setcolor(output,COLOR_HEXFIELD); + if (addrwidth==8) mvwprintw(output->win,i+1,0, "% 8X ",(tUInt32)firstpos1); + else mvwprintw(output->win,i+1,0,"% 16llX ",firstpos1); + + mvwprintw(output->win,i+1,COLS-bytesperline-5," "); + wmove(output->win,i+1,addrwidth+3); + colhex=1; + for (j=0;j<bytesperline;j++) + { + tInt16 c; + if ((intpos1+j)<hBuf1->filesize) c=hBuf1->data[intpos1+j]; + else c=-1; + if (!(j&7)) wprintw(output->win," "); + wprintw(output->win," "); + for (k=0;k<hBuf1->changesnum;k++) + { + if (hBuf1->changes[k].pos==(firstpos1+j)) + { + setcolor(output,COLOR_DIFF); + c=hBuf1->changes[k].after; + colhex=0; + } + } + if (cursorpos1==(firstpos1+j) && windowfield==0) + { + setcolor(output,COLOR_INPUT); + colhex=0; + } + // TODO: setcolor(hBuf1->data[intpos1]!=buf2->data[intpos2]?COLOR_DIFF:COLOR_HEXFIELD); + if (c>=0) + { + if (hBuf1->nibble && hBuf1->changepos==(firstpos1+j)) + + wprintw(output->win,"%01x ",hBuf1->nexthex&0xf); + else + wprintw(output->win,"%02x",c&0xff); + } + else + wprintw(output->win," "); + + if (!colhex) setcolor(output,COLOR_HEXFIELD); + colhex=1; +// mvwprintw(output->win,i+1,addrwidth+5+j*3+j/8," "); + } + for (j=0;j<bytesperline;j++) + { + unsigned char c; + if (intpos1<hBuf1->filesize) + c=hBuf1->data[intpos1]; + else c=' '; + for (k=0;k<hBuf1->changesnum;k++) + { + if (hBuf1->changes[k].pos==(firstpos1)) + { + setcolor(output,COLOR_DIFF); + c=hBuf1->changes[k].after; + } + } + if (cursorpos1==firstpos1 && windowfield==1) setcolor(output,COLOR_INPUT); + // TODO: setcolor(buf1->data[intpos1]!=buf2->data[intpos2]?COLOR_DIFF:COLOR_HEXFIELD); + mvwprintw(output->win,i+1,COLS-bytesperline+j,"%c",(c>=32 && c<127)?c:'.'); + intpos1++; + firstpos1++; + setcolor(output,COLOR_HEXFIELD); + } + } + } +} +void printbufferdiff(tOutput* output,tBuffer* hBuf1,tBuffer* hBuf2,tInt64 cursorpos1,tInt64 cursorpos2) +{ + int i; + int j; + int addrwidth; + int bytesperline; + tInt32 intpos1; + tInt32 intpos1b; + tInt32 intpos2; + tInt32 intpos2b; + tInt32 charcnt; + uicolors oldcolor; + + + addrwidth=(hBuf1->bufsize>0xffffffffull || hBuf2->bufsize>0xffffffffull)?16:8; + bytesperline=(COLS-(addrwidth+3+3))*8/(8*3+8+1); // this many bytes can be printed in one line. every 8 bytes there is an extra space in the hex field. + + setcolor(output,COLOR_HEADLINE); + wmove(output->win,0,0); + for (i=0;i<COLS;i++) + { + waddch(output->win,ACS_HLINE); + } + wmove(output->win,LINES/2,0); + for (i=0;i<COLS;i++) + { + waddch(output->win,ACS_HLINE); + } + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,0,COLS-3-strlen(hBuf1->filename),"["); + mvwprintw(output->win,0,COLS-2,"]"); + mvwprintw(output->win,LINES/2,COLS-3-strlen(hBuf2->filename),"["); + mvwprintw(output->win,LINES/2,COLS-2,"]"); + if (addrwidth==16) + { + mvwprintw(output->win,0,1,"[ / ]"); + mvwprintw(output->win,LINES/2,1,"[ / ]"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,0,2,"%16llX",cursorpos1); + mvwprintw(output->win,0,19,"%16llX",hBuf1->bufsize); + mvwprintw(output->win,LINES/2,2,"%16llX",cursorpos1); + mvwprintw(output->win,LINES/2,19,"%16llX",hBuf1->bufsize); + + } else { + mvwprintw(output->win,0,1,"[ / ]"); + mvwprintw(output->win,LINES/2,1,"[ / ]"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,0,2,"%8X",(tUInt32)cursorpos1); + mvwprintw(output->win,0,11,"%8X",(tUInt32)hBuf1->bufsize); + mvwprintw(output->win,LINES/2,2,"%8X",(tUInt32)cursorpos2); + mvwprintw(output->win,LINES/2,11,"%8X",(tUInt32)hBuf2->bufsize); + } + setcolor(output,COLOR_HEADER); + mvwprintw(output->win,0,COLS-2-strlen(hBuf1->filename),"%s",hBuf1->filename); + mvwprintw(output->win,LINES/2,COLS-2-strlen(hBuf2->filename),"%s",hBuf2->filename); + if (cursorpos1<0) + { + getbufferidx(hBuf1,0); + intpos1=cursorpos1; + } else { + intpos1=getbufferidx(hBuf1,cursorpos1); + } + if (cursorpos2<0) + { + getbufferidx(hBuf2,0); + intpos2=cursorpos2; + } else { + intpos2=getbufferidx(hBuf2,cursorpos2); + } + if (intpos1>=0 || intpos2>=0) + { + charcnt=0; + intpos1b=intpos1; + intpos2b=intpos2; + + for (i=0;i<(LINES+1)/2-2;i++) + { + setcolor(output,COLOR_HEXFIELD); + if (addrwidth==8) mvwprintw(output->win,i+1,0, "% 8X ",(tUInt32)cursorpos1); + else mvwprintw(output->win,i+1,0,"% 16llX ",cursorpos1); + + mvwprintw(output->win,i+1,COLS-bytesperline-5," "); + oldcolor=COLOR_HEXFIELD; + wmove(output->win,i+1,addrwidth+3); + for (j=0;j<bytesperline;j++) + { + tInt16 c1,c2; + if ((intpos1+j)>=0 && (intpos1+j)<hBuf1->filesize) c1=hBuf1->data[intpos1+j]; + else c1=-1; + if ((intpos2+j)>=0 && (intpos2+j)<hBuf2->filesize) c2=hBuf2->data[intpos2+j]; + else c2=-1; + if (c1!=c2 && oldcolor==COLOR_HEXFIELD) + { + setcolor(output,COLOR_DIFF); + oldcolor=COLOR_DIFF; + } else if (c1==c2) { + setcolor(output,COLOR_HEXFIELD); + oldcolor=COLOR_HEXFIELD; + } + wprintw(output->win," "); + if (j!=(bytesperline-1)) + { + if (!(j&7)) wprintw(output->win," "); + } + if (c1>=0) + { + wprintw(output->win,"%02x",(c1&0xff)); + } + else + wprintw(output->win," "); + + } + wmove(output->win,i+1,COLS-bytesperline); + for (j=0;j<bytesperline;j++) + { + unsigned char c1,c2; + if (intpos1>=0 && intpos1<hBuf1->filesize) + c1=hBuf1->data[intpos1]; + else c1=' '; + if (intpos2>=0 && intpos2<hBuf2->filesize) + c2=hBuf2->data[intpos2]; + else c2=' '; + + if (c1!=c2 && oldcolor==COLOR_HEXFIELD) + { + setcolor(output,COLOR_DIFF); + oldcolor=COLOR_DIFF; + } else if (c1==c2) { + setcolor(output,COLOR_HEXFIELD); + oldcolor=COLOR_HEXFIELD; + } + wprintw(output->win,"%c",(c1>=32 && c1<127)?c1:'.'); + intpos1++; + cursorpos1++; + intpos2++; + } + } + oldcolor=COLOR_HEXFIELD; + setcolor(output,COLOR_HEXFIELD); + if (!(LINES&1)) + { + wmove(output->win,LINES/2-1,0); + for (i=0;i<COLS;i++) wprintw(output->win," "); + } + + intpos1=intpos1b; + intpos2=intpos2b; + for (i=0;i<(LINES+1)/2-2;i++) + { + setcolor(output,COLOR_HEXFIELD); + if (addrwidth==8) mvwprintw(output->win,i+1+LINES/2,0, "% 8X ",(tUInt32)cursorpos2); + else mvwprintw(output->win,i+1+LINES/2,0,"% 16llX ",cursorpos2); + + mvwprintw(output->win,i+1+LINES/2,COLS-bytesperline-5," "); + oldcolor=COLOR_HEXFIELD; + wmove(output->win,i+1+LINES/2,addrwidth+3); + for (j=0;j<bytesperline;j++) + { + tInt16 c1,c2; + if ((intpos1+j)>=0 && (intpos1+j)<hBuf1->filesize) c1=hBuf1->data[intpos1+j]; + else c1=-1; + if ((intpos2+j)>=0 && (intpos2+j)<hBuf2->filesize) c2=hBuf2->data[intpos2+j]; + else c2=-1; + if (c1!=c2 && oldcolor==COLOR_HEXFIELD) + { + setcolor(output,COLOR_DIFF); + oldcolor=COLOR_DIFF; + } else if (c1==c2) { + setcolor(output,COLOR_HEXFIELD); + oldcolor=COLOR_HEXFIELD; + } + wprintw(output->win," "); + if (j!=(bytesperline-1)) + { + if (!(j&7)) wprintw(output->win," "); + } + if (c2>=0) + { + wprintw(output->win,"%02x",(c2&0xff)); + } + else + wprintw(output->win," "); + + } + wmove(output->win,i+1+LINES/2,COLS-bytesperline); + for (j=0;j<bytesperline;j++) + { + unsigned char c1,c2; + if (intpos1>=0 && intpos1<hBuf1->filesize) + c1=hBuf1->data[intpos1]; + else c1=' '; + if (intpos2>=0 && intpos2<hBuf2->filesize) + c2=hBuf2->data[intpos2]; + else c2=' '; + + if (c1!=c2 && oldcolor==COLOR_HEXFIELD) + { + setcolor(output,COLOR_DIFF); + oldcolor=COLOR_DIFF; + } else if (c1==c2) { + setcolor(output,COLOR_HEXFIELD); + oldcolor=COLOR_HEXFIELD; + } + wprintw(output->win,"%c",(c2>=32 && c2<127)?c2:'.'); + intpos1++; + intpos2++; + cursorpos2++; + } + } + } +} +void printmainmenu(tOutput* output,tBool diffmode) +{ + int i; + int x; + unsigned char* menutextsnodiff[]={ +"Goto ", // F1 +"Search", // F2 +"Next ", // F3 +"Prev ", // F4 +"HexCal", // F5 +" ", // F6 +" ", // F7 +" ", // F8 +"Undo ", // F9 +"Quit "}; // F10 + + unsigned char* menutextsdiff[]={ +" ", // F1 +" ", // F2 +"Next ", // F3 +"Prev ", // F4 +"HexCal", // F5 +"Corr. ", // F6 +" ", // F7 +" ", // F8 +" ", // F9 +"Quit "}; // F10 + + setcolor(output,COLOR_MENUHOTKEY); + + x=0; + for (i=0;i<10;i++) + { + mvwprintw(output->win,LINES-1,x," %i",(i+1)%10); + x+=8; + } + setcolor(output,COLOR_MENUNORMAL); + x=2; + for (i=0;i<10;i++) + { + mvwprintw(output->win,LINES-1,x,"%s",diffmode?menutextsdiff[i]:menutextsnodiff[i]); + x+=8; + } + +} +tInt32 movepositions(tInt64* cursorpos,tInt64* firstpos,tInt64 maxbufsize,tInt32 chars,tInt32 lines,tInt32 pages,tBool diffmode) +{ + tInt32 bytesperline; + tInt32 bytesperhalfpage; + tInt32 bytesperpage; + tInt32 addrwidth; + + tInt64 newfirstpos=*firstpos; + tInt64 newcursorpos=*cursorpos; + + + addrwidth=(maxbufsize>0xffffffffull)?16:8; + bytesperline=(COLS-(addrwidth+3+3))*8/(8*3+8+1); // this many bytes can be printed in one line. every 8 bytes there is an extra space in the hex field. + bytesperhalfpage=bytesperline*(LINES/2-2); + bytesperpage=bytesperline*(LINES-2); + + + newcursorpos+=(chars+lines*bytesperline+pages*(diffmode?bytesperhalfpage:bytesperpage)); + if (newcursorpos>=(newfirstpos+(diffmode?bytesperhalfpage:bytesperpage)) || (newcursorpos<newfirstpos)) newfirstpos+=(chars+lines*bytesperline+pages*(diffmode?bytesperhalfpage:bytesperpage)); + + *firstpos=newfirstpos; + *cursorpos=newcursorpos; + if (newcursorpos<0 || newfirstpos<0 || newcursorpos>maxbufsize || newfirstpos>maxbufsize) return RETNOK; + return RETOK; + +} diff --git a/output.h b/output.h new file mode 100644 index 0000000..cef29e9 --- /dev/null +++ b/output.h @@ -0,0 +1,21 @@ +#ifndef OUTPUT_H +#define OUTPUT_H + +#include <stdio.h> +#include <ncurses.h> +#include "buffers.h" +#include "machine_type.h" +#include "datatypes.h" + +void initcolors(); +void colorpair(tOutput* output,uicolors uicol,short fg,short bg,int attr); +void pairsinit(tOutput* output); +void setcolor(tOutput* output,uicolors col); +void printbuffersingle(tOutput* output,tBuffer* hBuf1,tInt64 cursorpos1,tUInt64 firstpos1,tUInt8 windowfield); +void printbufferdiff(tOutput* output,tBuffer* hBuf1,tBuffer* hBuf2,tInt64 cursorpos1,tInt64 cursorpos2); +void printmainmenu(tOutput* output,tBool diffmode); +void drawframe(tOutput* output,tInt16 y,tInt16 x,tInt8 h,tInt8 w,char* header); +void drawcenterframe(tOutput* output,tInt8 h,tInt8 w,char* header); +tInt32 movepositions(tInt64* cursorpos,tInt64* firstpos,tInt64 maxbufsize,tInt32 chars,tInt32 lines,tInt32 pages,tBool diffmode); + +#endif diff --git a/search.c b/search.c new file mode 100644 index 0000000..5a7370e --- /dev/null +++ b/search.c @@ -0,0 +1,139 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include "search.h" +#include "buffers.h" +#include "machine_type.h" + +void clearsearch(tSearch* search) +{ + memset(search,0,sizeof(tSearch)); + search->forwardnotbackward=1; +} +tInt8 searchfor(tSearch* search,tBuffer* buf,tUInt64* cursorpos,tBool nextnotprev) +{ + tInt64 actcursorpos=*cursorpos; + tInt64 oldcursorpos=*cursorpos; + tBool forward; + tBool done; + tBool found=0; + tFptr fwlog; + tFptr frlog; + unsigned char c; + tInt32 idx; + tBool increment; + tUInt64 searched=0; + int i; + + + forward=(search->forwardnotbackward==nextnotprev); + actcursorpos=actcursorpos+(forward?1:-1); + done=0; + frlog=NULL; + fwlog=NULL; + if (buf->bufsize<search->searchlen) oldcursorpos=0; + if (search->readsearchlog) + { + frlog=fopen(search->readlogfilename,"rb"); + + if (frlog==NULL) done=1; + else if (feof(frlog)) done=1; + } + if (search->writesearchlog) + { + fwlog=fopen(search->writelogfilename,"wb"); + + if (fwlog==NULL) done=1; + else { + fprintf(fwlog,"#DHEX SEARCHLOG\n"); + fprintf(fwlog,"#VERSION 0\n"); + fprintf(fwlog,"#Search was for"); + for (i=0;i<search->searchlen;i++) + { + fprintf(fwlog," %02x",((unsigned int)search->searchstring[i])&0xff); + } + fprintf(fwlog,"\n"); + fprintf(fwlog,"#lines are all in hex\n"); + } + } + increment=!search->writesearchlog; + while (!done && buf->bufsize) + { + found=0; + if (searched++>=buf->bufsize) done=1; // avoid any theoretical infinite loops + if (!search->readsearchlog) + { + if (increment) + { + actcursorpos=actcursorpos+(forward?1:-1); + if (actcursorpos<0) actcursorpos=buf->bufsize-search->searchlen-1; + if ((actcursorpos+search->searchlen)>=buf->bufsize) actcursorpos=0; + if (actcursorpos==oldcursorpos) done=1; + } + } else { + tUInt8 state=0; // state 0: skip the spaces at the beginning + // state 1: collect the number + // state 2: read until the end of the line + tUInt64 x=0; + tBool havenum; + tInt64 firstsearchlogpos; + + firstsearchlogpos=search->lastsearchlogpos; + + setfilepos(frlog,search->lastsearchlogpos); + havenum=0; + while (!done && !havenum) + { + c=32; + x=0; + state=0; + while (c>=32 && !done) + { + fread(&c,sizeof(char),1,frlog); + done=feof(frlog); + if (!done) + { + if (c=='#') state=2; + if (c>='a' && c<='z') c-=32; + if (state==0) if ((c>='0' && c<='9') || (c>='A' && c<='F')) state=1; + if (state==1) + { + havenum=1; // this is a valid line + if (c>='0' && c<='9') + { + x<<=4; + x|=(c-'0'); + } + else if (c>='A' && c<='F') + { + x<<=4; + x|=(c-'A'+10); + } else state=2; + } + } + } + } + actcursorpos=x; + search->lastsearchlogpos=getfilepos(frlog); + } + increment=1; + idx=getbufferidx(buf,actcursorpos); + if ((actcursorpos+search->searchlen)<=buf->bufsize) + found=(memcmp(&buf->data[idx],search->searchstring,search->searchlen)==0); + else found=0; + if (found) + { + search->occurancesfound++; + search->lastoccurance=actcursorpos; + if (search->writesearchlog) fprintf(fwlog,"%016llx\n",(tUInt64)actcursorpos); else done=1; + } + } + if (frlog) fclose(frlog); + if (fwlog) fclose(fwlog); + if (found && !search->writesearchlog) + { + *cursorpos=actcursorpos; + } + return RETOK; +} diff --git a/search.h b/search.h new file mode 100644 index 0000000..1928596 --- /dev/null +++ b/search.h @@ -0,0 +1,10 @@ +#ifndef SEARCH_H +#define SEARCH_H +#include "machine_type.h" +#include "buffers.h" +#include "datatypes.h" + +void clearsearch(tSearch* search); +tInt8 searchfor(tSearch* search,tBuffer* buf,tUInt64* cursorpos,tBool nextnotprev); + +#endif diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..8798b98 --- /dev/null +++ b/todo.txt @@ -0,0 +1,6 @@ +- error: when searching, the changes are being ignored +- feature: correlation +- feature: snapshot +- the length of input fields is restricted by the gui +- return value of dhex itself +- try compiling it under windows with cl.exe @@ -0,0 +1,207 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include <ncurses.h> +#include "machine_type.h" +#include "output.h" +#include "input.h" +#include "menu.h" +#include "search.h" +#include "correlation.h" + +void searchmask(tOutput* output,tSearch* search,tBuffer* buf,tUInt64* cursorpos) +{ + tInt8 itemnums[10]; + tMenu Menu1; + tInt8 selected; + tInt16 offsx; + tInt16 offsy; + int i; + + offsx=COLS/2-30; + offsy=LINES/2-7; + + drawcenterframe(output,14,60,"Search..."); + clearMenu(&Menu1); + + newMenuItem(&Menu1,"Searchstring: (hex)",1,1,'S',0,&itemnums[0]); + newMenuItem(&Menu1,"Searchstring: (asc)",3,1,0,0,&itemnums[1]); + newMenuItem(&Menu1,"Forward",4,1,'F',0,&itemnums[2]); + newMenuItem(&Menu1,"Backward",4,17,'B',0,&itemnums[3]); + newMenuItem(&Menu1,"Write to searchlog",6,1,'W',0,&itemnums[4]); + newMenuItem(&Menu1,"File:",7,1,0,0,&itemnums[5]); + newMenuItem(&Menu1,"Read from searchlog",9,1,'R',0,&itemnums[6]); + newMenuItem(&Menu1,"File:",10,1,0,0,&itemnums[7]); + newMenuItem(&Menu1,"Go",13,1,'G',0,&itemnums[8]); + newMenuItem(&Menu1,"Cancel",13,51,'C',1,&itemnums[9]); + selected=-1; + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,offsy+2,offsx+1,"[ ]"); + mvwprintw(output->win,offsy+3,offsx+38,"[ ]"); + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,offsy+4,offsx+11,"( )"); + mvwprintw(output->win,offsy+4,offsx+28,"( )"); + mvwprintw(output->win,offsy+6,offsx+22,"[ ]"); + mvwprintw(output->win,offsy+9,offsx+23,"[ ]"); + mvwprintw(output->win,offsy+7 ,offsx+7,"[ ]"); + mvwprintw(output->win,offsy+10,offsx+7,"[ ]"); + while (selected!=itemnums[8] && selected!=itemnums[9]) + { + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+4,offsx+12,"%c",search->forwardnotbackward?'o':' '); + mvwprintw(output->win,offsy+4,offsx+29,"%c",search->forwardnotbackward?' ':'o'); + mvwprintw(output->win,offsy+6,offsx+23,"%c",search->writesearchlog?'X':' '); + mvwprintw(output->win,offsy+9,offsx+24,"%c",search->readsearchlog?'X':' '); + setcolor(output,COLOR_TEXT); + for (i=0;i<19;i++) + { + if (i<search->searchlen) mvwprintw(output->win,offsy+2,offsx+2+i*3,"%02x",(tUInt32)(search->searchstring[i]&0xff)); + else mvwprintw(output->win,offsy+2,offsx+2+i*3," "); + + if (i<search->searchlen) mvwprintw(output->win,offsy+3,offsx+39+i,"%c",(search->searchstring[i]>=32 && search->searchstring[i]<127)?search->searchstring[i]:'.'); + else mvwprintw(output->win,offsy+3,offsx+39+i," "); + } + + selected=MenuInteract(output,&Menu1,offsy,offsx); + + if (selected==itemnums[0]) + { + hexinput2(output,offsy+2,offsx+1,search->searchstring,&search->searchlen,19); + } + if (selected==itemnums[1]) + { + char tmp[32]; + memset(tmp,0,32); + for (i=0;i<search->searchlen && i<19;i++) tmp[i]=(search->searchstring[i]>=32 && search->searchstring[i]<127)?search->searchstring[i]:'.'; + + if (stringinput(output,offsy+3,offsx+38,tmp,19)==KEYENTER) + { + search->searchlen=strlen(tmp); + memcpy(search->searchstring,tmp,19); + } + } + if (selected==itemnums[2]) search->forwardnotbackward=1; + if (selected==itemnums[3]) search->forwardnotbackward=0; + if (selected==itemnums[4]) search->writesearchlog=!search->writesearchlog; + if (selected==itemnums[5]) + { + stringinput(output,offsy+7,offsx+7,search->writelogfilename,50); + } + if (selected==itemnums[6]) search->readsearchlog=!search->readsearchlog; + if (selected==itemnums[7]) + { + stringinput(output,offsy+10,offsx+7,search->readlogfilename,50); + } + if (selected==itemnums[8]) + { + searchfor(search,buf,cursorpos,1); + if (search->writesearchlog) + { + drawcenterframe(output,14,60,"Found"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+13,offsx+1,"%lld occurances found",search->occurancesfound); + getkey((tKeyTab*)output->pKeyTab,1); + } + } + + } +} +tInt8 savedialog(tOutput* output,tBuffer* hBuf) +{ + tInt16 offsx; + tInt16 offsy; + tMenu Menu1; + tInt8 itemnums[3]; + tInt8 selected; + + offsx=COLS/2-13; + offsy=LINES/2-2; + + drawcenterframe(output,3,26,"Save changes?"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+2,offsx+1,"Save %12i byte%s",hBuf->changesnum,(hBuf->changesnum==1)?"?":"s?"); + clearMenu(&Menu1); + newMenuItem(&Menu1,"Yes",3,1,'Y',0,&itemnums[0]); + newMenuItem(&Menu1,"No",3,9,'N',0,&itemnums[1]); + newMenuItem(&Menu1,"Cancel",3,19,'C',1,&itemnums[2]); + selected=MenuInteract(output,&Menu1,offsy,offsx); + if (selected==itemnums[2]) return RETNOK; + if (selected==itemnums[0]) + { + if (savechanges(hBuf)!=RETOK) + { + drawcenterframe(output,3,22,"ERROR"); + setcolor(output,COLOR_TEXT); + mvwprintw(output->win,offsy+1,offsx+1,"Could not save\n"); + return RETNOK; + } + } + return RETOK; +} +tInt8 correlationmask(tOutput* output,tCorrelation* correlation) +{ + tInt16 offsx; + tInt16 offsy; + tMenu Menu1; + tInt8 itemnums[10]; + tInt8 selected; + tInt8 retval=RETOK; + tBool done=0; + + offsx=COLS/2-21; + offsy=LINES/2-3; + drawcenterframe(output,6,42,"Correlation"); + clearMenu(&Menu1); + newMenuItem(&Menu1,"best match",1,5,'B',0,&itemnums[0]); + newMenuItem(&Menu1,"longest match",2,5,'L',0,&itemnums[1]); + newMenuItem(&Menu1,"minimum difference",3,5,'D',0,&itemnums[2]); + newMenuItem(&Menu1,"upper diff limit",4,1,'S',0,&itemnums[3]); + newMenuItem(&Menu1,"Go",5,1,'G',0,&itemnums[4]); + newMenuItem(&Menu1,"Cancel",5,35,'C',1,&itemnums[5]); + selected=itemnums[0]; + while (!done) + { + setcolor(output,COLOR_BRACKETS); + mvwprintw(output->win,offsy+1,offsx+1,"( )"); + mvwprintw(output->win,offsy+2,offsx+1,"( )"); + mvwprintw(output->win,offsy+3,offsx+1,"( )"); + mvwprintw(output->win,offsy+4,offsx+22,"[ ]"); + setcolor(output,COLOR_TEXT); + switch(correlation->algorithm) + { + case CORR_BEST_MATCH: mvwprintw(output->win,offsy+1,offsx+2,"o");break; + case CORR_LONGEST_MATCH: mvwprintw(output->win,offsy+2,offsx+2,"o");break; + case CORR_MIN_DIFF: mvwprintw(output->win,offsy+3,offsx+2,"o");break; + } + mvwprintw(output->win,offsy+4,offsx+23,"%17lli",correlation->start_mindiff); + wrefresh(output->win); + selected=MenuInteract(output,&Menu1,offsy,offsx); + if (selected==itemnums[0]) + { + correlation->algorithm=CORR_BEST_MATCH; + } + if (selected==itemnums[1]) + { + correlation->algorithm=CORR_LONGEST_MATCH; + } + if (selected==itemnums[2]) + { + correlation->algorithm=CORR_MIN_DIFF; + } + if (selected==itemnums[3]) + { + decinput(output,offsy+4,offsx+22,&correlation->start_mindiff,18); + } + if (selected==itemnums[4]) + { + done=1; + retval=RETOK; + } + if (selected==itemnums[5]) { + done=1; + retval=RETNOK; + } + } + return retval; +} @@ -0,0 +1,11 @@ +#ifndef UI_H +#define UI_H +#include "machine_type.h" +#include "buffers.h" +#include "search.h" +#include "output.h" +#include "correlation.h" +void searchmask(tOutput* output,tSearch* search,tBuffer* buf,tUInt64* cursorpos); +tInt8 savedialog(tOutput* output,tBuffer* buf); +tInt8 correlationmask(tOutput* output,tCorrelation* correlation); +#endif |