test5.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. #include "sqliteInt.h"
  19. #include "vdbeInt.h"
  20. #include "tcl.h"
  21. #include <stdlib.h>
  22. #include <string.h>
  23. /*
  24. ** The first argument is a TCL UTF-8 string. Return the byte array
  25. ** object with the encoded representation of the string, including
  26. ** the NULL terminator.
  27. */
  28. static int binarize(
  29. void * clientData,
  30. Tcl_Interp *interp,
  31. int objc,
  32. Tcl_Obj *CONST objv[]
  33. ){
  34. int len;
  35. char *bytes;
  36. Tcl_Obj *pRet;
  37. assert(objc==2);
  38. bytes = Tcl_GetStringFromObj(objv[1], &len);
  39. pRet = Tcl_NewByteArrayObj((u8*)bytes, len+1);
  40. Tcl_SetObjResult(interp, pRet);
  41. return TCL_OK;
  42. }
  43. /*
  44. ** Usage: test_value_overhead <repeat-count> <do-calls>.
  45. **
  46. ** This routine is used to test the overhead of calls to
  47. ** sqlite3_value_text(), on a value that contains a UTF-8 string. The idea
  48. ** is to figure out whether or not it is a problem to use sqlite3_value
  49. ** structures with collation sequence functions.
  50. **
  51. ** If <do-calls> is 0, then the calls to sqlite3_value_text() are not
  52. ** actually made.
  53. */
  54. static int test_value_overhead(
  55. void * clientData,
  56. Tcl_Interp *interp,
  57. int objc,
  58. Tcl_Obj *CONST objv[]
  59. ){
  60. int do_calls;
  61. int repeat_count;
  62. int i;
  63. Mem val;
  64. if( objc!=3 ){
  65. Tcl_AppendResult(interp, "wrong # args: should be \"",
  66. Tcl_GetStringFromObj(objv[0], 0), " <repeat-count> <do-calls>", 0);
  67. return TCL_ERROR;
  68. }
  69. if( Tcl_GetIntFromObj(interp, objv[1], &repeat_count) ) return TCL_ERROR;
  70. if( Tcl_GetIntFromObj(interp, objv[2], &do_calls) ) return TCL_ERROR;
  71. val.flags = MEM_Str|MEM_Term|MEM_Static;
  72. val.z = "hello world";
  73. val.type = SQLITE_TEXT;
  74. val.enc = SQLITE_UTF8;
  75. for(i=0; i<repeat_count; i++){
  76. if( do_calls ){
  77. sqlite3_value_text(&val);
  78. }
  79. }
  80. return TCL_OK;
  81. }
  82. static u8 name_to_enc(Tcl_Interp *interp, Tcl_Obj *pObj){
  83. struct EncName {
  84. char *zName;
  85. u8 enc;
  86. } encnames[] = {
  87. { "UTF8", SQLITE_UTF8 },
  88. { "UTF16LE", SQLITE_UTF16LE },
  89. { "UTF16BE", SQLITE_UTF16BE },
  90. { "UTF16", SQLITE_UTF16 },
  91. { 0, 0 }
  92. };
  93. struct EncName *pEnc;
  94. char *z = Tcl_GetString(pObj);
  95. for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
  96. if( 0==sqlite3StrICmp(z, pEnc->zName) ){
  97. break;
  98. }
  99. }
  100. if( !pEnc->enc ){
  101. Tcl_AppendResult(interp, "No such encoding: ", z, 0);
  102. }
  103. if( pEnc->enc==SQLITE_UTF16 ){
  104. return SQLITE_UTF16NATIVE;
  105. }
  106. return pEnc->enc;
  107. }
  108. /*
  109. ** Usage: test_translate <string/blob> <from enc> <to enc> ?<transient>?
  110. **
  111. */
  112. static int test_translate(
  113. void * clientData,
  114. Tcl_Interp *interp,
  115. int objc,
  116. Tcl_Obj *CONST objv[]
  117. ){
  118. u8 enc_from;
  119. u8 enc_to;
  120. sqlite3_value *pVal;
  121. char *z;
  122. int len;
  123. void (*xDel)(void *p) = SQLITE_STATIC;
  124. if( objc!=4 && objc!=5 ){
  125. Tcl_AppendResult(interp, "wrong # args: should be \"",
  126. Tcl_GetStringFromObj(objv[0], 0),
  127. " <string/blob> <from enc> <to enc>", 0
  128. );
  129. return TCL_ERROR;
  130. }
  131. if( objc==5 ){
  132. xDel = sqlite3_free;
  133. }
  134. enc_from = name_to_enc(interp, objv[2]);
  135. if( !enc_from ) return TCL_ERROR;
  136. enc_to = name_to_enc(interp, objv[3]);
  137. if( !enc_to ) return TCL_ERROR;
  138. pVal = sqlite3ValueNew(0);
  139. if( enc_from==SQLITE_UTF8 ){
  140. z = Tcl_GetString(objv[1]);
  141. if( objc==5 ){
  142. z = sqlite3_mprintf("%s", z);
  143. }
  144. sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
  145. }else{
  146. z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len);
  147. if( objc==5 ){
  148. char *zTmp = z;
  149. z = sqlite3_malloc(len);
  150. memcpy(z, zTmp, len);
  151. }
  152. sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
  153. }
  154. z = (char *)sqlite3ValueText(pVal, enc_to);
  155. len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2);
  156. Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len));
  157. sqlite3ValueFree(pVal);
  158. return TCL_OK;
  159. }
  160. /*
  161. ** Usage: translate_selftest
  162. **
  163. ** Call sqlite3UtfSelfTest() to run the internal tests for unicode
  164. ** translation. If there is a problem an assert() will fail.
  165. **/
  166. void sqlite3UtfSelfTest(void);
  167. static int test_translate_selftest(
  168. void * clientData,
  169. Tcl_Interp *interp,
  170. int objc,
  171. Tcl_Obj *CONST objv[]
  172. ){
  173. #ifndef SQLITE_OMIT_UTF16
  174. sqlite3UtfSelfTest();
  175. #endif
  176. return SQLITE_OK;
  177. }
  178. /*
  179. ** Register commands with the TCL interpreter.
  180. */
  181. int Sqlitetest5_Init(Tcl_Interp *interp){
  182. static struct {
  183. char *zName;
  184. Tcl_ObjCmdProc *xProc;
  185. } aCmd[] = {
  186. { "binarize", (Tcl_ObjCmdProc*)binarize },
  187. { "test_value_overhead", (Tcl_ObjCmdProc*)test_value_overhead },
  188. { "test_translate", (Tcl_ObjCmdProc*)test_translate },
  189. { "translate_selftest", (Tcl_ObjCmdProc*)test_translate_selftest},
  190. };
  191. int i;
  192. for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  193. Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  194. }
  195. return SQLITE_OK;
  196. }