diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/jni/src/c/sqlite3-jni.c | 82 | ||||
-rw-r--r-- | ext/jni/src/c/sqlite3-jni.h | 8 | ||||
-rw-r--r-- | ext/jni/src/org/sqlite/jni/SQLite3Jni.java | 15 |
3 files changed, 66 insertions, 39 deletions
diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c index a24ed2518..0f18fa5a0 100644 --- a/ext/jni/src/c/sqlite3-jni.c +++ b/ext/jni/src/c/sqlite3-jni.c @@ -887,7 +887,7 @@ static int s3jni_db_error(sqlite3* const db, int err_code, ** errors are enabled). p may be NULL, in which case the array is ** created but no bytes are filled. */ -static jbyteArray s3jni_new_jbyteArray(JNIEnv * const env, +static jbyteArray s3jni__new_jbyteArray(JNIEnv * const env, const void * const p, int nP){ jbyteArray jba = (*env)->NewByteArray(env, (jint)nP); @@ -898,6 +898,9 @@ static jbyteArray s3jni_new_jbyteArray(JNIEnv * const env, return jba; } +#define s3jni_new_jbyteArray(P,n) s3jni__new_jbyteArray(env, P, n) + + /* ** Uses the java.lang.String(byte[],Charset) constructor to create a ** new String from UTF-8 string z. n is the number of bytes to @@ -910,8 +913,8 @@ static jbyteArray s3jni_new_jbyteArray(JNIEnv * const env, ** standard UTF-8 to a Java string, but JNI offers only algorithms for ** working with MUTF-8, not UTF-8. */ -static jstring s3jni_utf8_to_jstring(JNIEnv * const env, - const char * const z, int n){ +static jstring s3jni__utf8_to_jstring(JNIEnv * const env, + const char * const z, int n){ jstring rv = NULL; if( 0==n || (n<0 && z && !z[0]) ){ /* Fast-track the empty-string case via the MUTF-8 API. We could @@ -921,7 +924,7 @@ static jstring s3jni_utf8_to_jstring(JNIEnv * const env, }else if( z ){ jbyteArray jba; if( n<0 ) n = sqlite3Strlen30(z); - jba = s3jni_new_jbyteArray(env, (unsigned const char *)z, n); + jba = s3jni_new_jbyteArray((unsigned const char *)z, n); if( jba ){ rv = (*env)->NewObject(env, SJG.g.cString, SJG.g.ctorStringBA, jba, SJG.g.oCharsetUtf8); @@ -935,6 +938,7 @@ static jstring s3jni_utf8_to_jstring(JNIEnv * const env, s3jni_oom_check( rv ); return rv; } +#define s3jni_utf8_to_jstring(CStr,n) s3jni__utf8_to_jstring(env, CStr, n) /* ** Converts the given java.lang.String object into a NUL-terminated @@ -951,7 +955,7 @@ static jstring s3jni_utf8_to_jstring(JNIEnv * const env, ** The returned memory is allocated from sqlite3_malloc() and ** ownership is transferred to the caller. */ -static char * s3jni_jstring_to_utf8(JNIEnv * const env, +static char * s3jni__jstring_to_utf8(JNIEnv * const env, jstring jstr, int *nLen){ jbyteArray jba; jsize nBa; @@ -978,6 +982,7 @@ static char * s3jni_jstring_to_utf8(JNIEnv * const env, S3JniUnrefLocal(jba); return rv; } +#define s3jni_jstring_to_utf8(JStr,n) s3jni__jstring_to_utf8(env, JStr, n) /* ** Expects to be passed a pointer from sqlite3_column_text16() or @@ -1025,7 +1030,7 @@ static char * s3jni_exception_error_msg(JNIEnv * const env, jthrowable jx ){ S3JniExceptionClear; return 0; } - zMsg = s3jni_jstring_to_utf8(env, msg, 0); + zMsg = s3jni_jstring_to_utf8( msg, 0); S3JniUnrefLocal(msg); return zMsg; } @@ -1564,9 +1569,9 @@ static int CollationState_xCompare(void *pArg, int nLhs, const void *lhs, S3JniHook_localdup(env, &ps->hooks.collation, &hook ); if( hook.jObj ){ - jbyteArray jbaLhs = s3jni_new_jbyteArray(env, lhs, (jint)nLhs); + jbyteArray jbaLhs = s3jni_new_jbyteArray(lhs, (jint)nLhs); jbyteArray jbaRhs = jbaLhs - ? s3jni_new_jbyteArray(env, rhs, (jint)nRhs) : 0; + ? s3jni_new_jbyteArray(rhs, (jint)nRhs) : 0; if( !jbaRhs ){ S3JniUnrefLocal(jbaLhs); s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0); @@ -1961,7 +1966,7 @@ static void udf_xInverse(sqlite3_context* cx, int argc, /** Create a trivial JNI wrapper for (jstring CName(sqlite3_stmt*,int)). */ #define WRAP_STR_STMT_INT(JniNameSuffix,CName) \ JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jobject pStmt, jint ndx){ \ - return s3jni_utf8_to_jstring(env, \ + return s3jni_utf8_to_jstring( \ CName(PtrGet_sqlite3_stmt(pStmt), (int)ndx), \ -1); \ } @@ -2482,7 +2487,7 @@ S3JniApi(sqlite3_column_blob(),jbyteArray,1column_1blob)( void const * const p = sqlite3_column_blob(pStmt, (int)ndx); int const n = p ? sqlite3_column_bytes(pStmt, (int)ndx) : 0; - return p ? s3jni_new_jbyteArray(env, p, n) : 0; + return p ? s3jni_new_jbyteArray(p, n) : 0; } S3JniApi(sqlite3_column_double(),jdouble,1column_1double)( @@ -2509,7 +2514,7 @@ S3JniApi(sqlite3_column_text(),jbyteArray,1column_1text_1utf8)( sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt); const int n = sqlite3_column_bytes(stmt, (int)ndx); const unsigned char * const p = sqlite3_column_text(stmt, (int)ndx); - return p ? s3jni_new_jbyteArray(env, p, n) : NULL; + return p ? s3jni_new_jbyteArray(p, n) : NULL; } S3JniApi(sqlite3_column_text16(),jstring,1column_1text16)( @@ -2666,7 +2671,7 @@ static void s3jni_config_sqllog(void *ignored, sqlite3 *pDb, const char *z, int switch( op ){ case 0: /* db opened */ case 1: /* SQL executed */ - jArg1 = s3jni_utf8_to_jstring(env, z, -1); + jArg1 = s3jni_utf8_to_jstring( z, -1); break; case 2: /* db closed */ break; @@ -2755,7 +2760,7 @@ S3JniApi(sqlite3_create_collation() sqlite3_create_collation_v2(), rc = s3jni_db_error(ps->pDb, SQLITE_ERROR, "Could not get xCompare() method for object."); }else{ - char * const zName = s3jni_jstring_to_utf8(env, name, 0); + char * const zName = s3jni_jstring_to_utf8( name, 0); if( zName ){ S3JniMutex_S3JniDb_enter; rc = sqlite3_create_collation_v2(ps->pDb, zName, (int)eTextRep, @@ -2797,7 +2802,7 @@ S3JniApi(sqlite3_create_function() sqlite3_create_function_v2() sqlite3_create_w S3JniUdf_free(env, s, 1); goto error_cleanup; } - zFuncName = s3jni_jstring_to_utf8(env,jFuncName,0); + zFuncName = s3jni_jstring_to_utf8(jFuncName,0); if( !zFuncName ){ rc = SQLITE_NOMEM; S3JniUdf_free(env, s, 1); @@ -2839,12 +2844,12 @@ S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)( if( !ps || !jDbName ){ return 0; } - zDbName = s3jni_jstring_to_utf8(env, jDbName, &nStr); + zDbName = s3jni_jstring_to_utf8( jDbName, &nStr); if( zDbName ){ char const * zRv = sqlite3_db_filename(ps->pDb, zDbName); sqlite3_free(zDbName); if( zRv ){ - jRv = s3jni_utf8_to_jstring(env, zRv, -1); + jRv = s3jni_utf8_to_jstring( zRv, -1); } } return jRv; @@ -2871,7 +2876,7 @@ S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/, S3JniMutex_S3JniDb_enter /* Protect against a race in modifying/freeing ps->zMainDbName. */; - zStr = s3jni_jstring_to_utf8(env, jStr, 0); + zStr = s3jni_jstring_to_utf8( jStr, 0); if( zStr ){ rc = sqlite3_db_config(ps->pDb, (int)op, zStr); if( rc ){ @@ -2974,7 +2979,7 @@ S3JniApi(sqlite3_errmsg(),jstring,1errmsg)( JniArgsEnvClass, jobject jpDb ){ sqlite3 * const pDb = PtrGet_sqlite3(jpDb); - return pDb ? s3jni_utf8_to_jstring(env, sqlite3_errmsg(pDb), -1) : 0; + return pDb ? s3jni_utf8_to_jstring( sqlite3_errmsg(pDb), -1) : 0; } S3JniApi(sqlite3_errstr(),jstring,1errstr)( @@ -2996,7 +3001,7 @@ S3JniApi(sqlite3_expanded_sql(),jstring,1expanded_1sql)( char * zSql = sqlite3_expanded_sql(pStmt); s3jni_oom_fatal(zSql); if( zSql ){ - rv = s3jni_utf8_to_jstring(env, zSql, -1); + rv = s3jni_utf8_to_jstring( zSql, -1); sqlite3_free(zSql); } } @@ -3077,7 +3082,7 @@ static int s3jni_open_pre(JNIEnv * const env, S3JniEnv **jc, rc = SQLITE_NOMEM; goto end; } - *zDbName = jDbName ? s3jni_jstring_to_utf8(env, jDbName, 0) : 0; + *zDbName = jDbName ? s3jni_jstring_to_utf8( jDbName, 0) : 0; if( jDbName && !*zDbName ){ rc = SQLITE_NOMEM; goto end; @@ -3166,7 +3171,7 @@ S3JniApi(sqlite3_open_v2(),jint,1open_1v2)( int rc = s3jni_open_pre(env, &jc, strName, &zName, &ps); if( 0==rc ){ if( strVfs ){ - zVfs = s3jni_jstring_to_utf8(env, strVfs, 0); + zVfs = s3jni_jstring_to_utf8( strVfs, 0); if( !zVfs ){ rc = SQLITE_NOMEM; } @@ -3291,8 +3296,8 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId, if( !hook.jObj ){ return; } - jDbName = s3jni_utf8_to_jstring(env, zDb, -1); - jTable = jDbName ? s3jni_utf8_to_jstring(env, zTable, -1) : 0; + jDbName = s3jni_utf8_to_jstring( zDb, -1); + jTable = jDbName ? s3jni_utf8_to_jstring( zTable, -1) : 0; S3JniIfThrew { S3JniExceptionClear; s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0); @@ -3770,10 +3775,10 @@ int s3jni_xAuth(void* pState, int op,const char*z0, const char*z1, S3JniHook_localdup(env, &ps->hooks.auth, &hook ); if( hook.jObj ){ - jstring const s0 = z0 ? s3jni_utf8_to_jstring(env, z0, -1) : 0; - jstring const s1 = z1 ? s3jni_utf8_to_jstring(env, z1, -1) : 0; - jstring const s2 = z2 ? s3jni_utf8_to_jstring(env, z2, -1) : 0; - jstring const s3 = z3 ? s3jni_utf8_to_jstring(env, z3, -1) : 0; + jstring const s0 = z0 ? s3jni_utf8_to_jstring( z0, -1) : 0; + jstring const s1 = z1 ? s3jni_utf8_to_jstring( z1, -1) : 0; + jstring const s2 = z2 ? s3jni_utf8_to_jstring( z2, -1) : 0; + jstring const s3 = z3 ? s3jni_utf8_to_jstring( z3, -1) : 0; rc = (*env)->CallIntMethod(env, hook.jObj, hook.midCallback, (jint)op, s0, s1, s3, s3); @@ -3954,7 +3959,7 @@ S3JniApi(sqlite3_sql(),jstring,1sql)( if( pStmt ){ const char * zSql = 0; zSql = sqlite3_sql(pStmt); - rv = s3jni_utf8_to_jstring(env, zSql, -1); + rv = s3jni_utf8_to_jstring( zSql, -1); } return rv; } @@ -3985,7 +3990,7 @@ static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){ } switch( traceflag ){ case SQLITE_TRACE_STMT: - jX = s3jni_utf8_to_jstring(env, (const char *)pX, -1); + jX = s3jni_utf8_to_jstring( (const char *)pX, -1); if( !jX ) rc = SQLITE_NOMEM; break; case SQLITE_TRACE_PROFILE: @@ -4084,7 +4089,7 @@ S3JniApi(sqlite3_value_blob(),jbyteArray,1value_1blob)( s3jni_oom_check( nLen ? !!pBytes : 1 ); return pBytes - ? s3jni_new_jbyteArray(env, pBytes, nLen) + ? s3jni_new_jbyteArray(pBytes, nLen) : NULL; } @@ -4134,7 +4139,16 @@ S3JniApi(sqlite3_value_text_utf8(),jbyteArray,1value_1text_1utf8)( sqlite3_value * const sv = PtrGet_sqlite3_value(jpSVal); int const n = sqlite3_value_bytes(sv); const unsigned char * const p = sqlite3_value_text(sv); - return p ? s3jni_new_jbyteArray(env, p, n) : 0; + return p ? s3jni_new_jbyteArray(p, n) : 0; +} + +S3JniApi(sqlite3_value_text(),jstring,1value_1text)( + JniArgsEnvClass, jobject jpSVal +){ + sqlite3_value * const sv = PtrGet_sqlite3_value(jpSVal); + int const n = sqlite3_value_bytes(sv); + const unsigned char * const p = sqlite3_value_text(sv); + return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0; } S3JniApi(sqlite3_value_text16(),jstring,1value_1text16)( @@ -4381,7 +4395,7 @@ JniDeclFtsXA(jint,xColumnText)(JniArgsEnvObj,jobject jCtx, jint iCol, int rc = fext->xColumnText(PtrGet_Fts5Context(jCtx), (int)iCol, &pz, &pn); if( 0==rc ){ - jstring jstr = pz ? s3jni_utf8_to_jstring(env, pz, pn) : 0; + jstring jstr = pz ? s3jni_utf8_to_jstring( pz, pn) : 0; if( pz ){ if( jstr ){ OutputPointer_set_String(env, jOut, jstr); @@ -4451,7 +4465,7 @@ JniDeclFtsApi(jint,xCreateFunction)(JniArgsEnvObj, jstring jName, Fts5JniAux * pAux; assert(pApi); - zName = s3jni_jstring_to_utf8(env, jName, 0); + zName = s3jni_jstring_to_utf8( jName, 0); if(!zName) return SQLITE_NOMEM; pAux = Fts5JniAux_alloc(env, jFunc); if( pAux ){ @@ -4722,7 +4736,7 @@ static int s3jni_xTokenize_xToken(void *p, int tFlags, const char* z, S3JniUnrefLocal(s->tok.jba); s->tok.zPrev = z; s->tok.nPrev = nZ; - s->tok.jba = s3jni_new_jbyteArray(env, z, nZ); + s->tok.jba = s3jni_new_jbyteArray(z, nZ); if( !s->tok.jba ) return SQLITE_NOMEM; jba = s->tok.jba; } diff --git a/ext/jni/src/c/sqlite3-jni.h b/ext/jni/src/c/sqlite3-jni.h index a58891423..7c44dfd75 100644 --- a/ext/jni/src/c/sqlite3-jni.h +++ b/ext/jni/src/c/sqlite3-jni.h @@ -1765,6 +1765,14 @@ JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text /* * Class: org_sqlite_jni_SQLite3Jni + * Method: sqlite3_value_text + * Signature: (Lorg/sqlite/jni/sqlite3_value;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_SQLite3Jni * Method: sqlite3_value_text16 * Signature: (Lorg/sqlite/jni/sqlite3_value;)Ljava/lang/String; */ diff --git a/ext/jni/src/org/sqlite/jni/SQLite3Jni.java b/ext/jni/src/org/sqlite/jni/SQLite3Jni.java index 1ad48250e..df4657fd2 100644 --- a/ext/jni/src/org/sqlite/jni/SQLite3Jni.java +++ b/ext/jni/src/org/sqlite/jni/SQLite3Jni.java @@ -1274,15 +1274,20 @@ public final class SQLite3Jni { /** Returns the given value as UTF-8-encoded bytes, or null if the - underlying C API returns null for sqlite3_value_text(). + underlying C-level sqlite3_value_text() returns NULL. */ public static native byte[] sqlite3_value_text_utf8(@NotNull sqlite3_value v); - public static String sqlite3_value_text(@NotNull sqlite3_value v){ - final byte[] ba = sqlite3_value_text_utf8(v); - return null==ba ? null : new String(ba, StandardCharsets.UTF_8); - } + public static native String sqlite3_value_text(@NotNull sqlite3_value v); + /** + In the Java layer, sqlite3_value_text() and + sqlite3_value_text16() are functionally equivalent, the + difference being only where the encoding to UTF-16 (if necessary) + takes place. This function does it via SQLite and + sqlite3_value_text() fetches UTF-8 (SQLite's default encoding) + and converts it to UTF-16 in Java. + */ public static native String sqlite3_value_text16(@NotNull sqlite3_value v); public static native int sqlite3_value_type(@NotNull sqlite3_value v); |