diff --git a/manifest b/manifest index a54c16f033..48f6318da3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sdefinitions\sof\sthe\sCollSeq\sand\sKeyInfo\sstructures.\s(CVS\s1399) -D 2004-05-18T23:21:36 +C Tests\sfor\stext\sencoding\sconversion\sfunctions.\sAlso\snew\ssqlite3_bindXX\sAPIs.\s(CVS\s1400) +D 2004-05-19T10:34:52 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -48,7 +48,7 @@ F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c 2981cafe3b21ca06c97ddec8c7181f209a06ee82 F src/shell.c 0c4662e13bfbfd3d13b066c5859cc97ad2f95d21 -F src/sqlite.h.in 799c5e726296ec7bc20e6407cdf4df0e0bc00c0c +F src/sqlite.h.in 8c62076ea226b1870df977d7438bf99383d02387 F src/sqliteInt.h 1da4a9c26da43f235c45c1de0c49fadf6c40d0e6 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1 @@ -56,14 +56,14 @@ F src/test1.c 12ef76b8aaba4408422f21f269256b630d4dd627 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872 F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968 F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296 -F src/test5.c eb39aac8fed61bd930b92613cd705c145244074a +F src/test5.c c92dca7028b19b9c8319d55e0a5037fc183640a6 F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847 F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f F src/update.c 0cc7291dd0e0f82cf93085e49c973e8ef9e51fd5 -F src/utf.c fc799748d43fe1982d157b871e3e420a19c85d4f -F src/util.c 6d4339b7f05ccdacaebcce67e7fb8c5b880620e8 +F src/utf.c 48c537bf7990ce32a36b051401874d024ec2a07b +F src/util.c b72f775a6c3fa404d70250382f63d708e17bc332 F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476 -F src/vdbe.c 37c3d0c45fd6bd7096ae50d08e864acf41924b34 +F src/vdbe.c f5451f1f71e46acebe0be797a138302b4b7ead43 F src/vdbe.h 314e9c07db73a42a6ba91ab7539e27652fc88870 F src/vdbeInt.h 5bac5f0f468205f6e43a4ba86a807abff4953abb F src/vdbeaux.c 95f5a9ff770794f5165d5827d2343eb2d83d7a6d @@ -193,7 +193,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P ae37e8a0bff39fd1568eae83f8761c34cd0184fc -R 3c5b4370c9c3ea00ed8ad90f1394d1c1 -U drh -Z b84fedd6f94a949476c1655f09bd2d6c +P cd1be81569aa6d5a365eb27b7d067a153079ce45 +R 334bdded4c677d317efa922d114eed4d +U danielk1977 +Z 68bec39604761b12cf9824e9ba6afe63 diff --git a/manifest.uuid b/manifest.uuid index 58547655f3..f9b5f73b79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd1be81569aa6d5a365eb27b7d067a153079ce45 \ No newline at end of file +4e602bb473e22cc45de2f5788c035d18586cb836 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7b3f32a209..9f35eb40b8 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.63 2004/05/10 16:18:48 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.64 2004/05/19 10:34:52 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -861,6 +861,16 @@ int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out); */ int sqlite_decode_binary(const unsigned char *in, unsigned char *out); +typedef sqlite_vm sqlite3_stmt; + +int sqlite3_bind_int32(sqlite3_stmt*, int i, int iValue); +int sqlite3_bind_int64(sqlite3_stmt*, int i, long long int iValue); +int sqlite3_bind_double(sqlite3_stmt*, int i, double iValue); +int sqlite3_bind_null(sqlite3_stmt*, int i); +int sqlite3_bind_text(sqlite3_stmt*, int i, const char*, int n, int eCopy); +int sqlite3_bind_text16(sqlite3_stmt*, int i, const void*, int, int eCopy); +int sqlite3_bind_blob(sqlite3_stmt*, int i, const void*, int n, int eCopy); + #if 0 /* @@ -887,14 +897,6 @@ int sqlite3_prepare16(sqlite3*, const void*, sqlite3_stmt**, const void**); int sqlite3_finalize(sqlite3_stmt*); int sqlite3_reset(sqlite3_stmt*); -int sqlite3_bind_int32(sqlite3_stmt*, int iParm, int iValue); -int sqlite3_bind_int64(sqlite3_stmt*, int iParm, long long int iValue); -int sqlite3_bind_double(sqlite3_stmt*, int iParm, double iValue); -int sqlite3_bind_null(sqlite3_stmt*, int iParm); -int sqlite3_bind_text(sqlite3_stmt*, int i, const char*, int n, int eCopy); -int sqlite3_bind_text16(sqlite3_stmt*, int i, const void*, int, int eCopy); -int sqlite3_bind_blob(sqlite3_stmt*, int i, const void*, int n, int eCopy); - int sqlite3_step(sqlite3_stmt*); #define SQLITE3_INTEGER 1 diff --git a/src/test5.c b/src/test5.c index ef0e90d394..816db4cc0b 100644 --- a/src/test5.c +++ b/src/test5.c @@ -11,9 +11,11 @@ ************************************************************************* ** Code for testing the utf.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated -** testing of the SQLite library. +** testing of the SQLite library. Specifically, the code in this file +** is used for testing the SQLite routines for converting between +** the various supported unicode encodings. ** -** $Id: +** $Id: test5.c,v 1.4 2004/05/19 10:34:53 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -21,8 +23,8 @@ #include /* -** Return the number of bytes up to and including the first \u0000 -** character in *pStr. +** Return the number of bytes up to and including the first pair of +** 0x00 bytes in *pStr. */ static int utf16_length(const unsigned char *pZ){ const unsigned char *pC1 = pZ; @@ -50,10 +52,10 @@ static int sqlite_utf8to16le( return TCL_ERROR; } - in = Tcl_GetByteArrayFromObj(objv[1], 0); + in = Tcl_GetString(objv[1]); out = (unsigned char *)sqlite3utf8to16le(in, -1); res = Tcl_NewByteArrayObj(out, utf16_length(out)); - sqliteFree(out); + sqliteFree(out); Tcl_SetObjResult(interp, res); @@ -77,6 +79,7 @@ static int sqlite_utf8to16be( } in = Tcl_GetByteArrayFromObj(objv[1], 0); + in = Tcl_GetString(objv[1]); out = (unsigned char *)sqlite3utf8to16be(in, -1); res = Tcl_NewByteArrayObj(out, utf16_length(out)); sqliteFree(out); @@ -158,13 +161,13 @@ static int sqlite_utf16to8( if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", - Tcl_GetStringFromObj(objv[0], 0), "", 0); + Tcl_GetStringFromObj(objv[0], 0), " ", 0); return TCL_ERROR; } in = Tcl_GetByteArrayFromObj(objv[1], 0); out = sqlite3utf16to8(in, -1); - res = Tcl_NewByteArrayObj(out, strlen(out)); + res = Tcl_NewByteArrayObj(out, strlen(out)+1); sqliteFree(out); Tcl_SetObjResult(interp, res); @@ -172,6 +175,28 @@ static int sqlite_utf16to8( return TCL_OK; } +/* +** The first argument is a TCL UTF-8 string. Return the byte array +** object with the encoded representation of the string, including +** the NULL terminator. +*/ +static int binarize( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int len; + char *bytes; + Tcl_Obj *pRet; + assert(objc==2); + + bytes = Tcl_GetStringFromObj(objv[1], &len); + pRet = Tcl_NewByteArrayObj(bytes, len+1); + Tcl_SetObjResult(interp, pRet); + return TCL_OK; +} + /* ** Register commands with the TCL interpreter. @@ -179,17 +204,18 @@ static int sqlite_utf16to8( int Sqlitetest5_Init(Tcl_Interp *interp){ static struct { char *zName; - Tcl_CmdProc *xProc; + Tcl_ObjCmdProc *xProc; } aCmd[] = { - { "sqlite_utf16to8", (Tcl_CmdProc*)sqlite_utf16to8 }, - { "sqlite_utf8to16le", (Tcl_CmdProc*)sqlite_utf8to16le }, - { "sqlite_utf8to16be", (Tcl_CmdProc*)sqlite_utf8to16be }, - { "sqlite_utf16to16le", (Tcl_CmdProc*)sqlite_utf16to16le }, - { "sqlite_utf16to16be", (Tcl_CmdProc*)sqlite_utf16to16be } + { "sqlite_utf16to8", (Tcl_ObjCmdProc*)sqlite_utf16to8 }, + { "sqlite_utf8to16le", (Tcl_ObjCmdProc*)sqlite_utf8to16le }, + { "sqlite_utf8to16be", (Tcl_ObjCmdProc*)sqlite_utf8to16be }, + { "sqlite_utf16to16le", (Tcl_ObjCmdProc*)sqlite_utf16to16le }, + { "sqlite_utf16to16be", (Tcl_ObjCmdProc*)sqlite_utf16to16be }, + { "binarize", (Tcl_ObjCmdProc*)binarize } }; int i; for(i=0; imax_code ){ + while( code>pRow->max_code ){ assert( pRow->max_code ); pRow++; } @@ -367,7 +367,7 @@ unsigned char *sqlite3utf16to8(const void *pData, int N){ ** this now. */ out.n = (in.n*1.5) + 1; - out.pZ = sqliteMalloc(in.n); + out.pZ = sqliteMalloc(out.n); if( !out.pZ ){ return 0; } @@ -402,7 +402,7 @@ static void *utf8toUtf16(const unsigned char *pIn, int N, int big_endian){ ** this now. */ out.n = (in.n*2) + 2; - out.pZ = sqliteMalloc(in.n); + out.pZ = sqliteMalloc(out.n); if( !out.pZ ){ return 0; } @@ -451,10 +451,20 @@ static void utf16to16(void *pData, int N, int big_endian){ } if( readUtf16Bom(&inout)!=big_endian ){ - swab(&inout.pZ[inout.c], inout.pZ, inout.n-inout.c); + /* swab(&inout.pZ[inout.c], inout.pZ, inout.n-inout.c); */ + int i; + for(i=0; i<(inout.n-inout.c); i += 2){ + char c1 = inout.pZ[i+inout.c]; + char c2 = inout.pZ[i+inout.c+1]; + inout.pZ[i] = c2; + inout.pZ[i+1] = c1; + } }else if( inout.c ){ memmove(inout.pZ, &inout.pZ[inout.c], inout.n-inout.c); } + + inout.pZ[inout.n-inout.c] = 0x00; + inout.pZ[inout.n-inout.c+1] = 0x00; } /* diff --git a/src/util.c b/src/util.c index 50c639a100..d37a56eb20 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.84 2004/05/18 22:03:43 drh Exp $ +** $Id: util.c,v 1.85 2004/05/19 10:34:57 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1180,3 +1180,4 @@ int sqlite3VarintLen(u64 v){ }while( v!=0 && i<9 ); return i; } + diff --git a/src/vdbe.c b/src/vdbe.c index 72052f4274..a16fbb5953 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.299 2004/05/18 22:17:46 drh Exp $ +** $Id: vdbe.c,v 1.300 2004/05/19 10:35:01 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -852,14 +852,41 @@ case OP_Real: { */ case OP_Variable: { int j = pOp->p1 - 1; - pTos++; - if( j>=0 && jnVar && p->azVar[j]!=0 ){ - pTos->z = p->azVar[j]; - pTos->n = p->anVar[j]; - pTos->flags = MEM_Str | MEM_Static; - }else{ - pTos->flags = MEM_Null; + Mem *pVar; + assert( j>=0 && jnVar ); + + /* If we need to translate between text encodings, do it now. If this is + ** required, then put the new string in p->azVar. This way, if the + ** variable is used again, even after the virtual machine is reset, the + ** conversion won't have to be done again. + ** + ** TODO: This is where we need to support databases that use other than + ** UTF-8 on disk. + */ + pVar = &p->azVar[j]; + if( pVar->flags&MEM_Str && !(pVar->flags&MEM_Utf8) ){ + char *zUtf8; + assert( pVar->flags&(MEM_Utf16le|MEM_Utf16be) ); + zUtf8 = sqlite3utf16to8(pVar->z, pVar->n); + if( !zUtf8 ){ + goto no_mem; + } + Release(pVar); + pVar->z = zUtf8; + pVar->n = strlen(zUtf8)+1; + pVar->flags = MEM_Str|MEM_Dyn; } + + /* Copy the value in pVar to the top of the stack. If pVar is a string or + ** a blob just store a pointer to the same memory, do not make a copy. + */ + pTos++; + memcpy(pTos, pVar, sizeof(*pVar)-NBFS); + if( pTos->flags&(MEM_Str|MEM_Blob) ){ + pTos->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Short); + pTos->flags |= MEM_Static; + } + break; } @@ -5166,7 +5193,7 @@ default: { /* Sanity checking on the top element of the stack */ if( pTos>=p->aStack ){ assert( pTos->flags!=0 ); /* Must define some type */ - if( pTos->flags & MEM_Str ){ + if( pTos->flags & (MEM_Str|MEM_Blob) ){ int x = pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short); assert( x!=0 ); /* Strings must define a string subtype */ assert( (x & (x-1))==0 ); /* Only one string subtype can be defined */