sl@0: /* sl@0: ** 2007 April 6 sl@0: ** sl@0: ** Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiaries. All rights reserved. sl@0: ** sl@0: ** The author disclaims copyright to this source code. In place of sl@0: ** a legal notice, here is a blessing: sl@0: ** sl@0: ** May you do good and not evil. sl@0: ** May you find forgiveness for yourself and forgive others. sl@0: ** May you share freely, never taking more than you give. sl@0: ** sl@0: ************************************************************************* sl@0: ** Code for testing all sorts of SQLite interfaces. This code sl@0: ** implements TCL commands for reading and writing the binary sl@0: ** database files and displaying the content of those files as sl@0: ** hexadecimal. We could, in theory, use the built-in "binary" sl@0: ** command of TCL to do a lot of this, but there are some issues sl@0: ** with historical versions of the "binary" command. So it seems sl@0: ** easier and safer to build our own mechanism. sl@0: ** sl@0: ** $Id: test_hexio.c,v 1.7 2008/05/12 16:17:42 drh Exp $ sl@0: */ sl@0: #include "sqliteInt.h" sl@0: #include "tcl.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: extern char* FullFilePath(char* aPath, const char* aFileName); sl@0: sl@0: /* Symbian OS - often TCL scripts attempt to open a file just using the file name without path. sl@0: This is not working on the hardware. The function bellow will contstruct the full file name. */ sl@0: extern char* GetFullFilePath(char* aPath, const char* aFileName) sl@0: { sl@0: return FullFilePath(aPath, aFileName); sl@0: } sl@0: sl@0: /* sl@0: ** Convert binary to hex. The input zBuf[] contains N bytes of sl@0: ** binary data. zBuf[] is 2*n+1 bytes long. Overwrite zBuf[] sl@0: ** with a hexadecimal representation of its original binary input. sl@0: */ sl@0: void sqlite3TestBinToHex(unsigned char *zBuf, int N){ sl@0: const unsigned char zHex[] = "0123456789ABCDEF"; sl@0: int i, j; sl@0: unsigned char c; sl@0: i = N*2; sl@0: zBuf[i--] = 0; sl@0: for(j=N-1; j>=0; j--){ sl@0: c = zBuf[j]; sl@0: zBuf[i--] = zHex[c&0xf]; sl@0: zBuf[i--] = zHex[c>>4]; sl@0: } sl@0: assert( i==-1 ); sl@0: } sl@0: sl@0: /* sl@0: ** Convert hex to binary. The input zIn[] contains N bytes of sl@0: ** hexadecimal. Convert this into binary and write aOut[] with sl@0: ** the binary data. Spaces in the original input are ignored. sl@0: ** Return the number of bytes of binary rendered. sl@0: */ sl@0: int sqlite3TestHexToBin(const unsigned char *zIn, int N, unsigned char *aOut){ sl@0: const unsigned char aMap[] = { sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0, sl@0: 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sl@0: }; sl@0: int i, j; sl@0: int hi=1; sl@0: unsigned char c; sl@0: sl@0: for(i=j=0; i=4 ){ sl@0: memcpy(aNum, aOut, 4); sl@0: }else{ sl@0: memset(aNum, 0, sizeof(aNum)); sl@0: memcpy(&aNum[4-nOut], aOut, nOut); sl@0: } sl@0: sqlite3_free(aOut); sl@0: val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3]; sl@0: Tcl_SetObjResult(interp, Tcl_NewIntObj(val)); sl@0: return TCL_OK; sl@0: } sl@0: sl@0: sl@0: /* sl@0: ** USAGE: hexio_render_int16 INTEGER sl@0: ** sl@0: ** Render INTEGER has a 16-bit big-endian integer in hexadecimal. sl@0: */ sl@0: static int hexio_render_int16( sl@0: void * clientData, sl@0: Tcl_Interp *interp, sl@0: int objc, sl@0: Tcl_Obj *CONST objv[] sl@0: ){ sl@0: int val; sl@0: unsigned char aNum[10]; sl@0: sl@0: if( objc!=2 ){ sl@0: Tcl_WrongNumArgs(interp, 1, objv, "INTEGER"); sl@0: return TCL_ERROR; sl@0: } sl@0: if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR; sl@0: aNum[0] = val>>8; sl@0: aNum[1] = val; sl@0: sqlite3TestBinToHex(aNum, 2); sl@0: Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 4)); sl@0: return TCL_OK; sl@0: } sl@0: sl@0: sl@0: /* sl@0: ** USAGE: hexio_render_int32 INTEGER sl@0: ** sl@0: ** Render INTEGER has a 32-bit big-endian integer in hexadecimal. sl@0: */ sl@0: static int hexio_render_int32( sl@0: void * clientData, sl@0: Tcl_Interp *interp, sl@0: int objc, sl@0: Tcl_Obj *CONST objv[] sl@0: ){ sl@0: int val; sl@0: unsigned char aNum[10]; sl@0: sl@0: if( objc!=2 ){ sl@0: Tcl_WrongNumArgs(interp, 1, objv, "INTEGER"); sl@0: return TCL_ERROR; sl@0: } sl@0: if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR; sl@0: aNum[0] = val>>24; sl@0: aNum[1] = val>>16; sl@0: aNum[2] = val>>8; sl@0: aNum[3] = val; sl@0: sqlite3TestBinToHex(aNum, 4); sl@0: Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 8)); sl@0: return TCL_OK; sl@0: } sl@0: sl@0: /* sl@0: ** USAGE: utf8_to_utf8 HEX sl@0: ** sl@0: ** The argument is a UTF8 string represented in hexadecimal. sl@0: ** The UTF8 might not be well-formed. Run this string through sl@0: ** sqlite3Utf8to8() convert it back to hex and return the result. sl@0: */ sl@0: static int utf8_to_utf8( sl@0: void * clientData, sl@0: Tcl_Interp *interp, sl@0: int objc, sl@0: Tcl_Obj *CONST objv[] sl@0: ){ sl@0: #ifdef SQLITE_DEBUG sl@0: int n; sl@0: int nOut; sl@0: const unsigned char *zOrig; sl@0: unsigned char *z; sl@0: if( objc!=2 ){ sl@0: Tcl_WrongNumArgs(interp, 1, objv, "HEX"); sl@0: return TCL_ERROR; sl@0: } sl@0: zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n); sl@0: z = sqlite3_malloc( n+3 ); sl@0: n = sqlite3TestHexToBin(zOrig, n, z); sl@0: z[n] = 0; sl@0: nOut = sqlite3Utf8To8(z); sl@0: sqlite3TestBinToHex(z,nOut); sl@0: Tcl_AppendResult(interp, (char*)z, 0); sl@0: sqlite3_free(z); sl@0: #endif sl@0: return TCL_OK; sl@0: } sl@0: sl@0: sl@0: /* sl@0: ** Register commands with the TCL interpreter. sl@0: */ sl@0: int Sqlitetest_hexio_Init(Tcl_Interp *interp){ sl@0: static struct { sl@0: char *zName; sl@0: Tcl_ObjCmdProc *xProc; sl@0: } aObjCmd[] = { sl@0: { "hexio_read", hexio_read }, sl@0: { "hexio_write", hexio_write }, sl@0: { "hexio_get_int", hexio_get_int }, sl@0: { "hexio_render_int16", hexio_render_int16 }, sl@0: { "hexio_render_int32", hexio_render_int32 }, sl@0: { "utf8_to_utf8", utf8_to_utf8 }, sl@0: }; sl@0: int i; sl@0: for(i=0; i