SQLValue SQLiteStatement::getColumnValue(int col) { ASSERT(col >= 0); if (!m_statement) if (prepareAndStep() != SQLITE_ROW) return SQLValue(); if (columnCount() <= col) return SQLValue(); // SQLite is typed per value. optional column types are // "(mostly) ignored" sqlite3_value* value = sqlite3_column_value(m_statement, col); switch (sqlite3_value_type(value)) { case SQLITE_INTEGER: // SQLValue and JS don't represent integers, so use // FLOAT -case case SQLITE_FLOAT: return SQLValue(sqlite3_value_double(value)); case SQLITE_BLOB: // SQLValue and JS don't represent blobs, so use TEXT // -case case SQLITE_TEXT: { const UChar* string = reinterpret_cast<const UChar*>(sqlite3_value_text16(value)); unsigned length = sqlite3_value_bytes16(value) / sizeof(UChar); return SQLValue(StringImpl::create8BitIfPossible(string, length)); } case SQLITE_NULL: return SQLValue(); default: break; } ASSERT_NOT_REACHED(); return SQLValue(); }
/* ** 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_value_bytes16 (ikptr s_value, ikpcb * pcb) { #ifdef HAVE_SQLITE3_VALUE_BYTES16 sqlite3_value * value = IK_SQLITE_VALUE(s_value); int rv; rv = sqlite3_value_bytes16(value); return ika_integer_from_int(pcb, rv); #else feature_failure(__func__); #endif }
ikptr ik_sqlite3_value_text16be (ikptr s_value, ikpcb * pcb) { #ifdef HAVE_SQLITE3_VALUE_TEXT16BE sqlite3_value * value = IK_SQLITE_VALUE(s_value); const void * data; int bytes; bytes = sqlite3_value_bytes16(value); data = sqlite3_value_text16be(value); return ika_bytevector_from_memory_block(pcb, data, bytes); #else feature_failure(__func__); #endif }
static void getUnicodeResult(const RtlFieldInfo *field, sqlite3_value *val, size32_t &chars, UChar * &result) { assertex(val); if (isNull(val)) { NullFieldProcessor p(field); rtlUnicodeToUnicodeX(chars, result, p.resultChars, p.unicodeResult); return; } if (sqlite3_value_type(val) != SQLITE_TEXT) typeError("string", field); const UChar *text = (const UChar *) sqlite3_value_text16(val); int bytes = sqlite3_value_bytes16(val); unsigned numchars = bytes / sizeof(UChar); rtlUnicodeToUnicodeX(chars, result, numchars, text); }
/* ** 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); }
// Called each time a custom function is evaluated. static void sqliteCustomFunctionCallback(sqlite3_context *context, int argc, sqlite3_value **argv) { JNIEnv* env = AndroidRuntime::getJNIEnv(); // Get the callback function object. // Create a new local reference to it in case the callback tries to do something // dumb like unregister the function (thereby destroying the global ref) while it is running. jobject functionObjGlobal = reinterpret_cast<jobject>(sqlite3_user_data(context)); jobject functionObj = env->NewLocalRef(functionObjGlobal); jobjectArray argsArray = env->NewObjectArray(argc, gStringClassInfo.clazz, NULL); if (argsArray) { for (int i = 0; i < argc; i++) { const jchar* arg = static_cast<const jchar*>(sqlite3_value_text16(argv[i])); if (!arg) { ALOGW("NULL argument in custom_function_callback. This should not happen."); } else { size_t argLen = sqlite3_value_bytes16(argv[i]) / sizeof(jchar); jstring argStr = env->NewString(arg, argLen); if (!argStr) { goto error; // out of memory error } env->SetObjectArrayElement(argsArray, i, argStr); env->DeleteLocalRef(argStr); } } // TODO: Support functions that return values. env->CallVoidMethod(functionObj, gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); error: env->DeleteLocalRef(argsArray); } env->DeleteLocalRef(functionObj); if (env->ExceptionCheck()) { ALOGE("An exception was thrown by custom SQLite function."); LOGE_EX(env); env->ExceptionClear(); } }
/* ** 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); }
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; }
__declspec(dllexport) int WINAPI sqlite3_value_bytes16_interop(sqlite3_value *val) { return sqlite3_value_bytes16(val); }
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ return sqlite3_value_bytes16( columnMem(pStmt,i) ); }
static void mmenc_func(sqlite3_context *db, int argc, sqlite3_value **argv) { mm_cipher_context_t *ctx; const UChar *src; int32_t src_len; char buf[1024]; char *dst = buf; int32_t dst_len; UErrorCode status = U_ZERO_ERROR; int arg_type; // only accept 1 argument. if (argc != 1) goto error_misuse; // encoding BLOB data type is not supported. arg_type = sqlite3_value_type(argv[0]); if (arg_type == SQLITE_BLOB) goto error_misuse; // for data types other than TEXT, just return them. if (arg_type != SQLITE_TEXT) { sqlite3_result_value(db, argv[0]); return; } ctx = (mm_cipher_context_t *) sqlite3_user_data(db); src_len = sqlite3_value_bytes16(argv[0]) / 2; src = (const UChar *) sqlite3_value_text16(argv[0]); // transform input string to BOCU-1 encoding. // try stack buffer first, if it doesn't fit, malloc a new buffer. dst_len = ucnv_fromUChars(ctx->cnv, dst, sizeof(buf), src, src_len, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { status = U_ZERO_ERROR; dst = (char *) sqlite3_malloc(dst_len); dst_len = ucnv_fromUChars(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 to internal encoding."); goto error_error; } // encrypt transformed BOCU-1 string. do_rc4(ctx, dst, dst_len); // return sqlite3_result_blob(db, dst, dst_len, SQLITE_TRANSIENT); if (dst != buf) sqlite3_free(dst); return; error_error: if (dst != buf) sqlite3_free(dst); sqlite3_result_error_code(db, SQLITE_ERROR); return; error_misuse: if (dst != buf) sqlite3_free(dst); sqlite3_result_error_code(db, SQLITE_MISUSE); return; }