os/persistentdata/persistentstorage/sqlite3api/TEST/SRC/test5.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 }