1/* Callbacks */ 2%define JAVA_CALLBACK(_sig, _jclass, _name) 3JAVA_TYPEMAP(_sig, _jclass, jboolean) 4%typemap(jtype) _sig "boolean" 5%typemap(javain) _sig %{ (_name##_handler = $javainput) != null %} 6 7/* 8 * The Java object is stored in the Db or DbEnv class. 9 * Here we only care whether it is non-NULL. 10 */ 11%typemap(in) _sig %{ 12 $1 = ($input == JNI_TRUE) ? __dbj_##_name : NULL; 13%} 14%enddef 15 16%{ 17static void __dbj_error(const DB_ENV *dbenv, 18 const char *prefix, const char *msg) 19{ 20 JNIEnv *jenv = __dbj_get_jnienv(); 21 jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv); 22 jobject jmsg; 23 24 COMPQUIET(prefix, NULL); 25 26 if (jdbenv != NULL){ 27 jmsg = (*jenv)->NewStringUTF(jenv, msg); 28 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class, 29 errcall_method, jmsg); 30 (*jenv)->DeleteLocalRef(jenv, jmsg); 31 } 32} 33 34static void __dbj_env_feedback(DB_ENV *dbenv, int opcode, int percent) 35{ 36 JNIEnv *jenv = __dbj_get_jnienv(); 37 jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv); 38 39 if (jdbenv != NULL) 40 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class, 41 env_feedback_method, opcode, percent); 42} 43 44static void __dbj_message(const DB_ENV *dbenv, const char *msg) 45{ 46 JNIEnv *jenv = __dbj_get_jnienv(); 47 jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv); 48 jobject jmsg; 49 50 if (jdbenv != NULL){ 51 jmsg = (*jenv)->NewStringUTF(jenv, msg); 52 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class, 53 msgcall_method, jmsg); 54 (*jenv)->DeleteLocalRef(jenv, jmsg); 55 } 56} 57 58static void __dbj_panic(DB_ENV *dbenv, int err) 59{ 60 JNIEnv *jenv = __dbj_get_jnienv(); 61 jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv); 62 63 if (jdbenv != NULL) 64 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class, 65 paniccall_method, 66 __dbj_get_except(jenv, err, NULL, NULL, jdbenv)); 67} 68 69static int __dbj_app_dispatch(DB_ENV *dbenv, 70 DBT *dbt, DB_LSN *lsn, db_recops recops) 71{ 72 JNIEnv *jenv = __dbj_get_jnienv(); 73 jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv); 74 jobject jdbt, jlsn; 75 jbyteArray jdbtarr; 76 int ret; 77 78 if (jdbenv == NULL) 79 return (EINVAL); 80 81 jdbt = (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 82 __dbj_dbt_copyout(jenv, dbt, &jdbtarr, jdbt); 83 if (jdbt == NULL) 84 return (ENOMEM); /* An exception is pending */ 85 86 jlsn = (lsn == NULL) ? NULL : __dbj_wrap_DB_LSN(jenv, lsn); 87 88 ret = (*jenv)->CallNonvirtualIntMethod(jenv, jdbenv, dbenv_class, 89 app_dispatch_method, jdbt, jlsn, recops); 90 91 if ((*jenv)->ExceptionOccurred(jenv)) { 92 /* The exception will be thrown, so this could be any error. */ 93 ret = EINVAL; 94 } 95 96 (*jenv)->DeleteLocalRef(jenv, jdbtarr); 97 (*jenv)->DeleteLocalRef(jenv, jdbt); 98 if (jlsn != NULL) 99 (*jenv)->DeleteLocalRef(jenv, jlsn); 100 101 return (ret); 102} 103 104static void __dbj_event_notify(DB_ENV *dbenv, u_int32_t event_id, void * info) 105{ 106 JNIEnv *jenv = __dbj_get_jnienv(); 107 jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv); 108 109 if (jdbenv == NULL) 110 return ; 111 112 switch (event_id) { 113 case DB_EVENT_PANIC: 114 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 115 dbenv_class, panic_event_notify_method); 116 break; 117 case DB_EVENT_REP_CLIENT: 118 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 119 dbenv_class, rep_client_event_notify_method); 120 break; 121 case DB_EVENT_REP_ELECTED: 122 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 123 dbenv_class, rep_elected_event_notify_method); 124 break; 125 case DB_EVENT_REP_MASTER: 126 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 127 dbenv_class, rep_master_event_notify_method); 128 break; 129 case DB_EVENT_REP_NEWMASTER: 130 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 131 dbenv_class, rep_new_master_event_notify_method, 132 *(int*)info); 133 break; 134 case DB_EVENT_REP_PERM_FAILED: 135 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 136 dbenv_class, rep_perm_failed_event_notify_method); 137 break; 138 case DB_EVENT_REP_STARTUPDONE: 139 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 140 dbenv_class, rep_startup_done_event_notify_method); 141 break; 142 case DB_EVENT_WRITE_FAILED: 143 (*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, 144 dbenv_class, write_failed_event_notify_method, 145 *(int*)info); 146 break; 147 default: 148 dbenv->errx(dbenv, "Unhandled event callback in the Java API"); 149 DB_ASSERT(dbenv->env, 0); 150 } 151} 152 153static int __dbj_rep_transport(DB_ENV *dbenv, 154 const DBT *control, const DBT *rec, const DB_LSN *lsn, int envid, 155 u_int32_t flags) 156{ 157 JNIEnv *jenv = __dbj_get_jnienv(); 158 jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv); 159 jobject jcontrol, jrec, jlsn; 160 jbyteArray jcontrolarr, jrecarr; 161 int ret; 162 163 if (jdbenv == NULL) 164 return (EINVAL); 165 166 jcontrol = (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 167 jrec = (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 168 if (jcontrol == NULL || jrec == NULL) 169 return (ENOMEM); /* An exception is pending */ 170 171 __dbj_dbt_copyout(jenv, control, &jcontrolarr, jcontrol); 172 __dbj_dbt_copyout(jenv, rec, &jrecarr, jrec); 173 jlsn = (lsn == NULL) ? NULL : __dbj_wrap_DB_LSN(jenv, (DB_LSN *)lsn); 174 175 if (jcontrolarr == NULL || jrecarr == NULL) 176 return (ENOMEM); /* An exception is pending */ 177 178 ret = (*jenv)->CallNonvirtualIntMethod(jenv, jdbenv, dbenv_class, 179 rep_transport_method, jcontrol, jrec, jlsn, envid, flags); 180 181 if ((*jenv)->ExceptionOccurred(jenv)) { 182 /* The exception will be thrown, so this could be any error. */ 183 ret = EINVAL; 184 } 185 186 (*jenv)->DeleteLocalRef(jenv, jrecarr); 187 (*jenv)->DeleteLocalRef(jenv, jcontrolarr); 188 (*jenv)->DeleteLocalRef(jenv, jrec); 189 (*jenv)->DeleteLocalRef(jenv, jcontrol); 190 if (jlsn != NULL) 191 (*jenv)->DeleteLocalRef(jenv, jlsn); 192 193 return (ret); 194} 195 196static int __dbj_foreignkey_nullify(DB *db, 197 const DBT *key, DBT *data, const DBT *skey, int *changed) 198{ 199 DBT_LOCKED lresult; 200 JNIEnv *jenv = __dbj_get_jnienv(); 201 jobject jdb = (jobject)DB_INTERNAL(db); 202 jobject jkey, jdata, jskey; 203 jbyteArray jkeyarr, jdataarr, jskeyarr; 204 jboolean jresult; 205 int ret; 206 207 if (jdb == NULL) 208 return (EINVAL); 209 210 jkey = (key->app_data != NULL) ? 211 ((DBT_LOCKED *)key->app_data)->jdbt : 212 (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 213 jdata = (data->app_data != NULL) ? 214 ((DBT_LOCKED *)data->app_data)->jdbt : 215 (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 216 jskey = (skey->app_data != NULL) ? 217 ((DBT_LOCKED *)skey->app_data)->jdbt : 218 (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 219 if (jkey == NULL || jdata == NULL || jskey == NULL) 220 return (ENOMEM); /* An exception is pending */ 221 222 if (key->app_data == NULL) { 223 __dbj_dbt_copyout(jenv, key, &jkeyarr, jkey); 224 if (jkeyarr == NULL) 225 return (ENOMEM); /* An exception is pending */ 226 } 227 if (data->app_data == NULL) { 228 __dbj_dbt_copyout(jenv, data, &jdataarr, jdata); 229 if (jdataarr == NULL) 230 return (ENOMEM); /* An exception is pending */ 231 } 232 if (skey->app_data == NULL) { 233 __dbj_dbt_copyout(jenv, skey, &jskeyarr, jskey); 234 if (jskeyarr == NULL) 235 return (ENOMEM); /* An exception is pending */ 236 } 237 238 jresult = (*jenv)->CallNonvirtualBooleanMethod(jenv, jdb, db_class, foreignkey_nullify_method, jkey, jdata, jskey); 239 240 if ((*jenv)->ExceptionOccurred(jenv)) { 241 /* The exception will be thrown, so this could be any error. */ 242 ret = EINVAL; 243 goto err; 244 } 245 246 if (jresult == JNI_FALSE) 247 *changed = ret = 0; 248 else{ 249 *changed = 1; 250 /* copy jdata into data */ 251 if ((ret = __dbj_dbt_copyin(jenv, &lresult, NULL, jdata, 0)) != 0) 252 goto err; 253 if (lresult.dbt.size != 0){ 254 data->size = lresult.dbt.size; 255 if ((ret = __os_umalloc( 256 NULL, data->size, &data->data)) != 0) 257 goto err; 258 if ((ret = __dbj_dbt_memcopy(&lresult.dbt, 0, 259 data->data, data->size, DB_USERCOPY_GETDATA)) != 0) 260 goto err; 261 __dbj_dbt_release(jenv, jdata, &lresult.dbt, &lresult); 262 (*jenv)->DeleteLocalRef(jenv, lresult.jarr); 263 F_SET(data, DB_DBT_APPMALLOC); 264 } 265 } 266 267err: if (key->app_data == NULL) { 268 (*jenv)->DeleteLocalRef(jenv, jkeyarr); 269 (*jenv)->DeleteLocalRef(jenv, jkey); 270 } 271 if (data->app_data == NULL) { 272 (*jenv)->DeleteLocalRef(jenv, jdataarr); 273 (*jenv)->DeleteLocalRef(jenv, jdata); 274 } 275 276 return ret; 277} 278 279static int __dbj_seckey_create(DB *db, 280 const DBT *key, const DBT *data, DBT *result) 281{ 282 JNIEnv *jenv = __dbj_get_jnienv(); 283 jobject jdb = (jobject)DB_INTERNAL(db); 284 jobject jkey, jdata, jresult; 285 jobjectArray jskeys; 286 jsize i, num_skeys; 287 jbyteArray jkeyarr, jdataarr; 288 DBT_LOCKED lresult; 289 DBT *tresult; 290 int ret; 291 292 if (jdb == NULL) 293 return (EINVAL); 294 295 jkey = (key->app_data != NULL) ? 296 ((DBT_LOCKED *)key->app_data)->jdbt : 297 (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 298 jdata = (data->app_data != NULL) ? 299 ((DBT_LOCKED *)data->app_data)->jdbt : 300 (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 301 if (jkey == NULL || jdata == NULL) 302 return (ENOMEM); /* An exception is pending */ 303 304 if (key->app_data == NULL) { 305 __dbj_dbt_copyout(jenv, key, &jkeyarr, jkey); 306 if (jkeyarr == NULL) 307 return (ENOMEM); /* An exception is pending */ 308 } 309 if (data->app_data == NULL) { 310 __dbj_dbt_copyout(jenv, data, &jdataarr, jdata); 311 if (jdataarr == NULL) 312 return (ENOMEM); /* An exception is pending */ 313 } 314 315 jskeys = (jobjectArray)(*jenv)->CallNonvirtualObjectMethod(jenv, 316 jdb, db_class, seckey_create_method, jkey, jdata); 317 318 if (jskeys == NULL || 319 (num_skeys = (*jenv)->GetArrayLength(jenv, jskeys)) == 0) { 320 ret = DB_DONOTINDEX; 321 goto err; 322 } else if (num_skeys == 1) { 323 memset(result, 0, sizeof (DBT)); 324 tresult = result; 325 } else { 326 if ((ret = __os_umalloc(db->env, 327 num_skeys * sizeof (DBT), &result->data)) != 0) 328 goto err; 329 memset(result->data, 0, num_skeys * sizeof (DBT)); 330 result->size = num_skeys; 331 F_SET(result, DB_DBT_APPMALLOC | DB_DBT_MULTIPLE); 332 tresult = (DBT *)result->data; 333 } 334 335 if ((*jenv)->ExceptionOccurred(jenv)) { 336 /* The exception will be thrown, so this could be any error. */ 337 ret = EINVAL; 338 goto err; 339 } 340 341 for (i = 0; i < num_skeys; i++, tresult++) { 342 jresult = (*jenv)->GetObjectArrayElement(jenv, jskeys, i); 343 344 if ((ret = 345 __dbj_dbt_copyin(jenv, &lresult, NULL, jresult, 0)) != 0) 346 goto err; 347 348 if (lresult.dbt.size != 0) { 349 /* If there's data, we need to take a copy of it. */ 350 tresult->size = lresult.dbt.size; 351 if ((ret = __os_umalloc(NULL, 352 tresult->size, &tresult->data)) != 0) 353 goto err; 354 if ((ret = __dbj_dbt_memcopy(&lresult.dbt, 0, 355 tresult->data, tresult->size, 356 DB_USERCOPY_GETDATA)) != 0) 357 goto err; 358 __dbj_dbt_release(jenv, 359 jresult, &lresult.dbt, &lresult); 360 (*jenv)->DeleteLocalRef(jenv, lresult.jarr); 361 F_SET(tresult, DB_DBT_APPMALLOC); 362 } 363 364 (*jenv)->DeleteLocalRef(jenv, jresult); 365 } 366 367err: if (key->app_data == NULL) { 368 (*jenv)->DeleteLocalRef(jenv, jkeyarr); 369 (*jenv)->DeleteLocalRef(jenv, jkey); 370 } 371 if (data->app_data == NULL) { 372 (*jenv)->DeleteLocalRef(jenv, jdataarr); 373 (*jenv)->DeleteLocalRef(jenv, jdata); 374 } 375 376 return (ret); 377} 378 379static int __dbj_append_recno(DB *db, DBT *dbt, db_recno_t recno) 380{ 381 JNIEnv *jenv = __dbj_get_jnienv(); 382 jobject jdb = (jobject)DB_INTERNAL(db); 383 jobject jdbt; 384 DBT_LOCKED lresult; 385 jbyteArray jdbtarr; 386 int ret; 387 388 if (jdb == NULL) 389 return (EINVAL); 390 391 /* 392 * The dbt we're passed will be from the application, but we can't 393 * just reuse it, since we will have already taken a copy of the data. 394 * Make a new DatabaseEntry object here for the callback. 395 */ 396 jdbt = (*jenv)->NewObject(jenv, dbt_class, dbt_construct); 397 if (jdbt == NULL) 398 return (ENOMEM); /* An exception is pending */ 399 400 __dbj_dbt_copyout(jenv, dbt, &jdbtarr, jdbt); 401 if (jdbtarr == NULL) 402 return (ENOMEM); /* An exception is pending */ 403 404 ret = 0; 405 (*jenv)->CallNonvirtualVoidMethod(jenv, jdb, db_class, 406 append_recno_method, jdbt, recno); 407 408 if ((*jenv)->ExceptionOccurred(jenv)) { 409 /* The exception will be thrown, so this could be any error. */ 410 return (EINVAL); 411 } 412 413 ret = __dbj_dbt_copyin(jenv, &lresult, NULL, jdbt, 0); 414 memset(dbt, 0, sizeof (DBT)); 415 416 if (ret == 0 && lresult.dbt.size != 0) { 417 /* If there's data, we need to take a copy of it. */ 418 dbt->size = lresult.dbt.size; 419 if ((ret = 420 __os_umalloc(NULL, dbt->size, &dbt->data)) != 0) 421 goto err; 422 if ((ret = __dbj_dbt_memcopy(&lresult.dbt, 0, 423 dbt->data, dbt->size, 424 DB_USERCOPY_GETDATA)) != 0) 425 goto err; 426 __dbj_dbt_release(jenv, jdbt, &lresult.dbt, &lresult); 427 (*jenv)->DeleteLocalRef(jenv, lresult.jarr); 428 F_SET(dbt, DB_DBT_APPMALLOC); 429 } 430 431err: (*jenv)->DeleteLocalRef(jenv, jdbtarr); 432 (*jenv)->DeleteLocalRef(jenv, jdbt); 433 434 return (ret); 435} 436 437/* 438 * Shared by __dbj_bt_compare and __dbj_h_compare 439 */ 440static int __dbj_am_compare(DB *db, const DBT *dbt1, const DBT *dbt2, 441 jmethodID compare_method) 442{ 443 JNIEnv *jenv = __dbj_get_jnienv(); 444 jobject jdb = (jobject)DB_INTERNAL(db); 445 jbyteArray jdbtarr1, jdbtarr2; 446 int ret; 447 448 if (jdb == NULL) 449 return (EINVAL); 450 451 if (dbt1->app_data != NULL) 452 jdbtarr1 = ((DBT_LOCKED *)dbt1->app_data)->jarr; 453 else { 454 jdbtarr1 = (*jenv)->NewByteArray(jenv, (jsize)dbt1->size); 455 if (jdbtarr1 == NULL) 456 return (ENOMEM); 457 (*jenv)->SetByteArrayRegion(jenv, jdbtarr1, 0, 458 (jsize)dbt1->size, (jbyte *)dbt1->data); 459 } 460 461 if (dbt2->app_data != NULL) 462 jdbtarr2 = ((DBT_LOCKED *)dbt2->app_data)->jarr; 463 else { 464 jdbtarr2 = (*jenv)->NewByteArray(jenv, (jsize)dbt2->size); 465 if (jdbtarr2 == NULL) 466 return (ENOMEM); 467 (*jenv)->SetByteArrayRegion(jenv, jdbtarr2, 0, 468 (jsize)dbt2->size, (jbyte *)dbt2->data); 469 } 470 471 ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class, 472 compare_method, jdbtarr1, jdbtarr2); 473 474 if ((*jenv)->ExceptionOccurred(jenv)) { 475 /* The exception will be thrown, so this could be any error. */ 476 ret = EINVAL; 477 } 478 479 if (dbt1->app_data == NULL) 480 (*jenv)->DeleteLocalRef(jenv, jdbtarr1); 481 if (dbt2->app_data == NULL) 482 (*jenv)->DeleteLocalRef(jenv, jdbtarr2); 483 484 return (ret); 485} 486 487static int __dbj_bt_compare(DB *db, const DBT *dbt1, const DBT *dbt2) 488{ 489 return __dbj_am_compare(db, dbt1, dbt2, bt_compare_method); 490} 491 492static size_t __dbj_bt_prefix(DB *db, const DBT *dbt1, const DBT *dbt2) 493{ 494 JNIEnv *jenv = __dbj_get_jnienv(); 495 jobject jdb = (jobject)DB_INTERNAL(db); 496 jobject jdbt1, jdbt2; 497 jbyteArray jdbtarr1, jdbtarr2; 498 int ret; 499 500 if (jdb == NULL) 501 return (EINVAL); 502 503 if (dbt1->app_data != NULL) 504 jdbt1 = ((DBT_LOCKED *)dbt1->app_data)->jdbt; 505 else { 506 if ((jdbt1 = 507 (*jenv)->NewObject(jenv, dbt_class, dbt_construct)) == NULL) 508 return (ENOMEM); /* An exception is pending */ 509 __dbj_dbt_copyout(jenv, dbt1, &jdbtarr1, jdbt1); 510 if (jdbtarr1 == NULL) 511 return (ENOMEM); /* An exception is pending */ 512 } 513 514 if (dbt2->app_data != NULL) 515 jdbt2 = ((DBT_LOCKED *)dbt2->app_data)->jdbt; 516 else { 517 if ((jdbt2 = 518 (*jenv)->NewObject(jenv, dbt_class, dbt_construct)) == NULL) 519 return (ENOMEM); /* An exception is pending */ 520 __dbj_dbt_copyout(jenv, dbt2, &jdbtarr2, jdbt2); 521 if (jdbtarr2 == NULL) 522 return (ENOMEM); /* An exception is pending */ 523 } 524 525 ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class, 526 bt_prefix_method, jdbt1, jdbt2); 527 528 if (dbt1->app_data == NULL) { 529 (*jenv)->DeleteLocalRef(jenv, jdbtarr1); 530 (*jenv)->DeleteLocalRef(jenv, jdbt1); 531 } 532 if (dbt2->app_data == NULL) { 533 (*jenv)->DeleteLocalRef(jenv, jdbtarr2); 534 (*jenv)->DeleteLocalRef(jenv, jdbt2); 535 } 536 537 return (ret); 538} 539 540static int __dbj_dup_compare(DB *db, const DBT *dbt1, const DBT *dbt2) 541{ 542 JNIEnv *jenv = __dbj_get_jnienv(); 543 jobject jdb = (jobject)DB_INTERNAL(db); 544 jbyteArray jdbtarr1, jdbtarr2; 545 int ret; 546 547 if (jdb == NULL) 548 return (EINVAL); 549 550 jdbtarr1 = (*jenv)->NewByteArray(jenv, (jsize)dbt1->size); 551 if (jdbtarr1 == NULL) 552 return (ENOMEM); 553 (*jenv)->SetByteArrayRegion(jenv, jdbtarr1, 0, (jsize)dbt1->size, 554 (jbyte *)dbt1->data); 555 556 jdbtarr2 = (*jenv)->NewByteArray(jenv, (jsize)dbt2->size); 557 if (jdbtarr2 == NULL) 558 return (ENOMEM); 559 (*jenv)->SetByteArrayRegion(jenv, jdbtarr2, 0, (jsize)dbt2->size, 560 (jbyte *)dbt2->data); 561 562 ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class, 563 dup_compare_method, jdbtarr1, jdbtarr2); 564 565 if ((*jenv)->ExceptionOccurred(jenv)) { 566 /* The exception will be thrown, so this could be any error. */ 567 ret = EINVAL; 568 } 569 570 (*jenv)->DeleteLocalRef(jenv, jdbtarr2); 571 (*jenv)->DeleteLocalRef(jenv, jdbtarr1); 572 573 return (ret); 574} 575 576static void __dbj_db_feedback(DB *db, int opcode, int percent) 577{ 578 JNIEnv *jenv = __dbj_get_jnienv(); 579 jobject jdb = (jobject)DB_INTERNAL(db); 580 581 if (jdb != NULL) 582 (*jenv)->CallNonvirtualVoidMethod(jenv, jdb, db_class, 583 db_feedback_method, opcode, percent); 584} 585 586static int __dbj_h_compare(DB *db, const DBT *dbt1, const DBT *dbt2) 587{ 588 return __dbj_am_compare(db, dbt1, dbt2, h_compare_method); 589} 590 591static u_int32_t __dbj_h_hash(DB *db, const void *data, u_int32_t len) 592{ 593 JNIEnv *jenv = __dbj_get_jnienv(); 594 jobject jdb = (jobject)DB_INTERNAL(db); 595 jbyteArray jarr = (*jenv)->NewByteArray(jenv, (jsize)len); 596 int ret; 597 598 if (jdb == NULL) 599 return (EINVAL); 600 601 if ((jarr = (*jenv)->NewByteArray(jenv, (jsize)len)) == NULL) 602 return (ENOMEM); /* An exception is pending */ 603 604 (*jenv)->SetByteArrayRegion(jenv, jarr, 0, (jsize)len, (jbyte *)data); 605 606 ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class, 607 h_hash_method, jarr, len); 608 609 (*jenv)->DeleteLocalRef(jenv, jarr); 610 611 return (ret); 612} 613%} 614 615JAVA_CALLBACK(void (*db_errcall_fcn)(const DB_ENV *, 616 const char *, const char *), com.sleepycat.db.ErrorHandler, error) 617JAVA_CALLBACK(void (*env_feedback_fcn)(DB_ENV *, int, int), 618 com.sleepycat.db.FeedbackHandler, env_feedback) 619JAVA_CALLBACK(void (*db_msgcall_fcn)(const DB_ENV *, const char *), 620 com.sleepycat.db.MessageHandler, message) 621JAVA_CALLBACK(void (*db_panic_fcn)(DB_ENV *, int), 622 com.sleepycat.db.PanicHandler, panic) 623JAVA_CALLBACK(void (*event_notify)(DB_ENV *, u_int32_t, void *), 624 com.sleepycat.db.EventHandler, event_notify) 625JAVA_CALLBACK(int (*tx_recover)(DB_ENV *, DBT *, DB_LSN *, db_recops), 626 com.sleepycat.db.LogRecordHandler, app_dispatch) 627JAVA_CALLBACK(int (*send)(DB_ENV *, const DBT *, const DBT *, 628 const DB_LSN *, int, u_int32_t), 629 com.sleepycat.db.ReplicationTransport, rep_transport) 630 631/* 632 * Db.associate is a special case, because the handler must be set in the 633 * secondary DB - that's what we have in the callback. In addition, there 634 * are two flavors of callback (single key and multi-key), so we need to 635 * check for both types when working out whether the C callback should 636 * be NULL. Note that this implies that the multi-key callback will be set 637 * on the secondary database *before* associate is called. 638 */ 639JAVA_CALLBACK(int (*callback)(DB *, const DBT *, const DBT *, DBT *), 640 com.sleepycat.db.SecondaryKeyCreator, seckey_create) 641%typemap(javain) int (*callback)(DB *, const DBT *, const DBT *, DBT *) 642 %{ (secondary.seckey_create_handler = $javainput) != null || 643 (secondary.secmultikey_create_handler != null) %} 644JAVA_CALLBACK(int (*callback)(DB *, const DBT *, DBT *, const DBT *, int *), 645 com.sleepycat.db.ForeignKeyNullifier, foreignkey_nullify) 646%typemap(javain) int (*callback)(DB *, const DBT *, DBT *, const DBT *, int *) 647 %{ (primary.foreignkey_nullify_handler = $javainput) != null || 648 (primary.foreignmultikey_nullify_handler != null) %} 649 650JAVA_CALLBACK(int (*db_append_recno_fcn)(DB *, DBT *, db_recno_t), 651 com.sleepycat.db.RecordNumberAppender, append_recno) 652JAVA_CALLBACK(int (*bt_compare_fcn)(DB *, const DBT *, const DBT *), 653 java.util.Comparator, bt_compare) 654JAVA_CALLBACK(size_t (*bt_prefix_fcn)(DB *, const DBT *, const DBT *), 655 com.sleepycat.db.BtreePrefixCalculator, bt_prefix) 656JAVA_CALLBACK(int (*dup_compare_fcn)(DB *, const DBT *, const DBT *), 657 java.util.Comparator, dup_compare) 658JAVA_CALLBACK(void (*db_feedback_fcn)(DB *, int, int), 659 com.sleepycat.db.FeedbackHandler, db_feedback) 660JAVA_CALLBACK(int (*h_compare_fcn)(DB *, const DBT *, const DBT *), 661 java.util.Comparator, h_compare) 662JAVA_CALLBACK(u_int32_t (*h_hash_fcn)(DB *, const void *, u_int32_t), 663 com.sleepycat.db.Hasher, h_hash) 664