summaryrefslogtreecommitdiff
path: root/bdb/libdb_java
diff options
context:
space:
mode:
authortim@threads.polyesthetic.msg <>2001-03-04 19:42:05 -0500
committertim@threads.polyesthetic.msg <>2001-03-04 19:42:05 -0500
commit89dad52004ecba5a380aeebb0e2a9beaae88eb86 (patch)
tree9dd732e08dba156ee3d7635caedc0dc3107ecac6 /bdb/libdb_java
parent639a1069d313843288ba6d9cb54b290073a748a7 (diff)
downloadmariadb-git-89dad52004ecba5a380aeebb0e2a9beaae88eb86.tar.gz
Import changeset
Diffstat (limited to 'bdb/libdb_java')
-rw-r--r--bdb/libdb_java/checkapi.prl132
-rw-r--r--bdb/libdb_java/com_sleepycat_db_Db.h349
-rw-r--r--bdb/libdb_java/com_sleepycat_db_DbEnv.h509
-rw-r--r--bdb/libdb_java/com_sleepycat_db_DbLock.h29
-rw-r--r--bdb/libdb_java/com_sleepycat_db_DbLsn.h29
-rw-r--r--bdb/libdb_java/com_sleepycat_db_DbTxn.h53
-rw-r--r--bdb/libdb_java/com_sleepycat_db_Dbc.h69
-rw-r--r--bdb/libdb_java/com_sleepycat_db_Dbt.h157
-rw-r--r--bdb/libdb_java/java_Db.c964
-rw-r--r--bdb/libdb_java/java_DbEnv.c1300
-rw-r--r--bdb/libdb_java/java_DbLock.c55
-rw-r--r--bdb/libdb_java/java_DbLsn.c43
-rw-r--r--bdb/libdb_java/java_DbTxn.c82
-rw-r--r--bdb/libdb_java/java_Dbc.c196
-rw-r--r--bdb/libdb_java/java_Dbt.c176
-rw-r--r--bdb/libdb_java/java_info.c1001
-rw-r--r--bdb/libdb_java/java_info.h200
-rw-r--r--bdb/libdb_java/java_locked.c294
-rw-r--r--bdb/libdb_java/java_locked.h98
-rw-r--r--bdb/libdb_java/java_util.c556
-rw-r--r--bdb/libdb_java/java_util.h359
21 files changed, 6651 insertions, 0 deletions
diff --git a/bdb/libdb_java/checkapi.prl b/bdb/libdb_java/checkapi.prl
new file mode 100644
index 00000000000..25882c056cc
--- /dev/null
+++ b/bdb/libdb_java/checkapi.prl
@@ -0,0 +1,132 @@
+#
+# Released to public domain by Donald Anderson dda@world.std.com
+# No warranties.
+#
+# Perl script to check for matching of JNI interfaces to implementation.
+# We check all .cpp arguments and .h arguments and make sure that for
+# each .h declaration (marked by JNIEXPORT keyword), there is a .cpp
+# definition for the same function (also marked by JNIEXPORT keyword),
+# and vice versa. Definitions and declarations are determined solely
+# by whether they are in a .h or .cpp file - we don't do any further
+# analysis.
+#
+# Some additions made to help with Berkeley DB sources:
+#
+# Berkeley DB Java sources use JAVADB_*_ACCESS #defines
+# to quickly define routine access functions.
+
+foreach $file (<@ARGV>) { # glob allows direct use from Win* makefiles
+ open (FILE, $file) || die "$file: cannot open\n";
+ $dot_h = 0;
+ if ($file =~ /.*[hH]$/) {
+ $dot_h = 1;
+ }
+ $in_def = 0;
+nextline:
+ while (<FILE>) {
+ chop;
+ if (/JNIEXPORT/ || /^JAVADB_.*_ACCESS/) {
+ $in_def = 1;
+ $def = "";
+ }
+ if ($in_def == 1) {
+ $def .= $_;
+ }
+ if (/\)/) {
+ $line = "";
+ $in_def = 0;
+ if ($def eq "") {
+ next nextline;
+ }
+ $_ = $def;
+ # remove comments
+ s@/\*[^*]*\*/@@g;
+ s@[ ][ ]*@ @g;
+ s@JNIEnv *\* *@JNIEnv @g;
+ s@([,*()]) @\1@g;
+ s@ ([,*()])@\1@g;
+
+ s/JAVADB_WO_ACCESS_METHOD/JAVADB_WO_ACCESS/;
+
+ if (/^JAVADB_.*_ACCESS/) {
+ s@ *@ @g;
+ s@_ACCESS_STRING\(([^,]*),@_ACCESS(\1,jstring,@;
+ s@_ACCESS_BEFORE_APPINIT@_ACCESS@;
+ s@_ACCESS\(@,normal,@;
+ s@JAVADB_@@;
+ s@\)@,@;
+ @vars = split(/,/);
+ $get = 0;
+ $set = 0;
+ if (@vars[0] eq "RW") {
+ $get = 1;
+ $set = 1;
+ }
+ if (@vars[0] eq "RO") {
+ $get = 1;
+ }
+ if (@vars[0] eq "WO") {
+ $set = 1;
+ }
+ if ($get == 0 && $set == 0) {
+ print "Invalid use of JAVADB_ macro\n";
+ }
+ if ($set == 1) {
+ $line = "JNIEXPORT void JNICALL Java_com_sleepycat_db_@vars[2]_set_1@vars[4](JNIEnv,jobject,@vars[3])";
+ }
+ if ($get == 1) {
+ $line2 = "JNIEXPORT @vars[3] JNICALL Java_com_sleepycat_db_@vars[2]_get_1@vars[4](JNIEnv,jobject)";
+ }
+ }
+ else {
+ s@([,(][a-zA-Z0-9_]*) [a-zA-Z0-9_]*@\1@g;
+ s@;$@@g;
+ $line = $_;
+ }
+
+ $def = "";
+
+ if ($line ne "") {
+ if ($lines{$line} eq "") {
+ $lines{$line} = 0;
+ }
+ if ($dot_h == 1) {
+ $lines{$line} += 1;
+ }
+ else {
+ $lines{$line} -= 1;
+ }
+ $line = "";
+ }
+ if ($line2 ne "") {
+ if ($lines{$line2} eq "") {
+ $lines{$line2} = 0;
+ }
+ if ($dot_h == 1) {
+ $lines{$line2} += 1;
+ }
+ else {
+ $lines{$line2} -= 1;
+ }
+ $line2 = "";
+ }
+ }
+ }
+ close (FILE);
+}
+
+$status = 0;
+foreach $key (sort keys %lines) {
+ if ($lines{$key} != 0) {
+ if ($lines{$key} > 0) {
+ print "Missing .cpp implementation: $lines${key}\n";
+ $status = 1;
+ }
+ else {
+ print "Missing .h declaration: $lines${key}\n";
+ $status = 1;
+ }
+ }
+}
+
+exit ($status);
diff --git a/bdb/libdb_java/com_sleepycat_db_Db.h b/bdb/libdb_java/com_sleepycat_db_Db.h
new file mode 100644
index 00000000000..d9e1f1cbbc7
--- /dev/null
+++ b/bdb/libdb_java/com_sleepycat_db_Db.h
@@ -0,0 +1,349 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_sleepycat_db_Db */
+
+#ifndef _Included_com_sleepycat_db_Db
+#define _Included_com_sleepycat_db_Db
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: _init
+ * Signature: (Lcom/sleepycat/db/DbEnv;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1init
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: _notify_internal
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1notify_1internal
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: _close
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db__1close
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: cursor
+ * Signature: (Lcom/sleepycat/db/DbTxn;I)Lcom/sleepycat/db/Dbc;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_cursor
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: del
+ * Signature: (Lcom/sleepycat/db/DbTxn;Lcom/sleepycat/db/Dbt;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_del
+ (JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: err
+ * Signature: (ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_err
+ (JNIEnv *, jobject, jint, jstring);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: errx
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_errx
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: fd
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_fd
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: _finalize
+ * Signature: (Lcom/sleepycat/db/DbErrcall;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1finalize
+ (JNIEnv *, jobject, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: get
+ * Signature: (Lcom/sleepycat/db/DbTxn;Lcom/sleepycat/db/Dbt;Lcom/sleepycat/db/Dbt;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_get
+ (JNIEnv *, jobject, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: get_byteswapped
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_sleepycat_db_Db_get_1byteswapped
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: get_type
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_get_1type
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: join
+ * Signature: ([Lcom/sleepycat/db/Dbc;I)Lcom/sleepycat/db/Dbc;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_join
+ (JNIEnv *, jobject, jobjectArray, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: key_range
+ * Signature: (Lcom/sleepycat/db/DbTxn;Lcom/sleepycat/db/Dbt;Lcom/sleepycat/db/DbKeyRange;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_key_1range
+ (JNIEnv *, jobject, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: _open
+ * Signature: (Ljava/lang/String;Ljava/lang/String;III)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1open
+ (JNIEnv *, jobject, jstring, jstring, jint, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: put
+ * Signature: (Lcom/sleepycat/db/DbTxn;Lcom/sleepycat/db/Dbt;Lcom/sleepycat/db/Dbt;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_put
+ (JNIEnv *, jobject, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: rename
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_rename
+ (JNIEnv *, jobject, jstring, jstring, jstring, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: remove
+ * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_remove
+ (JNIEnv *, jobject, jstring, jstring, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: append_recno_changed
+ * Signature: (Lcom/sleepycat/db/DbAppendRecno;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_append_1recno_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: bt_compare_changed
+ * Signature: (Lcom/sleepycat/db/DbBtreeCompare;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_bt_1compare_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_bt_maxkey
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1bt_1maxkey
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_bt_minkey
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1bt_1minkey
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: bt_prefix_changed
+ * Signature: (Lcom/sleepycat/db/DbBtreePrefix;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_bt_1prefix_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_cachesize
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1cachesize
+ (JNIEnv *, jobject, jint, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: dup_compare_changed
+ * Signature: (Lcom/sleepycat/db/DbDupCompare;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_dup_1compare_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: feedback_changed
+ * Signature: (Lcom/sleepycat/db/DbFeedback;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_feedback_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_flags
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1flags
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_h_ffactor
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1h_1ffactor
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: hash_changed
+ * Signature: (Lcom/sleepycat/db/DbHash;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_hash_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_h_nelem
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1h_1nelem
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_lorder
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1lorder
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_pagesize
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1pagesize
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_re_delim
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1re_1delim
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_re_len
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1re_1len
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_re_pad
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1re_1pad
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_re_source
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1re_1source
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: set_q_extentsize
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1q_1extentsize
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: stat
+ * Signature: (I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_stat
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: sync
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_sync
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: upgrade
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_upgrade
+ (JNIEnv *, jobject, jstring, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: verify
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/io/OutputStream;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_verify
+ (JNIEnv *, jobject, jstring, jstring, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Db
+ * Method: one_time_init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_one_1time_1init
+ (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bdb/libdb_java/com_sleepycat_db_DbEnv.h b/bdb/libdb_java/com_sleepycat_db_DbEnv.h
new file mode 100644
index 00000000000..4168ea9abe2
--- /dev/null
+++ b/bdb/libdb_java/com_sleepycat_db_DbEnv.h
@@ -0,0 +1,509 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_sleepycat_db_DbEnv */
+
+#ifndef _Included_com_sleepycat_db_DbEnv
+#define _Included_com_sleepycat_db_DbEnv
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _close
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1close
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: err
+ * Signature: (ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_err
+ (JNIEnv *, jobject, jint, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: errx
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_errx
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _finalize
+ * Signature: (Lcom/sleepycat/db/DbErrcall;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1finalize
+ (JNIEnv *, jobject, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _init
+ * Signature: (Lcom/sleepycat/db/DbErrcall;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1init
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _init_using_db
+ * Signature: (Lcom/sleepycat/db/DbErrcall;Lcom/sleepycat/db/Db;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1init_1using_1db
+ (JNIEnv *, jobject, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _notify_db_close
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1notify_1db_1close
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: open
+ * Signature: (Ljava/lang/String;II)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_open
+ (JNIEnv *, jobject, jstring, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: remove
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_remove
+ (JNIEnv *, jobject, jstring, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_cachesize
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1cachesize
+ (JNIEnv *, jobject, jint, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _set_errcall
+ * Signature: (Lcom/sleepycat/db/DbErrcall;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1set_1errcall
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _set_errpfx
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1set_1errpfx
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: feedback_changed
+ * Signature: (Lcom/sleepycat/db/DbFeedback;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_feedback_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_verbose
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1verbose
+ (JNIEnv *, jobject, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_data_dir
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1data_1dir
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lg_bsize
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lg_1bsize
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lg_dir
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lg_1dir
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lg_max
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lg_1max
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lk_conflicts
+ * Signature: ([[B)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lk_1conflicts
+ (JNIEnv *, jobject, jobjectArray);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lk_detect
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lk_1detect
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lk_max
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lk_1max
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lk_max_lockers
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lk_1max_1lockers
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lk_max_locks
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lk_1max_1locks
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_lk_max_objects
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lk_1max_1objects
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_mp_mmapsize
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1mp_1mmapsize
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_mutexlocks
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1mutexlocks
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_pageyield
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1pageyield
+ (JNIEnv *, jclass, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_panicstate
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1panicstate
+ (JNIEnv *, jclass, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: recovery_init_changed
+ * Signature: (Lcom/sleepycat/db/DbRecoveryInit;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_recovery_1init_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_region_init
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1region_1init
+ (JNIEnv *, jclass, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_flags
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1flags
+ (JNIEnv *, jobject, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_server
+ * Signature: (Ljava/lang/String;JJI)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1server
+ (JNIEnv *, jobject, jstring, jlong, jlong, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_shm_key
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1shm_1key
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_tas_spins
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1tas_1spins
+ (JNIEnv *, jclass, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_tmp_dir
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1tmp_1dir
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: tx_recover_changed
+ * Signature: (Lcom/sleepycat/db/DbTxnRecover;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_tx_1recover_1changed
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: set_tx_max
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1tx_1max
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: _set_tx_timestamp
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1set_1tx_1timestamp
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: get_version_major
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1major
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: get_version_minor
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1minor
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: get_version_patch
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1patch
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: get_version_string
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1string
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: strerror
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_sleepycat_db_DbEnv_strerror
+ (JNIEnv *, jclass, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: lock_detect
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_lock_1detect
+ (JNIEnv *, jobject, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: lock_get
+ * Signature: (IILcom/sleepycat/db/Dbt;I)Lcom/sleepycat/db/DbLock;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_lock_1get
+ (JNIEnv *, jobject, jint, jint, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: lock_id
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_lock_1id
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: lock_stat
+ * Signature: ()Lcom/sleepycat/db/DbLockStat;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_lock_1stat
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_archive
+ * Signature: (I)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_com_sleepycat_db_DbEnv_log_1archive
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_compare
+ * Signature: (Lcom/sleepycat/db/DbLsn;Lcom/sleepycat/db/DbLsn;)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_log_1compare
+ (JNIEnv *, jclass, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_file
+ * Signature: (Lcom/sleepycat/db/DbLsn;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_sleepycat_db_DbEnv_log_1file
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_flush
+ * Signature: (Lcom/sleepycat/db/DbLsn;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1flush
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_get
+ * Signature: (Lcom/sleepycat/db/DbLsn;Lcom/sleepycat/db/Dbt;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1get
+ (JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_put
+ * Signature: (Lcom/sleepycat/db/DbLsn;Lcom/sleepycat/db/Dbt;I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1put
+ (JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_stat
+ * Signature: ()Lcom/sleepycat/db/DbLogStat;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_log_1stat
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_register
+ * Signature: (Lcom/sleepycat/db/Db;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1register
+ (JNIEnv *, jobject, jobject, jstring);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: log_unregister
+ * Signature: (Lcom/sleepycat/db/Db;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1unregister
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: memp_stat
+ * Signature: ()Lcom/sleepycat/db/DbMpoolStat;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_memp_1stat
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: memp_fstat
+ * Signature: ()[Lcom/sleepycat/db/DbMpoolFStat;
+ */
+JNIEXPORT jobjectArray JNICALL Java_com_sleepycat_db_DbEnv_memp_1fstat
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: memp_trickle
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_memp_1trickle
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: txn_begin
+ * Signature: (Lcom/sleepycat/db/DbTxn;I)Lcom/sleepycat/db/DbTxn;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_txn_1begin
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: txn_checkpoint
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_txn_1checkpoint
+ (JNIEnv *, jobject, jint, jint, jint);
+
+/*
+ * Class: com_sleepycat_db_DbEnv
+ * Method: txn_stat
+ * Signature: ()Lcom/sleepycat/db/DbTxnStat;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_txn_1stat
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bdb/libdb_java/com_sleepycat_db_DbLock.h b/bdb/libdb_java/com_sleepycat_db_DbLock.h
new file mode 100644
index 00000000000..8a1c135bb3b
--- /dev/null
+++ b/bdb/libdb_java/com_sleepycat_db_DbLock.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_sleepycat_db_DbLock */
+
+#ifndef _Included_com_sleepycat_db_DbLock
+#define _Included_com_sleepycat_db_DbLock
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_sleepycat_db_DbLock
+ * Method: finalize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLock_finalize
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbLock
+ * Method: put
+ * Signature: (Lcom/sleepycat/db/DbEnv;)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLock_put
+ (JNIEnv *, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bdb/libdb_java/com_sleepycat_db_DbLsn.h b/bdb/libdb_java/com_sleepycat_db_DbLsn.h
new file mode 100644
index 00000000000..093eaf372b5
--- /dev/null
+++ b/bdb/libdb_java/com_sleepycat_db_DbLsn.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_sleepycat_db_DbLsn */
+
+#ifndef _Included_com_sleepycat_db_DbLsn
+#define _Included_com_sleepycat_db_DbLsn
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_sleepycat_db_DbLsn
+ * Method: finalize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLsn_finalize
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbLsn
+ * Method: init_lsn
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLsn_init_1lsn
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bdb/libdb_java/com_sleepycat_db_DbTxn.h b/bdb/libdb_java/com_sleepycat_db_DbTxn.h
new file mode 100644
index 00000000000..4dcf47405c0
--- /dev/null
+++ b/bdb/libdb_java/com_sleepycat_db_DbTxn.h
@@ -0,0 +1,53 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_sleepycat_db_DbTxn */
+
+#ifndef _Included_com_sleepycat_db_DbTxn
+#define _Included_com_sleepycat_db_DbTxn
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_sleepycat_db_DbTxn
+ * Method: abort
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_abort
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbTxn
+ * Method: commit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_commit
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_DbTxn
+ * Method: id
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbTxn_id
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbTxn
+ * Method: prepare
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_prepare
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_DbTxn
+ * Method: finalize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_finalize
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bdb/libdb_java/com_sleepycat_db_Dbc.h b/bdb/libdb_java/com_sleepycat_db_Dbc.h
new file mode 100644
index 00000000000..e62679c6f66
--- /dev/null
+++ b/bdb/libdb_java/com_sleepycat_db_Dbc.h
@@ -0,0 +1,69 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_sleepycat_db_Dbc */
+
+#ifndef _Included_com_sleepycat_db_Dbc
+#define _Included_com_sleepycat_db_Dbc
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_sleepycat_db_Dbc
+ * Method: close
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbc_close
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbc
+ * Method: count
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_count
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbc
+ * Method: del
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_del
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbc
+ * Method: dup
+ * Signature: (I)Lcom/sleepycat/db/Dbc;
+ */
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Dbc_dup
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbc
+ * Method: get
+ * Signature: (Lcom/sleepycat/db/Dbt;Lcom/sleepycat/db/Dbt;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_get
+ (JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbc
+ * Method: put
+ * Signature: (Lcom/sleepycat/db/Dbt;Lcom/sleepycat/db/Dbt;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_put
+ (JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbc
+ * Method: finalize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbc_finalize
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bdb/libdb_java/com_sleepycat_db_Dbt.h b/bdb/libdb_java/com_sleepycat_db_Dbt.h
new file mode 100644
index 00000000000..cdb58c682c9
--- /dev/null
+++ b/bdb/libdb_java/com_sleepycat_db_Dbt.h
@@ -0,0 +1,157 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_sleepycat_db_Dbt */
+
+#ifndef _Included_com_sleepycat_db_Dbt
+#define _Included_com_sleepycat_db_Dbt
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: finalize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_finalize
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_data
+ * Signature: ()[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_com_sleepycat_db_Dbt_get_1data
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: internal_set_data
+ * Signature: ([B)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_internal_1set_1data
+ (JNIEnv *, jobject, jbyteArray);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: set_offset
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1offset
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_offset
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1offset
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_size
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1size
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: set_size
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1size
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_ulen
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1ulen
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: set_ulen
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1ulen
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_dlen
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1dlen
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: set_dlen
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1dlen
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_doff
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1doff
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: set_doff
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1doff
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_flags
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1flags
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: set_flags
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1flags
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: set_recno_key_data
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1recno_1key_1data
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: get_recno_key_data
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1recno_1key_1data
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_sleepycat_db_Dbt
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_init
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bdb/libdb_java/java_Db.c b/bdb/libdb_java/java_Db.c
new file mode 100644
index 00000000000..5b01e5068d6
--- /dev/null
+++ b/bdb/libdb_java/java_Db.c
@@ -0,0 +1,964 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_Db.c,v 11.34 2000/11/30 00:58:38 ubell Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "db_int.h"
+#include "db_page.h"
+#include "db_ext.h"
+#include "java_util.h"
+#include "com_sleepycat_db_Db.h"
+
+/* This struct is used in Db.verify and its callback */
+struct verify_callback_struct {
+ JNIEnv *env;
+ jobject streamobj;
+ jbyteArray bytes;
+ int nbytes;
+ jmethodID writemid;
+};
+
+JAVADB_WO_ACCESS_METHOD(Db, jint, flags, DB, flags)
+JAVADB_WO_ACCESS_METHOD(Db, jint, h_1ffactor, DB, h_ffactor)
+JAVADB_WO_ACCESS_METHOD(Db, jint, h_1nelem, DB, h_nelem)
+JAVADB_WO_ACCESS_METHOD(Db, jint, lorder, DB, lorder)
+JAVADB_WO_ACCESS_METHOD(Db, jint, re_1delim, DB, re_delim)
+JAVADB_WO_ACCESS_METHOD(Db, jint, re_1len, DB, re_len)
+JAVADB_WO_ACCESS_METHOD(Db, jint, re_1pad, DB, re_pad)
+JAVADB_WO_ACCESS_METHOD(Db, jint, q_1extentsize, DB, q_extentsize)
+JAVADB_WO_ACCESS_METHOD(Db, jint, bt_1maxkey, DB, bt_maxkey)
+JAVADB_WO_ACCESS_METHOD(Db, jint, bt_1minkey, DB, bt_minkey)
+
+/* This only gets called once ever, at the beginning of execution
+ * and can be used to initialize unchanging methodIds, fieldIds, etc.
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_one_1time_1init
+ (JNIEnv *jnienv, /*Db.class*/ jclass jthisclass)
+{
+ COMPQUIET(jnienv, NULL);
+ COMPQUIET(jthisclass, NULL);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1init
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbEnv*/ jobject jdbenv, jint flags)
+{
+ int err;
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+ DB_ENV *dbenv;
+
+ dbenv = get_DB_ENV(jnienv, jdbenv);
+ dbinfo = get_DB_JAVAINFO(jnienv, jthis);
+ DB_ASSERT(dbinfo == NULL);
+
+ err = db_create(&db, dbenv, flags);
+ if (verify_return(jnienv, err, 0)) {
+ set_private_dbobj(jnienv, name_DB, jthis, db);
+ dbinfo = dbji_construct(jnienv, flags);
+ set_private_info(jnienv, name_DB, jthis, dbinfo);
+ db->cj_internal = dbinfo;
+ }
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db__1close
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jint flags)
+{
+ int err;
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+
+ db = get_DB(jnienv, jthis);
+ dbinfo = get_DB_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return (0);
+
+ JAVADB_API_BEGIN(db, jthis);
+
+ /* Null out the private data to indicate the DB is invalid.
+ * We do this in advance to help guard against multithreading
+ * issues.
+ */
+ set_private_dbobj(jnienv, name_DB, jthis, 0);
+
+ err = db->close(db, flags);
+ if (err != DB_INCOMPLETE)
+ verify_return(jnienv, err, 0);
+ dbji_dealloc(dbinfo, jnienv);
+
+ /* don't call JAVADB_API_END - db cannot be used */
+ return (err);
+}
+
+/* We are being notified that the parent DbEnv has closed.
+ * Zero out the pointer to the DB, since it is no longer
+ * valid, to prevent mistakes. The user will get a null
+ * pointer exception if they try to use this Db again.
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1notify_1internal
+ (JNIEnv *jnienv, /*Db*/ jobject jthis)
+{
+ set_private_dbobj(jnienv, name_DB, jthis, 0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_append_1recno_1changed
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbAppendRecno*/ jobject jcallback)
+{
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+
+ JAVADB_API_BEGIN(db, jthis);
+ dbinfo = (DB_JAVAINFO*)db->cj_internal;
+ dbji_set_append_recno_object(dbinfo, jnienv, db, jcallback);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_bt_1compare_1changed
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbBtreeCompare*/ jobject jbtcompare)
+{
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+
+ JAVADB_API_BEGIN(db, jthis);
+ dbinfo = (DB_JAVAINFO*)db->cj_internal;
+ dbji_set_bt_compare_object(dbinfo, jnienv, db, jbtcompare);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_bt_1prefix_1changed
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbBtreePrefix*/ jobject jbtprefix)
+{
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+
+ JAVADB_API_BEGIN(db, jthis);
+ dbinfo = (DB_JAVAINFO*)db->cj_internal;
+ dbji_set_bt_prefix_object(dbinfo, jnienv, db, jbtprefix);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_cursor
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid, jint flags)
+{
+ int err;
+ DBC *dbc;
+ DB *db = get_DB(jnienv, jthis);
+ DB_TXN *dbtxnid = get_DB_TXN(jnienv, txnid);
+
+ if (!verify_non_null(jnienv, db))
+ return (NULL);
+ err = db->cursor(db, dbtxnid, &dbc, flags);
+ verify_return(jnienv, err, 0);
+ return (get_Dbc(jnienv, dbc));
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_del
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
+ /*Dbt*/ jobject key, jint dbflags)
+{
+ int err;
+ DB_TXN *dbtxnid;
+ DB *db;
+ JDBT dbkey;
+
+ err = 0;
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return (0);
+
+ JAVADB_API_BEGIN(db, jthis);
+ dbtxnid = get_DB_TXN(jnienv, txnid);
+ if (jdbt_lock(&dbkey, jnienv, key, inOp) != 0)
+ goto out;
+
+ err = db->del(db, dbtxnid, &dbkey.dbt->dbt, dbflags);
+ if (err != DB_NOTFOUND) {
+ verify_return(jnienv, err, 0);
+ }
+
+ out:
+ jdbt_unlock(&dbkey, jnienv);
+ JAVADB_API_END(db);
+ return (err);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_dup_1compare_1changed
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbDupCompare*/ jobject jdupcompare)
+{
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+
+ JAVADB_API_BEGIN(db, jthis);
+ dbinfo = (DB_JAVAINFO*)db->cj_internal;
+ dbji_set_dup_compare_object(dbinfo, jnienv, db, jdupcompare);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_err
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jint ecode, jstring msg)
+{
+ DB *db;
+ JSTR msg_string;
+
+ if (jstr_lock(&msg_string, jnienv, msg) != 0)
+ goto out;
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ goto out;
+
+ JAVADB_API_BEGIN(db, jthis);
+ db->err(db, ecode, msg_string.string);
+ JAVADB_API_END(db);
+
+ out:
+ jstr_unlock(&msg_string, jnienv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_errx
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring msg)
+{
+ JSTR msg_string;
+ DB *db = get_DB(jnienv, jthis);
+
+ if (jstr_lock(&msg_string, jnienv, msg) != 0)
+ goto out;
+ if (!verify_non_null(jnienv, db))
+ goto out;
+
+ JAVADB_API_BEGIN(db, jthis);
+ db->errx(db, msg_string.string);
+ JAVADB_API_END(db);
+
+ out:
+ jstr_unlock(&msg_string, jnienv);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_fd
+ (JNIEnv *jnienv, /*Db*/ jobject jthis)
+{
+ int err;
+ int return_value = 0;
+ DB *db = get_DB(jnienv, jthis);
+
+ if (!verify_non_null(jnienv, db))
+ return (0);
+
+ JAVADB_API_BEGIN(db, jthis);
+ err = db->fd(db, &return_value);
+ verify_return(jnienv, err, 0);
+ JAVADB_API_END(db);
+
+ return (return_value);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_feedback_1changed
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbFeedback*/ jobject jfeedback)
+{
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+
+ JAVADB_API_BEGIN(db, jthis);
+ dbinfo = (DB_JAVAINFO*)db->cj_internal;
+ dbji_set_feedback_object(dbinfo, jnienv, db, jfeedback);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_get
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
+ /*Dbt*/ jobject key, /*Dbt*/ jobject data, jint flags)
+{
+ int err, op_flags, retry;
+ DB *db;
+ OpKind keyop, dataop;
+ DB_TXN *dbtxnid;
+ JDBT dbkey, dbdata;
+
+ err = 0;
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ goto out3;
+
+ JAVADB_API_BEGIN(db, jthis);
+
+ /* Depending on flags, the key may be input/output. */
+ keyop = inOp;
+ dataop = outOp;
+ op_flags = flags & DB_OPFLAGS_MASK;
+ if (op_flags == DB_SET_RECNO) {
+ keyop = inOutOp;
+ }
+ else if (op_flags == DB_GET_BOTH) {
+ keyop = inOutOp;
+ dataop = inOutOp;
+ }
+
+ dbtxnid = get_DB_TXN(jnienv, txnid);
+
+ if (jdbt_lock(&dbkey, jnienv, key, keyop) != 0)
+ goto out2;
+ if (jdbt_lock(&dbdata, jnienv, data, dataop) != 0)
+ goto out1;
+ for (retry = 0; retry < 3; retry++) {
+ err = db->get(db, dbtxnid, &dbkey.dbt->dbt, &dbdata.dbt->dbt, flags);
+
+ /* If we failed due to lack of memory in our DBT arrays,
+ * retry.
+ */
+ if (err != ENOMEM)
+ break;
+ if (!jdbt_realloc(&dbdata, jnienv))
+ break;
+ }
+ if (err != DB_NOTFOUND) {
+ verify_return(jnienv, err, 0);
+ }
+ out1:
+ jdbt_unlock(&dbdata, jnienv);
+ out2:
+ jdbt_unlock(&dbkey, jnienv);
+ out3:
+ JAVADB_API_END(db);
+ return (err);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_hash_1changed
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbHash*/ jobject jhash)
+{
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+
+ JAVADB_API_BEGIN(db, jthis);
+ dbinfo = (DB_JAVAINFO*)db->cj_internal;
+ dbji_set_h_hash_object(dbinfo, jnienv, db, jhash);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_join
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*Dbc[]*/ jobjectArray curslist,
+ jint flags)
+{
+ int err;
+ DB *db = get_DB(jnienv, jthis);
+ int count = (*jnienv)->GetArrayLength(jnienv, curslist);
+ DBC **newlist = (DBC **)malloc(sizeof(DBC *) * (count+1));
+ DBC *dbc;
+ int i;
+
+ /* Convert the java array of Dbc's to a C array of DBC's. */
+ for (i=0; i<count; i++) {
+ jobject jobj = (*jnienv)->GetObjectArrayElement(jnienv, curslist, i);
+ if (jobj == 0) {
+ /*
+ * An embedded null in the array is treated
+ * as an endpoint.
+ */
+ newlist[i] = 0;
+ break;
+ }
+ else {
+ newlist[i] = get_DBC(jnienv, jobj);
+ }
+ }
+ newlist[count] = 0;
+
+ if (!verify_non_null(jnienv, db))
+ return (NULL);
+ JAVADB_API_BEGIN(db, jthis);
+
+ err = db->join(db, newlist, &dbc, flags);
+ free(newlist);
+ verify_return(jnienv, err, 0);
+
+ JAVADB_API_END(db);
+ return (get_Dbc(jnienv, dbc));
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_key_1range
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject jtxn,
+ /*Dbt*/ jobject jkey, jobject /*DbKeyRange*/ range, jint flags)
+{
+ int err;
+ DB *db = get_DB(jnienv, jthis);
+ DB_TXN *txn = get_DB_TXN(jnienv, jtxn);
+ JDBT dbkey;
+ DB_KEY_RANGE result;
+ jfieldID fid;
+ jclass krclass;
+
+ if (!verify_non_null(jnienv, db))
+ return;
+ JAVADB_API_BEGIN(db, jthis);
+ if (!verify_non_null(jnienv, range))
+ return;
+ if (jdbt_lock(&dbkey, jnienv, jkey, inOp) != 0)
+ goto out;
+ err = db->key_range(db, txn, &dbkey.dbt->dbt, &result, flags);
+ if (verify_return(jnienv, err, 0)) {
+ /* fill in the values of the DbKeyRange structure */
+ krclass = get_class(jnienv, "DbKeyRange");
+ fid = (*jnienv)->GetFieldID(jnienv, krclass, "less", "D");
+ (*jnienv)->SetDoubleField(jnienv, range, fid, result.less);
+ fid = (*jnienv)->GetFieldID(jnienv, krclass, "equal", "D");
+ (*jnienv)->SetDoubleField(jnienv, range, fid, result.equal);
+ fid = (*jnienv)->GetFieldID(jnienv, krclass, "greater", "D");
+ (*jnienv)->SetDoubleField(jnienv, range, fid, result.greater);
+ }
+ out:
+ jdbt_unlock(&dbkey, jnienv);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_put
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
+ /*Dbt*/ jobject key, /*Dbt*/ jobject data, jint flags)
+{
+ int err;
+ DB *db;
+ DB_TXN *dbtxnid;
+ JDBT dbkey, dbdata;
+
+ err = 0;
+ db = get_DB(jnienv, jthis);
+ dbtxnid = get_DB_TXN(jnienv, txnid);
+ if (!verify_non_null(jnienv, db))
+ return (0); /* error will be thrown, retval doesn't matter */
+ JAVADB_API_BEGIN(db, jthis);
+
+ if (jdbt_lock(&dbkey, jnienv, key, inOp) != 0)
+ goto out2;
+ if (jdbt_lock(&dbdata, jnienv, data, inOp) != 0)
+ goto out1;
+
+ if (!verify_non_null(jnienv, db))
+ goto out1;
+ err = db->put(db, dbtxnid, &dbkey.dbt->dbt, &dbdata.dbt->dbt, flags);
+ if (err != DB_KEYEXIST) {
+ verify_return(jnienv, err, 0);
+ }
+ out1:
+ jdbt_unlock(&dbdata, jnienv);
+ out2:
+ jdbt_unlock(&dbkey, jnienv);
+ JAVADB_API_END(db);
+ return (err);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_rename
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring file,
+ jstring database, jstring newname, jint flags)
+{
+ int err;
+ DB *db;
+ DB_JAVAINFO *dbinfo;
+ JSTR j_file;
+ JSTR j_database;
+ JSTR j_newname;
+
+ db = get_DB(jnienv, jthis);
+ dbinfo = get_DB_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+ JAVADB_API_BEGIN(db, jthis);
+ if (jstr_lock(&j_file, jnienv, file) != 0)
+ goto out3;
+ if (jstr_lock(&j_database, jnienv, database) != 0)
+ goto out2;
+ if (jstr_lock(&j_newname, jnienv, newname) != 0)
+ goto out1;
+
+ err = db->rename(db, j_file.string, j_database.string,
+ j_newname.string, flags);
+
+ verify_return(jnienv, err, EXCEPTION_FILE_NOT_FOUND);
+ dbji_dealloc(dbinfo, jnienv);
+ set_private_dbobj(jnienv, name_DB, jthis, 0);
+
+ out1:
+ jstr_unlock(&j_newname, jnienv);
+ out2:
+ jstr_unlock(&j_database, jnienv);
+ out3:
+ jstr_unlock(&j_file, jnienv);
+ /* don't call JAVADB_API_END - db cannot be used */
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_remove
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring file,
+ jstring database, jint flags)
+{
+ int err;
+ DB *db = get_DB(jnienv, jthis);
+ DB_JAVAINFO *dbinfo = get_DB_JAVAINFO(jnienv, jthis);
+ JSTR j_file;
+ JSTR j_database;
+
+ dbinfo = get_DB_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+ JAVADB_API_BEGIN(db, jthis);
+ if (jstr_lock(&j_file, jnienv, file) != 0)
+ goto out2;
+ if (jstr_lock(&j_database, jnienv, database) != 0)
+ goto out1;
+ err = db->remove(db, j_file.string, j_database.string, flags);
+
+ set_private_dbobj(jnienv, name_DB, jthis, 0);
+ verify_return(jnienv, err, EXCEPTION_FILE_NOT_FOUND);
+ dbji_dealloc(dbinfo, jnienv);
+
+ out1:
+ jstr_unlock(&j_database, jnienv);
+ out2:
+ jstr_unlock(&j_file, jnienv);
+ /* don't call JAVADB_API_END - db cannot be used */
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_Db_set_1pagesize
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jlong value)
+{
+ int err;
+ DB *db;
+
+ db = get_DB(jnienv, jthis);
+ if (verify_non_null(jnienv, db)) {
+ JAVADB_API_BEGIN(db, jthis);
+ err = db->set_pagesize(db, (u_int32_t)value);
+ verify_return(jnienv, err, 0);
+ JAVADB_API_END(db);
+ }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_Db_set_1cachesize
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jint gbytes, jint bytes,
+ jint ncaches)
+{
+ int err;
+ DB *db;
+
+ db = get_DB(jnienv, jthis);
+ if (verify_non_null(jnienv, db)) {
+ JAVADB_API_BEGIN(db, jthis);
+ err = db->set_cachesize(db, gbytes, bytes, ncaches);
+ verify_return(jnienv, err, 0);
+ JAVADB_API_END(db);
+ }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_Db_set_1re_1source
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring re_source)
+{
+ int err;
+ DB *db;
+
+ db = get_DB(jnienv, jthis);
+ if (verify_non_null(jnienv, db)) {
+ JAVADB_API_BEGIN(db, jthis);
+
+ /* XXX does the string from get_c_string ever get freed? */
+ if (re_source != NULL)
+ err = db->set_re_source(db, get_c_string(jnienv, re_source));
+ else
+ err = db->set_re_source(db, 0);
+
+ verify_return(jnienv, err, 0);
+ JAVADB_API_END(db);
+ }
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_stat
+ (JNIEnv *jnienv, jobject jthis, jint flags)
+{
+ int err;
+ DB *db = get_DB(jnienv, jthis);
+ jobject retval = NULL;
+ jclass dbclass;
+ void *statp = 0;
+ DB_BTREE_STAT *bstp;
+ DB_HASH_STAT *hstp;
+ DB_QUEUE_STAT *qstp;
+
+ if (!verify_non_null(jnienv, db))
+ return (NULL);
+
+ JAVADB_API_BEGIN(db, jthis);
+
+ err = db->stat(db, &statp, NULL, flags);
+ if (verify_return(jnienv, err, 0)) {
+ DBTYPE dbtype = db->get_type(db);
+ switch (dbtype) {
+
+ /* Btree and recno share the same stat structure */
+ case DB_BTREE:
+ case DB_RECNO:
+ bstp = (DB_BTREE_STAT *)statp;
+ retval = create_default_object(jnienv,
+ name_DB_BTREE_STAT);
+ dbclass = get_class(jnienv, name_DB_BTREE_STAT);
+
+ /* Set the individual fields */
+ set_int_field(jnienv, dbclass, retval,
+ "bt_magic", bstp->bt_magic);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_version", bstp->bt_version);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_metaflags", bstp->bt_metaflags);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_nkeys", bstp->bt_nkeys);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_ndata", bstp->bt_ndata);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_pagesize", bstp->bt_pagesize);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_maxkey", bstp->bt_maxkey);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_minkey", bstp->bt_minkey);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_re_len", bstp->bt_re_len);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_re_pad", bstp->bt_re_pad);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_levels", bstp->bt_levels);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_int_pg", bstp->bt_int_pg);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_leaf_pg", bstp->bt_leaf_pg);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_dup_pg", bstp->bt_dup_pg);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_over_pg", bstp->bt_over_pg);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_free", bstp->bt_free);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_int_pgfree", bstp->bt_int_pgfree);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_leaf_pgfree", bstp->bt_leaf_pgfree);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_dup_pgfree", bstp->bt_dup_pgfree);
+ set_int_field(jnienv, dbclass, retval,
+ "bt_over_pgfree", bstp->bt_over_pgfree);
+
+ break;
+
+ /* Hash stat structure */
+ case DB_HASH:
+ hstp = (DB_HASH_STAT *)statp;
+ retval = create_default_object(jnienv,
+ name_DB_HASH_STAT);
+ dbclass = get_class(jnienv, name_DB_HASH_STAT);
+
+ /* Set the individual fields */
+ set_int_field(jnienv, dbclass, retval,
+ "hash_magic", hstp->hash_magic);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_version", hstp->hash_version);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_metaflags", hstp->hash_metaflags);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_nkeys", hstp->hash_nkeys);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_ndata", hstp->hash_ndata);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_pagesize", hstp->hash_pagesize);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_nelem", hstp->hash_nelem);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_ffactor", hstp->hash_ffactor);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_buckets", hstp->hash_buckets);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_free", hstp->hash_free);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_bfree", hstp->hash_bfree);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_bigpages", hstp->hash_bigpages);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_big_bfree", hstp->hash_big_bfree);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_overflows", hstp->hash_overflows);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_ovfl_free", hstp->hash_ovfl_free);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_dup", hstp->hash_dup);
+ set_int_field(jnienv, dbclass, retval,
+ "hash_dup_free", hstp->hash_dup_free);
+
+ break;
+
+ case DB_QUEUE:
+ qstp = (DB_QUEUE_STAT *)statp;
+ retval = create_default_object(jnienv,
+ name_DB_QUEUE_STAT);
+ dbclass = get_class(jnienv, name_DB_QUEUE_STAT);
+
+ /* Set the individual fields */
+ set_int_field(jnienv, dbclass, retval,
+ "qs_magic", qstp->qs_magic);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_version", qstp->qs_version);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_metaflags", qstp->qs_metaflags);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_nkeys", qstp->qs_nkeys);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_ndata", qstp->qs_ndata);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_pagesize", qstp->qs_pagesize);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_pages", qstp->qs_pages);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_re_len", qstp->qs_re_len);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_re_pad", qstp->qs_re_pad);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_pgfree", qstp->qs_pgfree);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_first_recno", qstp->qs_first_recno);
+ set_int_field(jnienv, dbclass, retval,
+ "qs_cur_recno", qstp->qs_cur_recno);
+ break;
+
+ /* That's all the database types we're aware of! */
+ default:
+ report_exception(jnienv,
+ "Db.stat not implemented for types"
+ "other than HASH, BTREE and RECNO",
+ EINVAL, 0);
+ break;
+ }
+ free(statp);
+ }
+ JAVADB_API_END(db);
+ return (retval);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_sync
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jint flags)
+{
+ int err;
+ DB *db = get_DB(jnienv, jthis);
+
+ if (!verify_non_null(jnienv, db))
+ return (0);
+ JAVADB_API_BEGIN(db, jthis);
+ err = db->sync(db, flags);
+ if (err != DB_INCOMPLETE)
+ verify_return(jnienv, err, 0);
+ JAVADB_API_END(db);
+ return (err);
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sleepycat_db_Db_get_1byteswapped
+ (JNIEnv *jnienv, /*Db*/ jobject jthis)
+{
+ DB *db;
+ jboolean retval;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return (0);
+
+ JAVADB_API_BEGIN(db, jthis);
+ retval = db->get_byteswapped(db) ? 1 : 0;
+ JAVADB_API_END(db);
+ return (retval);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_get_1type
+ (JNIEnv *jnienv, /*Db*/ jobject jthis)
+{
+ DB *db;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return (0);
+
+ return ((jint)db->type);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1open
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring file, jstring database,
+ jint type, jint flags, jint mode)
+{
+ int err;
+ DB *db;
+ JSTR dbfile;
+ JSTR dbdatabase;
+
+ /* Java is assumed to be threaded. */
+ flags |= DB_THREAD;
+
+ db = get_DB(jnienv, jthis);
+ if (jstr_lock(&dbfile, jnienv, file) != 0)
+ goto out2;
+ if (jstr_lock(&dbdatabase, jnienv, database) != 0)
+ goto out1;
+ if (verify_non_null(jnienv, db)) {
+ JAVADB_API_BEGIN(db, jthis);
+ err = db->open(db, dbfile.string, dbdatabase.string,
+ (DBTYPE)type, flags, mode);
+ verify_return(jnienv, err, EXCEPTION_FILE_NOT_FOUND);
+ JAVADB_API_END(db);
+ }
+ out1:
+ jstr_unlock(&dbdatabase, jnienv);
+ out2:
+ jstr_unlock(&dbfile, jnienv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_upgrade
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring name,
+ jint flags)
+{
+ int err;
+ DB *db = get_DB(jnienv, jthis);
+ JSTR j_name;
+
+ if (verify_non_null(jnienv, db)) {
+ JAVADB_API_BEGIN(db, jthis);
+ if (jstr_lock(&j_name, jnienv, name) != 0)
+ goto out;
+ err = db->upgrade(db, j_name.string, flags);
+ verify_return(jnienv, err, 0);
+ JAVADB_API_END(db);
+ }
+ out:
+ jstr_unlock(&j_name, jnienv);
+}
+
+static int java_verify_callback(void *handle, const void *str_arg)
+{
+ char *str;
+ struct verify_callback_struct *vc;
+ int len;
+ jthrowable except;
+ JNIEnv *jnienv;
+
+ str = (char *)str_arg;
+ vc = (struct verify_callback_struct *)handle;
+ jnienv = vc->env;
+ len = strlen(str)+1;
+ if (len > vc->nbytes) {
+ vc->nbytes = len;
+ vc->bytes = (*jnienv)->NewByteArray(jnienv, len);
+ }
+ (*jnienv)->SetByteArrayRegion(jnienv, vc->bytes, 0, len, (jbyte*)str);
+ (*jnienv)->CallVoidMethod(jnienv, vc->streamobj,
+ vc->writemid, vc->bytes, 0, len-1);
+
+ if ((except = (*jnienv)->ExceptionOccurred(jnienv)) != NULL)
+ return (EIO);
+
+ return (0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_verify
+ (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring name,
+ jstring subdb, jobject stream, jint flags)
+{
+ int err;
+ DB *db;
+ JSTR j_name;
+ JSTR j_subdb;
+ struct verify_callback_struct vcs;
+ jclass streamclass;
+
+ db = get_DB(jnienv, jthis);
+ if (!verify_non_null(jnienv, db))
+ return;
+ JAVADB_API_BEGIN(db, jthis);
+
+ if (jstr_lock(&j_name, jnienv, name) != 0)
+ goto out2;
+ if (jstr_lock(&j_subdb, jnienv, subdb) != 0)
+ goto out1;
+
+ /* set up everything we need for the callbacks */
+ vcs.env = jnienv;
+ vcs.streamobj = stream;
+ vcs.nbytes = 100;
+ vcs.bytes = (*jnienv)->NewByteArray(jnienv, vcs.nbytes);
+
+ /* get the method ID for OutputStream.write(byte[], int, int); */
+ streamclass = (*jnienv)->FindClass(jnienv, "java/io/OutputStream");
+ vcs.writemid = (*jnienv)->GetMethodID(jnienv, streamclass,
+ "write", "([BII)V");
+
+ /* invoke verify - this will invoke the callback repeatedly. */
+ err = __db_verify_internal(db, j_name.string, j_subdb.string,
+ &vcs, java_verify_callback, flags);
+ verify_return(jnienv, err, 0);
+
+out1:
+ jstr_unlock(&j_subdb, jnienv);
+out2:
+ jstr_unlock(&j_name, jnienv);
+ JAVADB_API_END(db);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1finalize
+ (JNIEnv *jnienv, jobject jthis,
+ jobject /*DbErrcall*/ errcall, jstring errpfx)
+{
+ DB_JAVAINFO *dbinfo;
+ DB *db;
+
+ dbinfo = get_DB_JAVAINFO(jnienv, jthis);
+ db = get_DB(jnienv, jthis);
+ DB_ASSERT(dbinfo != NULL);
+
+ /* Note: We can never be sure if the underlying DB is attached to
+ * a DB_ENV that was already closed. Sure, that's a user error,
+ * but it shouldn't crash the VM. Therefore, we cannot just
+ * automatically close if the handle indicates we are not yet
+ * closed. The best we can do is detect this and report it.
+ */
+ if (db != NULL) {
+ /* If this error occurs, this object was never closed. */
+ report_errcall(jnienv, errcall, errpfx,
+ "Db.finalize: open Db object destroyed");
+ }
+
+ /* Shouldn't see this object again, but just in case */
+ set_private_dbobj(jnienv, name_DB, jthis, 0);
+ set_private_info(jnienv, name_DB, jthis, 0);
+
+ dbji_destroy(dbinfo, jnienv);
+}
diff --git a/bdb/libdb_java/java_DbEnv.c b/bdb/libdb_java/java_DbEnv.c
new file mode 100644
index 00000000000..ff9207dd2c8
--- /dev/null
+++ b/bdb/libdb_java/java_DbEnv.c
@@ -0,0 +1,1300 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_DbEnv.c,v 11.37 2001/01/11 18:19:52 bostic Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "db_int.h"
+#include "java_util.h"
+#include "com_sleepycat_db_DbEnv.h"
+
+/* We keep these lined up, and alphabetical by field name,
+ * for comparison with C++'s list.
+ */
+JAVADB_WO_ACCESS_STRING(DbEnv, data_1dir, DB_ENV, data_dir)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, lg_1bsize, DB_ENV, lg_bsize)
+JAVADB_WO_ACCESS_STRING(DbEnv, lg_1dir, DB_ENV, lg_dir)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, lg_1max, DB_ENV, lg_max)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, lk_1detect, DB_ENV, lk_detect)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, lk_1max, DB_ENV, lk_max)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, lk_1max_1locks, DB_ENV, lk_max_locks)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, lk_1max_1lockers, DB_ENV, lk_max_lockers)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, lk_1max_1objects, DB_ENV, lk_max_objects)
+/* mp_mmapsize is declared below, it needs an extra cast */
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, mutexlocks, DB_ENV, mutexlocks)
+JAVADB_WO_ACCESS_STRING(DbEnv, tmp_1dir, DB_ENV, tmp_dir)
+JAVADB_WO_ACCESS_METHOD(DbEnv, jint, tx_1max, DB_ENV, tx_max)
+
+static void DbEnv_errcall_callback(const char *prefix, char *message)
+{
+ JNIEnv *jnienv;
+ DB_ENV_JAVAINFO *envinfo = (DB_ENV_JAVAINFO *)prefix;
+ jstring pre;
+
+ /* Note: these error cases are "impossible", and would
+ * normally warrant an exception. However, without
+ * a jnienv, we cannot throw an exception...
+ * We don't want to trap or exit, since the point of
+ * this facility is for the user to completely control
+ * error situations.
+ */
+ if (envinfo == NULL) {
+ /* Something is *really* wrong here, the
+ * prefix is set in every environment created.
+ */
+ fprintf(stderr, "Error callback failed!\n");
+ fprintf(stderr, "error: %s\n", message);
+ return;
+ }
+
+ /* Should always succeed... */
+ jnienv = dbjie_get_jnienv(envinfo);
+
+ if (jnienv == NULL) {
+
+ /* But just in case... */
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ fprintf(stderr, "error: %s\n", message);
+ return;
+ }
+
+ pre = dbjie_get_errpfx(envinfo, jnienv);
+ report_errcall(jnienv, dbjie_get_errcall(envinfo), pre, message);
+}
+
+static void DbEnv_initialize(JNIEnv *jnienv, DB_ENV *dbenv,
+ /*DbEnv*/ jobject jenv,
+ /*DbErrcall*/ jobject jerrcall,
+ int is_dbopen)
+{
+ DB_ENV_JAVAINFO *envinfo;
+
+ envinfo = get_DB_ENV_JAVAINFO(jnienv, jenv);
+ DB_ASSERT(envinfo == NULL);
+ envinfo = dbjie_construct(jnienv, jerrcall, is_dbopen);
+ set_private_info(jnienv, name_DB_ENV, jenv, envinfo);
+ dbenv->set_errpfx(dbenv, (const char*)envinfo);
+ dbenv->set_errcall(dbenv, DbEnv_errcall_callback);
+ dbenv->cj_internal = envinfo;
+ set_private_dbobj(jnienv, name_DB_ENV, jenv, dbenv);
+}
+
+/* This is called when this DbEnv was made on behalf of a Db
+ * created directly (without a parent DbEnv), and the Db is
+ * being closed. We'll zero out the pointer to the DB_ENV,
+ * since it is no longer valid, to prevent mistakes.
+ */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1notify_1db_1close
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis)
+{
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ set_private_dbobj(jnienv, name_DB_ENV, jthis, 0);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (dbenvinfo != NULL)
+ dbjie_dealloc(dbenvinfo, jnienv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_feedback_1changed
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbFeedback*/ jobject jfeedback)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv) ||
+ !verify_non_null(jnienv, dbenvinfo))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ dbjie_set_feedback_object(dbenvinfo, jnienv, dbenv, jfeedback);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1init
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jobject /*DbErrcall*/ jerrcall,
+ jint flags)
+{
+ int err;
+ DB_ENV *dbenv;
+
+ err = db_env_create(&dbenv, flags);
+ if (verify_return(jnienv, err, 0))
+ DbEnv_initialize(jnienv, dbenv, jthis, jerrcall, 0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1init_1using_1db
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jobject /*DbErrcall*/ jerrcall,
+ /*Db*/ jobject jdb)
+{
+ DB_ENV *dbenv;
+ DB *db;
+
+ db = get_DB(jnienv, jdb);
+ dbenv = db->dbenv;
+ DbEnv_initialize(jnienv, dbenv, jthis, jerrcall, 1);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_open
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jstring db_home,
+ jint flags, jint mode)
+{
+ int err;
+ DB_ENV *dbenv;
+ JSTR j_home;
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv) ||
+ !verify_non_null(jnienv, dbenvinfo))
+ return;
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ if (jstr_lock(&j_home, jnienv, db_home) != 0)
+ goto out;
+
+ /* Java is assumed to be threaded. */
+ flags |= DB_THREAD;
+
+ err = dbenv->open(dbenv, j_home.string, flags, mode);
+ verify_return(jnienv, err, EXCEPTION_FILE_NOT_FOUND);
+ out:
+ jstr_unlock(&j_home, jnienv);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_remove
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jstring db_home, jint flags)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+ JSTR j_home;
+ int err = 0;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ if (jstr_lock(&j_home, jnienv, db_home) != 0)
+ goto out;
+
+ err = dbenv->remove(dbenv, j_home.string, flags);
+ set_private_dbobj(jnienv, name_DB_ENV, jthis, 0);
+
+ if (dbenvinfo != NULL)
+ dbjie_dealloc(dbenvinfo, jnienv);
+
+ verify_return(jnienv, err, 0);
+ out:
+ jstr_unlock(&j_home, jnienv);
+ /* don't call JAVADB_ENV_API_END - env cannot be used */
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1close
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint flags)
+{
+ int err;
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ err = dbenv->close(dbenv, flags);
+ set_private_dbobj(jnienv, name_DB_ENV, jthis, 0);
+
+ if (dbenvinfo != NULL)
+ dbjie_dealloc(dbenvinfo, jnienv);
+
+ /* Throw an exception if the close failed. */
+ verify_return(jnienv, err, 0);
+
+ /* don't call JAVADB_ENV_API_END - env cannot be used */
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_err
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint ecode, jstring msg)
+{
+ JSTR msg_string;
+ DB_ENV *dbenv;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ if (jstr_lock(&msg_string, jnienv, msg) != 0)
+ goto out;
+
+ dbenv->err(dbenv, ecode, msg_string.string);
+ out:
+ jstr_unlock(&msg_string, jnienv);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_errx
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jstring msg)
+{
+ JSTR msg_string;
+ DB_ENV *dbenv;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ if (jstr_lock(&msg_string, jnienv, msg) != 0)
+ goto out;
+
+ dbenv->errx(dbenv, msg_string.string);
+ out:
+ jstr_unlock(&msg_string, jnienv);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+/*static*/
+JNIEXPORT jstring JNICALL Java_com_sleepycat_db_DbEnv_strerror
+ (JNIEnv *jnienv, jclass jthis_class, jint ecode)
+{
+ const char *message;
+
+ COMPQUIET(jthis_class, NULL);
+ message = db_strerror(ecode);
+ return (get_java_string(jnienv, message));
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1cachesize
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint gbytes, jint bytes,
+ jint ncaches)
+{
+ DB_ENV *dbenv;
+ int err;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = dbenv->set_cachesize(dbenv, gbytes, bytes, ncaches);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1flags
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint flags, jint onoff)
+{
+ DB_ENV *dbenv;
+ int err;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = dbenv->set_flags(dbenv, flags, onoff);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1mp_1mmapsize
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jlong value)
+{
+ DB_ENV *dbenv;
+ int err;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = dbenv->set_mp_mmapsize(dbenv, (size_t)value);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+/*static*/
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1pageyield
+ (JNIEnv *jnienv, jclass jthis_class, jint value)
+{
+ int err;
+
+ COMPQUIET(jthis_class, NULL);
+ err = db_env_set_pageyield(value);
+ verify_return(jnienv, err, 0);
+}
+
+/*static*/
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1panicstate
+ (JNIEnv *jnienv, jclass jthis_class, jint value)
+{
+ int err;
+
+ COMPQUIET(jthis_class, NULL);
+ err = db_env_set_panicstate(value);
+ verify_return(jnienv, err, 0);
+}
+
+/*static*/
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1region_1init
+ (JNIEnv *jnienv, jclass jthis_class, jint value)
+{
+ int err;
+
+ COMPQUIET(jthis_class, NULL);
+ err = db_env_set_region_init(value);
+ verify_return(jnienv, err, 0);
+}
+
+/*static*/
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1tas_1spins
+ (JNIEnv *jnienv, jclass jthis_class, jint value)
+{
+ int err;
+
+ COMPQUIET(jthis_class, NULL);
+ err = db_env_set_tas_spins(value);
+ verify_return(jnienv, err, 0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_recovery_1init_1changed
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbRecoveryInit*/ jobject jrecoveryinit)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv) ||
+ !verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ dbjie_set_recovery_init_object(dbenvinfo, jnienv, dbenv, jrecoveryinit);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_set_1lk_1conflicts
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jobjectArray array)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+ int err;
+ jsize i, len;
+ unsigned char *newarr;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv) ||
+ !verify_non_null(jnienv, dbenvinfo))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ len = (*jnienv)->GetArrayLength(jnienv, array);
+
+ newarr = (unsigned char *)malloc(sizeof(unsigned char) * len * len);
+
+ for (i=0; i<len; i++) {
+ jobject subArray =
+ (*jnienv)->GetObjectArrayElement(jnienv, array, i);
+ (*jnienv)->GetByteArrayRegion(jnienv, (jbyteArray)subArray,
+ 0, len,
+ (jbyte *)&newarr[i*len]);
+ }
+ dbjie_set_conflict(dbenvinfo, newarr);
+ err = dbenv->set_lk_conflicts(dbenv, newarr, len);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1server
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jstring jhost, jlong tsec,
+ jlong ssec, jint flags)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+ const char *host = (*jnienv)->GetStringUTFChars(jnienv, jhost, NULL);
+
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = dbenv->set_server(dbenv, (char *)host,
+ (long)tsec, (long)ssec, flags);
+
+ /* Throw an exception if the call failed. */
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1shm_1key
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jlong shm_key)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = dbenv->set_shm_key(dbenv, (long)shm_key);
+
+ /* Throw an exception if the call failed. */
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv__1set_1tx_1timestamp
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jlong seconds)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+ time_t time = seconds;
+
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = dbenv->set_tx_timestamp(dbenv, &time);
+
+ /* Throw an exception if the call failed. */
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sleepycat_db_DbEnv_set_1verbose
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint which, jint onoff)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = dbenv->set_verbose(dbenv, which, onoff);
+
+ /* Throw an exception if the call failed. */
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+/*static*/
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1major
+ (JNIEnv * jnienv, jclass this_class)
+{
+ COMPQUIET(jnienv, NULL);
+ COMPQUIET(this_class, NULL);
+
+ return (DB_VERSION_MAJOR);
+}
+
+/*static*/
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1minor
+ (JNIEnv * jnienv, jclass this_class)
+{
+ COMPQUIET(jnienv, NULL);
+ COMPQUIET(this_class, NULL);
+
+ return (DB_VERSION_MINOR);
+}
+
+/*static*/
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1patch
+ (JNIEnv * jnienv, jclass this_class)
+{
+ COMPQUIET(jnienv, NULL);
+ COMPQUIET(this_class, NULL);
+
+ return (DB_VERSION_PATCH);
+}
+
+/*static*/
+JNIEXPORT jstring JNICALL Java_com_sleepycat_db_DbEnv_get_1version_1string
+ (JNIEnv *jnienv, jclass this_class)
+{
+ COMPQUIET(this_class, NULL);
+
+ return ((*jnienv)->NewStringUTF(jnienv, DB_VERSION_STRING));
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_lock_1id
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis)
+{
+ int err;
+ u_int32_t id;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+
+ if (!verify_non_null(jnienv, dbenv))
+ return (-1);
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = lock_id(dbenv, &id);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ return (id);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_lock_1stat
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+ DB_LOCK_STAT *statp = NULL;
+ jobject retval = NULL;
+ jclass dbclass;
+
+ if (!verify_non_null(jnienv, dbenv))
+ return (NULL);
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ /* We cannot use the default allocator (on Win* platforms anyway)
+ * because it often causes problems when we free storage
+ * in a DLL that was allocated in another DLL. Using
+ * our own allocator (ours just calls malloc!) ensures
+ * that there is no mismatch.
+ */
+ err = lock_stat(dbenv, &statp, NULL);
+ if (verify_return(jnienv, err, 0)) {
+ retval = create_default_object(jnienv, name_DB_LOCK_STAT);
+ dbclass = get_class(jnienv, name_DB_LOCK_STAT);
+
+ /* Set the individual fields */
+ set_int_field(jnienv, dbclass, retval,
+ "st_maxlocks", statp->st_maxlocks);
+ set_int_field(jnienv, dbclass, retval,
+ "st_nmodes", statp->st_nmodes);
+ set_int_field(jnienv, dbclass, retval,
+ "st_nlockers", statp->st_nlockers);
+ set_int_field(jnienv, dbclass, retval,
+ "st_nconflicts", statp->st_nconflicts);
+ set_int_field(jnienv, dbclass, retval,
+ "st_nrequests", statp->st_nrequests);
+ set_int_field(jnienv, dbclass, retval,
+ "st_nreleases", statp->st_nreleases);
+ set_int_field(jnienv, dbclass, retval,
+ "st_ndeadlocks", statp->st_ndeadlocks);
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_wait", statp->st_region_wait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_nowait", statp->st_region_nowait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_regsize", statp->st_regsize);
+
+ free(statp);
+ }
+ JAVADB_ENV_API_END(dbenv);
+ return (retval);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_lock_1detect
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint atype, jint flags)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+ int aborted;
+
+ if (!verify_non_null(jnienv, dbenv))
+ return (0);
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = lock_detect(dbenv, atype, flags, &aborted);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ return (aborted);
+}
+
+JNIEXPORT /*DbLock*/ jobject JNICALL Java_com_sleepycat_db_DbEnv_lock_1get
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*u_int32_t*/ jint locker,
+ jint flags, /*const Dbt*/ jobject obj, /*db_lockmode_t*/ jint lock_mode)
+{
+ int err;
+ DB_ENV *dbenv;
+ DB_LOCK *dblock;
+ JDBT dbobj;
+ /*DbLock*/ jobject retval;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return (NULL);
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ dblock = (DB_LOCK*)malloc(sizeof(DB_LOCK));
+ memset(dblock, 0, sizeof(DB_LOCK));
+ err = 0;
+ retval = NULL;
+ if (jdbt_lock(&dbobj, jnienv, obj, inOp) != 0)
+ goto out;
+
+ err = lock_get(dbenv, locker, flags, &dbobj.dbt->dbt,
+ (db_lockmode_t)lock_mode, dblock);
+ if (verify_return(jnienv, err, 0)) {
+ retval = create_default_object(jnienv, name_DB_LOCK);
+ set_private_dbobj(jnienv, name_DB_LOCK, retval, dblock);
+ }
+ out:
+ jdbt_unlock(&dbobj, jnienv);
+ JAVADB_ENV_API_END(dbenv);
+ return (retval);
+}
+
+JNIEXPORT jobjectArray JNICALL Java_com_sleepycat_db_DbEnv_log_1archive
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint flags)
+{
+ int err, len, i;
+ char** ret;
+ jclass stringClass;
+ jobjectArray strarray;
+ DB_ENV *dbenv;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ strarray = NULL;
+ if (!verify_non_null(jnienv, dbenv))
+ return (0);
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = log_archive(dbenv, &ret, flags, 0);
+ if (!verify_return(jnienv, err, 0))
+ return (0);
+
+ if (ret != NULL) {
+ len = 0;
+ while (ret[len] != NULL)
+ len++;
+ stringClass = (*jnienv)->FindClass(jnienv, "java/lang/String");
+ strarray = (*jnienv)->NewObjectArray(jnienv, len,
+ stringClass, 0);
+ for (i=0; i<len; i++) {
+ jstring str = (*jnienv)->NewStringUTF(jnienv, ret[i]);
+ (*jnienv)->SetObjectArrayElement(jnienv, strarray,
+ i, str);
+ }
+ }
+ JAVADB_ENV_API_END(dbenv);
+ return (strarray);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_log_1compare
+ (JNIEnv *jnienv, jclass jthis_class,
+ /*DbLsn*/ jobject lsn0, /*DbLsn*/ jobject lsn1)
+{
+ DB_LSN *dblsn0;
+ DB_LSN *dblsn1;
+
+ COMPQUIET(jthis_class, NULL);
+ dblsn0 = get_DB_LSN(jnienv, lsn0);
+ dblsn1 = get_DB_LSN(jnienv, lsn1);
+
+ return (log_compare(dblsn0, dblsn1));
+}
+
+JNIEXPORT jstring JNICALL Java_com_sleepycat_db_DbEnv_log_1file
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbLsn*/ jobject lsn)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+ DB_LSN *dblsn = get_DB_LSN(jnienv, lsn);
+ char filename[FILENAME_MAX+1] = "";
+
+ if (!verify_non_null(jnienv, dbenv))
+ return (NULL);
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ err = log_file(dbenv, dblsn, filename, FILENAME_MAX);
+ verify_return(jnienv, err, 0);
+ filename[FILENAME_MAX] = '\0'; /* just to be sure */
+ JAVADB_ENV_API_END(dbenv);
+ return (get_java_string(jnienv, filename));
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1flush
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbLsn*/ jobject lsn)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+ DB_LSN *dblsn = get_DB_LSN(jnienv, lsn);
+
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ err = log_flush(dbenv, dblsn);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1get
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbLsn*/ jobject lsn,
+ /*DbDbt*/ jobject data, jint flags)
+{
+ int err, retry;
+ DB_ENV *dbenv;
+ DB_LSN *dblsn;
+ JDBT dbdata;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dblsn = get_DB_LSN(jnienv, lsn);
+
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ if (jdbt_lock(&dbdata, jnienv, data, outOp) != 0)
+ goto out;
+
+ for (retry = 0; retry < 3; retry++) {
+ err = log_get(dbenv, dblsn, &dbdata.dbt->dbt, flags);
+ /* If we failed due to lack of memory in our DBT arrays,
+ * retry.
+ */
+ if (err != ENOMEM)
+ break;
+ if (!jdbt_realloc(&dbdata, jnienv))
+ break;
+ }
+
+ verify_return(jnienv, err, 0);
+
+ out:
+ jdbt_unlock(&dbdata, jnienv);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1put
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbLsn*/ jobject lsn,
+ /*DbDbt*/ jobject data, jint flags)
+{
+ int err;
+ DB_ENV *dbenv;
+ DB_LSN *dblsn;
+ JDBT dbdata;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dblsn = get_DB_LSN(jnienv, lsn);
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ if (jdbt_lock(&dbdata, jnienv, data, inOp) != 0)
+ goto out;
+
+ err = log_put(dbenv, dblsn, &dbdata.dbt->dbt, flags);
+ verify_return(jnienv, err, 0);
+ out:
+ jdbt_unlock(&dbdata, jnienv);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1register
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*Db*/ jobject dbp,
+ jstring name)
+{
+ int err;
+ DB_ENV *dbenv;
+ DB *dbdb;
+ JSTR dbname;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbdb = get_DB(jnienv, dbp);
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ if (jstr_lock(&dbname, jnienv, name) != 0)
+ goto out;
+
+ err = log_register(dbenv, dbdb, dbname.string);
+ verify_return(jnienv, err, 0);
+ out:
+ jstr_unlock(&dbname, jnienv);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_log_1unregister
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*Db*/ jobject dbp)
+{
+ int err;
+ DB_ENV *dbenv;
+ DB *dbdb;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbdb = get_DB(jnienv, dbp);
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ err = log_unregister(dbenv, dbdb);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_log_1stat
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis)
+{
+ int err;
+ DB_ENV *dbenv;
+ DB_LOG_STAT *statp;
+ jobject retval;
+ jclass dbclass;
+
+ retval = NULL;
+ statp = NULL;
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return (NULL);
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ /* We cannot use the default allocator (on Win* platforms anyway)
+ * because it often causes problems when we free storage
+ * in a DLL that was allocated in another DLL. Using
+ * our own allocator (ours just calls malloc!) ensures
+ * that there is no mismatch.
+ */
+ err = log_stat(dbenv, &statp, NULL);
+ if (verify_return(jnienv, err, 0)) {
+ retval = create_default_object(jnienv, name_DB_LOG_STAT);
+ dbclass = get_class(jnienv, name_DB_LOG_STAT);
+
+ /* Set the individual fields */
+ set_int_field(jnienv, dbclass, retval,
+ "st_magic", statp->st_magic);
+ set_int_field(jnienv, dbclass, retval,
+ "st_version", statp->st_version);
+ set_int_field(jnienv, dbclass, retval,
+ "st_mode", statp->st_mode);
+ set_int_field(jnienv, dbclass, retval,
+ "st_lg_max", statp->st_lg_max);
+ set_int_field(jnienv, dbclass, retval,
+ "st_w_bytes", statp->st_w_bytes);
+ set_int_field(jnienv, dbclass, retval,
+ "st_w_mbytes", statp->st_w_mbytes);
+ set_int_field(jnienv, dbclass, retval,
+ "st_wc_bytes", statp->st_wc_bytes);
+ set_int_field(jnienv, dbclass, retval,
+ "st_wc_mbytes", statp->st_wc_mbytes);
+ set_int_field(jnienv, dbclass, retval,
+ "st_wcount", statp->st_wcount);
+ set_int_field(jnienv, dbclass, retval,
+ "st_scount", statp->st_scount);
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_wait", statp->st_region_wait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_nowait", statp->st_region_nowait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_cur_file", statp->st_cur_file);
+ set_int_field(jnienv, dbclass, retval,
+ "st_cur_offset", statp->st_cur_offset);
+ set_int_field(jnienv, dbclass, retval,
+ "st_regsize", statp->st_regsize);
+
+ free(statp);
+ }
+ JAVADB_ENV_API_END(dbenv);
+ return (retval);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_memp_1stat
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis)
+{
+ int err;
+ jclass dbclass;
+ DB_ENV *dbenv;
+ DB_MPOOL_STAT *statp;
+ jobject retval;
+
+ retval = NULL;
+ statp = NULL;
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return (NULL);
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ /* We cannot use the default allocator (on Win* platforms anyway)
+ * because it often causes problems when we free storage
+ * in a DLL that was allocated in another DLL. Using
+ * our own allocator (ours just calls malloc!) ensures
+ * that there is no mismatch.
+ */
+ err = memp_stat(dbenv, &statp, 0, NULL);
+ if (verify_return(jnienv, err, 0)) {
+ retval = create_default_object(jnienv, name_DB_MPOOL_STAT);
+ dbclass = get_class(jnienv, name_DB_MPOOL_STAT);
+
+ set_int_field(jnienv, dbclass, retval, "st_cachesize", 0);
+ set_int_field(jnienv, dbclass, retval,
+ "st_cache_hit", statp->st_cache_hit);
+ set_int_field(jnienv, dbclass, retval,
+ "st_cache_miss", statp->st_cache_miss);
+ set_int_field(jnienv, dbclass, retval,
+ "st_map", statp->st_map);
+ set_int_field(jnienv, dbclass, retval,
+ "st_page_create", statp->st_page_create);
+ set_int_field(jnienv, dbclass, retval,
+ "st_page_in", statp->st_page_in);
+ set_int_field(jnienv, dbclass, retval,
+ "st_page_out", statp->st_page_out);
+ set_int_field(jnienv, dbclass, retval,
+ "st_ro_evict", statp->st_ro_evict);
+ set_int_field(jnienv, dbclass, retval,
+ "st_rw_evict", statp->st_rw_evict);
+ set_int_field(jnienv, dbclass, retval,
+ "st_hash_buckets", statp->st_hash_buckets);
+ set_int_field(jnienv, dbclass, retval,
+ "st_hash_searches", statp->st_hash_searches);
+ set_int_field(jnienv, dbclass, retval,
+ "st_hash_longest", statp->st_hash_longest);
+ set_int_field(jnienv, dbclass, retval,
+ "st_hash_examined", statp->st_hash_examined);
+ set_int_field(jnienv, dbclass, retval,
+ "st_page_clean", statp->st_page_clean);
+ set_int_field(jnienv, dbclass, retval,
+ "st_page_dirty", statp->st_page_dirty);
+ set_int_field(jnienv, dbclass, retval,
+ "st_page_trickle", statp->st_page_trickle);
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_wait", statp->st_region_wait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_nowait", statp->st_region_nowait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_regsize", statp->st_regsize);
+
+ free(statp);
+ }
+ JAVADB_ENV_API_END(dbenv);
+ return (retval);
+}
+
+JNIEXPORT jobjectArray JNICALL Java_com_sleepycat_db_DbEnv_memp_1fstat
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis)
+{
+ int err, i, len;
+ jclass fstat_class;
+ DB_ENV *dbenv;
+ DB_MPOOL_FSTAT **fstatp;
+ jobjectArray retval;
+ jfieldID filename_id;
+ jstring jfilename;
+
+ fstatp = NULL;
+ retval = NULL;
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return (NULL);
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ /* We cannot use the default allocator (on Win* platforms anyway)
+ * because it often causes problems when we free storage
+ * in a DLL that was allocated in another DLL. Using
+ * our own allocator (ours just calls malloc!) ensures
+ * that there is no mismatch.
+ */
+ err = memp_stat(dbenv, 0, &fstatp, NULL);
+ if (verify_return(jnienv, err, 0)) {
+ len = 0;
+ while (fstatp[len])
+ len++;
+ fstat_class = get_class(jnienv, name_DB_MPOOL_FSTAT);
+ retval = (*jnienv)->NewObjectArray(jnienv, len,
+ fstat_class, 0);
+ for (i=0; i<len; i++) {
+ jobject obj = create_default_object(jnienv,
+ name_DB_MPOOL_FSTAT);
+ (*jnienv)->SetObjectArrayElement(jnienv, retval,
+ i, obj);
+
+ /* Set the string field. */
+ filename_id =
+ (*jnienv)->GetFieldID(jnienv, fstat_class,
+ "file_name",
+ string_signature);
+ jfilename =
+ get_java_string(jnienv, fstatp[i]->file_name);
+ (*jnienv)->SetObjectField(jnienv, obj,
+ filename_id, jfilename);
+
+ set_int_field(jnienv, fstat_class, obj,
+ "st_pagesize", fstatp[i]->st_pagesize);
+ set_int_field(jnienv, fstat_class, obj,
+ "st_cache_hit", fstatp[i]->st_cache_hit);
+ set_int_field(jnienv, fstat_class, obj,
+ "st_cache_miss", fstatp[i]->st_cache_miss);
+ set_int_field(jnienv, fstat_class, obj,
+ "st_map", fstatp[i]->st_map);
+ set_int_field(jnienv, fstat_class, obj,
+ "st_page_create", fstatp[i]->st_page_create);
+ set_int_field(jnienv, fstat_class, obj,
+ "st_page_in", fstatp[i]->st_page_in);
+ set_int_field(jnienv, fstat_class, obj,
+ "st_page_out", fstatp[i]->st_page_out);
+ free(fstatp[i]);
+ }
+ free(fstatp);
+ }
+ JAVADB_ENV_API_END(dbenv);
+ return (retval);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_memp_1trickle
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint pct)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+ int result = 0;
+
+ if (verify_non_null(jnienv, dbenv)) {
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = memp_trickle(dbenv, pct, &result);
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ }
+ return (result);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_txn_1begin
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbTxn*/ jobject pid, jint flags)
+{
+ int err;
+ DB_TXN *dbpid, *result;
+ DB_ENV *dbenv;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return (0);
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ dbpid = get_DB_TXN(jnienv, pid);
+ result = 0;
+
+ err = txn_begin(dbenv, dbpid, &result, flags);
+ if (!verify_return(jnienv, err, 0))
+ return (0);
+ JAVADB_ENV_API_END(dbenv);
+ return (get_DbTxn(jnienv, result));
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbEnv_txn_1checkpoint
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jint kbyte, jint min, jint flags)
+{
+ int err;
+ DB_ENV *dbenv = get_DB_ENV(jnienv, jthis);
+
+ if (!verify_non_null(jnienv, dbenv))
+ return (0);
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ err = txn_checkpoint(dbenv, kbyte, min, flags);
+ if (err != DB_INCOMPLETE)
+ verify_return(jnienv, err, 0);
+ JAVADB_ENV_API_END(dbenv);
+ return (err);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv_tx_1recover_1changed
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, /*DbFeedback*/ jobject jtxrecover)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv) ||
+ !verify_non_null(jnienv, dbenvinfo))
+ return;
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ dbjie_set_tx_recover_object(dbenvinfo, jnienv, dbenv, jtxrecover);
+ JAVADB_ENV_API_END(dbenv);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_DbEnv_txn_1stat
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis)
+{
+ int err;
+ DB_ENV *dbenv;
+ DB_TXN_STAT *statp;
+ jobject retval, obj;
+ jclass dbclass, active_class;
+ char active_signature[512];
+ jfieldID arrid;
+ jobjectArray actives;
+ unsigned int i;
+
+ retval = NULL;
+ statp = NULL;
+ dbenv = get_DB_ENV(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbenv))
+ return (NULL);
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+
+ /* We cannot use the default allocator (on Win* platforms anyway)
+ * because it often causes problems when we free storage
+ * in a DLL that was allocated in another DLL. Using
+ * our own allocator (ours just calls malloc!) ensures
+ * that there is no mismatch.
+ */
+ err = txn_stat(dbenv, &statp, NULL);
+ if (verify_return(jnienv, err, 0)) {
+ retval = create_default_object(jnienv, name_DB_TXN_STAT);
+ dbclass = get_class(jnienv, name_DB_TXN_STAT);
+
+ /* Set the individual fields */
+
+ set_lsn_field(jnienv, dbclass, retval,
+ "st_last_ckp", statp->st_last_ckp);
+ set_lsn_field(jnienv, dbclass, retval,
+ "st_pending_ckp", statp->st_pending_ckp);
+ set_long_field(jnienv, dbclass, retval,
+ "st_time_ckp", statp->st_time_ckp);
+ set_int_field(jnienv, dbclass, retval,
+ "st_last_txnid", statp->st_last_txnid);
+ set_int_field(jnienv, dbclass, retval,
+ "st_maxtxns", statp->st_maxtxns);
+ set_int_field(jnienv, dbclass, retval,
+ "st_naborts", statp->st_naborts);
+ set_int_field(jnienv, dbclass, retval,
+ "st_nbegins", statp->st_nbegins);
+ set_int_field(jnienv, dbclass, retval,
+ "st_ncommits", statp->st_ncommits);
+ set_int_field(jnienv, dbclass, retval,
+ "st_nactive", statp->st_nactive);
+ set_int_field(jnienv, dbclass, retval,
+ "st_maxnactive", statp->st_maxnactive);
+
+ active_class = get_class(jnienv, name_DB_TXN_STAT_ACTIVE);
+ actives =
+ (*jnienv)->NewObjectArray(jnienv, statp->st_nactive,
+ active_class, 0);
+
+ /* Set the st_txnarray field. This is a little more involved
+ * than other fields, since the type is an array, so none
+ * of our utility functions help.
+ */
+ strncpy(active_signature, "[L", sizeof(active_signature));
+ strncat(active_signature, DB_PACKAGE_NAME,
+ sizeof(active_signature));
+ strncat(active_signature, name_DB_TXN_STAT_ACTIVE,
+ sizeof(active_signature));
+ strncat(active_signature, ";", sizeof(active_signature));
+
+ arrid = (*jnienv)->GetFieldID(jnienv, dbclass, "st_txnarray",
+ active_signature);
+ (*jnienv)->SetObjectField(jnienv, retval, arrid, actives);
+
+ /* Now fill the in the elements of st_txnarray. */
+ for (i=0; i<statp->st_nactive; i++) {
+ obj = create_default_object(jnienv, name_DB_TXN_STAT_ACTIVE);
+ (*jnienv)->SetObjectArrayElement(jnienv, actives, i, obj);
+
+ set_int_field(jnienv, active_class, obj,
+ "txnid", statp->st_txnarray[i].txnid);
+ set_int_field(jnienv, active_class, obj,
+ "parentid", statp->st_txnarray[i].parentid);
+ set_lsn_field(jnienv, active_class, obj,
+ "lsn", statp->st_txnarray[i].lsn);
+ }
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_wait", statp->st_region_wait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_region_nowait", statp->st_region_nowait);
+ set_int_field(jnienv, dbclass, retval,
+ "st_regsize", statp->st_regsize);
+
+ free(statp);
+ }
+ JAVADB_ENV_API_END(dbenv);
+ return (retval);
+}
+
+/* See discussion on errpfx, errcall in DB_ENV_JAVAINFO */
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1set_1errcall
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jobject errcall)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+
+ if (verify_non_null(jnienv, dbenv) &&
+ verify_non_null(jnienv, dbenvinfo)) {
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ dbjie_set_errcall(dbenvinfo, jnienv, errcall);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1set_1errpfx
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis, jstring str)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *dbenvinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ dbenvinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+
+ if (verify_non_null(jnienv, dbenv) &&
+ verify_non_null(jnienv, dbenvinfo)) {
+
+ JAVADB_ENV_API_BEGIN(dbenv, jthis);
+ dbjie_set_errpfx(dbenvinfo, jnienv, str);
+ JAVADB_ENV_API_END(dbenv);
+ }
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbEnv__1finalize
+ (JNIEnv *jnienv, /*DbEnv*/ jobject jthis,
+ jobject /*DbErrcall*/ errcall, jstring errpfx)
+{
+ DB_ENV *dbenv;
+ DB_ENV_JAVAINFO *envinfo;
+
+ dbenv = get_DB_ENV(jnienv, jthis);
+ envinfo = get_DB_ENV_JAVAINFO(jnienv, jthis);
+ DB_ASSERT(envinfo != NULL);
+
+ /* Note: We detect unclosed DbEnvs and report it.
+ */
+ if (dbenv != NULL && envinfo != NULL && !dbjie_is_dbopen(envinfo)) {
+
+ /* If this error occurs, this object was never closed. */
+ report_errcall(jnienv, errcall, errpfx,
+ "DbEnv.finalize: open DbEnv object destroyed");
+ }
+
+ /* Shouldn't see this object again, but just in case */
+ set_private_dbobj(jnienv, name_DB_ENV, jthis, 0);
+ set_private_info(jnienv, name_DB_ENV, jthis, 0);
+
+ dbjie_destroy(envinfo, jnienv);
+}
diff --git a/bdb/libdb_java/java_DbLock.c b/bdb/libdb_java/java_DbLock.c
new file mode 100644
index 00000000000..287ca6622e5
--- /dev/null
+++ b/bdb/libdb_java/java_DbLock.c
@@ -0,0 +1,55 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_DbLock.c,v 11.4 2000/11/30 00:58:39 ubell Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "java_util.h"
+#include "com_sleepycat_db_DbLock.h"
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLock_put
+ (JNIEnv *jnienv, jobject jthis, /*DbEnv*/ jobject env)
+{
+ int err;
+ DB_LOCK *dblock = get_DB_LOCK(jnienv, jthis);
+ DB_ENV *dbenv = get_DB_ENV(jnienv, env);
+
+ if (!verify_non_null(jnienv, dbenv))
+ return;
+
+ if (!verify_non_null(jnienv, dblock))
+ return;
+
+ err = lock_put(dbenv, dblock);
+ if (verify_return(jnienv, err, 0)) {
+ /* After a successful put, the DbLock can no longer
+ * be used, so we release the storage related to it
+ * (allocated in DbEnv.lock_get() or lock_tget()).
+ */
+ free(dblock);
+
+ set_private_dbobj(jnienv, name_DB_LOCK, jthis, 0);
+ }
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLock_finalize
+ (JNIEnv *jnienv, jobject jthis)
+{
+ DB_LOCK *dblock = get_DB_LOCK(jnienv, jthis);
+ if (dblock) {
+ /* Free any data related to DB_LOCK here */
+ free(dblock);
+ }
+ set_private_dbobj(jnienv, name_DB_LOCK, jthis, 0); /* paranoia */
+}
diff --git a/bdb/libdb_java/java_DbLsn.c b/bdb/libdb_java/java_DbLsn.c
new file mode 100644
index 00000000000..8f26f2ecb58
--- /dev/null
+++ b/bdb/libdb_java/java_DbLsn.c
@@ -0,0 +1,43 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_DbLsn.c,v 11.5 2000/11/30 00:58:39 ubell Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h> /* needed for FILENAME_MAX */
+
+#include "db.h"
+#include "db_int.h"
+#include "java_util.h"
+#include "com_sleepycat_db_DbLsn.h"
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLsn_init_1lsn
+ (JNIEnv *jnienv, /*DbLsn*/ jobject jthis)
+{
+ /* Note: the DB_LSN object stored in the private_dbobj_
+ * is allocated in get_DbLsn().
+ */
+
+ COMPQUIET(jnienv, NULL);
+ COMPQUIET(jthis, NULL);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbLsn_finalize
+ (JNIEnv *jnienv, jobject jthis)
+{
+ DB_LSN *dblsn;
+
+ dblsn = get_DB_LSN(jnienv, jthis);
+ if (dblsn) {
+ free(dblsn);
+ }
+}
diff --git a/bdb/libdb_java/java_DbTxn.c b/bdb/libdb_java/java_DbTxn.c
new file mode 100644
index 00000000000..67c2599a6fc
--- /dev/null
+++ b/bdb/libdb_java/java_DbTxn.c
@@ -0,0 +1,82 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_DbTxn.c,v 11.3 2000/09/18 18:32:25 dda Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "java_util.h"
+#include "com_sleepycat_db_DbTxn.h"
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_abort
+ (JNIEnv *jnienv, jobject jthis)
+{
+ int err;
+ DB_TXN *dbtxn = get_DB_TXN(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbtxn))
+ return;
+
+ err = txn_abort(dbtxn);
+ verify_return(jnienv, err, 0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_commit
+ (JNIEnv *jnienv, jobject jthis, jint flags)
+{
+ int err;
+ DB_TXN *dbtxn = get_DB_TXN(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbtxn))
+ return;
+
+ err = txn_commit(dbtxn, flags);
+ verify_return(jnienv, err, 0);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_DbTxn_id
+ (JNIEnv *jnienv, jobject jthis)
+{
+ int retval = 0;
+ DB_TXN *dbtxn = get_DB_TXN(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbtxn))
+ return (-1);
+
+ /* No error to check for from txn_id */
+ retval = txn_id(dbtxn);
+ return (retval);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_prepare
+ (JNIEnv *jnienv, jobject jthis)
+{
+ int err;
+ DB_TXN *dbtxn = get_DB_TXN(jnienv, jthis);
+ if (!verify_non_null(jnienv, dbtxn))
+ return;
+
+ err = txn_prepare(dbtxn);
+ verify_return(jnienv, err, 0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_DbTxn_finalize
+ (JNIEnv *jnienv, jobject jthis)
+{
+ DB_TXN *dbtxn = get_DB_TXN(jnienv, jthis);
+ if (dbtxn) {
+ /* Free any data related to DB_TXN here
+ * Note: we don't make a policy of doing
+ * a commit or abort here. The txnmgr
+ * should be closed, and DB will clean up.
+ */
+ }
+}
diff --git a/bdb/libdb_java/java_Dbc.c b/bdb/libdb_java/java_Dbc.c
new file mode 100644
index 00000000000..f1d0acdec85
--- /dev/null
+++ b/bdb/libdb_java/java_Dbc.c
@@ -0,0 +1,196 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_Dbc.c,v 11.10 2000/10/25 19:54:55 dda Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef DIAGNOSTIC
+#include <stdio.h>
+#endif
+
+#include "db.h"
+#include "db_int.h"
+#include "java_util.h"
+#include "com_sleepycat_db_Dbc.h"
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbc_close
+ (JNIEnv *jnienv, jobject jthis)
+{
+ int err;
+ DBC *dbc = get_DBC(jnienv, jthis);
+
+ if (!verify_non_null(jnienv, dbc))
+ return;
+ err = dbc->c_close(dbc);
+ if (verify_return(jnienv, err, 0)) {
+ set_private_dbobj(jnienv, name_DBC, jthis, 0);
+ }
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_count
+ (JNIEnv *jnienv, jobject jthis, jint flags)
+{
+ int err;
+ DBC *dbc = get_DBC(jnienv, jthis);
+ db_recno_t count;
+
+ if (!verify_non_null(jnienv, dbc))
+ return (0);
+ err = dbc->c_count(dbc, &count, flags);
+ verify_return(jnienv, err, 0);
+ return (count);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_del
+ (JNIEnv *jnienv, jobject jthis, jint flags)
+{
+ int err;
+ DBC *dbc = get_DBC(jnienv, jthis);
+
+ if (!verify_non_null(jnienv, dbc))
+ return (0);
+ err = dbc->c_del(dbc, flags);
+ if (err != DB_KEYEMPTY) {
+ verify_return(jnienv, err, 0);
+ }
+ return (err);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Dbc_dup
+ (JNIEnv *jnienv, jobject jthis, jint flags)
+{
+ int err;
+ DBC *dbc = get_DBC(jnienv, jthis);
+ DBC *dbc_ret = NULL;
+
+ if (!verify_non_null(jnienv, dbc))
+ return (0);
+ err = dbc->c_dup(dbc, &dbc_ret, flags);
+ if (!verify_return(jnienv, err, 0))
+ return (0);
+
+ return (get_Dbc(jnienv, dbc_ret));
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_get
+ (JNIEnv *jnienv, jobject jthis,
+ /*Dbt*/ jobject key, /*Dbt*/ jobject data, jint flags)
+{
+ int err, retry, op_flags;
+ DBC *dbc;
+ JDBT dbkey, dbdata;
+ OpKind keyop, dataop;
+
+ /* Depending on flags, the user may be supplying the key,
+ * or else we may have to retrieve it.
+ */
+ err = 0;
+ keyop = outOp;
+ dataop = outOp;
+
+ op_flags = flags & DB_OPFLAGS_MASK;
+ if (op_flags == DB_SET) {
+ keyop = inOp;
+ }
+ else if (op_flags == DB_SET_RANGE ||
+ op_flags == DB_SET_RECNO) {
+ keyop = inOutOp;
+ }
+ else if (op_flags == DB_GET_BOTH) {
+ keyop = inOutOp;
+ dataop = inOutOp;
+ }
+
+ dbc = get_DBC(jnienv, jthis);
+ if (jdbt_lock(&dbkey, jnienv, key, keyop) != 0)
+ goto out2;
+ if (jdbt_lock(&dbdata, jnienv, data, dataop) != 0)
+ goto out1;
+
+ if (!verify_non_null(jnienv, dbc))
+ goto out1;
+
+ for (retry = 0; retry < 3; retry++) {
+ err = dbc->c_get(dbc, &dbkey.dbt->dbt, &dbdata.dbt->dbt, flags);
+
+ /* If we failed due to lack of memory in our DBT arrays,
+ * retry.
+ */
+ if (err != ENOMEM)
+ break;
+ if (!jdbt_realloc(&dbkey, jnienv) && !jdbt_realloc(&dbdata, jnienv))
+ break;
+ }
+ if (err != DB_NOTFOUND) {
+ verify_return(jnienv, err, 0);
+ }
+ out1:
+ jdbt_unlock(&dbdata, jnienv);
+ out2:
+ jdbt_unlock(&dbkey, jnienv);
+ return (err);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbc_put
+ (JNIEnv *jnienv, jobject jthis,
+ /*Dbt*/ jobject key, /*Dbt*/ jobject data, jint flags)
+{
+ int err;
+ DBC *dbc;
+ JDBT dbkey, dbdata;
+
+ err = 0;
+ dbc = get_DBC(jnienv, jthis);
+ if (jdbt_lock(&dbkey, jnienv, key, inOp) != 0)
+ goto out2;
+ if (jdbt_lock(&dbdata, jnienv, data, inOp) != 0)
+ goto out1;
+
+ if (!verify_non_null(jnienv, dbc))
+ goto out1;
+ err = dbc->c_put(dbc, &dbkey.dbt->dbt, &dbdata.dbt->dbt, flags);
+ if (err != DB_KEYEXIST) {
+ verify_return(jnienv, err, 0);
+ }
+ out1:
+ jdbt_unlock(&dbdata, jnienv);
+ out2:
+ jdbt_unlock(&dbkey, jnienv);
+ return (err);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbc_finalize
+ (JNIEnv *jnienv, jobject jthis)
+{
+ /* Free any data related to DBC here.
+ * If we ever have java-only data embedded in the DBC
+ * and need to do this, we'll have to track Dbc's
+ * according to which Db owns them, just as
+ * we track Db's according to which DbEnv owns them.
+ * That's necessary to avoid double freeing that
+ * comes about when closes interact with GC.
+ */
+
+#ifdef DIAGNOSTIC
+ DBC *dbc;
+
+ dbc = get_DBC(jnienv, jthis);
+ if (dbc != NULL)
+ fprintf(stderr, "Java API: Dbc has not been closed\n");
+#else
+
+ COMPQUIET(jnienv, NULL);
+ COMPQUIET(jthis, NULL);
+
+#endif
+}
diff --git a/bdb/libdb_java/java_Dbt.c b/bdb/libdb_java/java_Dbt.c
new file mode 100644
index 00000000000..0e094da6a2d
--- /dev/null
+++ b/bdb/libdb_java/java_Dbt.c
@@ -0,0 +1,176 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_Dbt.c,v 11.10 2000/10/25 19:54:55 dda Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "java_util.h"
+#include "com_sleepycat_db_Dbt.h"
+
+JAVADB_RW_ACCESS(Dbt, jint, size, DBT, size)
+JAVADB_RW_ACCESS(Dbt, jint, ulen, DBT, ulen)
+JAVADB_RW_ACCESS(Dbt, jint, dlen, DBT, dlen)
+JAVADB_RW_ACCESS(Dbt, jint, doff, DBT, doff)
+JAVADB_RW_ACCESS(Dbt, jint, flags, DBT, flags)
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_init
+ (JNIEnv *jnienv, jobject jthis)
+{
+ DBT_JAVAINFO *dbtji;
+
+ dbtji = dbjit_construct();
+ set_private_dbobj(jnienv, name_DBT, jthis, dbtji);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_internal_1set_1data
+ (JNIEnv *jnienv, jobject jthis, jbyteArray array)
+{
+ DBT_JAVAINFO *db_this;
+
+ db_this = get_DBT_JAVAINFO(jnienv, jthis);
+ if (verify_non_null(jnienv, db_this)) {
+
+ /* If we previously allocated an array for java,
+ * must release reference.
+ */
+ dbjit_release(db_this, jnienv);
+
+ /* Make the array a global ref,
+ * it won't be GC'd till we release it.
+ */
+ if (array)
+ array = (jbyteArray)NEW_GLOBAL_REF(jnienv, array);
+ db_this->array_ = array;
+ }
+}
+
+JNIEXPORT jbyteArray JNICALL Java_com_sleepycat_db_Dbt_get_1data
+ (JNIEnv *jnienv, jobject jthis)
+{
+ DBT_JAVAINFO *db_this;
+ jbyteArray arr;
+ int len;
+
+ db_this = get_DBT_JAVAINFO(jnienv, jthis);
+ if (verify_non_null(jnienv, db_this)) {
+ /* XXX this will copy the data on each call to get_data,
+ * even if it is unchanged.
+ */
+ if (db_this->create_array_ != 0) {
+ /* XXX we should reuse the existing array if we can */
+ len = db_this->dbt.size;
+ if (db_this->array_ != NULL)
+ DELETE_GLOBAL_REF(jnienv, db_this->array_);
+ arr = (*jnienv)->NewByteArray(jnienv, len);
+ db_this->array_ =
+ (jbyteArray)NEW_GLOBAL_REF(jnienv, arr);
+ (*jnienv)->SetByteArrayRegion(jnienv, arr, 0, len,
+ db_this->dbt.data);
+ }
+ return (db_this->array_);
+ }
+ return (0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1offset
+ (JNIEnv *jnienv, jobject jthis, jint offset)
+{
+ DBT_JAVAINFO *db_this;
+
+ db_this = get_DBT_JAVAINFO(jnienv, jthis);
+ if (verify_non_null(jnienv, db_this)) {
+ db_this->offset_ = offset;
+ }
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1offset
+ (JNIEnv *jnienv, jobject jthis)
+{
+ DBT_JAVAINFO *db_this;
+
+ db_this = get_DBT_JAVAINFO(jnienv, jthis);
+ if (verify_non_null(jnienv, db_this)) {
+ return db_this->offset_;
+ }
+ return (0);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_set_1recno_1key_1data(JNIEnv *jnienv, jobject jthis, jint value)
+{
+ JDBT jdbt;
+
+ if (jdbt_lock(&jdbt, jnienv, jthis, inOp) != 0)
+ goto out;
+
+ if (!jdbt.dbt->dbt.data ||
+ jdbt.java_array_len_ < sizeof(db_recno_t)) {
+ char buf[200];
+ sprintf(buf, "set_recno_key_data error: %p %p %d %d",
+ &jdbt.dbt->dbt, jdbt.dbt->dbt.data,
+ jdbt.dbt->dbt.ulen, sizeof(db_recno_t));
+ report_exception(jnienv, buf, 0, 0);
+ }
+ else {
+ *(db_recno_t*)(jdbt.dbt->dbt.data) = value;
+ }
+ out:
+ jdbt_unlock(&jdbt, jnienv);
+}
+
+JNIEXPORT jint JNICALL Java_com_sleepycat_db_Dbt_get_1recno_1key_1data(JNIEnv *jnienv, jobject jthis)
+{
+ jint ret;
+ JDBT jdbt;
+
+ ret = 0;
+
+ /* Although this is kind of like "retrieve", we don't support
+ * DB_DBT_MALLOC for this operation, so we tell jdbt_lock
+ * that is not a retrieve.
+ */
+ if (jdbt_lock(&jdbt, jnienv, jthis, inOp) != 0)
+ goto out;
+
+ if (!jdbt.dbt->dbt.data ||
+ jdbt.java_array_len_ < sizeof(db_recno_t)) {
+ char buf[200];
+ sprintf(buf, "get_recno_key_data error: %p %p %d %d",
+ &jdbt.dbt->dbt, jdbt.dbt->dbt.data,
+ jdbt.dbt->dbt.ulen, sizeof(db_recno_t));
+ report_exception(jnienv, buf, 0, 0);
+ }
+ else {
+ ret = *(db_recno_t*)(jdbt.dbt->dbt.data);
+ }
+ out:
+ jdbt_unlock(&jdbt, jnienv);
+ return (ret);
+}
+
+JNIEXPORT void JNICALL Java_com_sleepycat_db_Dbt_finalize
+ (JNIEnv *jnienv, jobject jthis)
+{
+ DBT_JAVAINFO *dbtji;
+
+ dbtji = get_DBT_JAVAINFO(jnienv, jthis);
+ if (dbtji) {
+ /* Free any data related to DBT here */
+ dbjit_release(dbtji, jnienv);
+
+ /* Extra paranoia */
+ memset(dbtji, 0, sizeof(DBT_JAVAINFO));
+ free(dbtji);
+ }
+}
diff --git a/bdb/libdb_java/java_info.c b/bdb/libdb_java/java_info.c
new file mode 100644
index 00000000000..ccd469fa256
--- /dev/null
+++ b/bdb/libdb_java/java_info.c
@@ -0,0 +1,1001 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_info.c,v 11.18 2000/10/28 13:09:39 dda Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "db_int.h"
+#include "java_util.h"
+
+/****************************************************************
+ *
+ * Callback functions
+ *
+ */
+
+static void Db_feedback_callback(DB *db, int opcode, int percent)
+{
+ DB_JAVAINFO *dbinfo;
+
+ DB_ASSERT(db != NULL);
+ dbinfo = (DB_JAVAINFO *)db->cj_internal;
+ dbji_call_feedback(dbinfo, db, dbinfo->jdbref_, opcode, percent);
+}
+
+static int Db_append_recno_callback(DB *db, DBT *dbt, db_recno_t recno)
+{
+ DB_JAVAINFO *dbinfo;
+
+ dbinfo = (DB_JAVAINFO *)db->cj_internal;
+ return (dbji_call_append_recno(dbinfo, db, dbinfo->jdbref_, dbt, recno));
+}
+
+static int Db_bt_compare_callback(DB *db, const DBT *dbt1, const DBT *dbt2)
+{
+ DB_JAVAINFO *dbinfo;
+
+ dbinfo = (DB_JAVAINFO *)db->cj_internal;
+ return (dbji_call_bt_compare(dbinfo, db, dbinfo->jdbref_, dbt1, dbt2));
+}
+
+static size_t Db_bt_prefix_callback(DB *db, const DBT *dbt1, const DBT *dbt2)
+{
+ DB_JAVAINFO *dbinfo;
+
+ dbinfo = (DB_JAVAINFO *)db->cj_internal;
+ return (dbji_call_bt_prefix(dbinfo, db, dbinfo->jdbref_, dbt1, dbt2));
+}
+
+static int Db_dup_compare_callback(DB *db, const DBT *dbt1, const DBT *dbt2)
+{
+ DB_JAVAINFO *dbinfo;
+
+ dbinfo = (DB_JAVAINFO *)db->cj_internal;
+ return (dbji_call_dup_compare(dbinfo, db, dbinfo->jdbref_, dbt1, dbt2));
+}
+
+static u_int32_t Db_h_hash_callback(DB *db, const void *data, u_int32_t len)
+{
+ DB_JAVAINFO *dbinfo;
+
+ dbinfo = (DB_JAVAINFO *)db->cj_internal;
+ return (dbji_call_h_hash(dbinfo, db, dbinfo->jdbref_, data, len));
+}
+
+static void DbEnv_feedback_callback(DB_ENV *dbenv, int opcode, int percent)
+{
+ DB_ENV_JAVAINFO *dbinfo;
+
+ DB_ASSERT(dbenv != NULL);
+ dbinfo = (DB_ENV_JAVAINFO *)dbenv->cj_internal;
+ dbjie_call_feedback(dbinfo, dbenv, dbinfo->jenvref_, opcode, percent);
+}
+
+static int DbEnv_recovery_init_callback(DB_ENV *dbenv)
+{
+ DB_ENV_JAVAINFO *dbinfo;
+
+ dbinfo = (DB_ENV_JAVAINFO *)dbenv->cj_internal;
+ return (dbjie_call_recovery_init(dbinfo, dbenv, dbinfo->jenvref_));
+}
+
+static int DbEnv_tx_recover_callback(DB_ENV *dbenv, DBT *dbt,
+ DB_LSN *lsn, db_recops recops)
+{
+ DB_ENV_JAVAINFO *dbinfo;
+
+ DB_ASSERT(dbenv != NULL);
+ dbinfo = (DB_ENV_JAVAINFO *)dbenv->cj_internal;
+ return dbjie_call_tx_recover(dbinfo, dbenv, dbinfo->jenvref_, dbt,
+ lsn, recops);
+}
+
+/****************************************************************
+ *
+ * Implementation of class DBT_javainfo
+ *
+ */
+DBT_JAVAINFO *
+dbjit_construct()
+{
+ DBT_JAVAINFO *dbjit;
+
+ dbjit = (DBT_JAVAINFO *)malloc(sizeof(DBT_JAVAINFO));
+ memset(dbjit, 0, sizeof(DBT_JAVAINFO));
+ return (dbjit);
+}
+
+void dbjit_destroy(DBT_JAVAINFO *dbjit)
+{
+ /* Sanity check:
+ * We cannot delete the global ref because we don't have a JNIEnv.
+ */
+ if (dbjit->array_ != NULL) {
+ fprintf(stderr, "object is not freed\n");
+ }
+
+ /* Extra paranoia */
+ memset(dbjit, 0, sizeof(DB_JAVAINFO));
+ free(dbjit);
+}
+
+void dbjit_release(DBT_JAVAINFO *dbjit, JNIEnv *jnienv)
+{
+ if (dbjit->array_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjit->array_);
+ dbjit->array_ = NULL;
+ }
+}
+
+/****************************************************************
+ *
+ * Implementation of class DB_ENV_JAVAINFO
+ *
+ */
+
+/* create/initialize an object */
+DB_ENV_JAVAINFO *
+dbjie_construct(JNIEnv *jnienv,
+ jobject default_errcall,
+ int is_dbopen)
+{
+ DB_ENV_JAVAINFO *dbjie;
+
+ dbjie = (DB_ENV_JAVAINFO *)malloc(sizeof(DB_ENV_JAVAINFO));
+ memset(dbjie, 0, sizeof(DB_ENV_JAVAINFO));
+ dbjie->is_dbopen_ = is_dbopen;
+
+ if ((*jnienv)->GetJavaVM(jnienv, &dbjie->javavm_) != 0) {
+ free(dbjie);
+ report_exception(jnienv, "cannot get Java VM", 0, 0);
+ return (NULL);
+ }
+
+ /* The default error call just prints to the 'System.err'
+ * stream. If the user does set_errcall to null, we'll
+ * want to have a reference to set it back to.
+ *
+ * Why do we have always set db_errcall to our own callback?
+ * Because it makes the interaction between setting the
+ * error prefix, error stream, and user's error callback
+ * that much easier.
+ */
+ dbjie->default_errcall_ = NEW_GLOBAL_REF(jnienv, default_errcall);
+ dbjie->errcall_ = NEW_GLOBAL_REF(jnienv, default_errcall);
+ return (dbjie);
+}
+
+/* release all objects held by this this one */
+void dbjie_dealloc(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv)
+{
+ if (dbjie->recovery_init_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->recovery_init_);
+ dbjie->recovery_init_ = NULL;
+ }
+ if (dbjie->feedback_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->feedback_);
+ dbjie->feedback_ = NULL;
+ }
+ if (dbjie->tx_recover_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->tx_recover_);
+ dbjie->tx_recover_ = NULL;
+ }
+ if (dbjie->errcall_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->errcall_);
+ dbjie->errcall_ = NULL;
+ }
+ if (dbjie->default_errcall_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->default_errcall_);
+ dbjie->default_errcall_ = NULL;
+ }
+
+ if (dbjie->conflict_ != NULL) {
+ free(dbjie->conflict_);
+ dbjie->conflict_ = NULL;
+ }
+ if (dbjie->errpfx_ != NULL) {
+ free(dbjie->errpfx_);
+ dbjie->errpfx_ = NULL;
+ }
+}
+
+/* free this object, releasing anything allocated on its behalf */
+void dbjie_destroy(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv)
+{
+ dbjie_dealloc(dbjie, jnienv);
+
+ /* Extra paranoia */
+ memset(dbjie, 0, sizeof(DB_ENV_JAVAINFO));
+ free(dbjie);
+}
+
+/* Attach to the current thread that is running and
+ * return that. We use the java virtual machine
+ * that we saved in the constructor.
+ */
+JNIEnv *
+dbjie_get_jnienv(DB_ENV_JAVAINFO *dbjie)
+{
+ /* Note:
+ * Different versions of the JNI disagree on the signature
+ * for AttachCurrentThread. The most recent documentation
+ * seems to say that (JNIEnv **) is correct, but newer
+ * JNIs seem to use (void **), oddly enough.
+ */
+#ifdef JNI_VERSION_1_2
+ void *attachret = 0;
+#else
+ JNIEnv *attachret = 0;
+#endif
+
+ /* This should always succeed, as we are called via
+ * some Java activity. I think therefore I am (a thread).
+ */
+ if ((*dbjie->javavm_)->AttachCurrentThread(dbjie->javavm_, &attachret, 0) != 0)
+ return (0);
+
+ return ((JNIEnv *)attachret);
+}
+
+jstring
+dbjie_get_errpfx(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv)
+{
+ return (get_java_string(jnienv, dbjie->errpfx_));
+}
+
+void
+dbjie_set_errcall(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, jobject new_errcall)
+{
+ /* If the new_errcall is null, we'll set the error call
+ * to the default one.
+ */
+ if (new_errcall == NULL)
+ new_errcall = dbjie->default_errcall_;
+
+ DELETE_GLOBAL_REF(jnienv, dbjie->errcall_);
+ dbjie->errcall_ = NEW_GLOBAL_REF(jnienv, new_errcall);
+}
+
+void
+dbjie_set_errpfx(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, jstring errpfx)
+{
+ if (dbjie->errpfx_ != NULL)
+ free(dbjie->errpfx_);
+
+ if (errpfx)
+ dbjie->errpfx_ = get_c_string(jnienv, errpfx);
+ else
+ dbjie->errpfx_ = NULL;
+}
+
+void
+dbjie_set_conflict(DB_ENV_JAVAINFO *dbjie, unsigned char *newarr)
+{
+ if (dbjie->conflict_)
+ free(dbjie->conflict_);
+ dbjie->conflict_ = newarr;
+}
+
+void dbjie_set_feedback_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv,
+ DB_ENV *dbenv, jobject jfeedback)
+{
+ int err;
+
+ if (dbjie->feedback_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->feedback_);
+ }
+ if (jfeedback == NULL) {
+ if ((err = dbenv->set_feedback(dbenv, NULL)) != 0)
+ report_exception(jnienv, "set_feedback failed",
+ err, 0);
+ }
+ else {
+ if ((err = dbenv->set_feedback(dbenv,
+ DbEnv_feedback_callback)) != 0)
+ report_exception(jnienv, "set_feedback failed",
+ err, 0);
+ }
+
+ dbjie->feedback_ = NEW_GLOBAL_REF(jnienv, jfeedback);
+}
+
+void dbjie_call_feedback(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv,
+ int opcode, int percent)
+{
+ JNIEnv *jnienv;
+ jclass feedback_class;
+ jmethodID id;
+
+ COMPQUIET(dbenv, NULL);
+ jnienv = dbjie_get_jnienv(dbjie);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return;
+ }
+
+ feedback_class = get_class(jnienv, name_DbEnvFeedback);
+ id = (*jnienv)->GetMethodID(jnienv, feedback_class,
+ "feedback",
+ "(Lcom/sleepycat/db/DbEnv;II)V");
+ if (!id) {
+ fprintf(stderr, "Cannot find callback class\n");
+ return;
+ }
+
+ (*jnienv)->CallVoidMethod(jnienv, dbjie->feedback_, id,
+ jenv, (jint)opcode, (jint)percent);
+}
+
+void dbjie_set_recovery_init_object(DB_ENV_JAVAINFO *dbjie,
+ JNIEnv *jnienv, DB_ENV *dbenv,
+ jobject jrecovery_init)
+{
+ int err;
+
+ if (dbjie->recovery_init_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->recovery_init_);
+ }
+ if (jrecovery_init == NULL) {
+ if ((err = dbenv->set_recovery_init(dbenv, NULL)) != 0)
+ report_exception(jnienv, "set_recovery_init failed",
+ err, 0);
+ }
+ else {
+ if ((err = dbenv->set_recovery_init(dbenv,
+ DbEnv_recovery_init_callback)) != 0)
+ report_exception(jnienv, "set_recovery_init failed",
+ err, 0);
+ }
+
+ dbjie->recovery_init_ = NEW_GLOBAL_REF(jnienv, jrecovery_init);
+}
+
+int dbjie_call_recovery_init(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv,
+ jobject jenv)
+{
+ JNIEnv *jnienv;
+ jclass recovery_init_class;
+ jmethodID id;
+
+ COMPQUIET(dbenv, NULL);
+ jnienv = dbjie_get_jnienv(dbjie);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return (EINVAL);
+ }
+
+ recovery_init_class = get_class(jnienv, name_DbRecoveryInit);
+ id = (*jnienv)->GetMethodID(jnienv, recovery_init_class,
+ "recovery_init",
+ "(Lcom/sleepycat/db/DbEnv;)V");
+ if (!id) {
+ fprintf(stderr, "Cannot find callback class\n");
+ return (EINVAL);
+ }
+ return (*jnienv)->CallIntMethod(jnienv, dbjie->recovery_init_,
+ id, jenv);
+}
+
+void dbjie_set_tx_recover_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv,
+ DB_ENV *dbenv, jobject jtx_recover)
+{
+ int err;
+
+ if (dbjie->tx_recover_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbjie->tx_recover_);
+ }
+ if (jtx_recover == NULL) {
+ if ((err = dbenv->set_tx_recover(dbenv, NULL)) != 0)
+ report_exception(jnienv, "set_tx_recover failed",
+ err, 0);
+ }
+ else {
+ if ((err = dbenv->set_tx_recover(dbenv,
+ DbEnv_tx_recover_callback)) != 0)
+ report_exception(jnienv, "set_tx_recover failed",
+ err, 0);
+ }
+
+ dbjie->tx_recover_ = NEW_GLOBAL_REF(jnienv, jtx_recover);
+}
+
+int dbjie_call_tx_recover(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv,
+ DBT *dbt, DB_LSN *lsn, int recops)
+{
+ JNIEnv *jnienv;
+ jclass tx_recover_class;
+ jmethodID id;
+ jobject jdbt;
+ jobject jlsn;
+
+ COMPQUIET(dbenv, NULL);
+ jnienv = dbjie_get_jnienv(dbjie);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return (0);
+ }
+
+ tx_recover_class = get_class(jnienv, name_DbTxnRecover);
+ id = (*jnienv)->GetMethodID(jnienv, tx_recover_class,
+ "tx_recover",
+ "(Lcom/sleepycat/db/DbEnv;"
+ "Lcom/sleepycat/db/Dbt;"
+ "Lcom/sleepycat/db/DbLsn;"
+ "I)I");
+ if (!id) {
+ fprintf(stderr, "Cannot find callback class\n");
+ return (0);
+ }
+
+ if (dbt == NULL)
+ jdbt = NULL;
+ else
+ jdbt = get_Dbt(jnienv, dbt);
+
+ if (lsn == NULL)
+ jlsn = NULL;
+ else
+ jlsn = get_DbLsn(jnienv, *lsn);
+
+ return (*jnienv)->CallIntMethod(jnienv, dbjie->tx_recover_, id, jenv,
+ jdbt, jlsn, recops);
+}
+
+jobject dbjie_get_errcall(DB_ENV_JAVAINFO *dbjie)
+{
+ return (dbjie->errcall_);
+}
+
+int dbjie_is_dbopen(DB_ENV_JAVAINFO *dbjie)
+{
+ return (dbjie->is_dbopen_);
+}
+
+/****************************************************************
+ *
+ * Implementation of class DB_JAVAINFO
+ *
+ */
+
+DB_JAVAINFO *dbji_construct(JNIEnv *jnienv, jint flags)
+{
+ DB_JAVAINFO *dbji;
+
+ dbji = (DB_JAVAINFO *)malloc(sizeof(DB_JAVAINFO));
+ memset(dbji, 0, sizeof(DB_JAVAINFO));
+
+ if ((*jnienv)->GetJavaVM(jnienv, &dbji->javavm_) != 0) {
+ report_exception(jnienv, "cannot get Java VM", 0, 0);
+ free(dbji);
+ return (NULL);
+ }
+ dbji->construct_flags_ = flags;
+ return (dbji);
+}
+
+void
+dbji_dealloc(DB_JAVAINFO *dbji, JNIEnv *jnienv)
+{
+ if (dbji->append_recno_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->append_recno_);
+ dbji->append_recno_ = NULL;
+ }
+ if (dbji->bt_compare_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->bt_compare_);
+ dbji->bt_compare_ = NULL;
+ }
+ if (dbji->bt_prefix_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix_);
+ dbji->bt_prefix_ = NULL;
+ }
+ if (dbji->dup_compare_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->dup_compare_);
+ dbji->dup_compare_ = NULL;
+ }
+ if (dbji->feedback_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->feedback_);
+ dbji->feedback_ = NULL;
+ }
+ if (dbji->h_hash_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->h_hash_);
+ dbji->h_hash_ = NULL;
+ }
+}
+
+void
+dbji_destroy(DB_JAVAINFO *dbji, JNIEnv *jnienv)
+{
+ dbji_dealloc(dbji, jnienv);
+ free(dbji);
+}
+
+JNIEnv *dbji_get_jnienv(DB_JAVAINFO *dbji)
+{
+ /* Note:
+ * Different versions of the JNI disagree on the signature
+ * for AttachCurrentThread. The most recent documentation
+ * seems to say that (JNIEnv **) is correct, but newer
+ * JNIs seem to use (void **), oddly enough.
+ */
+#ifdef JNI_VERSION_1_2
+ void *attachret = 0;
+#else
+ JNIEnv *attachret = 0;
+#endif
+
+ /* This should always succeed, as we are called via
+ * some Java activity. I think therefore I am (a thread).
+ */
+ if ((*dbji->javavm_)->AttachCurrentThread(dbji->javavm_, &attachret, 0) != 0)
+ return (0);
+
+ return ((JNIEnv *)attachret);
+}
+
+jint dbji_get_flags(DB_JAVAINFO *dbji)
+{
+ return (dbji->construct_flags_);
+}
+
+void dbji_set_feedback_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
+ DB *db, jobject jfeedback)
+{
+ jclass feedback_class;
+
+ if (dbji->feedback_method_id_ == NULL) {
+ feedback_class = get_class(jnienv, name_DbFeedback);
+ dbji->feedback_method_id_ =
+ (*jnienv)->GetMethodID(jnienv, feedback_class,
+ "feedback",
+ "(Lcom/sleepycat/db/Db;II)V");
+ if (dbji->feedback_method_id_ != NULL) {
+ /* XXX
+ * We should really have a better way
+ * to translate this to a Java exception class.
+ * In theory, it shouldn't happen.
+ */
+ report_exception(jnienv, "Cannot find callback method",
+ EFAULT, 0);
+ return;
+ }
+ }
+
+ if (dbji->feedback_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->feedback_);
+ }
+ if (jfeedback == NULL) {
+ db->set_feedback(db, NULL);
+ }
+ else {
+ db->set_feedback(db, Db_feedback_callback);
+ }
+
+ dbji->feedback_ = NEW_GLOBAL_REF(jnienv, jfeedback);
+
+}
+
+void dbji_call_feedback(DB_JAVAINFO *dbji, DB *db, jobject jdb,
+ int opcode, int percent)
+{
+ JNIEnv *jnienv;
+
+ COMPQUIET(db, NULL);
+ jnienv = dbji_get_jnienv(dbji);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return;
+ }
+
+ DB_ASSERT(dbji->feedback_method_id_ != NULL);
+ (*jnienv)->CallVoidMethod(jnienv, dbji->feedback_,
+ dbji->feedback_method_id_,
+ jdb, (jint)opcode, (jint)percent);
+}
+
+void dbji_set_append_recno_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
+ DB *db, jobject jcallback)
+{
+ jclass append_recno_class;
+
+ if (dbji->append_recno_method_id_ == NULL) {
+ append_recno_class = get_class(jnienv, name_DbAppendRecno);
+ dbji->append_recno_method_id_ =
+ (*jnienv)->GetMethodID(jnienv, append_recno_class,
+ "db_append_recno",
+ "(Lcom/sleepycat/db/Db;"
+ "Lcom/sleepycat/db/Dbt;I)V");
+ if (dbji->append_recno_method_id_ == NULL) {
+ /* XXX
+ * We should really have a better way
+ * to translate this to a Java exception class.
+ * In theory, it shouldn't happen.
+ */
+ report_exception(jnienv, "Cannot find callback method",
+ EFAULT, 0);
+ return;
+ }
+ }
+
+ if (dbji->append_recno_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->append_recno_);
+ }
+ if (jcallback == NULL) {
+ db->set_append_recno(db, NULL);
+ }
+ else {
+ db->set_append_recno(db, Db_append_recno_callback);
+ }
+
+ dbji->append_recno_ = NEW_GLOBAL_REF(jnienv, jcallback);
+}
+
+extern int dbji_call_append_recno(DB_JAVAINFO *dbji, DB *db, jobject jdb,
+ DBT *dbt, jint recno)
+{
+ JNIEnv *jnienv;
+ jobject jdbt;
+ DBT_JAVAINFO *dbtji;
+ jbyteArray arr;
+ unsigned int arraylen;
+ unsigned char *data;
+
+ COMPQUIET(db, NULL);
+ jnienv = dbji_get_jnienv(dbji);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return (0);
+ }
+
+ /* XXX
+ * We should have a pool of Dbt objects used for this purpose
+ * instead of creating new ones each time. Because of
+ * multithreading, we may need an arbitrary number (more than two).
+ * We might also have a byte arrays that grow as needed,
+ * so we don't need to allocate those either.
+ *
+ * Note, we do not set the 'create_array_' flag as on other
+ * callbacks as we are creating the array here.
+ */
+ jdbt = create_default_object(jnienv, name_DBT);
+ dbtji = get_DBT_JAVAINFO(jnienv, jdbt);
+ memcpy(&dbtji->dbt, dbt, sizeof(DBT));
+ dbtji->dbt.data = NULL;
+ arr = (*jnienv)->NewByteArray(jnienv, dbt->size);
+ (*jnienv)->SetByteArrayRegion(jnienv, arr, 0, dbt->size,
+ (jbyte *)dbt->data);
+ dbtji->array_ = (jbyteArray)NEW_GLOBAL_REF(jnienv, arr);
+
+ DB_ASSERT(dbji->append_recno_method_id_ != NULL);
+ (*jnienv)->CallVoidMethod(jnienv, dbji->append_recno_,
+ dbji->append_recno_method_id_,
+ jdb, jdbt, recno);
+
+ /* The underlying C API requires that an errno be returned
+ * on error. Java users know nothing of errnos, so we
+ * allow them to throw exceptions instead. We leave the
+ * exception in place and return DB_JAVA_CALLBACK to the C API
+ * that called us. Eventually the DB->get will fail and
+ * when java prepares to throw an exception in
+ * report_exception(), this will be spotted as a special case,
+ * and the original exception will be preserved.
+ *
+ * Note: we have sometimes noticed strange behavior with
+ * exceptions under Linux 1.1.7 JVM. (i.e. multiple calls
+ * to ExceptionOccurred() may report different results).
+ * Currently we don't know of any problems related to this
+ * in our code, but if it pops up in the future, users are
+ * encouranged to get a more recent JVM.
+ */
+ if ((*jnienv)->ExceptionOccurred(jnienv) != NULL)
+ return (DB_JAVA_CALLBACK);
+
+ if (dbtji->array_ == NULL) {
+ report_exception(jnienv, "Dbt.data is null", 0, 0);
+ return (EFAULT);
+ }
+
+ arraylen = (*jnienv)->GetArrayLength(jnienv, dbtji->array_);
+ if (dbtji->offset_ < 0 ) {
+ report_exception(jnienv, "Dbt.offset illegal", 0, 0);
+ return (EFAULT);
+ }
+ if (dbt->ulen + dbtji->offset_ > arraylen) {
+ report_exception(jnienv,
+ "Dbt.ulen + Dbt.offset greater than array length", 0, 0);
+ return (EFAULT);
+ }
+
+ data = (*jnienv)->GetByteArrayElements(jnienv, dbtji->array_,
+ (jboolean *)0);
+ dbt->data = data + dbtji->offset_;
+ return (0);
+}
+
+void dbji_set_bt_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
+ DB *db, jobject jcompare)
+{
+ jclass bt_compare_class;
+
+ if (dbji->bt_compare_method_id_ == NULL) {
+ bt_compare_class = get_class(jnienv, name_DbBtreeCompare);
+ dbji->bt_compare_method_id_ =
+ (*jnienv)->GetMethodID(jnienv, bt_compare_class,
+ "bt_compare",
+ "(Lcom/sleepycat/db/Db;"
+ "Lcom/sleepycat/db/Dbt;"
+ "Lcom/sleepycat/db/Dbt;)I");
+ if (dbji->bt_compare_method_id_ == NULL) {
+ /* XXX
+ * We should really have a better way
+ * to translate this to a Java exception class.
+ * In theory, it shouldn't happen.
+ */
+ report_exception(jnienv, "Cannot find callback method",
+ EFAULT, 0);
+ return;
+ }
+ }
+
+ if (dbji->bt_compare_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->bt_compare_);
+ }
+ if (jcompare == NULL) {
+ db->set_bt_compare(db, NULL);
+ }
+ else {
+ db->set_bt_compare(db, Db_bt_compare_callback);
+ }
+
+ dbji->bt_compare_ = NEW_GLOBAL_REF(jnienv, jcompare);
+}
+
+int dbji_call_bt_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb,
+ const DBT *dbt1, const DBT *dbt2)
+{
+ JNIEnv *jnienv;
+ jobject jdbt1, jdbt2;
+ DBT_JAVAINFO *dbtji1, *dbtji2;
+
+ COMPQUIET(db, NULL);
+ jnienv = dbji_get_jnienv(dbji);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return (0);
+ }
+
+ /* XXX
+ * We should have a pool of Dbt objects used for this purpose
+ * instead of creating new ones each time. Because of
+ * multithreading, we may need an arbitrary number (more than two).
+ * We might also have a byte arrays that grow as needed,
+ * so we don't need to allocate those either.
+ */
+ jdbt1 = create_default_object(jnienv, name_DBT);
+ jdbt2 = create_default_object(jnienv, name_DBT);
+ dbtji1 = get_DBT_JAVAINFO(jnienv, jdbt1);
+ memcpy(&dbtji1->dbt, dbt1, sizeof(DBT));
+ dbtji1->create_array_ = 1;
+ dbtji2 = get_DBT_JAVAINFO(jnienv, jdbt2);
+ memcpy(&dbtji2->dbt, dbt2, sizeof(DBT));
+ dbtji2->create_array_ = 1;
+
+ DB_ASSERT(dbji->bt_compare_method_id_ != NULL);
+ return (*jnienv)->CallIntMethod(jnienv, dbji->bt_compare_,
+ dbji->bt_compare_method_id_,
+ jdb, jdbt1, jdbt2);
+}
+
+void dbji_set_bt_prefix_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
+ DB *db, jobject jprefix)
+{
+ jclass bt_prefix_class;
+
+ if (dbji->bt_prefix_method_id_ == NULL) {
+ bt_prefix_class = get_class(jnienv, name_DbBtreePrefix);
+ dbji->bt_prefix_method_id_ =
+ (*jnienv)->GetMethodID(jnienv, bt_prefix_class,
+ "bt_prefix",
+ "(Lcom/sleepycat/db/Db;"
+ "Lcom/sleepycat/db/Dbt;"
+ "Lcom/sleepycat/db/Dbt;)I");
+ if (dbji->bt_prefix_method_id_ == NULL) {
+ /* XXX
+ * We should really have a better way
+ * to translate this to a Java exception class.
+ * In theory, it shouldn't happen.
+ */
+ report_exception(jnienv, "Cannot find callback method",
+ EFAULT, 0);
+ return;
+ }
+ }
+
+ if (dbji->bt_prefix_ != NULL) {
+ DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix_);
+ }
+ if (jprefix == NULL) {
+ db->set_bt_prefix(db, NULL);
+ }
+ else {
+ db->set_bt_prefix(db, Db_bt_prefix_callback);
+ }
+
+ dbji->bt_prefix_ = NEW_GLOBAL_REF(jnienv, jprefix);
+}
+
+size_t dbji_call_bt_prefix(DB_JAVAINFO *dbji, DB *db, jobject jdb,
+ const DBT *dbt1, const DBT *dbt2)
+{
+ JNIEnv *jnienv;
+ jobject jdbt1, jdbt2;
+ DBT_JAVAINFO *dbtji1, *dbtji2;
+
+ COMPQUIET(db, NULL);
+ jnienv = dbji_get_jnienv(dbji);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return (0);
+ }
+
+ /* XXX
+ * We should have a pool of Dbt objects used for this purpose
+ * instead of creating new ones each time. Because of
+ * multithreading, we may need an arbitrary number (more than two).
+ * We might also have a byte arrays that grow as needed,
+ * so we don't need to allocate those either.
+ */
+ jdbt1 = create_default_object(jnienv, name_DBT);
+ jdbt2 = create_default_object(jnienv, name_DBT);
+ dbtji1 = get_DBT_JAVAINFO(jnienv, jdbt1);
+ memcpy(&dbtji1->dbt, dbt1, sizeof(DBT));
+ dbtji1->create_array_ = 1;
+ dbtji2 = get_DBT_JAVAINFO(jnienv, jdbt2);
+ memcpy(&dbtji2->dbt, dbt2, sizeof(DBT));
+ dbtji2->create_array_ = 1;
+
+ DB_ASSERT(dbji->bt_prefix_method_id_ != NULL);
+ return (size_t)(*jnienv)->CallIntMethod(jnienv, dbji->bt_prefix_,
+ dbji->bt_prefix_method_id_,
+ jdb, jdbt1, jdbt2);
+}
+
+void dbji_set_dup_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
+ DB *db, jobject jcompare)
+{
+ jclass dup_compare_class;
+
+ if (dbji->dup_compare_method_id_ == NULL) {
+ dup_compare_class = get_class(jnienv, name_DbDupCompare);
+ dbji->dup_compare_method_id_ =
+ (*jnienv)->GetMethodID(jnienv, dup_compare_class,
+ "dup_compare",
+ "(Lcom/sleepycat/db/Db;"
+ "Lcom/sleepycat/db/Dbt;"
+ "Lcom/sleepycat/db/Dbt;)I");
+ if (dbji->dup_compare_method_id_ == NULL) {
+ /* XXX
+ * We should really have a better way
+ * to translate this to a Java exception class.
+ * In theory, it shouldn't happen.
+ */
+ report_exception(jnienv, "Cannot find callback method",
+ EFAULT, 0);
+ return;
+ }
+ }
+
+ if (dbji->dup_compare_ != NULL)
+ DELETE_GLOBAL_REF(jnienv, dbji->dup_compare_);
+
+ if (jcompare == NULL)
+ db->set_dup_compare(db, NULL);
+ else
+ db->set_dup_compare(db, Db_dup_compare_callback);
+
+ dbji->dup_compare_ = NEW_GLOBAL_REF(jnienv, jcompare);
+}
+
+int dbji_call_dup_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb,
+ const DBT *dbt1, const DBT *dbt2)
+{
+ JNIEnv *jnienv;
+ jobject jdbt1, jdbt2;
+ DBT_JAVAINFO *dbtji1, *dbtji2;
+
+ COMPQUIET(db, NULL);
+ jnienv = dbji_get_jnienv(dbji);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return (0);
+ }
+
+ /* XXX
+ * We should have a pool of Dbt objects used for this purpose
+ * instead of creating new ones each time. Because of
+ * multithreading, we may need an arbitrary number (more than two).
+ * We might also have a byte arrays that grow as needed,
+ * so we don't need to allocate those either.
+ */
+ jdbt1 = create_default_object(jnienv, name_DBT);
+ jdbt2 = create_default_object(jnienv, name_DBT);
+ dbtji1 = get_DBT_JAVAINFO(jnienv, jdbt1);
+ memcpy(&dbtji1->dbt, dbt1, sizeof(DBT));
+ dbtji1->create_array_ = 1;
+ dbtji2 = get_DBT_JAVAINFO(jnienv, jdbt2);
+ memcpy(&dbtji2->dbt, dbt2, sizeof(DBT));
+ dbtji2->create_array_ = 1;
+
+ DB_ASSERT(dbji->dup_compare_method_id_ != NULL);
+ return (*jnienv)->CallIntMethod(jnienv, dbji->dup_compare_,
+ dbji->dup_compare_method_id_,
+ jdb, jdbt1, jdbt2);
+}
+
+void dbji_set_h_hash_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
+ DB *db, jobject jhash)
+{
+ jclass h_hash_class;
+
+ if (dbji->h_hash_method_id_ == NULL) {
+ h_hash_class = get_class(jnienv, name_DbHash);
+ dbji->h_hash_method_id_ =
+ (*jnienv)->GetMethodID(jnienv, h_hash_class,
+ "hash",
+ "(Lcom/sleepycat/db/Db;"
+ "[BI)I");
+ if (dbji->h_hash_method_id_ == NULL) {
+ /* XXX
+ * We should really have a better way
+ * to translate this to a Java exception class.
+ * In theory, it shouldn't happen.
+ */
+ report_exception(jnienv, "Cannot find callback method",
+ EFAULT, 0);
+ return;
+ }
+ }
+
+ if (dbji->h_hash_ != NULL)
+ DELETE_GLOBAL_REF(jnienv, dbji->h_hash_);
+
+ if (jhash == NULL)
+ db->set_h_hash(db, NULL);
+ else
+ db->set_h_hash(db, Db_h_hash_callback);
+
+ dbji->h_hash_ = NEW_GLOBAL_REF(jnienv, jhash);
+}
+
+int dbji_call_h_hash(DB_JAVAINFO *dbji, DB *db, jobject jdb,
+ const void *data, int len)
+{
+ JNIEnv *jnienv;
+ jbyteArray jarray;
+
+ COMPQUIET(db, NULL);
+ jnienv = dbji_get_jnienv(dbji);
+ if (jnienv == NULL) {
+ fprintf(stderr, "Cannot attach to current thread!\n");
+ return (0);
+ }
+
+ DB_ASSERT(dbji->h_hash_method_id_ != NULL);
+
+ jarray = (*jnienv)->NewByteArray(jnienv, len);
+ (*jnienv)->SetByteArrayRegion(jnienv, jarray, 0, len, (void *)data);
+ return (*jnienv)->CallIntMethod(jnienv, dbji->h_hash_,
+ dbji->h_hash_method_id_,
+ jdb, jarray, len);
+}
diff --git a/bdb/libdb_java/java_info.h b/bdb/libdb_java/java_info.h
new file mode 100644
index 00000000000..69032be80e6
--- /dev/null
+++ b/bdb/libdb_java/java_info.h
@@ -0,0 +1,200 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ *
+ * $Id: java_info.h,v 11.17 2000/07/31 20:28:30 dda Exp $
+ */
+
+#ifndef _JAVA_INFO_H_
+#define _JAVA_INFO_H_
+
+/*
+ * "Info" classes for Java implementation of Berkeley DB API.
+ * These classes hold extra information for which there is
+ * no room or counterpart in the base classes used in the C API.
+ * In the case of a DBT, the DBT_javainfo class is stored in the
+ * 'private' variable of the java Dbt, and the DBT_javainfo is subclassed
+ * from a DBT. In the case of DB and DB_ENV, the appropriate
+ * info objects are pointed to by the DB and DB_ENV objects.
+ * This is convenient to implement callbacks.
+ */
+
+/****************************************************************
+ *
+ * Declaration of class DBT_javainfo
+ *
+ * A DBT_javainfo is created whenever a Dbt (java) object is created,
+ * and a pointer to it is stored in its private info storage.
+ * It is subclassed from DBT, because we must retain some extra
+ * information in it while it is in use. In particular, when
+ * a java array is associated with it, we need to keep a Globally
+ * Locked reference to it so it is not GC'd. This reference is
+ * destroyed when the Dbt is GC'd.
+ */
+typedef struct _dbt_javainfo
+{
+ DBT dbt;
+ DB *db_; /* associated DB */
+ jobject dbtref_; /* the java Dbt object */
+ jbyteArray array_;
+ int offset_;
+ int create_array_; /* flag to create the array as needed */
+}
+DBT_JAVAINFO; /* used with all 'dbtji' functions */
+
+extern DBT_JAVAINFO *dbjit_construct();
+extern void dbjit_release(DBT_JAVAINFO *dbjit, JNIEnv *jnienv);
+
+/****************************************************************
+ *
+ * Declaration of class DB_ENV_JAVAINFO
+ *
+ * A DB_ENV_JAVAINFO is allocated and stuffed into the cj_internal
+ * and the db_errpfx for every DB_ENV created. It holds a
+ * little extra info that is needed to support callbacks.
+ *
+ * There's a bit of trickery here, because we have built this
+ * above a layer that has a C function callback that gets
+ * invoked when an error occurs. One of the C callback's arguments
+ * is the prefix from the DB_ENV, but since we stuffed a pointer
+ * to our own DB_ENV_JAVAINFO into the prefix, we get that object as an
+ * argument to the C callback. Thus, the C callback can have
+ * access to much more than just the prefix, and it needs that
+ * to call back into the Java enviroment.
+ *
+ * The DB_ENV_JAVAINFO object holds a copy of the Java Virtual Machine,
+ * which is needed to attach to the current running thread
+ * whenever we need to make a callback. (This is more reliable
+ * than our previous approach, which was to save the thread
+ * that created the DbEnv). It also has the Java callback object,
+ * as well as a 'default' callback object that is used when the
+ * caller sets the callback to null. It also has the original
+ * error prefix, since we overwrote the one in the DB_ENV.
+ * There are also fields that are unrelated to the handling
+ * of callbacks, but are convenient to attach to a DB_ENV.
+ *
+ * Note: We assume that the Java layer is the only one
+ * fiddling with the contents of db_errpfx, db_errcall, cj_internal
+ * for a DB_ENV that was created via Java. Since the Java layer should
+ * have the only pointer to such a DB_ENV, this should be true.
+ */
+typedef struct _db_env_javainfo
+{
+ JavaVM *javavm_;
+ int is_dbopen_;
+ char *errpfx_;
+ jobject jdbref_; /* temporary reference */
+ jobject jenvref_; /* temporary reference */
+ jobject default_errcall_; /* global reference */
+ jobject errcall_; /* global reference */
+ jobject feedback_; /* global reference */
+ jobject tx_recover_; /* global reference */
+ jobject recovery_init_; /* global reference */
+ unsigned char *conflict_;
+}
+DB_ENV_JAVAINFO; /* used with all 'dbjie' functions */
+
+/* create/initialize an object */
+extern DB_ENV_JAVAINFO *dbjie_construct(JNIEnv *jnienv,
+ jobject default_errcall,
+ int is_dbopen);
+
+/* release all objects held by this this one */
+extern void dbjie_dealloc(DB_ENV_JAVAINFO *, JNIEnv *jnienv);
+
+/* free this object, releasing anything allocated on its behalf */
+extern void dbjie_destroy(DB_ENV_JAVAINFO *, JNIEnv *jnienv);
+
+/* This gets the environment for the current thread */
+extern JNIEnv *dbjie_get_jnienv(DB_ENV_JAVAINFO *);
+
+extern void dbjie_set_errpfx(DB_ENV_JAVAINFO *, JNIEnv *jnienv,
+ jstring errpfx);
+extern jstring dbjie_get_errpfx(DB_ENV_JAVAINFO *, JNIEnv *jnienv);
+extern void dbjie_set_errcall(DB_ENV_JAVAINFO *, JNIEnv *jnienv,
+ jobject new_errcall);
+extern void dbjie_set_conflict(DB_ENV_JAVAINFO *, unsigned char *v);
+extern void dbjie_set_feedback_object(DB_ENV_JAVAINFO *, JNIEnv *jnienv,
+ DB_ENV *dbenv, jobject value);
+extern void dbjie_call_feedback(DB_ENV_JAVAINFO *, DB_ENV *dbenv, jobject jenv,
+ int opcode, int percent);
+extern void dbjie_set_recovery_init_object(DB_ENV_JAVAINFO *, JNIEnv *jnienv,
+ DB_ENV *dbenv, jobject value);
+extern int dbjie_call_recovery_init(DB_ENV_JAVAINFO *, DB_ENV *dbenv,
+ jobject jenv);
+extern void dbjie_set_tx_recover_object(DB_ENV_JAVAINFO *, JNIEnv *jnienv,
+ DB_ENV *dbenv, jobject value);
+extern int dbjie_call_tx_recover(DB_ENV_JAVAINFO *,
+ DB_ENV *dbenv, jobject jenv,
+ DBT *dbt, DB_LSN *lsn, int recops);
+extern jobject dbjie_get_errcall(DB_ENV_JAVAINFO *) ;
+extern int dbjie_is_dbopen(DB_ENV_JAVAINFO *);
+
+/****************************************************************
+ *
+ * Declaration of class DB_JAVAINFO
+ *
+ * A DB_JAVAINFO is allocated and stuffed into the cj_internal field
+ * for every DB created. It holds a little extra info that is needed
+ * to support callbacks.
+ *
+ * Note: We assume that the Java layer is the only one
+ * fiddling with the contents of cj_internal
+ * for a DB that was created via Java. Since the Java layer should
+ * have the only pointer to such a DB, this should be true.
+ */
+typedef struct _db_javainfo
+{
+ JavaVM *javavm_;
+ jobject jdbref_; /* temporary reference during callback */
+ jobject feedback_; /* global reference */
+ jobject append_recno_; /* global reference */
+ jobject bt_compare_; /* global reference */
+ jobject bt_prefix_; /* global reference */
+ jobject dup_compare_; /* global reference */
+ jobject h_hash_; /* global reference */
+ jmethodID feedback_method_id_;
+ jmethodID append_recno_method_id_;
+ jmethodID bt_compare_method_id_;
+ jmethodID bt_prefix_method_id_;
+ jmethodID dup_compare_method_id_;
+ jmethodID h_hash_method_id_;
+ jint construct_flags_;
+} DB_JAVAINFO;
+
+/* create/initialize an object */
+extern DB_JAVAINFO *dbji_construct(JNIEnv *jnienv, jint flags);
+
+/* release all objects held by this this one */
+extern void dbji_dealloc(DB_JAVAINFO *, JNIEnv *jnienv);
+
+/* free this object, releasing anything allocated on its behalf */
+extern void dbji_destroy(DB_JAVAINFO *, JNIEnv *jnienv);
+
+/* This gets the environment for the current thread */
+extern JNIEnv *dbji_get_jnienv();
+extern jint dbji_get_flags();
+
+extern void dbji_set_feedback_object(DB_JAVAINFO *, JNIEnv *jnienv, DB *db, jobject value);
+extern void dbji_call_feedback(DB_JAVAINFO *, DB *db, jobject jdb,
+ int opcode, int percent);
+
+extern void dbji_set_append_recno_object(DB_JAVAINFO *, JNIEnv *jnienv, DB *db, jobject value);
+extern int dbji_call_append_recno(DB_JAVAINFO *, DB *db, jobject jdb,
+ DBT *dbt, jint recno);
+extern void dbji_set_bt_compare_object(DB_JAVAINFO *, JNIEnv *jnienv, DB *db, jobject value);
+extern int dbji_call_bt_compare(DB_JAVAINFO *, DB *db, jobject jdb,
+ const DBT *dbt1, const DBT *dbt2);
+extern void dbji_set_bt_prefix_object(DB_JAVAINFO *, JNIEnv *jnienv, DB *db, jobject value);
+extern size_t dbji_call_bt_prefix(DB_JAVAINFO *, DB *db, jobject jdb,
+ const DBT *dbt1, const DBT *dbt2);
+extern void dbji_set_dup_compare_object(DB_JAVAINFO *, JNIEnv *jnienv, DB *db, jobject value);
+extern int dbji_call_dup_compare(DB_JAVAINFO *, DB *db, jobject jdb,
+ const DBT *dbt1, const DBT *dbt2);
+extern void dbji_set_h_hash_object(DB_JAVAINFO *, JNIEnv *jnienv, DB *db, jobject value);
+extern int dbji_call_h_hash(DB_JAVAINFO *, DB *db, jobject jdb,
+ const void *data, int len);
+
+#endif /* !_JAVA_INFO_H_ */
diff --git a/bdb/libdb_java/java_locked.c b/bdb/libdb_java/java_locked.c
new file mode 100644
index 00000000000..a5603df5d60
--- /dev/null
+++ b/bdb/libdb_java/java_locked.c
@@ -0,0 +1,294 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_locked.c,v 11.11 2000/10/25 19:54:55 dda Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "java_util.h"
+
+/****************************************************************
+ *
+ * Implementation of class LockedDBT
+ *
+ */
+int
+jdbt_lock(JDBT *jdbt, JNIEnv *jnienv, jobject obj, OpKind kind)
+{
+ DBT *dbt;
+
+ jdbt->obj_ = obj;
+ jdbt->do_realloc_ = 0;
+ jdbt->kind_ = kind;
+ jdbt->java_array_len_= 0;
+ jdbt->java_data_ = 0;
+ jdbt->before_data_ = 0;
+ jdbt->has_error_ = 0;
+ jdbt->dbt = (DBT_JAVAINFO *)get_private_dbobj(jnienv, name_DBT, obj);
+
+ if (!verify_non_null(jnienv, jdbt->dbt)) {
+ jdbt->has_error_ = 1;
+ return (EINVAL);
+ }
+ dbt = &jdbt->dbt->dbt;
+
+ if (kind == outOp &&
+ (dbt->flags & (DB_DBT_USERMEM | DB_DBT_MALLOC | DB_DBT_REALLOC)) == 0) {
+ report_exception(jnienv,
+ "Dbt.flags must be set to Db.DB_DBT_USERMEM, "
+ "Db.DB_DBT_MALLOC or Db.DB_DBT_REALLOC",
+ 0, 0);
+ jdbt->has_error_ = 1;
+ return (EINVAL);
+ }
+
+ /* If this is requested to be realloc, we cannot use the
+ * underlying realloc, because the array we will pass in
+ * is not allocated by us, but the Java VM, so it cannot
+ * be successfully realloced. We simulate the reallocation,
+ * by using USERMEM and reallocating the java array when a
+ * ENOMEM error occurs. We change the flags during the operation,
+ * and they are reset when the operation completes (in the
+ * LockedDBT destructor.
+ */
+ if ((dbt->flags & DB_DBT_REALLOC) != 0) {
+ dbt->flags &= ~DB_DBT_REALLOC;
+ dbt->flags |= DB_DBT_USERMEM;
+ jdbt->do_realloc_ = 1;
+ }
+
+ if ((dbt->flags & DB_DBT_USERMEM) || kind != outOp) {
+
+ /* If writing with DB_DBT_USERMEM/REALLOC
+ * or it's a set (or get/set) operation,
+ * then the data should point to a java array.
+ * Note that outOp means data is coming out of the database
+ * (it's a get). inOp means data is going into the database
+ * (either a put, or a key input).
+ */
+ if (!jdbt->dbt->array_) {
+ report_exception(jnienv, "Dbt.data is null", 0, 0);
+ jdbt->has_error_ = 1;
+ return (EINVAL);
+ }
+
+ /* Verify other parameters */
+ jdbt->java_array_len_ = (*jnienv)->GetArrayLength(jnienv, jdbt->dbt->array_);
+ if (jdbt->dbt->offset_ < 0 ) {
+ report_exception(jnienv, "Dbt.offset illegal", 0, 0);
+ jdbt->has_error_ = 1;
+ return (EINVAL);
+ }
+ if (dbt->ulen + jdbt->dbt->offset_ > jdbt->java_array_len_) {
+ report_exception(jnienv,
+ "Dbt.ulen + Dbt.offset greater than array length", 0, 0);
+ jdbt->has_error_ = 1;
+ return (EINVAL);
+ }
+
+ jdbt->java_data_ = (*jnienv)->GetByteArrayElements(jnienv, jdbt->dbt->array_,
+ (jboolean *)0);
+ dbt->data = jdbt->before_data_ = jdbt->java_data_ + jdbt->dbt->offset_;
+ }
+ else {
+
+ /* If writing with DB_DBT_MALLOC, then the data is
+ * allocated by DB.
+ */
+ dbt->data = jdbt->before_data_ = 0;
+ }
+ return (0);
+}
+
+/* The LockedDBT destructor is called when the java handler returns
+ * to the user, since that's when the LockedDBT objects go out of scope.
+ * Since it is thus called after any call to the underlying database,
+ * it copies any information from temporary structures back to user
+ * accessible arrays, and of course must free memory and remove references.
+ */
+void
+jdbt_unlock(JDBT *jdbt, JNIEnv *jnienv)
+{
+ DBT *dbt;
+
+ dbt = &jdbt->dbt->dbt;
+
+ /* Fix up the flags if we changed them. */
+ if (jdbt->do_realloc_) {
+ dbt->flags &= ~DB_DBT_USERMEM;
+ dbt->flags |= DB_DBT_REALLOC;
+ }
+
+ if ((dbt->flags & (DB_DBT_USERMEM | DB_DBT_REALLOC)) ||
+ jdbt->kind_ == inOp) {
+
+ /* If writing with DB_DBT_USERMEM/REALLOC or it's a set
+ * (or get/set) operation, then the data may be already in
+ * the java array, in which case, we just need to release it.
+ * If DB didn't put it in the array (indicated by the
+ * dbt->data changing), we need to do that
+ */
+ if (jdbt->before_data_ != jdbt->java_data_) {
+ (*jnienv)->SetByteArrayRegion(jnienv,
+ jdbt->dbt->array_,
+ jdbt->dbt->offset_,
+ dbt->ulen,
+ jdbt->before_data_);
+ }
+ (*jnienv)->ReleaseByteArrayElements(jnienv, jdbt->dbt->array_, jdbt->java_data_, 0);
+ dbt->data = 0;
+ }
+ if ((dbt->flags & DB_DBT_MALLOC) && jdbt->kind_ != inOp) {
+
+ /* If writing with DB_DBT_MALLOC, then the data was allocated
+ * by DB. If dbt->data is zero, it means an error occurred
+ * (and should have been already reported).
+ */
+ if (dbt->data) {
+
+ /* Release any old references. */
+ dbjit_release(jdbt->dbt, jnienv);
+
+ /* In the case of SET_RANGE, the key is inOutOp
+ * and when not found, its data will be left as
+ * its original value. Only copy and free it
+ * here if it has been allocated by DB
+ * (dbt->data has changed).
+ */
+ if (dbt->data != jdbt->before_data_) {
+ jdbt->dbt->array_ = (jbyteArray)
+ NEW_GLOBAL_REF(jnienv,
+ (*jnienv)->NewByteArray(jnienv,
+ dbt->size));
+ jdbt->dbt->offset_ = 0;
+ (*jnienv)->SetByteArrayRegion(jnienv,
+ jdbt->dbt->array_, 0, dbt->size,
+ (jbyte *)dbt->data);
+ free(dbt->data);
+ dbt->data = 0;
+ }
+ }
+ }
+}
+
+/* Realloc the java array to receive data if the DBT was marked
+ * for realloc, and the last operation set the size field to an
+ * amount greater than ulen.
+ */
+int jdbt_realloc(JDBT *jdbt, JNIEnv *jnienv)
+{
+ DBT *dbt;
+
+ dbt = &jdbt->dbt->dbt;
+
+ if (!jdbt->do_realloc_ || jdbt->has_error_ || dbt->size <= dbt->ulen)
+ return (0);
+
+ (*jnienv)->ReleaseByteArrayElements(jnienv, jdbt->dbt->array_, jdbt->java_data_, 0);
+ dbjit_release(jdbt->dbt, jnienv);
+
+ /* We allocate a new array of the needed size.
+ * We'll set the offset to 0, as the old offset
+ * really doesn't make any sense.
+ */
+ jdbt->java_array_len_ = dbt->ulen = dbt->size;
+ jdbt->dbt->offset_ = 0;
+ jdbt->dbt->array_ = (jbyteArray)
+ NEW_GLOBAL_REF(jnienv, (*jnienv)->NewByteArray(jnienv, dbt->size));
+
+ jdbt->java_data_ = (*jnienv)->GetByteArrayElements(jnienv,
+ jdbt->dbt->array_,
+ (jboolean *)0);
+ dbt->data = jdbt->before_data_ = jdbt->java_data_;
+ return (1);
+}
+
+/****************************************************************
+ *
+ * Implementation of class JSTR
+ *
+ */
+int
+jstr_lock(JSTR *js, JNIEnv *jnienv, jstring jstr)
+{
+ js->jstr_ = jstr;
+
+ if (jstr == 0)
+ js->string = 0;
+ else
+ js->string = (*jnienv)->GetStringUTFChars(jnienv, jstr,
+ (jboolean *)0);
+ return (0);
+}
+
+void jstr_unlock(JSTR *js, JNIEnv *jnienv)
+{
+ if (js->jstr_)
+ (*jnienv)->ReleaseStringUTFChars(jnienv, js->jstr_, js->string);
+}
+
+/****************************************************************
+ *
+ * Implementation of class JSTRARRAY
+ *
+ */
+int
+jstrarray_lock(JSTRARRAY *jsa, JNIEnv *jnienv, jobjectArray arr)
+{
+ int i;
+
+ jsa->arr_ = arr;
+ jsa->array = 0;
+
+ if (arr != 0) {
+ int count = (*jnienv)->GetArrayLength(jnienv, arr);
+ const char **new_array =
+ (const char **)malloc((sizeof(const char *))*(count+1));
+ for (i=0; i<count; i++) {
+ jstring jstr = (jstring)(*jnienv)->GetObjectArrayElement(jnienv, arr, i);
+ if (jstr == 0) {
+ /*
+ * An embedded null in the string array
+ * is treated as an endpoint.
+ */
+ new_array[i] = 0;
+ break;
+ }
+ else {
+ new_array[i] =
+ (*jnienv)->GetStringUTFChars(jnienv, jstr, (jboolean *)0);
+ }
+ }
+ new_array[count] = 0;
+ jsa->array = new_array;
+ }
+ return (0);
+}
+
+void jstrarray_unlock(JSTRARRAY *jsa, JNIEnv *jnienv)
+{
+ int i;
+ jstring jstr;
+
+ if (jsa->arr_) {
+ int count = (*jnienv)->GetArrayLength(jnienv, jsa->arr_);
+ for (i=0; i<count; i++) {
+ if (jsa->array[i] == 0)
+ break;
+ jstr = (jstring)(*jnienv)->GetObjectArrayElement(jnienv, jsa->arr_, i);
+ (*jnienv)->ReleaseStringUTFChars(jnienv, jstr, jsa->array[i]);
+ }
+ free((void*)jsa->array);
+ }
+}
diff --git a/bdb/libdb_java/java_locked.h b/bdb/libdb_java/java_locked.h
new file mode 100644
index 00000000000..9b88cdd0619
--- /dev/null
+++ b/bdb/libdb_java/java_locked.h
@@ -0,0 +1,98 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ *
+ * $Id: java_locked.h,v 11.9 2000/10/25 19:54:55 dda Exp $
+ */
+
+#ifndef _JAVA_LOCKED_H_
+#define _JAVA_LOCKED_H_
+
+/*
+ * Used internally by LockedDBT constructor.
+ */
+typedef enum _OpKind {
+ inOp, /* setting data in database (passing data in) */
+ outOp, /* getting data from database to user memory */
+ inOutOp /* both getting/setting data */
+} OpKind;
+
+/*
+ *
+ * Declaration of JDBT
+ *
+ * A JDBT object exists during a
+ * single native call to the DB API. Its constructor's job is
+ * to temporarily convert any java array found in the DBT_JAVAINFO
+ * to actual bytes in memory that remain locked in place. These
+ * bytes are used during the call to the underlying DB C layer,
+ * and are released and/or copied back by the destructor.
+ * Thus, a LockedDBT must be declared as a stack object to
+ * function properly.
+ */
+typedef struct _jdbt
+{
+ /* these are accessed externally to ldbt_ functions */
+ DBT_JAVAINFO *dbt;
+ unsigned int java_array_len_;
+
+ /* these are for used internally by ldbt_ functions */
+ jobject obj_;
+ jbyte *java_data_;
+ jbyte *before_data_;
+ int has_error_;
+ int do_realloc_;
+ OpKind kind_;
+} JDBT;
+
+extern int jdbt_lock(JDBT *, JNIEnv *jnienv, jobject obj, OpKind kind);
+extern void jdbt_unlock(JDBT *, JNIEnv *jnienv); /* this unlocks and frees the memory */
+extern int jdbt_realloc(JDBT *, JNIEnv *jnienv); /* returns 1 if reallocation took place */
+
+/****************************************************************
+ *
+ * Declaration of JSTR
+ *
+ * A JSTR exists temporarily to convert a java jstring object
+ * to a char *. Because the memory for the char * string is
+ * managed by the JVM, it must be released when we are done
+ * looking at it. Typically, jstr_lock() is called at the
+ * beginning of a function for each jstring object, and jstr_unlock
+ * is called at the end of each function for each JSTR.
+ */
+typedef struct _jstr
+{
+ /* this accessed externally to jstr_ functions */
+ const char *string;
+
+ /* this is used internally by jstr_ functions */
+ jstring jstr_;
+} JSTR;
+
+extern int jstr_lock(JSTR *, JNIEnv *jnienv, jstring jstr);
+extern void jstr_unlock(JSTR *, JNIEnv *jnienv); /* this unlocks and frees mem */
+
+/****************************************************************
+ *
+ * Declaration of class LockedStrarray
+ *
+ * Given a java jobjectArray object (that must be a String[]),
+ * we extract the individual strings and build a const char **
+ * When the LockedStrarray object is destroyed, the individual
+ * strings are released.
+ */
+typedef struct _jstrarray
+{
+ /* this accessed externally to jstrarray_ functions */
+ const char **array;
+
+ /* this is used internally by jstrarray_ functions */
+ jobjectArray arr_;
+} JSTRARRAY;
+
+extern int jstrarray_lock(JSTRARRAY *, JNIEnv *jnienv, jobjectArray arr);
+extern void jstrarray_unlock(JSTRARRAY *, JNIEnv *jnienv); /* this unlocks and frees mem */
+
+#endif /* !_JAVA_LOCKED_H_ */
diff --git a/bdb/libdb_java/java_util.c b/bdb/libdb_java/java_util.c
new file mode 100644
index 00000000000..f42ceafbee8
--- /dev/null
+++ b/bdb/libdb_java/java_util.c
@@ -0,0 +1,556 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char revid[] = "$Id: java_util.c,v 11.17 2000/10/28 13:09:39 dda Exp $";
+#endif /* not lint */
+
+#include <jni.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "java_util.h"
+
+#ifdef DB_WIN32
+#define sys_errlist _sys_errlist
+#define sys_nerr _sys_nerr
+#endif
+
+const char * const name_DB = "Db";
+const char * const name_DB_BTREE_STAT = "DbBtreeStat";
+const char * const name_DBC = "Dbc";
+const char * const name_DB_DEADLOCK_EX = "DbDeadlockException";
+const char * const name_DB_ENV = "DbEnv";
+const char * const name_DB_EXCEPTION = "DbException";
+const char * const name_DB_HASH_STAT = "DbHashStat";
+const char * const name_DB_LOCK = "DbLock";
+const char * const name_DB_LOCK_STAT = "DbLockStat";
+const char * const name_DB_LOG_STAT = "DbLogStat";
+const char * const name_DB_LSN = "DbLsn";
+const char * const name_DB_MEMORY_EX = "DbMemoryException";
+const char * const name_DB_MPOOL_FSTAT = "DbMpoolFStat";
+const char * const name_DB_MPOOL_STAT = "DbMpoolStat";
+const char * const name_DB_QUEUE_STAT = "DbQueueStat";
+const char * const name_DB_RUNRECOVERY_EX = "DbRunRecoveryException";
+const char * const name_DBT = "Dbt";
+const char * const name_DB_TXN = "DbTxn";
+const char * const name_DB_TXN_STAT = "DbTxnStat";
+const char * const name_DB_TXN_STAT_ACTIVE = "DbTxnStat$Active";
+const char * const name_DbAppendRecno = "DbAppendRecno";
+const char * const name_DbBtreeCompare = "DbBtreeCompare";
+const char * const name_DbBtreePrefix = "DbBtreePrefix";
+const char * const name_DbDupCompare = "DbDupCompare";
+const char * const name_DbEnvFeedback = "DbEnvFeedback";
+const char * const name_DbErrcall = "DbErrcall";
+const char * const name_DbHash = "DbHash";
+const char * const name_DbFeedback = "DbFeedback";
+const char * const name_DbRecoveryInit = "DbRecoveryInit";
+const char * const name_DbTxnRecover = "DbTxnRecover";
+
+const char * const string_signature = "Ljava/lang/String;";
+
+/****************************************************************
+ *
+ * Utility functions used by "glue" functions.
+ *
+ */
+
+/* Get the private data from a Db* object that points back to a C DB_* object.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void *get_private_dbobj(JNIEnv *jnienv, const char *classname,
+ jobject obj)
+{
+ jclass dbClass;
+ jfieldID id;
+ long_to_ptr lp;
+
+ if (!obj)
+ return (0);
+
+ dbClass = get_class(jnienv, classname);
+ id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_dbobj_", "J");
+ lp.java_long = (*jnienv)->GetLongField(jnienv, obj, id);
+ return (lp.ptr);
+}
+
+/* Set the private data in a Db* object that points back to a C DB_* object.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void set_private_dbobj(JNIEnv *jnienv, const char *classname,
+ jobject obj, void *value)
+{
+ long_to_ptr lp;
+ jclass dbClass;
+ jfieldID id;
+
+ lp.java_long = 0; /* no junk in case sizes mismatch */
+ lp.ptr = value;
+ dbClass = get_class(jnienv, classname);
+ id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_dbobj_", "J");
+ (*jnienv)->SetLongField(jnienv, obj, id, lp.java_long);
+}
+
+/* Get the private data in a Db/DbEnv object that holds additional 'side data'.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void *get_private_info(JNIEnv *jnienv, const char *classname,
+ jobject obj)
+{
+ jclass dbClass;
+ jfieldID id;
+ long_to_ptr lp;
+
+ if (!obj)
+ return (0);
+
+ dbClass = get_class(jnienv, classname);
+ id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_info_", "J");
+ lp.java_long = (*jnienv)->GetLongField(jnienv, obj, id);
+ return (lp.ptr);
+}
+
+/* Set the private data in a Db/DbEnv object that holds additional 'side data'.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void set_private_info(JNIEnv *jnienv, const char *classname,
+ jobject obj, void *value)
+{
+ long_to_ptr lp;
+ jclass dbClass;
+ jfieldID id;
+
+ lp.java_long = 0; /* no junk in case sizes mismatch */
+ lp.ptr = value;
+ dbClass = get_class(jnienv, classname);
+ id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_info_", "J");
+ (*jnienv)->SetLongField(jnienv, obj, id, lp.java_long);
+}
+
+/*
+ * Given a non-qualified name (e.g. "foo"), get the class handle
+ * for the fully qualified name (e.g. "com.sleepycat.db.foo")
+ */
+jclass get_class(JNIEnv *jnienv, const char *classname)
+{
+ /* Note: PERFORMANCE: It should be possible to cache jclass's.
+ * If we do a NewGlobalRef on each one, we can keep them
+ * around in a table. A jclass is a jobject, and
+ * since NewGlobalRef returns a jobject, it isn't
+ * technically right, but it would likely work with
+ * most implementations. Possibly make it configurable.
+ */
+ char fullname[128] = DB_PACKAGE_NAME;
+ strncat(fullname, classname, sizeof(fullname));
+ return ((*jnienv)->FindClass(jnienv, fullname));
+}
+
+/* Set an individual field in a Db* object.
+ * The field must be a DB object type.
+ */
+void set_object_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *object_classname,
+ const char *name_of_field, jobject obj)
+{
+ char signature[512];
+ jfieldID id;
+
+ strncpy(signature, "L", sizeof(signature));
+ strncat(signature, DB_PACKAGE_NAME, sizeof(signature));
+ strncat(signature, object_classname, sizeof(signature));
+ strncat(signature, ";", sizeof(signature));
+
+ id = (*jnienv)->GetFieldID(jnienv, class_of_this, name_of_field, signature);
+ (*jnienv)->SetObjectField(jnienv, jthis, id, obj);
+}
+
+/* Set an individual field in a Db* object.
+ * The field must be an integer type.
+ */
+void set_int_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *name_of_field, jint value)
+{
+ jfieldID id = (*jnienv)->GetFieldID(jnienv, class_of_this, name_of_field, "I");
+ (*jnienv)->SetIntField(jnienv, jthis, id, value);
+}
+
+/* Set an individual field in a Db* object.
+ * The field must be an integer type.
+ */
+void set_long_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *name_of_field, jlong value)
+{
+ jfieldID id = (*jnienv)->GetFieldID(jnienv, class_of_this, name_of_field, "J");
+ (*jnienv)->SetLongField(jnienv, jthis, id, value);
+}
+
+/* Set an individual field in a Db* object.
+ * The field must be an integer type.
+ */
+void set_lsn_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *name_of_field, DB_LSN value)
+{
+ set_object_field(jnienv, class_of_this, jthis, name_DB_LSN,
+ name_of_field, get_DbLsn(jnienv, value));
+}
+
+/* Report an exception back to the java side.
+ */
+void report_exception(JNIEnv *jnienv, const char *text, int err,
+ unsigned long expect_mask)
+{
+ jstring textString;
+ jclass dbexcept;
+ jclass javaexcept;
+ jmethodID constructId;
+ jthrowable obj;
+
+ textString = NULL;
+ dbexcept = NULL;
+ javaexcept = NULL;
+ constructId = NULL;
+ obj = NULL;
+
+ switch (err) {
+ /* DB_JAVA_CALLBACK is returned by dbji_call_append_recno()
+ * (the append_recno callback) when the Java version of the
+ * callback has thrown an exception, and we want to pass the
+ * exception on. The exception has already been thrown, we
+ * don't want to throw a new one.
+ */
+ case DB_JAVA_CALLBACK:
+ break;
+ case ENOMEM:
+ dbexcept = get_class(jnienv, name_DB_MEMORY_EX);
+ break;
+ case ENOENT:
+ /* In this case there is a corresponding standard java
+ * exception type that we'll use. First we make sure
+ * that the calling function expected this kind of error,
+ * if not we give an 'internal error' DbException, since
+ * we must not throw an exception type that isn't
+ * declared in the signature.
+ *
+ * We'll make this a little more general if/when we add
+ * more java standard exceptions.
+ */
+ if ((expect_mask & EXCEPTION_FILE_NOT_FOUND) == 0) {
+ char errstr[1024];
+
+ strncpy(errstr, "internal error: unexpected errno: ",
+ sizeof(errstr));
+ strncat(errstr, text, sizeof(errstr));
+ textString = get_java_string(jnienv, errstr);
+ dbexcept = get_class(jnienv, name_DB_EXCEPTION);
+ }
+ else {
+ javaexcept =
+ (*jnienv)->FindClass(jnienv, "java/io/FileNotFoundException");
+ }
+ break;
+ case DB_RUNRECOVERY:
+ dbexcept = get_class(jnienv, name_DB_RUNRECOVERY_EX);
+ break;
+ case DB_LOCK_DEADLOCK:
+ dbexcept = get_class(jnienv, name_DB_DEADLOCK_EX);
+ break;
+ default:
+ dbexcept = get_class(jnienv, name_DB_EXCEPTION);
+ break;
+ }
+ if (dbexcept != NULL) {
+ if (textString == NULL)
+ textString = get_java_string(jnienv, text);
+ constructId = (*jnienv)->GetMethodID(jnienv, dbexcept,
+ "<init>",
+ "(Ljava/lang/String;I)V");
+ obj = (jthrowable)(*jnienv)->NewObject(jnienv, dbexcept,
+ constructId, textString,
+ err);
+ (*jnienv)->Throw(jnienv, obj);
+ }
+ else if (javaexcept != NULL) {
+ javaexcept =
+ (*jnienv)->FindClass(jnienv, "java/io/FileNotFoundException");
+ (*jnienv)->ThrowNew(jnienv, javaexcept, text);
+ }
+}
+
+/* Report an error via the errcall mechanism.
+ */
+void report_errcall(JNIEnv *jnienv, jobject errcall,
+ jstring prefix, const char *message)
+{
+ jmethodID id;
+ jclass errcall_class;
+ jstring msg;
+
+ errcall_class = get_class(jnienv, name_DbErrcall);
+ msg = get_java_string(jnienv, message);
+
+ id = (*jnienv)->GetMethodID(jnienv, errcall_class,
+ "errcall",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (id == NULL) {
+ fprintf(stderr, "Cannot get errcall methodID!\n");
+ fprintf(stderr, "error: %s\n", message);
+ return;
+ }
+
+ (*jnienv)->CallVoidMethod(jnienv, errcall, id, prefix, msg);
+}
+
+/* If the object is null, report an exception and return false (0),
+ * otherwise return true (1).
+ */
+int verify_non_null(JNIEnv *jnienv, void *obj)
+{
+ if (obj == NULL) {
+ report_exception(jnienv, "null object", EINVAL, 0);
+ return (0);
+ }
+ return (1);
+}
+
+/* If the error code is non-zero, report an exception and return false (0),
+ * otherwise return true (1).
+ */
+int verify_return(JNIEnv *jnienv, int err, unsigned long expect_mask)
+{
+ if (err == 0)
+ return 1;
+
+ report_exception(jnienv, db_strerror(err), err, expect_mask);
+ return 0;
+}
+
+/* Create an object of the given class, calling its default constructor.
+ */
+jobject create_default_object(JNIEnv *jnienv, const char *class_name)
+{
+ jclass dbclass = get_class(jnienv, class_name);
+ jmethodID id = (*jnienv)->GetMethodID(jnienv, dbclass, "<init>", "()V");
+ jobject object = (*jnienv)->NewObject(jnienv, dbclass, id);
+ return (object);
+}
+
+/* Convert an DB object to a Java encapsulation of that object.
+ * Note: This implementation creates a new Java object on each call,
+ * so it is generally useful when a new DB object has just been created.
+ */
+jobject convert_object(JNIEnv *jnienv, const char *class_name, void *dbobj)
+{
+ jobject jo;
+
+ if (!dbobj)
+ return (0);
+
+ jo = create_default_object(jnienv, class_name);
+ set_private_dbobj(jnienv, class_name, jo, dbobj);
+ return (jo);
+}
+
+/* Create a copy of the string
+ */
+char *dup_string(const char *str)
+{
+ int len;
+ char *retval;
+
+ len = strlen(str) + 1;
+ retval = (char *)malloc(sizeof(char)*len);
+ strncpy(retval, str, len);
+ return (retval);
+}
+
+/* Create a java string from the given string
+ */
+jstring get_java_string(JNIEnv *jnienv, const char* string)
+{
+ if (string == 0)
+ return (0);
+ return ((*jnienv)->NewStringUTF(jnienv, string));
+}
+
+/* Create a malloc'ed copy of the java string.
+ * Caller must free it.
+ */
+char *get_c_string(JNIEnv *jnienv, jstring jstr)
+{
+ const jbyte *utf;
+ char *retval;
+
+ utf = (*jnienv)->GetStringUTFChars(jnienv, jstr, NULL);
+ retval = dup_string((const char *)utf);
+ (*jnienv)->ReleaseStringUTFChars(jnienv, jstr, utf);
+ return retval;
+}
+
+/* Convert a java object to the various C pointers they represent.
+ */
+DB *get_DB(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB *)get_private_dbobj(jnienv, name_DB, obj));
+}
+
+DB_BTREE_STAT *get_DB_BTREE_STAT(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_BTREE_STAT *)get_private_dbobj(jnienv, name_DB_BTREE_STAT, obj));
+}
+
+DBC *get_DBC(JNIEnv *jnienv, jobject obj)
+{
+ return ((DBC *)get_private_dbobj(jnienv, name_DBC, obj));
+}
+
+DB_ENV *get_DB_ENV(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_ENV *)get_private_dbobj(jnienv, name_DB_ENV, obj));
+}
+
+DB_ENV_JAVAINFO *get_DB_ENV_JAVAINFO(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_ENV_JAVAINFO *)get_private_info(jnienv, name_DB_ENV, obj));
+}
+
+DB_HASH_STAT *get_DB_HASH_STAT(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_HASH_STAT *)get_private_dbobj(jnienv, name_DB_HASH_STAT, obj));
+}
+
+DB_JAVAINFO *get_DB_JAVAINFO(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_JAVAINFO *)get_private_info(jnienv, name_DB, obj));
+}
+
+DB_LOCK *get_DB_LOCK(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_LOCK *)get_private_dbobj(jnienv, name_DB_LOCK, obj));
+}
+
+DB_LOG_STAT *get_DB_LOG_STAT(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_LOG_STAT *)get_private_dbobj(jnienv, name_DB_LOG_STAT, obj));
+}
+
+DB_LSN *get_DB_LSN(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_LSN *)get_private_dbobj(jnienv, name_DB_LSN, obj));
+}
+
+DB_MPOOL_FSTAT *get_DB_MPOOL_FSTAT(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_MPOOL_FSTAT *)get_private_dbobj(jnienv, name_DB_MPOOL_FSTAT, obj));
+}
+
+DB_MPOOL_STAT *get_DB_MPOOL_STAT(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_MPOOL_STAT *)get_private_dbobj(jnienv, name_DB_MPOOL_STAT, obj));
+}
+
+DB_QUEUE_STAT *get_DB_QUEUE_STAT(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_QUEUE_STAT *)get_private_dbobj(jnienv, name_DB_QUEUE_STAT, obj));
+}
+
+DB_TXN *get_DB_TXN(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_TXN *)get_private_dbobj(jnienv, name_DB_TXN, obj));
+}
+
+DB_TXN_STAT *get_DB_TXN_STAT(JNIEnv *jnienv, jobject obj)
+{
+ return ((DB_TXN_STAT *)get_private_dbobj(jnienv, name_DB_TXN_STAT, obj));
+}
+
+DBT *get_DBT(JNIEnv *jnienv, jobject obj)
+{
+ DBT_JAVAINFO *ji;
+
+ ji = (DBT_JAVAINFO *)get_private_dbobj(jnienv, name_DBT, obj);
+ if (ji == NULL)
+ return (NULL);
+ else
+ return (&ji->dbt);
+}
+
+DBT_JAVAINFO *get_DBT_JAVAINFO(JNIEnv *jnienv, jobject obj)
+{
+ return ((DBT_JAVAINFO *)get_private_dbobj(jnienv, name_DBT, obj));
+}
+
+/* Convert a C pointer to the various Java objects they represent.
+ */
+jobject get_DbBtreeStat(JNIEnv *jnienv, DB_BTREE_STAT *dbobj)
+{
+ return (convert_object(jnienv, name_DB_BTREE_STAT, dbobj));
+}
+
+jobject get_Dbc(JNIEnv *jnienv, DBC *dbobj)
+{
+ return (convert_object(jnienv, name_DBC, dbobj));
+}
+
+jobject get_DbHashStat(JNIEnv *jnienv, DB_HASH_STAT *dbobj)
+{
+ return (convert_object(jnienv, name_DB_HASH_STAT, dbobj));
+}
+
+jobject get_DbLogStat(JNIEnv *jnienv, DB_LOG_STAT *dbobj)
+{
+ return (convert_object(jnienv, name_DB_LOG_STAT, dbobj));
+}
+
+/* LSNs are different since they are really normally
+ * treated as by-value objects. We actually create
+ * a pointer to the LSN and store that, deleting it
+ * when the LSN is GC'd.
+ */
+jobject get_DbLsn(JNIEnv *jnienv, DB_LSN dbobj)
+{
+ DB_LSN *lsnp = (DB_LSN *)malloc(sizeof(DB_LSN));
+ memset(lsnp, 0, sizeof(DB_LSN));
+ *lsnp = dbobj;
+ return (convert_object(jnienv, name_DB_LSN, lsnp));
+}
+
+jobject get_Dbt(JNIEnv *jnienv, DBT *dbt)
+{
+ return (convert_object(jnienv, name_DBT, dbt));
+}
+
+jobject get_DbMpoolFStat(JNIEnv *jnienv, DB_MPOOL_FSTAT *dbobj)
+{
+ return (convert_object(jnienv, name_DB_MPOOL_FSTAT, dbobj));
+}
+
+jobject get_DbMpoolStat(JNIEnv *jnienv, DB_MPOOL_STAT *dbobj)
+{
+ return (convert_object(jnienv, name_DB_MPOOL_STAT, dbobj));
+}
+
+jobject get_DbQueueStat(JNIEnv *jnienv, DB_QUEUE_STAT *dbobj)
+{
+ return (convert_object(jnienv, name_DB_QUEUE_STAT, dbobj));
+}
+
+jobject get_DbTxn(JNIEnv *jnienv, DB_TXN *dbobj)
+{
+ return (convert_object(jnienv, name_DB_TXN, dbobj));
+}
+
+jobject get_DbTxnStat(JNIEnv *jnienv, DB_TXN_STAT *dbobj)
+{
+ return (convert_object(jnienv, name_DB_TXN_STAT, dbobj));
+}
diff --git a/bdb/libdb_java/java_util.h b/bdb/libdb_java/java_util.h
new file mode 100644
index 00000000000..eb47dc67629
--- /dev/null
+++ b/bdb/libdb_java/java_util.h
@@ -0,0 +1,359 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ *
+ * $Id: java_util.h,v 11.22 2001/01/11 18:19:53 bostic Exp $
+ */
+
+#ifndef _JAVA_UTIL_H_
+#define _JAVA_UTIL_H_
+
+#ifdef _MSC_VER
+
+/* These are level 4 warnings that are explicitly disabled.
+ * With Visual C++, by default you do not see above level 3 unless
+ * you use /W4. But we like to compile with the highest level
+ * warnings to catch other errors.
+ *
+ * 4201: nameless struct/union
+ * triggered by standard include file <winnt.h>
+ *
+ * 4244: '=' : convert from '__int64' to 'unsigned int', possible loss of data
+ * results from making size_t data members correspond to jlongs
+ *
+ * 4514: unreferenced inline function has been removed
+ * jni.h defines methods that are not called
+ *
+ * 4127: conditional expression is constant
+ * occurs because of arg in JAVADB_RW_ACCESS_STRING macro
+ */
+#pragma warning(disable: 4244 4201 4514 4127)
+
+#endif
+
+#include "db_config.h"
+#include "db.h"
+#include "java_info.h"
+#include "java_locked.h"
+#include <jni.h>
+#include <string.h> /* needed for memset */
+
+#define DB_PACKAGE_NAME "com/sleepycat/db/"
+
+/* Union to convert longs to pointers (see {get,set}_private_dbobj).
+ */
+typedef union {
+ jlong java_long;
+ void *ptr;
+} long_to_ptr;
+
+/****************************************************************
+ *
+ * Utility functions and definitions used by "glue" functions.
+ *
+ */
+
+#define NOT_IMPLEMENTED(str) \
+ report_exception(jnienv, str /*concatenate*/ ": not implemented", 0)
+
+/* Get, delete a global reference.
+ * Making this operation a function call allows for
+ * easier tracking for debugging. Global references
+ * are mostly grabbed at 'open' and 'close' points,
+ * so there shouldn't be a big performance hit.
+ *
+ * Macro-izing this makes it easier to add debugging code
+ * to track unreleased references.
+ */
+#ifdef DBJAVA_DEBUG
+#include <unistd.h>
+static void wrdebug(const char *str)
+{
+ write(2, str, strlen(str));
+ write(2, "\n", 1);
+}
+
+static jobject debug_new_global_ref(JNIEnv *jnienv, jobject obj, const char *s)
+{
+ wrdebug(s);
+ return (*jnienv)->NewGlobalRef(jnienv, obj);
+}
+
+static void debug_delete_global_ref(JNIEnv *jnienv, jobject obj, const char *s)
+{
+ wrdebug(s);
+ (*jnienv)->DeleteGlobalRef(jnienv, obj);
+}
+
+#define NEW_GLOBAL_REF(jnienv, obj) \
+ debug_new_global_ref(jnienv, obj, "+Ref: " #obj)
+#define DELETE_GLOBAL_REF(jnienv, obj) \
+ debug_delete_global_ref(jnienv, obj, "-Ref: " #obj)
+#else
+#define NEW_GLOBAL_REF(jnienv, obj) (*jnienv)->NewGlobalRef(jnienv, obj)
+#define DELETE_GLOBAL_REF(jnienv, obj) (*jnienv)->DeleteGlobalRef(jnienv, obj)
+#define wrdebug(x)
+#endif
+
+/* Get the private data from a Db* object that points back to a C DB_* object.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void *get_private_dbobj(JNIEnv *jnienv, const char *classname,
+ jobject obj);
+
+/* Set the private data in a Db* object that points back to a C DB_* object.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void set_private_dbobj(JNIEnv *jnienv, const char *classname,
+ jobject obj, void *value);
+
+/* Get the private data in a Db/DbEnv object that holds additional 'side data'.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void *get_private_info(JNIEnv *jnienv, const char *classname,
+ jobject obj);
+
+/* Set the private data in a Db/DbEnv object that holds additional 'side data'.
+ * The private data is stored in the object as a Java long (64 bits),
+ * which is long enough to store a pointer on current architectures.
+ */
+void set_private_info(JNIEnv *jnienv, const char *classname,
+ jobject obj, void *value);
+
+/*
+ * Given a non-qualified name (e.g. "foo"), get the class handl
+ * for the fully qualified name (e.g. "com.sleepycat.db.foo")
+ */
+jclass get_class(JNIEnv *jnienv, const char *classname);
+
+/* Set an individual field in a Db* object.
+ * The field must be a DB object type.
+ */
+void set_object_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *object_classname,
+ const char *name_of_field, jobject obj);
+
+/* Set an individual field in a Db* object.
+ * The field must be an integer type.
+ */
+void set_int_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *name_of_field, jint value);
+
+/* Set an individual field in a Db* object.
+ * The field must be an integer type.
+ */
+void set_long_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *name_of_field, jlong value);
+
+/* Set an individual field in a Db* object.
+ * The field must be an DbLsn type.
+ */
+void set_lsn_field(JNIEnv *jnienv, jclass class_of_this,
+ jobject jthis, const char *name_of_field, DB_LSN value);
+
+/* Values of expect_mask
+ */
+static const int EXCEPTION_FILE_NOT_FOUND = 0x0001;
+
+/* Report an exception back to the java side.
+ */
+void report_exception(JNIEnv *jnienv, const char *text, int err,
+ unsigned long expect_mask);
+
+/* Report an error via the errcall mechanism.
+ */
+void report_errcall(JNIEnv *jnienv, jobject errcall,
+ jstring prefix, const char *message);
+
+/* If the object is null, report an exception and return false (0),
+ * otherwise return true (1).
+ */
+int verify_non_null(JNIEnv *jnienv, void *obj);
+
+/* If the error code is non-zero, report an exception and return false (0),
+ * otherwise return true (1).
+ */
+int verify_return(JNIEnv *jnienv, int err, unsigned long expect_mask);
+
+/* Create an object of the given class, calling its default constructor.
+ */
+jobject create_default_object(JNIEnv *jnienv, const char *class_name);
+
+/* Convert an DB object to a Java encapsulation of that object.
+ * Note: This implementation creates a new Java object on each call,
+ * so it is generally useful when a new DB object has just been created.
+ */
+jobject convert_object(JNIEnv *jnienv, const char *class_name, void *dbobj);
+
+/* Create a copy of the string
+ */
+char *dup_string(const char *str);
+
+/* Create a malloc'ed copy of the java string.
+ * Caller must free it.
+ */
+char *get_c_string(JNIEnv *jnienv, jstring jstr);
+
+/* Create a java string from the given string
+ */
+jstring get_java_string(JNIEnv *jnienv, const char* string);
+
+/* Convert a java object to the various C pointers they represent.
+ */
+DB *get_DB (JNIEnv *jnienv, jobject obj);
+DB_BTREE_STAT *get_DB_BTREE_STAT (JNIEnv *jnienv, jobject obj);
+DBC *get_DBC (JNIEnv *jnienv, jobject obj);
+DB_ENV *get_DB_ENV (JNIEnv *jnienv, jobject obj);
+DB_ENV_JAVAINFO *get_DB_ENV_JAVAINFO (JNIEnv *jnienv, jobject obj);
+DB_HASH_STAT *get_DB_HASH_STAT (JNIEnv *jnienv, jobject obj);
+DB_JAVAINFO *get_DB_JAVAINFO (JNIEnv *jnienv, jobject obj);
+DB_LOCK *get_DB_LOCK (JNIEnv *jnienv, jobject obj);
+DB_LOG_STAT *get_DB_LOG_STAT (JNIEnv *jnienv, jobject obj);
+DB_LSN *get_DB_LSN (JNIEnv *jnienv, jobject obj);
+DB_MPOOL_FSTAT *get_DB_MPOOL_FSTAT(JNIEnv *jnienv, jobject obj);
+DB_MPOOL_STAT *get_DB_MPOOL_STAT (JNIEnv *jnienv, jobject obj);
+DB_QUEUE_STAT *get_DB_QUEUE_STAT (JNIEnv *jnienv, jobject obj);
+DB_TXN *get_DB_TXN (JNIEnv *jnienv, jobject obj);
+DB_TXN_STAT *get_DB_TXN_STAT (JNIEnv *jnienv, jobject obj);
+DBT *get_DBT (JNIEnv *jnienv, jobject obj);
+DBT_JAVAINFO *get_DBT_JAVAINFO (JNIEnv *jnienv, jobject obj);
+
+/* From a C object, create a Java object.
+ */
+jobject get_DbBtreeStat (JNIEnv *jnienv, DB_BTREE_STAT *dbobj);
+jobject get_Dbc (JNIEnv *jnienv, DBC *dbobj);
+jobject get_DbHashStat (JNIEnv *jnienv, DB_HASH_STAT *dbobj);
+jobject get_DbLogStat (JNIEnv *jnienv, DB_LOG_STAT *dbobj);
+jobject get_DbLsn (JNIEnv *jnienv, DB_LSN dbobj);
+jobject get_DbMpoolStat (JNIEnv *jnienv, DB_MPOOL_STAT *dbobj);
+jobject get_DbMpoolFStat (JNIEnv *jnienv, DB_MPOOL_FSTAT *dbobj);
+jobject get_DbQueueStat (JNIEnv *jnienv, DB_QUEUE_STAT *dbobj);
+jobject get_Dbt (JNIEnv *jnienv, DBT *dbt);
+jobject get_DbTxn (JNIEnv *jnienv, DB_TXN *dbobj);
+jobject get_DbTxnStat (JNIEnv *jnienv, DB_TXN_STAT *dbobj);
+
+/* The java names of DB classes */
+extern const char * const name_DB;
+extern const char * const name_DB_BTREE_STAT;
+extern const char * const name_DBC;
+extern const char * const name_DB_DEADLOCK_EX;
+extern const char * const name_DB_ENV;
+extern const char * const name_DB_EXCEPTION;
+extern const char * const name_DB_HASH_STAT;
+extern const char * const name_DB_LOCK;
+extern const char * const name_DB_LOCK_STAT;
+extern const char * const name_DB_LOG_STAT;
+extern const char * const name_DB_LSN;
+extern const char * const name_DB_MEMORY_EX;
+extern const char * const name_DB_MPOOL_FSTAT;
+extern const char * const name_DB_MPOOL_STAT;
+extern const char * const name_DB_QUEUE_STAT;
+extern const char * const name_DB_RUNRECOVERY_EX;
+extern const char * const name_DBT;
+extern const char * const name_DB_TXN;
+extern const char * const name_DB_TXN_STAT;
+extern const char * const name_DB_TXN_STAT_ACTIVE;
+extern const char * const name_DbAppendRecno;
+extern const char * const name_DbBtreeCompare;
+extern const char * const name_DbBtreePrefix;
+extern const char * const name_DbDupCompare;
+extern const char * const name_DbEnvFeedback;
+extern const char * const name_DbErrcall;
+extern const char * const name_DbFeedback;
+extern const char * const name_DbHash;
+extern const char * const name_DbRecoveryInit;
+extern const char * const name_DbTxnRecover;
+
+extern const char * const string_signature;
+
+#define JAVADB_RO_ACCESS(j_class, j_fieldtype, j_field, c_type, c_field) \
+JNIEXPORT j_fieldtype JNICALL \
+ Java_com_sleepycat_db_##j_class##_get_1##j_field \
+ (JNIEnv *jnienv, jobject jthis) \
+{ \
+ c_type *db_this = get_##c_type(jnienv, jthis); \
+ \
+ if (verify_non_null(jnienv, db_this)) { \
+ return db_this->c_field; \
+ } \
+ return 0; \
+}
+
+#define JAVADB_WO_ACCESS(j_class, j_fieldtype, j_field, c_type, c_field) \
+JNIEXPORT void JNICALL \
+ Java_com_sleepycat_db_##j_class##_set_1##j_field \
+ (JNIEnv *jnienv, jobject jthis, j_fieldtype value) \
+{ \
+ c_type *db_this = get_##c_type(jnienv, jthis); \
+ \
+ if (verify_non_null(jnienv, db_this)) { \
+ db_this->c_field = value; \
+ } \
+}
+
+/* This is a variant of the JAVADB_WO_ACCESS macro to define a simple set_
+ * method using a C "method" call. These should be used with set_
+ * methods that cannot invoke java 'callbacks' (no set_ method currently
+ * does that). That assumption allows us to optimize (and simplify)
+ * by not calling API_BEGIN/END macros.
+ */
+#define JAVADB_WO_ACCESS_METHOD(j_class, j_fieldtype, \
+ j_field, c_type, c_field) \
+JNIEXPORT void JNICALL \
+ Java_com_sleepycat_db_##j_class##_set_1##j_field \
+ (JNIEnv *jnienv, jobject jthis, j_fieldtype value) \
+{ \
+ c_type *db_this; \
+ int err; \
+ \
+ db_this = get_##c_type(jnienv, jthis); \
+ if (verify_non_null(jnienv, db_this)) { \
+ err = db_this->set_##c_field(db_this, value); \
+ verify_return(jnienv, err, 0); \
+ } \
+}
+
+#define JAVADB_RW_ACCESS(j_class, j_fieldtype, j_field, c_type, c_field) \
+ JAVADB_RO_ACCESS(j_class, j_fieldtype, j_field, c_type, c_field) \
+ JAVADB_WO_ACCESS(j_class, j_fieldtype, j_field, c_type, c_field)
+
+#define JAVADB_WO_ACCESS_STRING(j_class, j_field, c_type, c_field) \
+JNIEXPORT void JNICALL \
+ Java_com_sleepycat_db_##j_class##_set_1##j_field \
+ (JNIEnv *jnienv, jobject jthis, jstring value) \
+{ \
+ c_type *db_this; \
+ int err; \
+ \
+ db_this = get_##c_type(jnienv, jthis); \
+ if (verify_non_null(jnienv, db_this)) { \
+ err = db_this->set_##c_field(db_this, \
+ (*jnienv)->GetStringUTFChars(jnienv, value, NULL)); \
+ verify_return(jnienv, err, 0); \
+ } \
+}
+
+#define JAVADB_API_BEGIN(db, jthis) \
+ if ((db) != NULL) \
+ ((DB_JAVAINFO*)(db)->cj_internal)->jdbref_ = \
+ ((DB_ENV_JAVAINFO*)((db)->dbenv->cj_internal))->jdbref_ = (jthis)
+
+#define JAVADB_API_END(db) \
+ if ((db) != NULL) \
+ ((DB_JAVAINFO*)(db)->cj_internal)->jdbref_ = \
+ ((DB_ENV_JAVAINFO*)((db)->dbenv->cj_internal))->jdbref_ = 0
+
+#define JAVADB_ENV_API_BEGIN(dbenv, jthis) \
+ if ((dbenv) != NULL) \
+ ((DB_ENV_JAVAINFO*)((dbenv)->cj_internal))->jenvref_ = (jthis)
+
+#define JAVADB_ENV_API_END(dbenv) \
+ if ((dbenv) != NULL) \
+ ((DB_ENV_JAVAINFO*)((dbenv)->cj_internal))->jenvref_ = 0
+
+#endif /* !_JAVA_UTIL_H_ */