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)); }
DB_TXN_STAT *get_DB_TXN_STAT(JNIEnv *jnienv, jobject obj) { return ((DB_TXN_STAT *)get_private_dbobj(jnienv, name_DB_TXN_STAT, obj)); }
DB_TXN *get_DB_TXN(JNIEnv *jnienv, jobject obj) { return ((DB_TXN *)get_private_dbobj(jnienv, name_DB_TXN, obj)); }
DB_LOCK *get_DB_LOCK(JNIEnv *jnienv, jobject obj) { return ((DB_LOCK *)get_private_dbobj(jnienv, name_DB_LOCK, obj)); }
DB_ENV *get_DB_ENV(JNIEnv *jnienv, jobject obj) { return ((DB_ENV *)get_private_dbobj(jnienv, name_DB_ENV, obj)); }
DBC *get_DBC(JNIEnv *jnienv, jobject obj) { return ((DBC *)get_private_dbobj(jnienv, name_DBC, obj)); }
/**************************************************************** * * Implementation of functions to manipulate LOCKED_DBT. */ int locked_dbt_get(LOCKED_DBT *ldbt, JNIEnv *jnienv, DB_ENV *dbenv, jobject jdbt, OpKind kind) { DBT *dbt; COMPQUIET(dbenv, NULL); ldbt->jdbt = jdbt; ldbt->java_array_len = 0; ldbt->flags = 0; ldbt->kind = kind; ldbt->java_data = 0; ldbt->before_data = 0; ldbt->javainfo = (DBT_JAVAINFO *)get_private_dbobj(jnienv, name_DBT, jdbt); if (!verify_non_null(jnienv, ldbt->javainfo)) { report_exception(jnienv, "Dbt is gc'ed?", 0, 0); F_SET(ldbt, LOCKED_ERROR); return (EINVAL); } if (F_ISSET(ldbt->javainfo, DBT_JAVAINFO_LOCKED)) { report_exception(jnienv, "Dbt is already in use", 0, 0); F_SET(ldbt, LOCKED_ERROR); return (EINVAL); } dbt = &ldbt->javainfo->dbt; if ((*jnienv)->GetBooleanField(jnienv, jdbt, fid_Dbt_must_create_data) != 0) F_SET(ldbt, LOCKED_CREATE_DATA); else ldbt->javainfo->array = (*jnienv)->GetObjectField(jnienv, jdbt, fid_Dbt_data); dbt->size = (*jnienv)->GetIntField(jnienv, jdbt, fid_Dbt_size); dbt->ulen = (*jnienv)->GetIntField(jnienv, jdbt, fid_Dbt_ulen); dbt->dlen = (*jnienv)->GetIntField(jnienv, jdbt, fid_Dbt_dlen); dbt->doff = (*jnienv)->GetIntField(jnienv, jdbt, fid_Dbt_doff); dbt->flags = (*jnienv)->GetIntField(jnienv, jdbt, fid_Dbt_flags); ldbt->javainfo->offset = (*jnienv)->GetIntField(jnienv, jdbt, fid_Dbt_offset); /* * If no flags are set, use default behavior of DB_DBT_MALLOC. * We can safely set dbt->flags because flags will never be copied * back to the Java Dbt. */ if (kind != inOp && !F_ISSET(dbt, DB_DBT_USERMEM | DB_DBT_MALLOC | DB_DBT_REALLOC)) F_SET(dbt, DB_DBT_MALLOC); /* * If this is requested to be realloc with an existing array, * we cannot use the underlying realloc, because the array we * will pass in is allocated by the Java VM, not us, so it * cannot be 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 locked_dbt_put). */ if (F_ISSET(dbt, DB_DBT_REALLOC) && ldbt->javainfo->array != NULL) { F_CLR(dbt, DB_DBT_REALLOC); F_SET(dbt, DB_DBT_USERMEM); F_SET(ldbt, LOCKED_REALLOC_NONNULL); } if ((F_ISSET(dbt, DB_DBT_USERMEM) || kind != outOp) && !F_ISSET(ldbt, LOCKED_CREATE_DATA)) { /* * If writing with DB_DBT_USERMEM * 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 (!ldbt->javainfo->array) { report_exception(jnienv, "Dbt.data is null", 0, 0); F_SET(ldbt, LOCKED_ERROR); return (EINVAL); } /* Verify other parameters */ ldbt->java_array_len = (*jnienv)->GetArrayLength(jnienv, ldbt->javainfo->array); if (ldbt->javainfo->offset < 0 ) { report_exception(jnienv, "Dbt.offset illegal", 0, 0); F_SET(ldbt, LOCKED_ERROR); return (EINVAL); } if (dbt->size + ldbt->javainfo->offset > ldbt->java_array_len) { report_exception(jnienv, "Dbt.size + Dbt.offset greater than array length", 0, 0); F_SET(ldbt, LOCKED_ERROR); return (EINVAL); } ldbt->java_data = (*jnienv)->GetByteArrayElements(jnienv, ldbt->javainfo->array, (jboolean *)0); dbt->data = ldbt->before_data = ldbt->java_data + ldbt->javainfo->offset; } else if (!F_ISSET(ldbt, LOCKED_CREATE_DATA)) { /* * If writing with DB_DBT_MALLOC or DB_DBT_REALLOC with * a null array, then the data is allocated by DB. */ dbt->data = ldbt->before_data = 0; } /* * RPC makes the assumption that if dbt->size is non-zero, there * is data to copy from dbt->data. We may have set dbt->size * to a non-zero integer above but decided not to point * dbt->data at anything. (One example is if we're doing an outOp * with an already-used Dbt whose values we expect to just * overwrite.) * * Clean up the dbt fields so we don't run into trouble. * (Note that doff, dlen, and flags all may contain meaningful * values.) */ if (dbt->data == NULL) dbt->size = dbt->ulen = 0; F_SET(ldbt->javainfo, DBT_JAVAINFO_LOCKED); return (0); }