| OLD | NEW | 
 | (Empty) | 
|    1 /* |  | 
|    2 ** 2001 September 15 |  | 
|    3 ** |  | 
|    4 ** The author disclaims copyright to this source code.  In place of |  | 
|    5 ** a legal notice, here is a blessing: |  | 
|    6 ** |  | 
|    7 **    May you do good and not evil. |  | 
|    8 **    May you find forgiveness for yourself and forgive others. |  | 
|    9 **    May you share freely, never taking more than you give. |  | 
|   10 ** |  | 
|   11 ************************************************************************* |  | 
|   12 ** Code for testing the utf.c module in SQLite.  This code |  | 
|   13 ** is not included in the SQLite library.  It is used for automated |  | 
|   14 ** testing of the SQLite library. Specifically, the code in this file |  | 
|   15 ** is used for testing the SQLite routines for converting between |  | 
|   16 ** the various supported unicode encodings. |  | 
|   17 ** |  | 
|   18 ** $Id: test5.c,v 1.22 2008/08/12 15:04:59 danielk1977 Exp $ |  | 
|   19 */ |  | 
|   20 #include "sqliteInt.h" |  | 
|   21 #include "vdbeInt.h" |  | 
|   22 #include "tcl.h" |  | 
|   23 #include <stdlib.h> |  | 
|   24 #include <string.h> |  | 
|   25  |  | 
|   26 /* |  | 
|   27 ** The first argument is a TCL UTF-8 string. Return the byte array |  | 
|   28 ** object with the encoded representation of the string, including |  | 
|   29 ** the NULL terminator. |  | 
|   30 */ |  | 
|   31 static int binarize( |  | 
|   32   void * clientData, |  | 
|   33   Tcl_Interp *interp, |  | 
|   34   int objc, |  | 
|   35   Tcl_Obj *CONST objv[] |  | 
|   36 ){ |  | 
|   37   int len; |  | 
|   38   char *bytes; |  | 
|   39   Tcl_Obj *pRet; |  | 
|   40   assert(objc==2); |  | 
|   41  |  | 
|   42   bytes = Tcl_GetStringFromObj(objv[1], &len); |  | 
|   43   pRet = Tcl_NewByteArrayObj((u8*)bytes, len+1); |  | 
|   44   Tcl_SetObjResult(interp, pRet); |  | 
|   45   return TCL_OK; |  | 
|   46 } |  | 
|   47  |  | 
|   48 /* |  | 
|   49 ** Usage: test_value_overhead <repeat-count> <do-calls>. |  | 
|   50 ** |  | 
|   51 ** This routine is used to test the overhead of calls to |  | 
|   52 ** sqlite3_value_text(), on a value that contains a UTF-8 string. The idea |  | 
|   53 ** is to figure out whether or not it is a problem to use sqlite3_value |  | 
|   54 ** structures with collation sequence functions. |  | 
|   55 ** |  | 
|   56 ** If <do-calls> is 0, then the calls to sqlite3_value_text() are not |  | 
|   57 ** actually made. |  | 
|   58 */ |  | 
|   59 static int test_value_overhead( |  | 
|   60   void * clientData, |  | 
|   61   Tcl_Interp *interp, |  | 
|   62   int objc, |  | 
|   63   Tcl_Obj *CONST objv[] |  | 
|   64 ){ |  | 
|   65   int do_calls; |  | 
|   66   int repeat_count; |  | 
|   67   int i; |  | 
|   68   Mem val; |  | 
|   69   const char *zVal; |  | 
|   70  |  | 
|   71   if( objc!=3 ){ |  | 
|   72     Tcl_AppendResult(interp, "wrong # args: should be \"", |  | 
|   73         Tcl_GetStringFromObj(objv[0], 0), " <repeat-count> <do-calls>", 0); |  | 
|   74     return TCL_ERROR; |  | 
|   75   } |  | 
|   76  |  | 
|   77   if( Tcl_GetIntFromObj(interp, objv[1], &repeat_count) ) return TCL_ERROR; |  | 
|   78   if( Tcl_GetIntFromObj(interp, objv[2], &do_calls) ) return TCL_ERROR; |  | 
|   79  |  | 
|   80   val.flags = MEM_Str|MEM_Term|MEM_Static; |  | 
|   81   val.z = "hello world"; |  | 
|   82   val.type = SQLITE_TEXT; |  | 
|   83   val.enc = SQLITE_UTF8; |  | 
|   84  |  | 
|   85   for(i=0; i<repeat_count; i++){ |  | 
|   86     if( do_calls ){ |  | 
|   87       zVal = (char*)sqlite3_value_text(&val); |  | 
|   88     } |  | 
|   89   } |  | 
|   90  |  | 
|   91   return TCL_OK; |  | 
|   92 } |  | 
|   93  |  | 
|   94 static u8 name_to_enc(Tcl_Interp *interp, Tcl_Obj *pObj){ |  | 
|   95   struct EncName { |  | 
|   96     char *zName; |  | 
|   97     u8 enc; |  | 
|   98   } encnames[] = { |  | 
|   99     { "UTF8", SQLITE_UTF8 }, |  | 
|  100     { "UTF16LE", SQLITE_UTF16LE }, |  | 
|  101     { "UTF16BE", SQLITE_UTF16BE }, |  | 
|  102     { "UTF16", SQLITE_UTF16 }, |  | 
|  103     { 0, 0 } |  | 
|  104   }; |  | 
|  105   struct EncName *pEnc; |  | 
|  106   char *z = Tcl_GetString(pObj); |  | 
|  107   for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ |  | 
|  108     if( 0==sqlite3StrICmp(z, pEnc->zName) ){ |  | 
|  109       break; |  | 
|  110     } |  | 
|  111   } |  | 
|  112   if( !pEnc->enc ){ |  | 
|  113     Tcl_AppendResult(interp, "No such encoding: ", z, 0); |  | 
|  114   } |  | 
|  115   if( pEnc->enc==SQLITE_UTF16 ){ |  | 
|  116     return SQLITE_UTF16NATIVE; |  | 
|  117   } |  | 
|  118   return pEnc->enc; |  | 
|  119 } |  | 
|  120  |  | 
|  121 /* |  | 
|  122 ** Usage:   test_translate <string/blob> <from enc> <to enc> ?<transient>? |  | 
|  123 ** |  | 
|  124 */ |  | 
|  125 static int test_translate( |  | 
|  126   void * clientData, |  | 
|  127   Tcl_Interp *interp, |  | 
|  128   int objc, |  | 
|  129   Tcl_Obj *CONST objv[] |  | 
|  130 ){ |  | 
|  131   u8 enc_from; |  | 
|  132   u8 enc_to; |  | 
|  133   sqlite3_value *pVal; |  | 
|  134  |  | 
|  135   char *z; |  | 
|  136   int len; |  | 
|  137   void (*xDel)(void *p) = SQLITE_STATIC; |  | 
|  138  |  | 
|  139   if( objc!=4 && objc!=5 ){ |  | 
|  140     Tcl_AppendResult(interp, "wrong # args: should be \"", |  | 
|  141         Tcl_GetStringFromObj(objv[0], 0),  |  | 
|  142         " <string/blob> <from enc> <to enc>", 0 |  | 
|  143     ); |  | 
|  144     return TCL_ERROR; |  | 
|  145   } |  | 
|  146   if( objc==5 ){ |  | 
|  147     xDel = sqlite3_free; |  | 
|  148   } |  | 
|  149  |  | 
|  150   enc_from = name_to_enc(interp, objv[2]); |  | 
|  151   if( !enc_from ) return TCL_ERROR; |  | 
|  152   enc_to = name_to_enc(interp, objv[3]); |  | 
|  153   if( !enc_to ) return TCL_ERROR; |  | 
|  154  |  | 
|  155   pVal = sqlite3ValueNew(0); |  | 
|  156  |  | 
|  157   if( enc_from==SQLITE_UTF8 ){ |  | 
|  158     z = Tcl_GetString(objv[1]); |  | 
|  159     if( objc==5 ){ |  | 
|  160       z = sqlite3DbStrDup(0, z); |  | 
|  161     } |  | 
|  162     sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); |  | 
|  163   }else{ |  | 
|  164     z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len); |  | 
|  165     if( objc==5 ){ |  | 
|  166       char *zTmp = z; |  | 
|  167       z = sqlite3_malloc(len); |  | 
|  168       memcpy(z, zTmp, len); |  | 
|  169     } |  | 
|  170     sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); |  | 
|  171   } |  | 
|  172  |  | 
|  173   z = (char *)sqlite3ValueText(pVal, enc_to); |  | 
|  174   len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2); |  | 
|  175   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len)); |  | 
|  176  |  | 
|  177   sqlite3ValueFree(pVal); |  | 
|  178  |  | 
|  179   return TCL_OK; |  | 
|  180 } |  | 
|  181  |  | 
|  182 /* |  | 
|  183 ** Usage: translate_selftest |  | 
|  184 ** |  | 
|  185 ** Call sqlite3UtfSelfTest() to run the internal tests for unicode |  | 
|  186 ** translation. If there is a problem an assert() will fail. |  | 
|  187 **/ |  | 
|  188 void sqlite3UtfSelfTest(void); |  | 
|  189 static int test_translate_selftest( |  | 
|  190   void * clientData, |  | 
|  191   Tcl_Interp *interp, |  | 
|  192   int objc, |  | 
|  193   Tcl_Obj *CONST objv[] |  | 
|  194 ){ |  | 
|  195 #ifndef SQLITE_OMIT_UTF16 |  | 
|  196   sqlite3UtfSelfTest(); |  | 
|  197 #endif |  | 
|  198   return SQLITE_OK; |  | 
|  199 } |  | 
|  200  |  | 
|  201  |  | 
|  202 /* |  | 
|  203 ** Register commands with the TCL interpreter. |  | 
|  204 */ |  | 
|  205 int Sqlitetest5_Init(Tcl_Interp *interp){ |  | 
|  206   static struct { |  | 
|  207     char *zName; |  | 
|  208     Tcl_ObjCmdProc *xProc; |  | 
|  209   } aCmd[] = { |  | 
|  210     { "binarize",                (Tcl_ObjCmdProc*)binarize }, |  | 
|  211     { "test_value_overhead",     (Tcl_ObjCmdProc*)test_value_overhead }, |  | 
|  212     { "test_translate",          (Tcl_ObjCmdProc*)test_translate     }, |  | 
|  213     { "translate_selftest",      (Tcl_ObjCmdProc*)test_translate_selftest}, |  | 
|  214   }; |  | 
|  215   int i; |  | 
|  216   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ |  | 
|  217     Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); |  | 
|  218   } |  | 
|  219   return SQLITE_OK; |  | 
|  220 } |  | 
| OLD | NEW |