]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
JNI: add sqlite3_blob_read_nio_buffer() and iron out the blob/ByteBuffer interface...
authorstephan <stephan@noemail.net>
Tue, 14 Nov 2023 04:59:57 +0000 (04:59 +0000)
committerstephan <stephan@noemail.net>
Tue, 14 Nov 2023 04:59:57 +0000 (04:59 +0000)
FossilOrigin-Name: 7df317b448a09ae77e2c68cc901fdb6d56a2246c1313f06bebd1f3e53f02c19b

ext/jni/src/c/sqlite3-jni.c
ext/jni/src/c/sqlite3-jni.h
ext/jni/src/org/sqlite/jni/capi/CApi.java
ext/jni/src/org/sqlite/jni/capi/Tester1.java
manifest
manifest.uuid

index dcf2cdb4cdd364086a2b92330b7d20e618cd1d46..6668f0b72874e92489f8af188e0f263b54538050 100644 (file)
@@ -2485,7 +2485,7 @@ struct S3JniNioArgs {
   jint iHowMany;       /* input - byte count to bind/read/write */
   jint nBuf;           /* output - jBuf's buffer size */
   void * p;            /* output - jBuf's buffer memory */
-  const void * pStart; /* output - offset of p to bind/read/write */
+  void * pStart;       /* output - offset of p to bind/read/write */
   int nOut;            /* output - number of bytes from pStart to bind/read/write */
 };
 typedef struct S3JniNioArgs S3JniNioArgs;
