1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/SRC/test_hexio.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,360 @@
1.4 +/*
1.5 +** 2007 April 6
1.6 +**
1.7 +** Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
1.8 +**
1.9 +** The author disclaims copyright to this source code. In place of
1.10 +** a legal notice, here is a blessing:
1.11 +**
1.12 +** May you do good and not evil.
1.13 +** May you find forgiveness for yourself and forgive others.
1.14 +** May you share freely, never taking more than you give.
1.15 +**
1.16 +*************************************************************************
1.17 +** Code for testing all sorts of SQLite interfaces. This code
1.18 +** implements TCL commands for reading and writing the binary
1.19 +** database files and displaying the content of those files as
1.20 +** hexadecimal. We could, in theory, use the built-in "binary"
1.21 +** command of TCL to do a lot of this, but there are some issues
1.22 +** with historical versions of the "binary" command. So it seems
1.23 +** easier and safer to build our own mechanism.
1.24 +**
1.25 +** $Id: test_hexio.c,v 1.7 2008/05/12 16:17:42 drh Exp $
1.26 +*/
1.27 +#include "sqliteInt.h"
1.28 +#include "tcl.h"
1.29 +#include <stdlib.h>
1.30 +#include <string.h>
1.31 +#include <assert.h>
1.32 +#include <unistd.h>
1.33 +#include <sys/param.h>
1.34 +
1.35 +extern char* FullFilePath(char* aPath, const char* aFileName);
1.36 +
1.37 +/* Symbian OS - often TCL scripts attempt to open a file just using the file name without path.
1.38 + This is not working on the hardware. The function bellow will contstruct the full file name. */
1.39 +extern char* GetFullFilePath(char* aPath, const char* aFileName)
1.40 + {
1.41 + return FullFilePath(aPath, aFileName);
1.42 + }
1.43 +
1.44 +/*
1.45 +** Convert binary to hex. The input zBuf[] contains N bytes of
1.46 +** binary data. zBuf[] is 2*n+1 bytes long. Overwrite zBuf[]
1.47 +** with a hexadecimal representation of its original binary input.
1.48 +*/
1.49 +void sqlite3TestBinToHex(unsigned char *zBuf, int N){
1.50 + const unsigned char zHex[] = "0123456789ABCDEF";
1.51 + int i, j;
1.52 + unsigned char c;
1.53 + i = N*2;
1.54 + zBuf[i--] = 0;
1.55 + for(j=N-1; j>=0; j--){
1.56 + c = zBuf[j];
1.57 + zBuf[i--] = zHex[c&0xf];
1.58 + zBuf[i--] = zHex[c>>4];
1.59 + }
1.60 + assert( i==-1 );
1.61 +}
1.62 +
1.63 +/*
1.64 +** Convert hex to binary. The input zIn[] contains N bytes of
1.65 +** hexadecimal. Convert this into binary and write aOut[] with
1.66 +** the binary data. Spaces in the original input are ignored.
1.67 +** Return the number of bytes of binary rendered.
1.68 +*/
1.69 +int sqlite3TestHexToBin(const unsigned char *zIn, int N, unsigned char *aOut){
1.70 + const unsigned char aMap[] = {
1.71 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.72 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.73 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.74 + 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0,
1.75 + 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.76 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.77 + 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.78 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.79 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.80 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.81 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.82 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.83 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.84 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.85 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.86 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.87 + };
1.88 + int i, j;
1.89 + int hi=1;
1.90 + unsigned char c;
1.91 +
1.92 + for(i=j=0; i<N; i++){
1.93 + c = aMap[zIn[i]];
1.94 + if( c==0 ) continue;
1.95 + if( hi ){
1.96 + aOut[j] = (c-1)<<4;
1.97 + hi = 0;
1.98 + }else{
1.99 + aOut[j++] |= c-1;
1.100 + hi = 1;
1.101 + }
1.102 + }
1.103 + return j;
1.104 +}
1.105 +
1.106 +
1.107 +/*
1.108 +** Usage: hexio_read FILENAME OFFSET AMT
1.109 +**
1.110 +** Read AMT bytes from file FILENAME beginning at OFFSET from the
1.111 +** beginning of the file. Convert that information to hexadecimal
1.112 +** and return the resulting HEX string.
1.113 +*/
1.114 +static int hexio_read(
1.115 + void * clientData,
1.116 + Tcl_Interp *interp,
1.117 + int objc,
1.118 + Tcl_Obj *CONST objv[]
1.119 +){
1.120 + int offset;
1.121 + int amt, got;
1.122 + const char *zFile;
1.123 + unsigned char *zBuf;
1.124 + FILE *in;
1.125 + char fnamebuf[MAXPATHLEN + 1];
1.126 +
1.127 + if( objc!=4 ){
1.128 + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET AMT");
1.129 + return TCL_ERROR;
1.130 + }
1.131 + if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR;
1.132 + if( Tcl_GetIntFromObj(interp, objv[3], &amt) ) return TCL_ERROR;
1.133 + zFile = Tcl_GetString(objv[1]);
1.134 + zBuf = sqlite3_malloc( amt*2+1 );
1.135 + if( zBuf==0 ){
1.136 + return TCL_ERROR;
1.137 + }
1.138 + if(GetFullFilePath(fnamebuf, zFile) == 0)
1.139 + return TCL_ERROR;
1.140 + in = fopen(fnamebuf, "rb");
1.141 + if( in==0 ){
1.142 + in = fopen(fnamebuf, "r");
1.143 + }
1.144 + if( in==0 ){
1.145 + Tcl_AppendResult(interp, "cannot open input file ", fnamebuf, 0);
1.146 + return TCL_ERROR;
1.147 + }
1.148 + fseek(in, offset, SEEK_SET);
1.149 + got = fread(zBuf, 1, amt, in);
1.150 + fclose(in);
1.151 + if( got<0 ){
1.152 + got = 0;
1.153 + }
1.154 + sqlite3TestBinToHex(zBuf, got);
1.155 + Tcl_AppendResult(interp, zBuf, 0);
1.156 + sqlite3_free(zBuf);
1.157 + return TCL_OK;
1.158 +}
1.159 +
1.160 +
1.161 +/*
1.162 +** Usage: hexio_write FILENAME OFFSET DATA
1.163 +**
1.164 +** Write DATA into file FILENAME beginning at OFFSET from the
1.165 +** beginning of the file. DATA is expressed in hexadecimal.
1.166 +*/
1.167 +static int hexio_write(
1.168 + void * clientData,
1.169 + Tcl_Interp *interp,
1.170 + int objc,
1.171 + Tcl_Obj *CONST objv[]
1.172 +){
1.173 + int offset;
1.174 + int nIn, nOut, written;
1.175 + const char *zFile;
1.176 + const unsigned char *zIn;
1.177 + unsigned char *aOut;
1.178 + FILE *out;
1.179 + char fnamebuf[MAXPATHLEN + 1];
1.180 +
1.181 + if( objc!=4 ){
1.182 + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET HEXDATA");
1.183 + return TCL_ERROR;
1.184 + }
1.185 + if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR;
1.186 + zFile = Tcl_GetString(objv[1]);
1.187 + zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn);
1.188 + aOut = sqlite3_malloc( nIn/2 );
1.189 + if( aOut==0 ){
1.190 + return TCL_ERROR;
1.191 + }
1.192 + nOut = sqlite3TestHexToBin(zIn, nIn, aOut);
1.193 + if(GetFullFilePath(fnamebuf, zFile) == 0)
1.194 + return TCL_ERROR;
1.195 + out = fopen(fnamebuf, "r+b");
1.196 + if( out==0 ){
1.197 + out = fopen(fnamebuf, "r+");
1.198 + }
1.199 + if( out==0 ){
1.200 + Tcl_AppendResult(interp, "cannot open output file ", fnamebuf, 0);
1.201 + return TCL_ERROR;
1.202 + }
1.203 + fseek(out, offset, SEEK_SET);
1.204 + written = fwrite(aOut, 1, nOut, out);
1.205 + sqlite3_free(aOut);
1.206 + fclose(out);
1.207 + Tcl_SetObjResult(interp, Tcl_NewIntObj(written));
1.208 + return TCL_OK;
1.209 +}
1.210 +
1.211 +/*
1.212 +** USAGE: hexio_get_int HEXDATA
1.213 +**
1.214 +** Interpret the HEXDATA argument as a big-endian integer. Return
1.215 +** the value of that integer. HEXDATA can contain between 2 and 8
1.216 +** hexadecimal digits.
1.217 +*/
1.218 +static int hexio_get_int(
1.219 + void * clientData,
1.220 + Tcl_Interp *interp,
1.221 + int objc,
1.222 + Tcl_Obj *CONST objv[]
1.223 +){
1.224 + int val;
1.225 + int nIn, nOut;
1.226 + const unsigned char *zIn;
1.227 + unsigned char *aOut;
1.228 + unsigned char aNum[4];
1.229 +
1.230 + if( objc!=2 ){
1.231 + Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA");
1.232 + return TCL_ERROR;
1.233 + }
1.234 + zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn);
1.235 + aOut = sqlite3_malloc( nIn/2 );
1.236 + if( aOut==0 ){
1.237 + return TCL_ERROR;
1.238 + }
1.239 + nOut = sqlite3TestHexToBin(zIn, nIn, aOut);
1.240 + if( nOut>=4 ){
1.241 + memcpy(aNum, aOut, 4);
1.242 + }else{
1.243 + memset(aNum, 0, sizeof(aNum));
1.244 + memcpy(&aNum[4-nOut], aOut, nOut);
1.245 + }
1.246 + sqlite3_free(aOut);
1.247 + val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3];
1.248 + Tcl_SetObjResult(interp, Tcl_NewIntObj(val));
1.249 + return TCL_OK;
1.250 +}
1.251 +
1.252 +
1.253 +/*
1.254 +** USAGE: hexio_render_int16 INTEGER
1.255 +**
1.256 +** Render INTEGER has a 16-bit big-endian integer in hexadecimal.
1.257 +*/
1.258 +static int hexio_render_int16(
1.259 + void * clientData,
1.260 + Tcl_Interp *interp,
1.261 + int objc,
1.262 + Tcl_Obj *CONST objv[]
1.263 +){
1.264 + int val;
1.265 + unsigned char aNum[10];
1.266 +
1.267 + if( objc!=2 ){
1.268 + Tcl_WrongNumArgs(interp, 1, objv, "INTEGER");
1.269 + return TCL_ERROR;
1.270 + }
1.271 + if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR;
1.272 + aNum[0] = val>>8;
1.273 + aNum[1] = val;
1.274 + sqlite3TestBinToHex(aNum, 2);
1.275 + Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 4));
1.276 + return TCL_OK;
1.277 +}
1.278 +
1.279 +
1.280 +/*
1.281 +** USAGE: hexio_render_int32 INTEGER
1.282 +**
1.283 +** Render INTEGER has a 32-bit big-endian integer in hexadecimal.
1.284 +*/
1.285 +static int hexio_render_int32(
1.286 + void * clientData,
1.287 + Tcl_Interp *interp,
1.288 + int objc,
1.289 + Tcl_Obj *CONST objv[]
1.290 +){
1.291 + int val;
1.292 + unsigned char aNum[10];
1.293 +
1.294 + if( objc!=2 ){
1.295 + Tcl_WrongNumArgs(interp, 1, objv, "INTEGER");
1.296 + return TCL_ERROR;
1.297 + }
1.298 + if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR;
1.299 + aNum[0] = val>>24;
1.300 + aNum[1] = val>>16;
1.301 + aNum[2] = val>>8;
1.302 + aNum[3] = val;
1.303 + sqlite3TestBinToHex(aNum, 4);
1.304 + Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 8));
1.305 + return TCL_OK;
1.306 +}
1.307 +
1.308 +/*
1.309 +** USAGE: utf8_to_utf8 HEX
1.310 +**
1.311 +** The argument is a UTF8 string represented in hexadecimal.
1.312 +** The UTF8 might not be well-formed. Run this string through
1.313 +** sqlite3Utf8to8() convert it back to hex and return the result.
1.314 +*/
1.315 +static int utf8_to_utf8(
1.316 + void * clientData,
1.317 + Tcl_Interp *interp,
1.318 + int objc,
1.319 + Tcl_Obj *CONST objv[]
1.320 +){
1.321 +#ifdef SQLITE_DEBUG
1.322 + int n;
1.323 + int nOut;
1.324 + const unsigned char *zOrig;
1.325 + unsigned char *z;
1.326 + if( objc!=2 ){
1.327 + Tcl_WrongNumArgs(interp, 1, objv, "HEX");
1.328 + return TCL_ERROR;
1.329 + }
1.330 + zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n);
1.331 + z = sqlite3_malloc( n+3 );
1.332 + n = sqlite3TestHexToBin(zOrig, n, z);
1.333 + z[n] = 0;
1.334 + nOut = sqlite3Utf8To8(z);
1.335 + sqlite3TestBinToHex(z,nOut);
1.336 + Tcl_AppendResult(interp, (char*)z, 0);
1.337 + sqlite3_free(z);
1.338 +#endif
1.339 + return TCL_OK;
1.340 +}
1.341 +
1.342 +
1.343 +/*
1.344 +** Register commands with the TCL interpreter.
1.345 +*/
1.346 +int Sqlitetest_hexio_Init(Tcl_Interp *interp){
1.347 + static struct {
1.348 + char *zName;
1.349 + Tcl_ObjCmdProc *xProc;
1.350 + } aObjCmd[] = {
1.351 + { "hexio_read", hexio_read },
1.352 + { "hexio_write", hexio_write },
1.353 + { "hexio_get_int", hexio_get_int },
1.354 + { "hexio_render_int16", hexio_render_int16 },
1.355 + { "hexio_render_int32", hexio_render_int32 },
1.356 + { "utf8_to_utf8", utf8_to_utf8 },
1.357 + };
1.358 + int i;
1.359 + for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
1.360 + Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
1.361 + }
1.362 + return TCL_OK;
1.363 +}