/* ** Implementations of scalar functions for case mapping - upper() and ** lower(). Function upper() converts its input to upper-case (ABC). ** Function lower() converts to lower-case (abc). ** ** ICU provides two types of case mapping, "general" case mapping and ** "language specific". Refer to ICU documentation for the differences ** between the two. ** ** To utilise "general" case mapping, the upper() or lower() scalar ** functions are invoked with one argument: ** ** upper('ABC') -> 'abc' ** lower('abc') -> 'ABC' ** ** To access ICU "language specific" case mapping, upper() or lower() ** should be invoked with two arguments. The second argument is the name ** of the locale to use. Passing an empty string ("") or SQL NULL value ** as the second argument is the same as invoking the 1 argument version ** of upper() or lower(). ** ** lower('I', 'en_us') -> 'i' ** lower('I', 'tr_tr') -> '\u131' (small dotless i) ** ** http://www.icu-project.org/userguide/posix.html#case_mappings */ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; /* Pointer to input string */ UChar *zOutput = 0; /* Pointer to output buffer */ int nInput; /* Size of utf-16 input string in bytes */ int nOut; /* Size of output buffer in bytes */ int cnt; int bToUpper; /* True for toupper(), false for tolower() */ UErrorCode status; const char *zLocale = 0; assert(nArg==1 || nArg==2); bToUpper = (sqlite3_user_data(p)!=0); if( nArg==2 ){ zLocale = (const char *)sqlite3_value_text(apArg[1]); } zInput = sqlite3_value_text16(apArg[0]); if( !zInput ){ return; } nOut = nInput = sqlite3_value_bytes16(apArg[0]); if( nOut==0 ){ sqlite3_result_text16(p, "", 0, SQLITE_STATIC); return; } for(cnt=0; cnt<2; cnt++){ UChar *zNew = sqlite3_realloc(zOutput, nOut); if( zNew==0 ){ sqlite3_free(zOutput); sqlite3_result_error_nomem(p); return; } zOutput = zNew; status = U_ZERO_ERROR; if( bToUpper ){ nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); }else{ nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); } if( U_SUCCESS(status) ){ sqlite3_result_text16(p, zOutput, nOut, xFree); }else if( status==U_BUFFER_OVERFLOW_ERROR ){ assert( cnt==0 ); continue; }else{ icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status); } return; } assert( 0 ); /* Unreachable */ }
ikptr ik_sqlite3_result_text16 (ikptr s_context, ikptr s_text_data, ikptr s_text_start, ikptr s_text_len, ikptr s_destructor, ikpcb * pcb) { #ifdef HAVE_SQLITE3_RESULT_TEXT16 sqlite3_context * context = IK_SQLITE_CONTEXT(s_context); void * ptr; int start; int len; sqlite3_destructor_type destructor; if (IK_IS_BYTEVECTOR(s_text_data)) { ptr = IK_BYTEVECTOR_DATA_VOIDP(s_text_data); if (IK_FALSE_OBJECT == s_text_len) len = IK_BYTEVECTOR_LENGTH(s_text_data); else len = ik_integer_to_int(s_text_len); } else if (IK_IS_POINTER(s_text_data)) { ptr = IK_POINTER_DATA_VOIDP(s_text_data); len = ik_integer_to_int(s_text_len); } else { /* we assume it is a memory-block */ ptr = IK_MBLOCK_DATA_VOIDP(s_text_data); if (IK_FALSE_OBJECT == s_text_len) len = IK_MBLOCK_SIZE_T(s_text_data); else len = ik_integer_to_int(s_text_len); } start = ik_integer_to_int(s_text_start); destructor = IK_DESTRUCTOR(s_destructor); sqlite3_result_text16(context, ptr+start, len, destructor); return IK_VOID_OBJECT; #else feature_failure(__func__); #endif }
static void test_agg_errmsg16_final(sqlite3_context *ctx){ #ifndef SQLITE_OMIT_UTF16 const void *z; sqlite3 * db = sqlite3_context_db_handle(ctx); sqlite3_aggregate_context(ctx, 2048); sqlite3BeginBenignMalloc(); z = sqlite3_errmsg16(db); sqlite3EndBenignMalloc(); sqlite3_result_text16(ctx, z, -1, SQLITE_TRANSIENT); #endif }
/* ** UTF-16 implementation of the substr() */ void sqlite3utf16Substr( sqlite3_context *context, int argc, sqlite3_value **argv ){ int y, z; unsigned char const *zStr; unsigned char const *zStrEnd; unsigned char const *zStart; unsigned char const *zEnd; int i; zStr = (unsigned char const *)sqlite3_value_text16(argv[0]); zStrEnd = &zStr[sqlite3_value_bytes16(argv[0])]; y = sqlite3_value_int(argv[1]); z = sqlite3_value_int(argv[2]); if( y>0 ){ y = y-1; zStart = zStr; if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){ for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16BE(zStart); }else{ for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16LE(zStart); } }else{ zStart = zStrEnd; if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){ for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16BE(zStart); }else{ for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16LE(zStart); } for(; i<0; i++) z -= 1; } zEnd = zStart; if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){ for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16BE(zEnd); }else{ for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16LE(zEnd); } sqlite3_result_text16(context, zStart, zEnd-zStart, SQLITE_TRANSIENT); }
/* ** Implementations of scalar functions for case mapping - upper() and ** lower(). Function upper() converts its input to upper-case (ABC). ** Function lower() converts to lower-case (abc). ** ** ICU provides two types of case mapping, "general" case mapping and ** "language specific". Refer to ICU documentation for the differences ** between the two. ** ** To utilise "general" case mapping, the upper() or lower() scalar ** functions are invoked with one argument: ** ** upper('ABC') -> 'abc' ** lower('abc') -> 'ABC' ** ** To access ICU "language specific" case mapping, upper() or lower() ** should be invoked with two arguments. The second argument is the name ** of the locale to use. Passing an empty string ("") or SQL NULL value ** as the second argument is the same as invoking the 1 argument version ** of upper() or lower(). ** ** lower('I', 'en_us') -> 'i' ** lower('I', 'tr_tr') -> 'ı' (small dotless i) ** ** http://www.icu-project.org/userguide/posix.html#case_mappings */ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; UChar *zOutput; int nInput; int nOutput; UErrorCode status = U_ZERO_ERROR; const char *zLocale = 0; assert(nArg==1 || nArg==2); if( nArg==2 ){ zLocale = (const char *)sqlite3_value_text(apArg[1]); } zInput = sqlite3_value_text16(apArg[0]); if( !zInput ){ return; } nInput = sqlite3_value_bytes16(apArg[0]); nOutput = nInput * 2 + 2; zOutput = sqlite3_malloc(nOutput); if( !zOutput ){ return; } if( sqlite3_user_data(p) ){ u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); }else{ u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); } if( !U_SUCCESS(status) ){ icuFunctionError(p, "u_strToLower()/u_strToUpper", status); return; } sqlite3_result_text16(p, zOutput, -1, xFree); }
static void test_destructor16( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ char *zVal; int len; test_destructor_count_var++; assert( nArg==1 ); if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; len = sqlite3_value_bytes16(argv[0]); zVal = testContextMalloc(pCtx, len+3); if( !zVal ){ return; } zVal[len+1] = 0; zVal[len+2] = 0; zVal++; memcpy(zVal, sqlite3_value_text16(argv[0]), len); sqlite3_result_text16(pCtx, zVal, -1, destructor); }
__declspec(dllexport) void WINAPI sqlite3_result_text16_interop(sqlite3_context *ctx, const void *pv, int n, void(*cb)(void *)) { sqlite3_result_text16(ctx, pv, n, cb); }
static void mmdec_func(sqlite3_context *db, int argc, sqlite3_value **argv) { mm_cipher_context_t *ctx; char src_buf[1024]; char *src = src_buf; int32_t src_len; UChar buf[512]; UChar *dst = buf; int32_t dst_len; UErrorCode status = U_ZERO_ERROR; int arg_type; // only accept 1 argument. if (argc != 1) goto error_misuse; arg_type = sqlite3_value_type(argv[0]); // for data types other than BLOB, just return them. if (arg_type != SQLITE_BLOB) { sqlite3_result_value(db, argv[0]); return; } ctx = (mm_cipher_context_t *) sqlite3_user_data(db); src_len = sqlite3_value_bytes(argv[0]); if (src_len > sizeof(src_buf)) { src = (char *) sqlite3_malloc(src_len); if (!src) goto error_error; } memcpy(src, sqlite3_value_blob(argv[0]), src_len); // decrypt transformed BOCU-1 string. do_rc4(ctx, src, src_len); // transform input string from BOCU-1 encoding. // try stack buffer first, if it doesn't fit, malloc a new buffer. dst_len = ucnv_toUChars(ctx->cnv, dst, sizeof(buf), src, src_len, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { status = U_ZERO_ERROR; dst = (UChar *) sqlite3_malloc(dst_len * sizeof(UChar)); dst_len = ucnv_toUChars(ctx->cnv, dst, dst_len, src, src_len, &status); } if (U_FAILURE(status) && status != U_STRING_NOT_TERMINATED_WARNING) { sqlite3_mm_set_last_error( "Failed transforming text from internal encoding."); goto error_error; } // return sqlite3_result_text16(db, dst, dst_len * sizeof(UChar), SQLITE_TRANSIENT); if (src != src_buf) sqlite3_free(src); if (dst != buf) sqlite3_free(dst); return; error_error: if (src != src_buf) sqlite3_free(src); if (dst != buf) sqlite3_free(dst); sqlite3_result_error_code(db, SQLITE_ERROR); return; error_misuse: if (src != src_buf) sqlite3_free(src); if (dst != buf) sqlite3_free(dst); sqlite3_result_error_code(db, SQLITE_MISUSE); return; }