@@ -2494,32 +2494,39 @@ static const S3JniNioArgs S3JniNioArgs_empty = {
 };
 
 /*
-** Internal helper for sqlite3_bind_nio_buffer() and
-** sqlite3_result_nio_buffer(). Populates pArgs and returns 0 on
-** success, non-0 if the operation should fail. The caller is required
-** to check for SJG.g.cByteBuffer!=0 before calling this and reporting
-** it in a way appropriate for that routine.  This function may
-** assert() that SJG.g.cByteBuffer is not 0.
+** Internal helper for sqlite3_bind_nio_buffer(),
+** sqlite3_result_nio_buffer(), and similar methods which take a
+** ByteBuffer object as either input or output. Populates pArgs and
+** returns 0 on success, non-0 if the operation should fail. The
+** caller is required to check for SJG.g.cByteBuffer!=0 before calling
+** this and reporting it in a way appropriate for that routine.  This
+** function may assert() that SJG.g.cByteBuffer is not 0.
 **
-** The (jBuffer, iOffset, iN) arguments are the (ByteBuffer, offset,
+** The (jBuffer, iOffset, iHowMany) arguments are the (ByteBuffer, offset,
 ** length) arguments to the bind/result method.
 **
+** If iHowMany is negative then it's treated as "until the end" and
+** the calculated slice is trimmed to fit if needed. If iHowMany is
+** positive and extends past the end of jBuffer then SQLITE_ERROR is
+** returned.
+**
 ** Returns 0 if everything looks to be in order, else some SQLITE_...
 ** result code
 */
 static int s3jni_setup_nio_args(
   JNIEnv *env, S3JniNioArgs * pArgs,
-  jobject jBuffer, jint iOffset, jint iN
+  jobject jBuffer, jint iOffset, jint iHowMany
 ){
   jlong iEnd = 0;
+  const int bAllowTruncate = iHowMany<0;
   *pArgs = S3JniNioArgs_empty;
   pArgs->jBuf = jBuffer;
   pArgs->iOffset = iOffset;
-  pArgs->iHowMany = iN;
+  pArgs->iHowMany = iHowMany;
   assert( SJG.g.cByteBuffer );
   if( pArgs->iOffset<0 ){
     return SQLITE_ERROR
-      /* SQLITE_MISUSE would arguably fit better but we use
+      /* SQLITE_MISUSE or SQLITE_RANGE would fit better but we use
          SQLITE_ERROR for consistency with the code documented for a
          negative target blob offset in sqlite3_blob_read/write(). */;
   }
@@ -2536,7 +2543,15 @@ static int s3jni_setup_nio_args(
   iEnd = pArgs->iHowMany<0
     ? pArgs->nBuf - pArgs->iOffset
     : pArgs->iOffset + pArgs->iHowMany;
-  if( iEnd>(jlong)pArgs->nBuf ) iEnd = pArgs->nBuf - pArgs->iOffset;
+  if( iEnd>(jlong)pArgs->nBuf ){
+    if( bAllowTruncate ){
+      iEnd = pArgs->nBuf - pArgs->iOffset;
+    }else{
+      return SQLITE_ERROR
+        /* again: for consistency with blob_read/write(), though
+           SQLITE_MISUSE or SQLITE_RANGE would be a better fit. */;
+    }
+  }
   if( iEnd - pArgs->iOffset > (jlong)SQLITE_MAX_LENGTH ){
     return SQLITE_TOOBIG;
   }
@@ -2545,6 +2560,7 @@ static int s3jni_setup_nio_args(
   pArgs->pStart = pArgs->p + pArgs->iOffset;
   pArgs->nOut = (int)(iEnd - pArgs->iOffset);
   assert( pArgs->nOut > 0 );
+  assert( (pArgs->pStart + pArgs->nOut) <= (pArgs->p + pArgs->nBuf) );
   return 0;
 }
 
@@ -2562,10 +2578,6 @@ S3JniApi(sqlite3_bind_nio_buffer(),jint,1bind_1nio_1buffer)(
   }else if( !args.pStart || !args.nOut ){
     return sqlite3_bind_null(pStmt, ndx);
   }
-  assert( args.nOut>0 );
-  assert( args.nBuf > 0 );
-  assert( args.pStart != 0 );
-  assert( (args.pStart + args.nOut) <= (args.p + args.nBuf) );
   return sqlite3_bind_blob( pStmt, (int)ndx, args.pStart,
                             args.nOut, SQLITE_TRANSIENT );
 }
@@ -2784,6 +2796,30 @@ S3JniApi(sqlite3_blob_read(),jint,1blob_1read)(
   return rc;
 }
 
+S3JniApi(sqlite3_blob_read_nio_buffer(),jint,1blob_1read_1nio_1buffer)(
+  JniArgsEnvClass, jlong jpBlob, jint iSrcOff, jobject jBB, jint iTgtOff, jint iHowMany
+){
+  sqlite3_blob * const b = LongPtrGet_sqlite3_blob(jpBlob);
+  S3JniNioArgs args;
+  int rc;
+  if( !b || !SJG.g.cByteBuffer || iHowMany<0 ){
+    return SQLITE_MISUSE;
+  }else if( iTgtOff<0 || iSrcOff<0 ){
+    return SQLITE_ERROR
+      /* for consistency with underlying sqlite3_blob_read() */;
+  }else if( 0==iHowMany ){
+    return 0;
+  }
+  rc = s3jni_setup_nio_args(env, &args, jBB, iTgtOff, iHowMany);
+  if(rc){
+    return rc;
+  }else if( !args.pStart || !args.nOut ){
+    return 0;
+  }
+  assert( args.iHowMany>0 );
+  return sqlite3_blob_read( b, args.pStart, (int)args.nOut, (int)iSrcOff );
+}
+
 S3JniApi(sqlite3_blob_reopen(),jint,1blob_1reopen)(
   JniArgsEnvClass, jlong jpBlob, jlong iNewRowId
 ){
@@ -2806,7 +2842,7 @@ S3JniApi(sqlite3_blob_write(),jint,1blob_1write)(
 }
 
 S3JniApi(sqlite3_blob_write_nio_buffer(),jint,1blob_1write_1nio_1buffer)(
-  JniArgsEnvClass, jlong jpBlob, jint iSrcOff, jobject jBB, jint iTgtOff, jint iHowMany
+  JniArgsEnvClass, jlong jpBlob, jint iTgtOff, jobject jBB, jint iSrcOff, jint iHowMany
 ){
   sqlite3_blob * const b = LongPtrGet_sqlite3_blob(jpBlob);
   S3JniNioArgs args;
@@ -2819,17 +2855,13 @@ S3JniApi(sqlite3_blob_write_nio_buffer(),jint,1blob_1write_1nio_1buffer)(
   }else if( 0==iHowMany ){
     return 0;
   }
-  rc = s3jni_setup_nio_args(env, &args, jBB, iTgtOff, iHowMany);
+  rc = s3jni_setup_nio_args(env, &args, jBB, iSrcOff, iHowMany);
   if(rc){
     return rc;
   }else if( !args.pStart || !args.nOut ){
     return 0;
   }
-  assert( args.nOut>0 );
-  assert( args.nBuf > 0 );
-  assert( args.pStart != 0 );
-  assert( (args.pStart + args.nOut) <= (args.p + args.nBuf) );
-  return sqlite3_blob_write( b, args.pStart, (int)args.nOut, iSrcOff );
+  return sqlite3_blob_write( b, args.pStart, (int)args.nOut, (int)iTgtOff );
 }
 
 /* Central C-to-Java busy handler proxy. */
index c3a5d178b29b7a62519478de4c7134616dbb94d3..20f42af46a61bd6f2529fac07dc595897f2c37dd 100644 (file)
@@ -1001,6 +1001,14 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1open
 JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1read
   (JNIEnv *, jclass, jlong, jbyteArray, jint);
 
+/*
+ * Class:     org_sqlite_jni_capi_CApi
+ * Method:    sqlite3_blob_read_nio_buffer
+ * Signature: (JILjava/nio/ByteBuffer;II)I
+ */
+JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1read_1nio_1buffer
+  (JNIEnv *, jclass, jlong, jint, jobject, jint, jint);
+
 /*
  * Class:     org_sqlite_jni_capi_CApi
  * Method:    sqlite3_blob_reopen
index 36f101c3e5426db745b58e2322aae985edc78fa0..090adf94f474b449ea520c8507485538ce9ffce7 100644 (file)
@@ -312,8 +312,8 @@ public final class CApi {
      but a negative howMany is interpretated as the remainder of the
      buffer past the given start position.
 
-     If beginPos+howMany would extend past the end of the buffer, the
-     range is silently truncated to fit the buffer.
+     If beginPos+howMany would extend past the end of the buffer then
+     SQLITE_ERROR is returned.
 
      If any of the following are true, this function behaves like
      sqlite3_bind_null(): the buffer is null, beginPos is at or past
@@ -559,13 +559,116 @@ public final class CApi {
   };
 
   private static native int sqlite3_blob_read(
-    @NotNull long ptrToBlob, @NotNull byte[] target, int iOffset
+    @NotNull long ptrToBlob, @NotNull byte[] target, int srcOffset
   );
 
+  /**
+     As per C's sqlite3_blob_read(), but writes its output to the
+     given byte array. Note that the final argument is the offset of
+     the source buffer, not the target array.
+   */
   public static int sqlite3_blob_read(
-    @NotNull sqlite3_blob b, @NotNull byte[] target, int iOffset
+    @NotNull sqlite3_blob src, @NotNull byte[] target, int srcOffset
   ){
-    return sqlite3_blob_read(b.getNativePointer(), target, iOffset);
+    return sqlite3_blob_read(src.getNativePointer(), target, srcOffset);
+  }
+
+  /**
+     An internal level of indirection.
+  */
+  private static native int sqlite3_blob_read_nio_buffer(
+    @NotNull long ptrToBlob, int srcOffset,
+    @NotNull java.nio.ByteBuffer tgt, int tgtOffset, int howMany
+  );
+
+  /**
+     Reads howMany bytes from offset srcOffset of src into position
+     tgtOffset of tgt.
+
+     Returns SQLITE_MISUSE if src is null, tgt is null, or
+     sqlite3_jni_supports_nio() returns false. Returns SQLITE_ERROR if
+     howMany or either offset are negative.  If argument validation
+     succeeds, it returns the result of the underlying call to
+     sqlite3_blob_read() (0 on success).
+  */
+  public static int sqlite3_blob_read_nio_buffer(
+    @NotNull sqlite3_blob src, int srcOffset,
+    @NotNull java.nio.ByteBuffer tgt, int tgtOffset, int howMany
+  ){
+    return (JNI_SUPPORTS_NIO && src!=null && tgt!=null)
+      ? sqlite3_blob_read_nio_buffer(
+        src.getNativePointer(), srcOffset, tgt, tgtOffset, howMany
+      )
+      : SQLITE_MISUSE;
+  }
+
+  /**
+     Convenience overload which reads howMany bytes from position
+     srcOffset of src and returns the result as a new ByteBuffer.
+
+     srcOffset may not be negative. If howMany is negative, it is
+     treated as all bytes following srcOffset.
+
+     Returns null if sqlite3_jni_supports_nio(), any arguments are
+     invalid, if the number of bytes to read is 0 or is larger than
+     the src blob, or the underlying call to sqlite3_blob_read() fails
+     for any reason.
+  */
+  public static java.nio.ByteBuffer sqlite3_blob_read_nio_buffer(
+    @NotNull sqlite3_blob src, int srcOffset, int howMany
+  ){
+    if( !JNI_SUPPORTS_NIO || src==null ) return null;
+    else if( srcOffset<0 ) return null;
+    final int nB = sqlite3_blob_bytes(src);
+    if( srcOffset>=nB ) return null;
+    else if( howMany<0 ) howMany = nB - srcOffset;
+    if( srcOffset + howMany > nB ) return null;
+    final java.nio.ByteBuffer tgt =
+      java.nio.ByteBuffer.allocateDirect(howMany);
+    final int rc = sqlite3_blob_read_nio_buffer(
+      src.getNativePointer(), srcOffset, tgt, 0, howMany
+    );
+    return 0==rc ? tgt : null;
+  }
+
+  /**
+     Overload alias for sqlite3_blob_read_nio_buffer().
+  */
+  public static int sqlite3_blob_read(
+    @NotNull sqlite3_blob src, int srcOffset,
+    @NotNull java.nio.ByteBuffer tgt,
+    int tgtOffset, int howMany
+  ){
+    return sqlite3_blob_read_nio_buffer(
+      src, srcOffset, tgt, tgtOffset, howMany
+    );
+  }
+
+  /**
+     Convenience overload which uses 0 for both src and tgt offsets
+     and reads a number of bytes equal to the smaller of
+     sqlite3_blob_bytes(src) and tgt.limit().
+
+     On success it sets tgt.limit() to the number of bytes read. On
+     error, tgt.limit() is not modified.
+
+     Returns 0 on success. Returns SQLITE_MISUSE is either argument is
+     null or sqlite3_jni_supports_nio() returns false. Else it returns
+     the result of the underlying call to sqlite3_blob_read().
+  */
+  public static int sqlite3_blob_read(
+    @NotNull sqlite3_blob src,
+    @NotNull java.nio.ByteBuffer tgt
+  ){
+    if(!JNI_SUPPORTS_NIO || src==null || tgt==null) return SQLITE_MISUSE;
+    final int nSrc = sqlite3_blob_bytes(src);
+    final int nTgt = tgt.limit();
+    final int nRead = nTgt<nSrc ? nTgt : nSrc;
+    final int rc = sqlite3_blob_read_nio_buffer(
+      src.getNativePointer(), 0, tgt, 0, nRead
+    );
+    if( 0==rc && nTgt!=nRead ) tgt.limit( nRead );
+    return rc;
   }
 
   private static native int sqlite3_blob_reopen(
@@ -586,13 +689,8 @@ public final class CApi {
     return sqlite3_blob_write(b.getNativePointer(), bytes, iOffset);
   }
 
-
   /**
-     An internal level of indirection in order to avoid having
-     overloaded names of sqlite3_blob_write() in the C API, as the
-     resulting mangled names are unwieldy. The public face of this
-     method is the sqlite3_blob_write() overload which takes a
-     java.nio.ByteBuffer.
+     An internal level of indirection.
   */
   private static native int sqlite3_blob_write_nio_buffer(
     @NotNull long ptrToBlob, int tgtOffset,
@@ -605,28 +703,63 @@ public final class CApi {
      buffer at position tgtOffset of b.
 
      If howMany is negative then it's equivalent to the number of
-     bytes remaining starting at srcOffset. If the computed input
-     slice exceeds src's bounds, the slice is silently truncated.
+     bytes remaining starting at srcOffset.
+
+     Returns SQLITE_MISUSE if tgt is null or sqlite3_jni_supports_nio()
+     returns false.
+
+     Returns SQLITE_MISUSE if src is null or
+     sqlite3_jni_supports_nio() returns false. Returns SQLITE_ERROR if
+     either offset is negative.  If argument validation succeeds, it
+     returns the result of the underlying call to sqlite3_blob_read().
+  */
+  public static int sqlite3_blob_write_nio_buffer(
+    @NotNull sqlite3_blob tgt, int tgtOffset,
+    @NotNull java.nio.ByteBuffer src,
+    int srcOffset, int howMany
+  ){
+    return sqlite3_blob_write_nio_buffer(
+      tgt.getNativePointer(), tgtOffset, src, srcOffset, howMany
+    );
+  }
+
+  /**
+     Overload alias for sqlite3_blob_write_nio_buffer().
   */
   public static int sqlite3_blob_write(
-    @NotNull sqlite3_blob b, int tgtOffset,
+    @NotNull sqlite3_blob tgt, int tgtOffset,
     @NotNull java.nio.ByteBuffer src,
     int srcOffset, int howMany
   ){
-    return sqlite3_blob_write_nio_buffer(b.getNativePointer(), tgtOffset,
-                                         src, srcOffset, howMany);
+    return sqlite3_blob_write_nio_buffer(
+      tgt.getNativePointer(), tgtOffset, src, srcOffset, howMany
+    );
   }
 
   /**
      Convenience overload which writes all of src to the given offset
      of b.
+  */
+  public static int sqlite3_blob_write(
+    @NotNull sqlite3_blob tgt, int tgtOffset,
+    @NotNull java.nio.ByteBuffer src
+  ){
+    return sqlite3_blob_write_nio_buffer(
+      tgt.getNativePointer(), tgtOffset, src, 0, -1
+    );
+  }
+
+  /**
+     Convenience overload which writes all of src to offset 0
+     of tgt.
    */
   public static int sqlite3_blob_write(
-    @NotNull sqlite3_blob b, int tgtOffset,
+    @NotNull sqlite3_blob tgt,
     @NotNull java.nio.ByteBuffer src
   ){
-    return sqlite3_blob_write_nio_buffer(b.getNativePointer(), tgtOffset,
-                                         src, 0, -1);
+    return sqlite3_blob_write_nio_buffer(
+      tgt.getNativePointer(), 0, src, 0, -1
+    );
   }
 
   private static native int sqlite3_busy_handler(
@@ -2710,8 +2843,8 @@ public final class CApi {
   public static final int SQLITE_FAIL = 3;
   public static final int SQLITE_REPLACE = 5;
   static {
-    // This MUST come after the SQLITE_MAX_... values or else
-    // attempting to modify them silently fails.
     init();
   }
+  /* Must come after static init(). */
+  private static final boolean JNI_SUPPORTS_NIO = sqlite3_jni_supports_nio();
 }
index 5faba3814e6f3781c85f23b1a8e7bbc51f68ff4d..3ff93a9ce2d19be5759fbbce65519d06624a415c 100644 (file)
@@ -1759,8 +1759,8 @@ public class Tester1 implements Runnable {
     for( byte i = 0; i < 10; ++i ){
       bb.put((int)i, (byte)(48+i & 0xff));
     }
-    rc = sqlite3_blob_write(b, 1, bb);
-    affirm( rc==SQLITE_ERROR, "Because b length < (offset 1 + bb length)" );
+    rc = sqlite3_blob_write(b, 1, bb, 1, 10);
+    affirm( rc==SQLITE_ERROR, "b length < (srcOffset + bb length)" );
     rc = sqlite3_blob_write(b, -1, bb);
     affirm( rc==SQLITE_ERROR, "Target offset may not be negative" );
     rc = sqlite3_blob_write(b, 0, bb, -1, -1);
@@ -1770,13 +1770,58 @@ public class Tester1 implements Runnable {
     // b's contents: 0 49  50  51  52  53  54  55  56  0
     //        ascii: 0 '1' '2' '3' '4' '5' '6' '7' '8' 0
     byte br[] = new byte[10];
+    java.nio.ByteBuffer bbr =
+      java.nio.ByteBuffer.allocateDirect(bb.limit());
     rc = sqlite3_blob_read( b, br, 0 );
-    sqlite3_blob_close(b);
     affirm( rc==0 );
+    rc = sqlite3_blob_read( b, bbr );
+    affirm( rc==0 );
+    java.nio.ByteBuffer bbr2 = sqlite3_blob_read_nio_buffer(b, 0, 12);
+    affirm( null==bbr2, "Read size is too big");
+    bbr2 = sqlite3_blob_read_nio_buffer(b, -1, 3);
+    affirm( null==bbr2, "Source offset is negative");
+    bbr2 = sqlite3_blob_read_nio_buffer(b, 5, 6);
+    affirm( null==bbr2, "Read pos+size is too big");
+    bbr2 = sqlite3_blob_read_nio_buffer(b, 4, 7);
+    affirm( null==bbr2, "Read pos+size is too big");
+    bbr2 = sqlite3_blob_read_nio_buffer(b, 4, 6);
+    affirm( null!=bbr2 );
+    java.nio.ByteBuffer bbr3 =
+      java.nio.ByteBuffer.allocateDirect(2 * bb.limit());
+    java.nio.ByteBuffer bbr4 =
+      java.nio.ByteBuffer.allocateDirect(5);
+    rc = sqlite3_blob_read( b, bbr3 );
+    affirm( rc==0 );
+    rc = sqlite3_blob_read( b, bbr4 );
+    affirm( rc==0 );
+    affirm( sqlite3_blob_bytes(b)==bbr3.limit() );
+    affirm( 5==bbr4.limit() );
+    sqlite3_blob_close(b);
     affirm( 0==br[0] );
     affirm( 0==br[9] );
+    affirm( 0==bbr.get(0) );
+    affirm( 0==bbr.get(9) );
+    affirm( bbr2.limit() == 6 );
+    affirm( 0==bbr3.get(0) );
+    {
+      Exception ex = null;
+      try{ bbr3.get(11); }
+      catch(Exception e){ex = e;}
+      affirm( ex instanceof IndexOutOfBoundsException,
+              "bbr3.limit() was reset by read()" );
+      ex = null;
+    }
+    affirm( 0==bbr4.get(0) );
     for( int i = 1; i < 9; ++i ){
       affirm( br[i] == 48 + i );
+      affirm( br[i] == bbr.get(i) );
+      affirm( br[i] == bbr3.get(i) );
+      if( i>3 ){
+        affirm( br[i] == bbr2.get(i-4) );
+      }
+      if( i < bbr4.limit() ){
+        affirm( br[i] == bbr4.get(i) );
+      }
     }
     sqlite3_close_v2(db);
   }
index 040b8a2110490bbe51a08f0590e8db27de2ab5d9..d62656917f332a99f2f08ad7c86ad985736f4232 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C JNI:\schange\ssqlite3_prepare_multi()'s\sexception-handling\ssemantics\sto\sbe\smore\sC-like\sand,\sto\ssupport\sthat,\sadd\sthe\spackage-private\ssqlite3_jni_db_error()\smethod\sto\sset\sthe\sdb\serror\sstate\sfrom\spackage-level\sJava\scode.
-D 2023-11-14T02:43:30.475
+C JNI:\sadd\ssqlite3_blob_read_nio_buffer()\sand\siron\sout\sthe\sblob/ByteBuffer\sinterface\ssomewhat.
+D 2023-11-14T04:59:57.233
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -241,8 +241,8 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3
 F ext/jni/GNUmakefile f2f3a31923293659b95225e932a286af1f2287d75bf88ad6c0fd1b9d9cd020d4
 F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4
 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
-F ext/jni/src/c/sqlite3-jni.c 7d14bf998e9862ecf01b121067b745eeb75668ca0a431df6e2a86fb5a500bca5
-F ext/jni/src/c/sqlite3-jni.h b8876cce091767e0655200b7653dc5a0ae117b53cff7b1090e9dbc2e69775ed5
+F ext/jni/src/c/sqlite3-jni.c 9828d7b6b584c55261e4dd65d86ce4da33daf6cee2966b191ac332ce47efac1c
+F ext/jni/src/c/sqlite3-jni.h 0ed09051f16f612680603a297fefa2c131c4a7e98e0b41cdd9ece08428b47d48
 F ext/jni/src/org/sqlite/jni/annotation/NotNull.java 02091a8112e33389f1c160f506cd413168c8dfacbeda608a4946c6e3557b7d5a
 F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba
 F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca
@@ -251,7 +251,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0b72cdff61533b564d65b63
 F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a
 F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759
 F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca
-F ext/jni/src/org/sqlite/jni/capi/CApi.java e96ed33a5c235082a59bf73d861acbbb7b760f2c790ac719e495d8512e4de8c3
+F ext/jni/src/org/sqlite/jni/capi/CApi.java a7c53a3226c6826ada00752a651a31e6cce3b8d741a02b2d45cb0d1e3dfc3a80
 F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 57e2d275dcebe690b1fc1f3d34eb96879b2d7039bce30b563aee547bf45d8a8b
 F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
 F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab
@@ -269,7 +269,7 @@ F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 0d1e9afc9ff8a2adb94a155b72385
 F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1
 F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615
 F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f
-F ext/jni/src/org/sqlite/jni/capi/Tester1.java fb0d859a07988bf0757b0910431d8d12a5f7f177eb7e7632f27eebc524b2aa92
+F ext/jni/src/org/sqlite/jni/capi/Tester1.java dcaa283a27aecb25dfd8f1a610885fb95d24945235b51ea13a1143585922de04
 F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723
 F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56
 F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 22d365746a78c5cd7ae10c39444eb7bbf1a819aad4bb7eb77b1edc47773a3950
@@ -2139,8 +2139,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ca32af8542aa2725cc87f54541b19897556f610e4674edf9f22a84e3d4097a82
-R 8cb29fe765a47cc780c8d97ffc39bea6
+P 46656b354311ec0a36832af1c4ccb3b6a244aa55cfb3681e25c3f42b13b387dd
+R 4e0b6f66f2c79b3b0f3d9c780b63f86e
 U stephan
-Z 32cdbaea235e75a5f5809e209395feaf
+Z 5994994aa13f973034ef1e21e15b70de
 # Remove this line to create a well-formed Fossil manifest.
index f6caae534c5ec7e9bc70e55395d6b3e7a8a9190e..8b049893ca8d451221811261e927e2cc6cb56629 100644 (file)
@@ -1 +1 @@
-46656b354311ec0a36832af1c4ccb3b6a244aa55cfb3681e25c3f42b13b387dd
\ No newline at end of file
+7df317b448a09ae77e2c68cc901fdb6d56a2246c1313f06bebd1f3e53f02c19b
\ No newline at end of file