java_util.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:26k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1997-2002
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: java_util.c,v 11.49 2002/09/13 03:09:30 mjc Exp $";
  10. #endif /* not lint */
  11. #include <jni.h>
  12. #include <errno.h>
  13. #include "db_int.h"
  14. #include "java_util.h"
  15. #ifdef DB_WIN32
  16. #define sys_errlist _sys_errlist
  17. #define sys_nerr _sys_nerr
  18. #endif
  19. const char * const name_DB                 = "Db";
  20. const char * const name_DB_BTREE_STAT      = "DbBtreeStat";
  21. const char * const name_DBC                = "Dbc";
  22. const char * const name_DB_DEADLOCK_EX     = "DbDeadlockException";
  23. const char * const name_DB_ENV             = "DbEnv";
  24. const char * const name_DB_EXCEPTION       = "DbException";
  25. const char * const name_DB_HASH_STAT       = "DbHashStat";
  26. const char * const name_DB_LOCK            = "DbLock";
  27. const char * const name_DB_LOCK_STAT       = "DbLockStat";
  28. const char * const name_DB_LOCKNOTGRANTED_EX = "DbLockNotGrantedException";
  29. const char * const name_DB_LOGC            = "DbLogc";
  30. const char * const name_DB_LOG_STAT        = "DbLogStat";
  31. const char * const name_DB_LSN             = "DbLsn";
  32. const char * const name_DB_MEMORY_EX       = "DbMemoryException";
  33. const char * const name_DB_MPOOL_FSTAT     = "DbMpoolFStat";
  34. const char * const name_DB_MPOOL_STAT      = "DbMpoolStat";
  35. const char * const name_DB_PREPLIST        = "DbPreplist";
  36. const char * const name_DB_QUEUE_STAT      = "DbQueueStat";
  37. const char * const name_DB_REP_STAT        = "DbRepStat";
  38. const char * const name_DB_RUNRECOVERY_EX  = "DbRunRecoveryException";
  39. const char * const name_DBT                = "Dbt";
  40. const char * const name_DB_TXN             = "DbTxn";
  41. const char * const name_DB_TXN_STAT        = "DbTxnStat";
  42. const char * const name_DB_TXN_STAT_ACTIVE = "DbTxnStat$Active";
  43. const char * const name_DB_UTIL            = "DbUtil";
  44. const char * const name_DbAppendRecno      = "DbAppendRecno";
  45. const char * const name_DbBtreeCompare     = "DbBtreeCompare";
  46. const char * const name_DbBtreePrefix      = "DbBtreePrefix";
  47. const char * const name_DbDupCompare       = "DbDupCompare";
  48. const char * const name_DbEnvFeedback      = "DbEnvFeedback";
  49. const char * const name_DbErrcall          = "DbErrcall";
  50. const char * const name_DbHash             = "DbHash";
  51. const char * const name_DbLockRequest      = "DbLockRequest";
  52. const char * const name_DbFeedback         = "DbFeedback";
  53. const char * const name_DbRecoveryInit     = "DbRecoveryInit";
  54. const char * const name_DbRepTransport    = "DbRepTransport";
  55. const char * const name_DbSecondaryKeyCreate = "DbSecondaryKeyCreate";
  56. const char * const name_DbTxnRecover       = "DbTxnRecover";
  57. const char * const name_RepElectResult = "DbEnv$RepElectResult";
  58. const char * const name_RepProcessMessage = "DbEnv$RepProcessMessage";
  59. const char * const string_signature    = "Ljava/lang/String;";
  60. jfieldID fid_Dbt_data;
  61. jfieldID fid_Dbt_offset;
  62. jfieldID fid_Dbt_size;
  63. jfieldID fid_Dbt_ulen;
  64. jfieldID fid_Dbt_dlen;
  65. jfieldID fid_Dbt_doff;
  66. jfieldID fid_Dbt_flags;
  67. jfieldID fid_Dbt_private_dbobj_;
  68. jfieldID fid_Dbt_must_create_data;
  69. jfieldID fid_DbLockRequest_op;
  70. jfieldID fid_DbLockRequest_mode;
  71. jfieldID fid_DbLockRequest_timeout;
  72. jfieldID fid_DbLockRequest_obj;
  73. jfieldID fid_DbLockRequest_lock;
  74. jfieldID fid_RepProcessMessage_envid;
  75. /****************************************************************
  76.  *
  77.  * Utility functions used by "glue" functions.
  78.  */
  79. /*
  80.  * Do any one time initialization, especially initializing any
  81.  * unchanging methodIds, fieldIds, etc.
  82.  */
  83. void one_time_init(JNIEnv *jnienv)
  84. {
  85.     jclass cl;
  86.     if ((cl = get_class(jnienv, name_DBT)) == NULL)
  87. return; /* An exception has been posted. */
  88.     fid_Dbt_data = (*jnienv)->GetFieldID(jnienv, cl, "data", "[B");
  89.     fid_Dbt_offset = (*jnienv)->GetFieldID(jnienv, cl, "offset", "I");
  90.     fid_Dbt_size = (*jnienv)->GetFieldID(jnienv, cl, "size", "I");
  91.     fid_Dbt_ulen = (*jnienv)->GetFieldID(jnienv, cl, "ulen", "I");
  92.     fid_Dbt_dlen = (*jnienv)->GetFieldID(jnienv, cl, "dlen", "I");
  93.     fid_Dbt_doff = (*jnienv)->GetFieldID(jnienv, cl, "doff", "I");
  94.     fid_Dbt_flags = (*jnienv)->GetFieldID(jnienv, cl, "flags", "I");
  95.     fid_Dbt_must_create_data = (*jnienv)->GetFieldID(jnienv, cl,
  96.      "must_create_data", "Z");
  97.     fid_Dbt_private_dbobj_ =
  98. (*jnienv)->GetFieldID(jnienv, cl, "private_dbobj_", "J");
  99.     if ((cl = get_class(jnienv, name_DbLockRequest)) == NULL)
  100. return; /* An exception has been posted. */
  101.     fid_DbLockRequest_op = (*jnienv)->GetFieldID(jnienv, cl, "op", "I");
  102.     fid_DbLockRequest_mode = (*jnienv)->GetFieldID(jnienv, cl, "mode", "I");
  103.     fid_DbLockRequest_timeout =
  104. (*jnienv)->GetFieldID(jnienv, cl, "timeout", "I");
  105.     fid_DbLockRequest_obj = (*jnienv)->GetFieldID(jnienv, cl, "obj",
  106.   "Lcom/sleepycat/db/Dbt;");
  107.     fid_DbLockRequest_lock = (*jnienv)->GetFieldID(jnienv, cl, "lock",
  108.    "Lcom/sleepycat/db/DbLock;");
  109.     if ((cl = get_class(jnienv, name_RepProcessMessage)) == NULL)
  110. return; /* An exception has been posted. */
  111.     fid_RepProcessMessage_envid =
  112. (*jnienv)->GetFieldID(jnienv, cl, "envid", "I");
  113. }
  114. /*
  115.  * Get the private data from a Db* object that points back to a C DB_* object.
  116.  * The private data is stored in the object as a Java long (64 bits),
  117.  * which is long enough to store a pointer on current architectures.
  118.  */
  119. void *get_private_dbobj(JNIEnv *jnienv, const char *classname,
  120. jobject obj)
  121. {
  122. jclass dbClass;
  123. jfieldID id;
  124. long_to_ptr lp;
  125. if (!obj)
  126. return (0);
  127. if ((dbClass = get_class(jnienv, classname)) == NULL)
  128. return (NULL); /* An exception has been posted. */
  129. id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_dbobj_", "J");
  130. lp.java_long = (*jnienv)->GetLongField(jnienv, obj, id);
  131. return (lp.ptr);
  132. }
  133. /*
  134.  * Set the private data in a Db* object that points back to a C DB_* object.
  135.  * The private data is stored in the object as a Java long (64 bits),
  136.  * which is long enough to store a pointer on current architectures.
  137.  */
  138. void set_private_dbobj(JNIEnv *jnienv, const char *classname,
  139.        jobject obj, void *value)
  140. {
  141. long_to_ptr lp;
  142. jclass dbClass;
  143. jfieldID id;
  144. lp.java_long = 0; /* no junk in case sizes mismatch */
  145. lp.ptr = value;
  146. if ((dbClass = get_class(jnienv, classname)) == NULL)
  147. return; /* An exception has been posted. */
  148. id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_dbobj_", "J");
  149. (*jnienv)->SetLongField(jnienv, obj, id, lp.java_long);
  150. }
  151. /*
  152.  * Get the private data in a Db/DbEnv object that holds additional 'side data'.
  153.  * The private data is stored in the object as a Java long (64 bits),
  154.  * which is long enough to store a pointer on current architectures.
  155.  */
  156. void *get_private_info(JNIEnv *jnienv, const char *classname,
  157.        jobject obj)
  158. {
  159. jclass dbClass;
  160. jfieldID id;
  161. long_to_ptr lp;
  162. if (!obj)
  163. return (NULL);
  164. if ((dbClass = get_class(jnienv, classname)) == NULL)
  165. return (NULL); /* An exception has been posted. */
  166. id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_info_", "J");
  167. lp.java_long = (*jnienv)->GetLongField(jnienv, obj, id);
  168. return (lp.ptr);
  169. }
  170. /*
  171.  * Set the private data in a Db/DbEnv object that holds additional 'side data'.
  172.  * The private data is stored in the object as a Java long (64 bits),
  173.  * which is long enough to store a pointer on current architectures.
  174.  */
  175. void set_private_info(JNIEnv *jnienv, const char *classname,
  176.       jobject obj, void *value)
  177. {
  178. long_to_ptr lp;
  179. jclass dbClass;
  180. jfieldID id;
  181. lp.java_long = 0; /* no junk in case sizes mismatch */
  182. lp.ptr = value;
  183. if ((dbClass = get_class(jnienv, classname)) == NULL)
  184. return; /* An exception has been posted. */
  185. id = (*jnienv)->GetFieldID(jnienv, dbClass, "private_info_", "J");
  186. (*jnienv)->SetLongField(jnienv, obj, id, lp.java_long);
  187. }
  188. /*
  189.  * Given a non-qualified name (e.g. "foo"), get the class handle
  190.  * for the fully qualified name (e.g. "com.sleepycat.db.foo")
  191.  */
  192. jclass get_class(JNIEnv *jnienv, const char *classname)
  193. {
  194. /*
  195.  * Note: PERFORMANCE: It should be possible to cache jclass's.
  196.  * If we do a NewGlobalRef on each one, we can keep them
  197.  * around in a table.  A jclass is a jobject, and
  198.  * since NewGlobalRef returns a jobject, it isn't
  199.  * technically right, but it would likely work with
  200.  * most implementations.  Possibly make it configurable.
  201.  */
  202. char fullname[128];
  203. (void)snprintf(fullname, sizeof(fullname),
  204.     "%s%s", DB_PACKAGE_NAME, classname);
  205. return ((*jnienv)->FindClass(jnienv, fullname));
  206. }
  207. /*
  208.  * Given a fully qualified name (e.g. "java.util.Hashtable")
  209.  * return the jclass object.  If it can't be found, an
  210.  * exception is raised and NULL is return.
  211.  * This is appropriate to be used for classes that may
  212.  * not be present.
  213.  */
  214. jclass get_fully_qualified_class(JNIEnv *jnienv, const char *classname)
  215. {
  216. jclass result;
  217. result = ((*jnienv)->FindClass(jnienv, classname));
  218. if (result == NULL) {
  219. jclass cnfe;
  220. char message[1024];
  221. cnfe = (*jnienv)->FindClass(jnienv,
  222.     "java/lang/ClassNotFoundException");
  223. strncpy(message, classname, sizeof(message));
  224. strncat(message, ": class not found", sizeof(message));
  225. (*jnienv)->ThrowNew(jnienv, cnfe, message);
  226. }
  227. return (result);
  228. }
  229. /*
  230.  * Set an individual field in a Db* object.
  231.  * The field must be a DB object type.
  232.  */
  233. void set_object_field(JNIEnv *jnienv, jclass class_of_this,
  234.       jobject jthis, const char *object_classname,
  235.       const char *name_of_field, jobject obj)
  236. {
  237. char signature[512];
  238. jfieldID id;
  239. (void)snprintf(signature, sizeof(signature),
  240.     "L%s%s;", DB_PACKAGE_NAME, object_classname);
  241. id  = (*jnienv)->GetFieldID(
  242.     jnienv, class_of_this, name_of_field, signature);
  243. (*jnienv)->SetObjectField(jnienv, jthis, id, obj);
  244. }
  245. /*
  246.  * Set an individual field in a Db* object.
  247.  * The field must be an integer type.
  248.  */
  249. void set_int_field(JNIEnv *jnienv, jclass class_of_this,
  250.    jobject jthis, const char *name_of_field, jint value)
  251. {
  252. jfieldID id  =
  253.     (*jnienv)->GetFieldID(jnienv, class_of_this, name_of_field, "I");
  254. (*jnienv)->SetIntField(jnienv, jthis, id, value);
  255. }
  256. /*
  257.  * Set an individual field in a Db* object.
  258.  * The field must be an integer type.
  259.  */
  260. void set_long_field(JNIEnv *jnienv, jclass class_of_this,
  261.     jobject jthis, const char *name_of_field, jlong value)
  262. {
  263. jfieldID id  = (*jnienv)->GetFieldID(jnienv, class_of_this,
  264.      name_of_field, "J");
  265. (*jnienv)->SetLongField(jnienv, jthis, id, value);
  266. }
  267. /*
  268.  * Set an individual field in a Db* object.
  269.  * The field must be an integer type.
  270.  */
  271. void set_lsn_field(JNIEnv *jnienv, jclass class_of_this,
  272.    jobject jthis, const char *name_of_field, DB_LSN value)
  273. {
  274. set_object_field(jnienv, class_of_this, jthis, name_DB_LSN,
  275.  name_of_field, get_DbLsn(jnienv, value));
  276. }
  277. /*
  278.  * Report an exception back to the java side.
  279.  */
  280. void report_exception(JNIEnv *jnienv, const char *text,
  281.       int err, unsigned long expect_mask)
  282. {
  283. jstring textString;
  284. jclass dbexcept;
  285. jclass javaexcept;
  286. jthrowable obj;
  287. textString = NULL;
  288. dbexcept = NULL;
  289. javaexcept = NULL;
  290. switch (err) {
  291. /*
  292.  * DB_JAVA_CALLBACK is returned by
  293.  * dbji_call_append_recno() (the append_recno callback)
  294.  * when the Java version of the callback has thrown
  295.  * an exception, and we want to pass the exception on.
  296.  * The exception has already been thrown, we
  297.  * don't want to throw a new one.
  298.  */
  299. case DB_JAVA_CALLBACK:
  300. break;
  301. case ENOENT:
  302. /*
  303.  * In this case there is a corresponding
  304.  * standard java exception type that we'll use.
  305.  * First we make sure that the calling function
  306.  * expected this kind of error, if not we give
  307.  * an 'internal error' DbException, since
  308.  * we must not throw an exception type that isn't
  309.  * declared in the signature.
  310.  *
  311.  * We'll make this a little more general if/when
  312.  * we add more java standard exceptions.
  313.  */
  314. if ((expect_mask & EXCEPTION_FILE_NOT_FOUND) != 0) {
  315. javaexcept = (*jnienv)->FindClass(jnienv,
  316.     "java/io/FileNotFoundException");
  317. }
  318. else {
  319. char errstr[1024];
  320. snprintf(errstr, sizeof(errstr),
  321.   "internal error: unexpected errno: %s",
  322.  text);
  323. textString = get_java_string(jnienv,
  324.      errstr);
  325. dbexcept = get_class(jnienv,
  326.      name_DB_EXCEPTION);
  327. }
  328. break;
  329. case DB_RUNRECOVERY:
  330. dbexcept = get_class(jnienv,
  331.      name_DB_RUNRECOVERY_EX);
  332. break;
  333. case DB_LOCK_DEADLOCK:
  334. dbexcept = get_class(jnienv, name_DB_DEADLOCK_EX);
  335. break;
  336. default:
  337. dbexcept = get_class(jnienv, name_DB_EXCEPTION);
  338. break;
  339. }
  340. if (dbexcept != NULL) {
  341. if (textString == NULL)
  342. textString = get_java_string(jnienv, text);
  343. if ((obj = create_exception(jnienv, textString, err, dbexcept))
  344.     != NULL)
  345. (*jnienv)->Throw(jnienv, obj);
  346. /* Otherwise, an exception has been posted. */
  347. }
  348. else if (javaexcept != NULL)
  349. (*jnienv)->ThrowNew(jnienv, javaexcept, text);
  350. else
  351. fprintf(stderr,
  352.     "report_exception: failed to create an exceptionn");
  353. }
  354. /*
  355.  * Report an exception back to the java side, for the specific
  356.  * case of DB_LOCK_NOTGRANTED, as more things are added to the
  357.  * constructor of this type of exception.
  358.  */
  359. void report_notgranted_exception(JNIEnv *jnienv, const char *text,
  360.  db_lockop_t op, db_lockmode_t mode,
  361.  jobject jdbt, jobject jlock, int index)
  362. {
  363. jstring textString;
  364. jclass dbexcept;
  365. jthrowable obj;
  366. jmethodID mid;
  367. if ((dbexcept = get_class(jnienv, name_DB_LOCKNOTGRANTED_EX)) == NULL)
  368. return; /* An exception has been posted. */
  369. textString = get_java_string(jnienv, text);
  370. mid = (*jnienv)->GetMethodID(jnienv, dbexcept, "<init>",
  371.      "(Ljava/lang/String;II"
  372.      "Lcom/sleepycat/db/Dbt;"
  373.      "Lcom/sleepycat/db/DbLock;I)V");
  374. if ((obj = (jthrowable)(*jnienv)->NewObject(jnienv, dbexcept,
  375.     mid, textString, op, mode, jdbt, jlock, index)) != NULL)
  376. (*jnienv)->Throw(jnienv, obj);
  377. else
  378. fprintf(stderr,
  379.     "report_notgranted_exception: failed to create an exceptionn");
  380. }
  381. /*
  382.  * Create an exception object and return it.
  383.  * The given class must have a constructor that has a
  384.  * constructor with args (java.lang.String text, int errno);
  385.  * DbException and its subclasses fit this bill.
  386.  */
  387. jobject create_exception(JNIEnv *jnienv, jstring text,
  388.   int err, jclass dbexcept)
  389. {
  390. jthrowable obj;
  391. jmethodID mid;
  392. mid = (*jnienv)->GetMethodID(jnienv, dbexcept, "<init>",
  393.      "(Ljava/lang/String;I)V");
  394. if (mid != NULL)
  395. obj = (jthrowable)(*jnienv)->NewObject(jnienv, dbexcept, mid,
  396.        text, err);
  397. else {
  398. fprintf(stderr, "Cannot get exception init method ID!n");
  399. obj = NULL;
  400. }
  401. return (obj);
  402. }
  403. /*
  404.  * Report an error via the errcall mechanism.
  405.  */
  406. void report_errcall(JNIEnv *jnienv, jobject errcall,
  407.     jstring prefix, const char *message)
  408. {
  409. jmethodID id;
  410. jclass errcall_class;
  411. jstring msg;
  412. if ((errcall_class = get_class(jnienv, name_DbErrcall)) == NULL)
  413. return; /* An exception has been posted. */
  414. msg = get_java_string(jnienv, message);
  415. id = (*jnienv)->GetMethodID(jnienv, errcall_class,
  416.  "errcall",
  417.  "(Ljava/lang/String;Ljava/lang/String;)V");
  418. if (id == NULL) {
  419. fprintf(stderr, "Cannot get errcall methodID!n");
  420. fprintf(stderr, "error: %sn", message);
  421. return;
  422. }
  423. (*jnienv)->CallVoidMethod(jnienv, errcall, id, prefix, msg);
  424. }
  425. /*
  426.  * If the object is null, report an exception and return false (0),
  427.  * otherwise return true (1).
  428.  */
  429. int verify_non_null(JNIEnv *jnienv, void *obj)
  430. {
  431. if (obj == NULL) {
  432. report_exception(jnienv, "null object", EINVAL, 0);
  433. return (0);
  434. }
  435. return (1);
  436. }
  437. /*
  438.  * If the error code is non-zero, report an exception and return false (0),
  439.  * otherwise return true (1).
  440.  */
  441. int verify_return(JNIEnv *jnienv, int err, unsigned long expect_mask)
  442. {
  443. if (err == 0)
  444. return (1);
  445. report_exception(jnienv, db_strerror(err), err, expect_mask);
  446. return (0);
  447. }
  448. /*
  449.  * Verify that there was no memory error due to undersized Dbt.
  450.  * If there is report a DbMemoryException, with the Dbt attached
  451.  * and return false (0), otherwise return true (1).
  452.  */
  453. int verify_dbt(JNIEnv *jnienv, int err, LOCKED_DBT *ldbt)
  454. {
  455. DBT *dbt;
  456. jobject exception;
  457. jstring text;
  458. jclass dbexcept;
  459. jmethodID mid;
  460. if (err != ENOMEM)
  461. return (1);
  462. dbt = &ldbt->javainfo->dbt;
  463. if (!F_ISSET(dbt, DB_DBT_USERMEM) || dbt->size <= dbt->ulen)
  464. return (1);
  465. /* Create/throw an exception of type DbMemoryException */
  466. if ((dbexcept = get_class(jnienv, name_DB_MEMORY_EX)) == NULL)
  467. return (1); /* An exception has been posted. */
  468. text = get_java_string(jnienv,
  469.        "Dbt not large enough for available data");
  470. exception = create_exception(jnienv, text, ENOMEM, dbexcept);
  471. /* Attach the dbt to the exception */
  472. mid = (*jnienv)->GetMethodID(jnienv, dbexcept, "set_dbt",
  473.      "(L" DB_PACKAGE_NAME "Dbt;)V");
  474. (*jnienv)->CallVoidMethod(jnienv, exception, mid, ldbt->jdbt);
  475. (*jnienv)->Throw(jnienv, exception);
  476. return (0);
  477. }
  478. /*
  479.  * Create an object of the given class, calling its default constructor.
  480.  */
  481. jobject create_default_object(JNIEnv *jnienv, const char *class_name)
  482. {
  483. jmethodID id;
  484. jclass dbclass;
  485. if ((dbclass = get_class(jnienv, class_name)) == NULL)
  486. return (NULL); /* An exception has been posted. */
  487. id = (*jnienv)->GetMethodID(jnienv, dbclass, "<init>", "()V");
  488. return ((*jnienv)->NewObject(jnienv, dbclass, id));
  489. }
  490. /*
  491.  * Convert an DB object to a Java encapsulation of that object.
  492.  * Note: This implementation creates a new Java object on each call,
  493.  * so it is generally useful when a new DB object has just been created.
  494.  */
  495. jobject convert_object(JNIEnv *jnienv, const char *class_name, void *dbobj)
  496. {
  497. jobject jo;
  498. if (!dbobj)
  499. return (0);
  500. jo = create_default_object(jnienv, class_name);
  501. set_private_dbobj(jnienv, class_name, jo, dbobj);
  502. return (jo);
  503. }
  504. /*
  505.  * Create a copy of the string
  506.  */
  507. char *dup_string(const char *str)
  508. {
  509. int len;
  510. char *retval;
  511. int err;
  512. len = strlen(str) + 1;
  513. if ((err = __os_malloc(NULL, sizeof(char)*len, &retval)) != 0)
  514. return (NULL);
  515. strncpy(retval, str, len);
  516. return (retval);
  517. }
  518. /*
  519.  * Create a java string from the given string
  520.  */
  521. jstring get_java_string(JNIEnv *jnienv, const char* string)
  522. {
  523. if (string == 0)
  524. return (0);
  525. return ((*jnienv)->NewStringUTF(jnienv, string));
  526. }
  527. /*
  528.  * Create a copy of the java string using __os_malloc.
  529.  * Caller must free it.
  530.  */
  531. char *get_c_string(JNIEnv *jnienv, jstring jstr)
  532. {
  533. const char *utf;
  534. char *retval;
  535. utf = (*jnienv)->GetStringUTFChars(jnienv, jstr, NULL);
  536. retval = dup_string(utf);
  537. (*jnienv)->ReleaseStringUTFChars(jnienv, jstr, utf);
  538. return (retval);
  539. }
  540. /*
  541.  * Convert a java object to the various C pointers they represent.
  542.  */
  543. DB *get_DB(JNIEnv *jnienv, jobject obj)
  544. {
  545. return ((DB *)get_private_dbobj(jnienv, name_DB, obj));
  546. }
  547. DB_BTREE_STAT *get_DB_BTREE_STAT(JNIEnv *jnienv, jobject obj)
  548. {
  549. return ((DB_BTREE_STAT *)
  550.     get_private_dbobj(jnienv, name_DB_BTREE_STAT, obj));
  551. }
  552. DBC *get_DBC(JNIEnv *jnienv, jobject obj)
  553. {
  554. return ((DBC *)get_private_dbobj(jnienv, name_DBC, obj));
  555. }
  556. DB_ENV *get_DB_ENV(JNIEnv *jnienv, jobject obj)
  557. {
  558. return ((DB_ENV *)get_private_dbobj(jnienv, name_DB_ENV, obj));
  559. }
  560. DB_ENV_JAVAINFO *get_DB_ENV_JAVAINFO(JNIEnv *jnienv, jobject obj)
  561. {
  562. return ((DB_ENV_JAVAINFO *)get_private_info(jnienv, name_DB_ENV, obj));
  563. }
  564. DB_HASH_STAT *get_DB_HASH_STAT(JNIEnv *jnienv, jobject obj)
  565. {
  566. return ((DB_HASH_STAT *)
  567.     get_private_dbobj(jnienv, name_DB_HASH_STAT, obj));
  568. }
  569. DB_JAVAINFO *get_DB_JAVAINFO(JNIEnv *jnienv, jobject obj)
  570. {
  571. return ((DB_JAVAINFO *)get_private_info(jnienv, name_DB, obj));
  572. }
  573. DB_LOCK *get_DB_LOCK(JNIEnv *jnienv, jobject obj)
  574. {
  575. return ((DB_LOCK *)get_private_dbobj(jnienv, name_DB_LOCK, obj));
  576. }
  577. DB_LOGC *get_DB_LOGC(JNIEnv *jnienv, jobject obj)
  578. {
  579. return ((DB_LOGC *)get_private_dbobj(jnienv, name_DB_LOGC, obj));
  580. }
  581. DB_LOG_STAT *get_DB_LOG_STAT(JNIEnv *jnienv, jobject obj)
  582. {
  583. return ((DB_LOG_STAT *)
  584.     get_private_dbobj(jnienv, name_DB_LOG_STAT, obj));
  585. }
  586. DB_LSN *get_DB_LSN(JNIEnv *jnienv, /* DbLsn */ jobject obj) {
  587. /*
  588.  * DbLsns that are created from within java (new DbLsn()) rather
  589.  * than from within C (get_DbLsn()) may not have a "private" DB_LSN
  590.  * structure allocated for them yet.  We can't do this in the
  591.  * actual constructor (init_lsn()), because there's no way to pass
  592.  * in an initializing value in, and because the get_DbLsn()/
  593.  * convert_object() code path needs a copy of the pointer before
  594.  * the constructor gets called.  Thus, get_DbLsn() allocates and
  595.  * fills a DB_LSN for the object it's about to create.
  596.  *
  597.  * Since "new DbLsn()" may reasonably be passed as an argument to
  598.  * functions such as DbEnv.log_put(), though, we need to make sure
  599.  * that DB_LSN's get allocated when the object was created from
  600.  * Java, too.  Here, we lazily allocate a new private DB_LSN if
  601.  * and only if it turns out that we don't already have one.
  602.  *
  603.  * The only exception is if the DbLsn object is a Java null
  604.  * (in which case the jobject will also be NULL). Then a NULL
  605.  * DB_LSN is legitimate.
  606.  */
  607. DB_LSN *lsnp;
  608. int err;
  609. if (obj == NULL)
  610. return (NULL);
  611. lsnp = (DB_LSN *)get_private_dbobj(jnienv, name_DB_LSN, obj);
  612. if (lsnp == NULL) {
  613. if ((err = __os_malloc(NULL, sizeof(DB_LSN), &lsnp)) != 0)
  614. return (NULL);
  615. memset(lsnp, 0, sizeof(DB_LSN));
  616. set_private_dbobj(jnienv, name_DB_LSN, obj, lsnp);
  617. }
  618. return (lsnp);
  619. }
  620. DB_MPOOL_FSTAT *get_DB_MPOOL_FSTAT(JNIEnv *jnienv, jobject obj)
  621. {
  622. return ((DB_MPOOL_FSTAT *)
  623.     get_private_dbobj(jnienv, name_DB_MPOOL_FSTAT, obj));
  624. }
  625. DB_MPOOL_STAT *get_DB_MPOOL_STAT(JNIEnv *jnienv, jobject obj)
  626. {
  627. return ((DB_MPOOL_STAT *)
  628.     get_private_dbobj(jnienv, name_DB_MPOOL_STAT, obj));
  629. }
  630. DB_QUEUE_STAT *get_DB_QUEUE_STAT(JNIEnv *jnienv, jobject obj)
  631. {
  632. return ((DB_QUEUE_STAT *)
  633.     get_private_dbobj(jnienv, name_DB_QUEUE_STAT, obj));
  634. }
  635. DB_TXN *get_DB_TXN(JNIEnv *jnienv, jobject obj)
  636. {
  637. return ((DB_TXN *)get_private_dbobj(jnienv, name_DB_TXN, obj));
  638. }
  639. DB_TXN_STAT *get_DB_TXN_STAT(JNIEnv *jnienv, jobject obj)
  640. {
  641. return ((DB_TXN_STAT *)
  642.     get_private_dbobj(jnienv, name_DB_TXN_STAT, obj));
  643. }
  644. DBT *get_DBT(JNIEnv *jnienv, jobject obj)
  645. {
  646. DBT_JAVAINFO *ji;
  647. ji = (DBT_JAVAINFO *)get_private_dbobj(jnienv, name_DBT, obj);
  648. if (ji == NULL)
  649. return (NULL);
  650. else
  651. return (&ji->dbt);
  652. }
  653. DBT_JAVAINFO *get_DBT_JAVAINFO(JNIEnv *jnienv, jobject obj)
  654. {
  655. return ((DBT_JAVAINFO *)get_private_dbobj(jnienv, name_DBT, obj));
  656. }
  657. /*
  658.  * Convert a C pointer to the various Java objects they represent.
  659.  */
  660. jobject get_DbBtreeStat(JNIEnv *jnienv, DB_BTREE_STAT *dbobj)
  661. {
  662. return (convert_object(jnienv, name_DB_BTREE_STAT, dbobj));
  663. }
  664. jobject get_Dbc(JNIEnv *jnienv, DBC *dbobj)
  665. {
  666. return (convert_object(jnienv, name_DBC, dbobj));
  667. }
  668. jobject get_DbHashStat(JNIEnv *jnienv, DB_HASH_STAT *dbobj)
  669. {
  670. return (convert_object(jnienv, name_DB_HASH_STAT, dbobj));
  671. }
  672. jobject get_DbLogc(JNIEnv *jnienv, DB_LOGC *dbobj)
  673. {
  674. return (convert_object(jnienv, name_DB_LOGC, dbobj));
  675. }
  676. jobject get_DbLogStat(JNIEnv *jnienv, DB_LOG_STAT *dbobj)
  677. {
  678. return (convert_object(jnienv, name_DB_LOG_STAT, dbobj));
  679. }
  680. /*
  681.  * LSNs are different since they are really normally
  682.  * treated as by-value objects.  We actually create
  683.  * a pointer to the LSN and store that, deleting it
  684.  * when the LSN is GC'd.
  685.  */
  686. jobject get_DbLsn(JNIEnv *jnienv, DB_LSN dbobj)
  687. {
  688. DB_LSN *lsnp;
  689. int err;
  690. if ((err = __os_malloc(NULL, sizeof(DB_LSN), &lsnp)) != 0)
  691. return (NULL);
  692. memset(lsnp, 0, sizeof(DB_LSN));
  693. *lsnp = dbobj;
  694. return (convert_object(jnienv, name_DB_LSN, lsnp));
  695. }
  696. /*
  697.  * Shared code for get_Dbt and get_const_Dbt.
  698.  *
  699.  * XXX
  700.  * Currently we make no distinction in implementation of these
  701.  * two kinds of Dbts, although in the future we may want to.
  702.  * (It's probably easier to make the optimizations listed below
  703.  * with readonly Dbts).
  704.  *
  705.  * Dbt's created via this function are only used for a short lifetime,
  706.  * during callback functions.  In the future, we should consider taking
  707.  * advantage of this by having a pool of Dbt objects instead of creating
  708.  * new ones each time.   Because of multithreading, we may need an
  709.  * arbitrary number.  We might also have sharing of the byte arrays
  710.  * used by the Dbts.
  711.  */
  712. static jobject get_Dbt_shared(JNIEnv *jnienv, const DBT *dbt, int readonly,
  713.       DBT_JAVAINFO **ret_info)
  714. {
  715. jobject jdbt;
  716. DBT_JAVAINFO *dbtji;
  717. COMPQUIET(readonly, 0);
  718. /* A NULL DBT should become a null Dbt. */
  719. if (dbt == NULL)
  720. return (NULL);
  721. /*
  722.  * Note that a side effect of creating a Dbt object
  723.  * is the creation of the attached DBT_JAVAINFO object
  724.  * (see the native implementation of Dbt.init())
  725.  * A DBT_JAVAINFO object contains its own DBT.
  726.  */
  727. jdbt = create_default_object(jnienv, name_DBT);
  728. dbtji = get_DBT_JAVAINFO(jnienv, jdbt);
  729. memcpy(&dbtji->dbt, dbt, sizeof(DBT));
  730. /*
  731.  * Set the boolean indicator so that the Java side knows to
  732.  * call back when it wants to look at the array.  This avoids
  733.  * needlessly creating/copying arrays that may never be looked at.
  734.  */
  735. (*jnienv)->SetBooleanField(jnienv, jdbt, fid_Dbt_must_create_data, 1);
  736. (*jnienv)->SetIntField(jnienv, jdbt, fid_Dbt_size, dbt->size);
  737. if (ret_info != NULL)
  738.     *ret_info = dbtji;
  739. return (jdbt);
  740. }
  741. /*
  742.  * Get a writeable Dbt.
  743.  *
  744.  * Currently we're sharing code with get_const_Dbt.
  745.  * It really shouldn't be this way, we have a DBT that we can
  746.  * change, and have some mechanism for copying back
  747.  * any changes to the original DBT.
  748.  */
  749. jobject get_Dbt(JNIEnv *jnienv, DBT *dbt,
  750. DBT_JAVAINFO **ret_info)
  751. {
  752. return (get_Dbt_shared(jnienv, dbt, 0, ret_info));
  753. }
  754. /*
  755.  * Get a Dbt that we promise not to change, or at least
  756.  * if there are changes, they don't matter and won't get
  757.  * seen by anyone.
  758.  */
  759. jobject get_const_Dbt(JNIEnv *jnienv, const DBT *dbt,
  760.       DBT_JAVAINFO **ret_info)
  761. {
  762. return (get_Dbt_shared(jnienv, dbt, 1, ret_info));
  763. }
  764. jobject get_DbMpoolFStat(JNIEnv *jnienv, DB_MPOOL_FSTAT *dbobj)
  765. {
  766. return (convert_object(jnienv, name_DB_MPOOL_FSTAT, dbobj));
  767. }
  768. jobject get_DbMpoolStat(JNIEnv *jnienv, DB_MPOOL_STAT *dbobj)
  769. {
  770. return (convert_object(jnienv, name_DB_MPOOL_STAT, dbobj));
  771. }
  772. jobject get_DbQueueStat(JNIEnv *jnienv, DB_QUEUE_STAT *dbobj)
  773. {
  774. return (convert_object(jnienv, name_DB_QUEUE_STAT, dbobj));
  775. }
  776. jobject get_DbTxn(JNIEnv *jnienv, DB_TXN *dbobj)
  777. {
  778. return (convert_object(jnienv, name_DB_TXN, dbobj));
  779. }
  780. jobject get_DbTxnStat(JNIEnv *jnienv, DB_TXN_STAT *dbobj)
  781. {
  782. return (convert_object(jnienv, name_DB_TXN_STAT, dbobj));
  783. }