📄 java_util.c
字号:
* 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; if ((errcall_class = get_class(jnienv, name_DbErrcall)) == NULL) return; /* An exception has been posted. */ 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);}/* * Verify that there was no memory error due to undersized Dbt. * If there is report a DbMemoryException, with the Dbt attached * and return false (0), otherwise return true (1). */int verify_dbt(JNIEnv *jnienv, int err, LOCKED_DBT *ldbt){ DBT *dbt; jobject exception; jstring text; jclass dbexcept; jmethodID mid; if (err != ENOMEM) return (1); dbt = &ldbt->javainfo->dbt; if (!F_ISSET(dbt, DB_DBT_USERMEM) || dbt->size <= dbt->ulen) return (1); /* Create/throw an exception of type DbMemoryException */ if ((dbexcept = get_class(jnienv, name_DB_MEMORY_EX)) == NULL) return (1); /* An exception has been posted. */ text = get_java_string(jnienv, "Dbt not large enough for available data"); exception = create_exception(jnienv, text, ENOMEM, dbexcept); /* Attach the dbt to the exception */ mid = (*jnienv)->GetMethodID(jnienv, dbexcept, "set_dbt", "(L" DB_PACKAGE_NAME "Dbt;)V"); (*jnienv)->CallVoidMethod(jnienv, exception, mid, ldbt->jdbt); (*jnienv)->Throw(jnienv, exception); return (0);}/* * Create an object of the given class, calling its default constructor. */jobject create_default_object(JNIEnv *jnienv, const char *class_name){ jmethodID id; jclass dbclass; if ((dbclass = get_class(jnienv, class_name)) == NULL) return (NULL); /* An exception has been posted. */ id = (*jnienv)->GetMethodID(jnienv, dbclass, "<init>", "()V"); return ((*jnienv)->NewObject(jnienv, dbclass, id));}/* * 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; int err; len = strlen(str) + 1; if ((err = __os_malloc(NULL, sizeof(char)*len, &retval)) != 0) return (NULL); 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 copy of the java string using __os_malloc. * Caller must free it. */char *get_c_string(JNIEnv *jnienv, jstring jstr){ const char *utf; char *retval; utf = (*jnienv)->GetStringUTFChars(jnienv, jstr, NULL); retval = dup_string(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_LOGC *get_DB_LOGC(JNIEnv *jnienv, jobject obj){ return ((DB_LOGC *)get_private_dbobj(jnienv, name_DB_LOGC, 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, /* DbLsn */ jobject obj) { /* * DbLsns that are created from within java (new DbLsn()) rather * than from within C (get_DbLsn()) may not have a "private" DB_LSN * structure allocated for them yet. We can't do this in the * actual constructor (init_lsn()), because there's no way to pass * in an initializing value in, and because the get_DbLsn()/ * convert_object() code path needs a copy of the pointer before * the constructor gets called. Thus, get_DbLsn() allocates and * fills a DB_LSN for the object it's about to create. * * Since "new DbLsn()" may reasonably be passed as an argument to * functions such as DbEnv.log_put(), though, we need to make sure * that DB_LSN's get allocated when the object was created from * Java, too. Here, we lazily allocate a new private DB_LSN if * and only if it turns out that we don't already have one. * * The only exception is if the DbLsn object is a Java null * (in which case the jobject will also be NULL). Then a NULL * DB_LSN is legitimate. */ DB_LSN *lsnp; int err; if (obj == NULL) return (NULL); lsnp = (DB_LSN *)get_private_dbobj(jnienv, name_DB_LSN, obj); if (lsnp == NULL) { if ((err = __os_malloc(NULL, sizeof(DB_LSN), &lsnp)) != 0) return (NULL); memset(lsnp, 0, sizeof(DB_LSN)); set_private_dbobj(jnienv, name_DB_LSN, obj, lsnp); } return (lsnp);}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_DbLogc(JNIEnv *jnienv, DB_LOGC *dbobj){ return (convert_object(jnienv, name_DB_LOGC, 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; int err; if ((err = __os_malloc(NULL, sizeof(DB_LSN), &lsnp)) != 0) return (NULL); memset(lsnp, 0, sizeof(DB_LSN)); *lsnp = dbobj; return (convert_object(jnienv, name_DB_LSN, lsnp));}/* * Shared code for get_Dbt and get_const_Dbt. * * XXX * Currently we make no distinction in implementation of these * two kinds of Dbts, although in the future we may want to. * (It's probably easier to make the optimizations listed below * with readonly Dbts). * * Dbt's created via this function are only used for a short lifetime, * during callback functions. In the future, we should consider taking * advantage of this by having a pool of Dbt objects instead of creating * new ones each time. Because of multithreading, we may need an * arbitrary number. We might also have sharing of the byte arrays * used by the Dbts. */static jobject get_Dbt_shared(JNIEnv *jnienv, const DBT *dbt, int readonly, DBT_JAVAINFO **ret_info){ jobject jdbt; DBT_JAVAINFO *dbtji; COMPQUIET(readonly, 0); /* A NULL DBT should become a null Dbt. */ if (dbt == NULL) return (NULL); /* * Note that a side effect of creating a Dbt object * is the creation of the attached DBT_JAVAINFO object * (see the native implementation of Dbt.init()) * A DBT_JAVAINFO object contains its own DBT. */ jdbt = create_default_object(jnienv, name_DBT); dbtji = get_DBT_JAVAINFO(jnienv, jdbt); memcpy(&dbtji->dbt, dbt, sizeof(DBT)); /* * Set the boolean indicator so that the Java side knows to * call back when it wants to look at the array. This avoids * needlessly creating/copying arrays that may never be looked at. */ (*jnienv)->SetBooleanField(jnienv, jdbt, fid_Dbt_must_create_data, 1); (*jnienv)->SetIntField(jnienv, jdbt, fid_Dbt_size, dbt->size); if (ret_info != NULL) *ret_info = dbtji; return (jdbt);}/* * Get a writeable Dbt. * * Currently we're sharing code with get_const_Dbt. * It really shouldn't be this way, we have a DBT that we can * change, and have some mechanism for copying back * any changes to the original DBT. */jobject get_Dbt(JNIEnv *jnienv, DBT *dbt, DBT_JAVAINFO **ret_info){ return (get_Dbt_shared(jnienv, dbt, 0, ret_info));}/* * Get a Dbt that we promise not to change, or at least * if there are changes, they don't matter and won't get * seen by anyone. */jobject get_const_Dbt(JNIEnv *jnienv, const DBT *dbt, DBT_JAVAINFO **ret_info){ return (get_Dbt_shared(jnienv, dbt, 1, ret_info));}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));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -