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.5 2004/05/22 03:05:34 danielk1977 Exp $ 19 */ 20 #include "sqliteInt.h" 21 #include "os.h" /* to get SQLITE3_BIGENDIAN */ 22 #include "tcl.h" 23 #include <stdlib.h> 24 #include <string.h> 25 26 /* 27 ** Return the number of bytes up to and including the first pair of 28 ** 0x00 bytes in *pStr. 29 */ 30 static int utf16_length(const unsigned char *pZ){ 31 const unsigned char *pC1 = pZ; 32 const unsigned char *pC2 = pZ+1; 33 while( *pC1 || *pC2 ){ 34 pC1 += 2; 35 pC2 += 2; 36 } 37 return (pC1-pZ)+2; 38 } 39 40 static int sqlite_utf8to16le( 41 void * clientData, 42 Tcl_Interp *interp, 43 int objc, 44 Tcl_Obj *CONST objv[] 45 ){ 46 unsigned char *out; 47 unsigned char *in; 48 Tcl_Obj *res; 49 50 if( objc!=2 ){ 51 Tcl_AppendResult(interp, "wrong # args: should be \"", 52 Tcl_GetStringFromObj(objv[0], 0), "<utf-8 encoded-string>", 0); 53 return TCL_ERROR; 54 } 55 56 in = Tcl_GetString(objv[1]); 57 out = (unsigned char *)sqlite3utf8to16le(in, -1); 58 res = Tcl_NewByteArrayObj(out, utf16_length(out)); 59 sqliteFree(out); 60 61 Tcl_SetObjResult(interp, res); 62 63 return TCL_OK; 64 } 65 66 static int sqlite_utf8to16be( 67 void * clientData, 68 Tcl_Interp *interp, 69 int objc, 70 Tcl_Obj *CONST objv[] 71 ){ 72 unsigned char *out; 73 unsigned char *in; 74 Tcl_Obj *res; 75 76 if( objc!=2 ){ 77 Tcl_AppendResult(interp, "wrong # args: should be \"", 78 Tcl_GetStringFromObj(objv[0], 0), "<utf-8 encoded-string>", 0); 79 return TCL_ERROR; 80 } 81 82 in = Tcl_GetByteArrayFromObj(objv[1], 0); 83 in = Tcl_GetString(objv[1]); 84 out = (unsigned char *)sqlite3utf8to16be(in, -1); 85 res = Tcl_NewByteArrayObj(out, utf16_length(out)); 86 sqliteFree(out); 87 88 Tcl_SetObjResult(interp, res); 89 90 return TCL_OK; 91 } 92 93 static int sqlite_utf16to16le( 94 void * clientData, 95 Tcl_Interp *interp, 96 int objc, 97 Tcl_Obj *CONST objv[] 98 ){ 99 unsigned char *out; 100 unsigned char *in; 101 int in_len; 102 Tcl_Obj *res; 103 104 if( objc!=2 ){ 105 Tcl_AppendResult(interp, "wrong # args: should be \"", 106 Tcl_GetStringFromObj(objv[0], 0), "<utf-16 encoded-string>", 0); 107 return TCL_ERROR; 108 } 109 110 in = Tcl_GetByteArrayFromObj(objv[1], &in_len); 111 out = (unsigned char *)sqliteMalloc(in_len); 112 memcpy(out, in, in_len); 113 114 sqlite3utf16to16le(out, -1); 115 res = Tcl_NewByteArrayObj(out, utf16_length(out)); 116 sqliteFree(out); 117 118 Tcl_SetObjResult(interp, res); 119 120 return TCL_OK; 121 } 122 123 static int sqlite_utf16to16be( 124 void * clientData, 125 Tcl_Interp *interp, 126 int objc, 127 Tcl_Obj *CONST objv[] 128 ){ 129 unsigned char *out; 130 unsigned char *in; 131 int in_len; 132 Tcl_Obj *res; 133 134 if( objc!=2 ){ 135 Tcl_AppendResult(interp, "wrong # args: should be \"", 136 Tcl_GetStringFromObj(objv[0], 0), "<utf-16 encoded-string>", 0); 137 return TCL_ERROR; 138 } 139 140 in = Tcl_GetByteArrayFromObj(objv[1], &in_len); 141 out = (unsigned char *)sqliteMalloc(in_len); 142 memcpy(out, in, in_len); 143 144 sqlite3utf16to16be(out, -1); 145 res = Tcl_NewByteArrayObj(out, utf16_length(out)); 146 sqliteFree(out); 147 148 Tcl_SetObjResult(interp, res); 149 150 return TCL_OK; 151 } 152 153 static int sqlite_utf16to8( 154 void * clientData, 155 Tcl_Interp *interp, 156 int objc, 157 Tcl_Obj *CONST objv[] 158 ){ 159 unsigned char *out; 160 unsigned char *in; 161 Tcl_Obj *res; 162 163 if( objc!=2 ){ 164 Tcl_AppendResult(interp, "wrong # args: should be \"", 165 Tcl_GetStringFromObj(objv[0], 0), " <utf-16 encoded-string>", 0); 166 return TCL_ERROR; 167 } 168 169 in = Tcl_GetByteArrayFromObj(objv[1], 0); 170 out = sqlite3utf16to8(in, -1, SQLITE3_BIGENDIAN); 171 res = Tcl_NewByteArrayObj(out, strlen(out)+1); 172 sqliteFree(out); 173 174 Tcl_SetObjResult(interp, res); 175 176 return TCL_OK; 177 } 178 179 /* 180 ** The first argument is a TCL UTF-8 string. Return the byte array 181 ** object with the encoded representation of the string, including 182 ** the NULL terminator. 183 */ 184 static int binarize( 185 void * clientData, 186 Tcl_Interp *interp, 187 int objc, 188 Tcl_Obj *CONST objv[] 189 ){ 190 int len; 191 char *bytes; 192 Tcl_Obj *pRet; 193 assert(objc==2); 194 195 bytes = Tcl_GetStringFromObj(objv[1], &len); 196 pRet = Tcl_NewByteArrayObj(bytes, len+1); 197 Tcl_SetObjResult(interp, pRet); 198 return TCL_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 { "sqlite_utf16to8", (Tcl_ObjCmdProc*)sqlite_utf16to8 }, 211 { "sqlite_utf8to16le", (Tcl_ObjCmdProc*)sqlite_utf8to16le }, 212 { "sqlite_utf8to16be", (Tcl_ObjCmdProc*)sqlite_utf8to16be }, 213 { "sqlite_utf16to16le", (Tcl_ObjCmdProc*)sqlite_utf16to16le }, 214 { "sqlite_utf16to16be", (Tcl_ObjCmdProc*)sqlite_utf16to16be }, 215 { "binarize", (Tcl_ObjCmdProc*)binarize } 216 }; 217 int i; 218 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 219 Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 220 } 221 222 return TCL_OK; 223 } 224 225 226 227