mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Remove doc outdated warning about sqlite3_trace_v2() JNI binding being incompatible with MUTF-8. Use new to-string capability to simplify Fts5ExtensionApi::xColumnText() JNI binding.
FossilOrigin-Name: ebcfc2379be12f76a96f3605b734f406b3354d4c985062cdbfca0cf7e3f31379
This commit is contained in:
@ -1075,11 +1075,13 @@ static int udf_setAggregateContext(JNIEnv * env, jobject jCx,
|
||||
stores it in pFieldId. Fails fatally if the property is not found,
|
||||
as that presents a serious internal misuse.
|
||||
|
||||
Property lookups are cached on a per-class basis.
|
||||
Property lookups are cached on a per-zClassName basis. Do not use
|
||||
this routine with the same zClassName but different zTypeSig: it
|
||||
will misbehave.
|
||||
*/
|
||||
static void setupOutputPointer(JNIEnv * env, const char *zClassName,
|
||||
const char *zTypeSig,
|
||||
jobject jOut, jfieldID * pFieldId){
|
||||
static void setupOutputPointer(JNIEnv * const env, const char *zClassName,
|
||||
const char * const zTypeSig,
|
||||
jobject const jOut, jfieldID * const pFieldId){
|
||||
jfieldID setter = 0;
|
||||
struct NphCacheLine * const cacheLine =
|
||||
S3Global_nph_cache(env, zClassName);
|
||||
@ -1087,6 +1089,7 @@ static void setupOutputPointer(JNIEnv * env, const char *zClassName,
|
||||
setter = cacheLine->fidValue;
|
||||
}else{
|
||||
const jclass klazz = (*env)->GetObjectClass(env, jOut);
|
||||
//MARKER(("%s => %s\n", zClassName, zTypeSig));
|
||||
setter = (*env)->GetFieldID(env, klazz, "value", zTypeSig);
|
||||
EXCEPTION_IS_FATAL("setupOutputPointer() could not find OutputPointer.*.value");
|
||||
if(cacheLine){
|
||||
@ -1099,7 +1102,7 @@ static void setupOutputPointer(JNIEnv * env, const char *zClassName,
|
||||
|
||||
/* Sets the value property of the OutputPointer.Int32 jOut object
|
||||
to v. */
|
||||
static void setOutputInt32(JNIEnv * env, jobject jOut, int v){
|
||||
static void setOutputInt32(JNIEnv * const env, jobject const jOut, int v){
|
||||
jfieldID setter = 0;
|
||||
setupOutputPointer(env, S3ClassNames.OutputPointer_Int32, "I", jOut, &setter);
|
||||
(*env)->SetIntField(env, jOut, setter, (jint)v);
|
||||
@ -1109,40 +1112,34 @@ static void setOutputInt32(JNIEnv * env, jobject jOut, int v){
|
||||
#ifdef SQLITE_ENABLE_FTS5
|
||||
/* Sets the value property of the OutputPointer.Int64 jOut object
|
||||
to v. */
|
||||
static void setOutputInt64(JNIEnv * env, jobject jOut, jlong v){
|
||||
static void setOutputInt64(JNIEnv * const env, jobject const jOut, jlong v){
|
||||
jfieldID setter = 0;
|
||||
setupOutputPointer(env, S3ClassNames.OutputPointer_Int64, "J", jOut, &setter);
|
||||
(*env)->SetLongField(env, jOut, setter, v);
|
||||
EXCEPTION_IS_FATAL("Cannot set OutputPointer.Int64.value");
|
||||
}
|
||||
#if 0
|
||||
/* Sets the value property of the OutputPointer.ByteArray jOut object
|
||||
to v. */
|
||||
static void setOutputByteArray(JNIEnv * env, jobject jOut, jbyteArray v){
|
||||
static void setOutputByteArray(JNIEnv * const env, jobject const jOut,
|
||||
jbyteArray const v){
|
||||
jfieldID setter = 0;
|
||||
setupOutputPointer(env, S3ClassNames.OutputPointer_ByteArray, "[B",
|
||||
jOut, &setter);
|
||||
(*env)->SetObjectField(env, jOut, setter, v);
|
||||
EXCEPTION_IS_FATAL("Cannot set OutputPointer.ByteArray.value");
|
||||
}
|
||||
#if 0
|
||||
#endif
|
||||
/* Sets the value property of the OutputPointer.String jOut object
|
||||
to v. */
|
||||
static void setOutputString(JNIEnv * env, jobject jOut, jstring v){
|
||||
static void setOutputString(JNIEnv * const env, jobject const jOut,
|
||||
jstring const v){
|
||||
jfieldID setter = 0;
|
||||
setupOutputPointer(env, S3ClassNames.OutputPointer_String, "Ljava/lang/String",
|
||||
jOut, &setter);
|
||||
setupOutputPointer(env, S3ClassNames.OutputPointer_String,
|
||||
"Ljava/lang/String;", jOut, &setter);
|
||||
(*env)->SetObjectField(env, jOut, setter, v);
|
||||
EXCEPTION_IS_FATAL("Cannot set OutputPointer.String.value");
|
||||
}
|
||||
//! Bad: uses MUTF-8 encoding.
|
||||
static void setOutputString2(JNIEnv * env, jobject jOut, const char * zStr){
|
||||
jstring const jStr = (*env)->NewStringUTF(env, zStr);
|
||||
if(jStr){
|
||||
setOutputString(env, jOut, jStr);
|
||||
UNREF_L(jStr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* SQLITE_ENABLE_FTS5 */
|
||||
|
||||
static int encodingTypeIsValid(int eTextRep){
|
||||
@ -3027,32 +3024,22 @@ JDECLFtsXA(jint,xColumnSize)(JENV_JSELF,jobject jCtx, jint iIdx, jobject jOut32)
|
||||
}
|
||||
|
||||
JDECLFtsXA(jint,xColumnText)(JENV_JSELF,jobject jCtx, jint iCol,
|
||||
jobject jOutBA){
|
||||
jobject jOut){
|
||||
Fts5ExtDecl;
|
||||
const char *pz = 0;
|
||||
int pn = 0;
|
||||
int rc = fext->xColumnText(PtrGet_Fts5Context(jCtx), (int)iCol,
|
||||
&pz, &pn);
|
||||
if( 0==rc ){
|
||||
/* Two problems here:
|
||||
|
||||
1) JNI doesn't give us a way to create strings from standard
|
||||
UTF-8. We're converting the results to MUTF-8, which may
|
||||
differ for exotic text.
|
||||
|
||||
2) JNI's NewStringUTF() (which treats its input as MUTF-8) does
|
||||
not take a _length_ - it requires the string to be
|
||||
NUL-terminated, which may not the case here.
|
||||
|
||||
So we use a byte array and convert it to UTF-8 Java-side.
|
||||
*/
|
||||
jbyteArray const jba = (*env)->NewByteArray(env, (jint)pn);
|
||||
if( jba ){
|
||||
(*env)->SetByteArrayRegion(env, jba, 0, (jint)pn, (const jbyte*)pz);
|
||||
setOutputByteArray(env, jOutBA, jba);
|
||||
UNREF_L(jba)/*jOutBA has a reference*/;
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
JNIEnvCacheLine * const jc = S3Global_JNIEnvCache_cache(env);
|
||||
jstring jstr = pz ? s3jni_string_from_utf8(jc, pz, pn) : 0;
|
||||
if( pz ){
|
||||
if( jstr ){
|
||||
setOutputString(env, jOut, jstr);
|
||||
UNREF_L(jstr)/*jOut has a reference*/;
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (jint)rc;
|
||||
|
@ -1675,7 +1675,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnSize
|
||||
/*
|
||||
* Class: org_sqlite_jni_Fts5ExtensionApi
|
||||
* Method: xColumnText
|
||||
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/OutputPointer/ByteArray;)I
|
||||
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/OutputPointer/String;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnText
|
||||
(JNIEnv *, jobject, jobject, jint, jobject);
|
||||
|
@ -40,20 +40,7 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
|
||||
public native int xColumnSize(@NotNull Fts5Context cx, int iCol,
|
||||
@NotNull OutputPointer.Int32 pnToken);
|
||||
public native int xColumnText(@NotNull Fts5Context cx, int iCol,
|
||||
@NotNull OutputPointer.ByteArray txt);
|
||||
/**
|
||||
Convenience overload which converts the output byte array
|
||||
to a UTF-8 string.
|
||||
*/
|
||||
public int xColumnText(@NotNull Fts5Context cx, int iCol,
|
||||
@NotNull OutputPointer.String txt){
|
||||
final OutputPointer.ByteArray out = new OutputPointer.ByteArray();
|
||||
int rc = xColumnText(cx, iCol, out);
|
||||
if( 0 == rc ){
|
||||
txt.setValue( new String(out.getValue(), StandardCharsets.UTF_8) );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@NotNull OutputPointer.String txt);
|
||||
public native int xColumnTotalSize(@NotNull Fts5Context fcx, int iCol,
|
||||
@NotNull OutputPointer.Int64 pnToken);
|
||||
public native Object xGetAuxdata(@NotNull Fts5Context cx, boolean clearIt);
|
||||
|
@ -47,10 +47,10 @@ public final class OutputPointer {
|
||||
}
|
||||
|
||||
public static final class ByteArray {
|
||||
private byte value[];
|
||||
private byte[] value;
|
||||
public ByteArray(){this(null);}
|
||||
public ByteArray(byte v[]){value = v;}
|
||||
public ByteArray(byte[] v){value = v;}
|
||||
public final byte[] getValue(){return value;}
|
||||
public final void setValue(byte v[]){value = v;}
|
||||
public final void setValue(byte[] v){value = v;}
|
||||
}
|
||||
}
|
||||
|
@ -94,13 +94,6 @@ import java.lang.annotation.ElementType;
|
||||
APIs will mis-translate them on their way between languages
|
||||
(possibly leading to a crash).
|
||||
|
||||
- sqlite3_trace_v2() is also currently affected by this, in that
|
||||
it requires that traced SQL statements be compatible with
|
||||
MUTF-8. The alternative would be to perform two extra layers of
|
||||
conversion for that performance-sensitive function: one from
|
||||
UTF-8 to a byte-array before passing the data from C to Java,
|
||||
and then from byte-array to String in the tracer implementation.
|
||||
|
||||
- C functions which take C-style strings without a length argument
|
||||
require special care when taking input from Java. In particular,
|
||||
Java strings converted to byte arrays for encoding purposes are
|
||||
|
Reference in New Issue
Block a user