/* ** 2007 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** implements TCL commands for reading and writing the binary ** database files and displaying the content of those files as ** hexadecimal. We could, in theory, use the built-in "binary" ** command of TCL to do a lot of this, but there are some issues ** with historical versions of the "binary" command. So it seems ** easier and safer to build our own mechanism. ** ** $Id: test_hexio.c,v 1.2 2007/04/09 20:30:11 drh Exp $ */ #include "tcl.h" #include #include #include /* hexio_read filename offset amt hexio_write filename offset hexdata hexio_get_int hexdata hexio_get_varint hexdata hexio_render_int8 integer hexio_render_int16 integer hexio_render_int38 integer hexio_render_varint integer */ /* ** Convert binary to hex. The input zBuf[] contains N bytes of ** binary data. zBuf[] is 2*n+1 bytes long. Overwrite zBuf[] ** with a hexadecimal representation of its original binary input. */ static void binToHex(unsigned char *zBuf, int N){ const unsigned char zHex[] = "0123456789ABCDEF"; int i, j; unsigned char c; i = N*2; zBuf[i--] = 0; for(j=N-1; j>=0; j--){ c = zBuf[j]; zBuf[i--] = zHex[c&0xf]; zBuf[i--] = zHex[c>>4]; } assert( i==-1 ); } /* ** Convert hex to binary. The input zIn[] contains N bytes of ** hexadecimal. Convert this into binary and write aOut[] with ** the binary data. Spaces in the original input are ignored. ** Return the number of bytes of binary rendered. */ static int hexToBin(const unsigned char *zIn, int N, unsigned char *aOut){ const unsigned char aMap[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0, 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; int i, j; int hi=1; unsigned char c; for(i=j=0; i=4 ){ memcpy(aNum, aOut, 4); }else{ memset(aNum, 0, sizeof(aNum)); memcpy(&aNum[4-nOut], aOut, nOut); } free(aOut); val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3]; Tcl_SetObjResult(interp, Tcl_NewIntObj(val)); return TCL_OK; } /* ** USAGE: hexio_render_int16 INTEGER ** ** Render INTEGER has a 16-bit big-endian integer in hexadecimal. */ static int hexio_render_int16( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int val; unsigned char aNum[10]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "INTEGER"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR; aNum[0] = val>>8; aNum[1] = val; binToHex(aNum, 2); Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 4)); return TCL_OK; } /* ** USAGE: hexio_render_int32 INTEGER ** ** Render INTEGER has a 32-bit big-endian integer in hexadecimal. */ static int hexio_render_int32( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int val; unsigned char aNum[10]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "INTEGER"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR; aNum[0] = val>>24; aNum[1] = val>>16; aNum[2] = val>>8; aNum[3] = val; binToHex(aNum, 4); Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 8)); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest_hexio_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; } aObjCmd[] = { { "hexio_read", hexio_read }, { "hexio_write", hexio_write }, { "hexio_get_int", hexio_get_int }, { "hexio_render_int16", hexio_render_int16 }, { "hexio_render_int32", hexio_render_int32 }, }; int i; for(i=0; i