1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
|
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1997-2002
* Sleepycat Software. All rights reserved.
*
* $Id: java_util.h,v 1.1.1.1 2003/11/20 22:13:34 toshok 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 "db_int.h"
#include <jni.h>
#include "java_info.h"
#include "java_locked.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
/*
* Do any one time initialization, especially initializing any
* unchanging methodIds, fieldIds, etc.
*/
void one_time_init(JNIEnv *jnienv);
/*
* Get the current JNIEnv from the java VM.
* If the jvm argument is null, uses the default
* jvm stored during the first invocation.
*/
JNIEnv *get_jnienv(JavaVM *jvm);
/*
* 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 handle
* 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 flags for verify_return() and report_exception().
* These indicate what sort of exceptions the method may throw
* (in addition to DbException).
*/
static const u_int32_t EXCEPTION_FILE_NOT_FOUND = 0x0001; /*FileNotFound*/
/*
* Report an exception back to the java side.
*/
void report_exception(JNIEnv *jnienv, const char *text,
int err, unsigned long expect_mask);
/*
* Report an exception back to the java side, for the specific
* case of DB_LOCK_NOTGRANTED, as more things are added to the
* constructor of this type of exception.
*/
void report_notgranted_exception(JNIEnv *jnienv, const char *text,
db_lockop_t op, db_lockmode_t mode,
jobject jdbt, jobject jlock, int index);
/*
* Create an exception object and return it.
* The given class must have a constructor that has a
* constructor with args (java.lang.String text, int errno);
* DbException and its subclasses fit this bill.
*/
jobject create_exception(JNIEnv *jnienv, jstring text,
int err, jclass dbexcept);
/*
* 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 flags);
/*
* 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 *locked_dbt);
/*
* Create an object of the given class, calling its default constructor.
*/
jobject create_default_object(JNIEnv *jnienv, const char *class_name);
/*
* Create a Dbt object, , calling its default constructor.
*/
jobject create_dbt(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 java string using __os_malloc.
* 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_LOGC *get_DB_LOGC (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_DbLogc (JNIEnv *jnienv, DB_LOGC *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_const_Dbt (JNIEnv *jnienv, const DBT *dbt, DBT_JAVAINFO **retp);
jobject get_Dbt (JNIEnv *jnienv, DBT *dbt, DBT_JAVAINFO **retp);
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_LOGC;
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_LOCKNOTGRANTED_EX;
extern const char * const name_DB_PREPLIST;
extern const char * const name_DB_QUEUE_STAT;
extern const char * const name_DB_REP_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_DB_UTIL;
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_DbRepTransport;
extern const char * const name_DbSecondaryKeyCreate;
extern const char * const name_DbTxnRecover;
extern const char * const name_RepElectResult;
extern const char * const name_RepProcessMessage;
extern const char * const string_signature;
extern jfieldID fid_Dbt_data;
extern jfieldID fid_Dbt_offset;
extern jfieldID fid_Dbt_size;
extern jfieldID fid_Dbt_ulen;
extern jfieldID fid_Dbt_dlen;
extern jfieldID fid_Dbt_doff;
extern jfieldID fid_Dbt_flags;
extern jfieldID fid_Dbt_must_create_data;
extern jfieldID fid_DbLockRequest_op;
extern jfieldID fid_DbLockRequest_mode;
extern jfieldID fid_DbLockRequest_timeout;
extern jfieldID fid_DbLockRequest_obj;
extern jfieldID fid_DbLockRequest_lock;
extern jfieldID fid_RepProcessMessage_envid;
#define JAVADB_ARGS JNIEnv *jnienv, jobject jthis
#define JAVADB_GET_FLD(j_class, j_fieldtype, j_field, c_type, c_field) \
JNIEXPORT j_fieldtype JNICALL \
Java_com_sleepycat_db_##j_class##_get_1##j_field \
(JAVADB_ARGS) \
{ \
c_type *db= get_##c_type(jnienv, jthis); \
\
if (verify_non_null(jnienv, db)) \
return (db->c_field); \
return (0); \
}
#define JAVADB_SET_FLD(j_class, j_fieldtype, j_field, c_type, c_field) \
JNIEXPORT void JNICALL \
Java_com_sleepycat_db_##j_class##_set_1##j_field \
(JAVADB_ARGS, j_fieldtype value) \
{ \
c_type *db= get_##c_type(jnienv, jthis); \
\
if (verify_non_null(jnienv, db)) \
db->c_field = value; \
}
#define JAVADB_METHOD(_meth, _argspec, c_type, c_meth, _args) \
JNIEXPORT void JNICALL Java_com_sleepycat_db_##_meth _argspec \
{ \
c_type *c_this = get_##c_type(jnienv, jthis); \
int ret; \
\
if (!verify_non_null(jnienv, c_this)) \
return; \
ret = c_this->c_meth _args; \
if (!DB_RETOK_STD(ret)) \
report_exception(jnienv, db_strerror(ret), ret, 0); \
}
#define JAVADB_METHOD_INT(_meth, _argspec, c_type, c_meth, _args, _retok) \
JNIEXPORT jint JNICALL Java_com_sleepycat_db_##_meth _argspec \
{ \
c_type *c_this = get_##c_type(jnienv, jthis); \
int ret; \
\
if (!verify_non_null(jnienv, c_this)) \
return (0); \
ret = c_this->c_meth _args; \
if (!_retok(ret)) \
report_exception(jnienv, db_strerror(ret), ret, 0); \
return ((jint)ret); \
}
#define JAVADB_SET_METH(j_class, j_type, j_fld, c_type, c_field) \
JAVADB_METHOD(j_class##_set_1##j_fld, (JAVADB_ARGS, j_type val), c_type, \
set_##c_field, (c_this, val))
#define JAVADB_SET_METH_STR(j_class, j_fld, c_type, c_field) \
JAVADB_METHOD(j_class##_set_1##j_fld, (JAVADB_ARGS, jstring val), c_type, \
set_##c_field, (c_this, (*jnienv)->GetStringUTFChars(jnienv, val, NULL)))
/*
* These macros are used by code generated by the s_java script.
*/
#define JAVADB_STAT_INT(env, cl, jobj, statp, name) \
set_int_field(jnienv, cl, jobj, #name, statp->name)
#define JAVADB_STAT_LSN(env, cl, jobj, statp, name) \
set_lsn_field(jnienv, cl, jobj, #name, statp->name)
#define JAVADB_STAT_LONG(env, cl, jobj, statp, name) \
set_long_field(jnienv, cl, jobj, #name, statp->name)
/*
* We build the active list separately.
*/
#define JAVADB_STAT_ACTIVE(env, cl, jobj, statp, name) \
do {} while(0)
#endif /* !_JAVA_UTIL_H_ */
|