1/* Typemaps */ 2%define JAVA_TYPEMAP(_ctype, _jtype, _jnitype) 3%typemap(jstype) _ctype #_jtype 4%typemap(jtype) _ctype #_jtype 5%typemap(jni) _ctype #_jnitype 6%typemap(out) _ctype %{ $result = (_jnitype)$1; %} 7%typemap(javain) _ctype "$javainput" 8%typemap(javaout) _ctype { return $jnicall; } 9%enddef 10 11JAVA_TYPEMAP(int32_t, int, jint) 12JAVA_TYPEMAP(u_int32_t, int, jint) 13JAVA_TYPEMAP(u_int32_t pagesize, long, jlong) 14JAVA_TYPEMAP(long, long, jlong) 15JAVA_TYPEMAP(db_seq_t, long, jlong) 16JAVA_TYPEMAP(pid_t, long, jlong) 17#ifndef SWIGJAVA 18JAVA_TYPEMAP(db_threadid_t, long, jlong) 19#endif 20JAVA_TYPEMAP(db_timeout_t, long, jlong) 21JAVA_TYPEMAP(size_t, long, jlong) 22JAVA_TYPEMAP(db_ret_t, void, void) 23%typemap(javaout) db_ret_t { $jnicall; } 24%typemap(out) db_ret_t "" 25 26JAVA_TYPEMAP(int_bool, boolean, jboolean) 27%typemap(in) int_bool %{ $1 = ($input == JNI_TRUE); %} 28%typemap(out) int_bool %{ $result = ($1) ? JNI_TRUE : JNI_FALSE; %} 29 30/* Dbt handling */ 31JAVA_TYPEMAP(DBT *, com.sleepycat.db.DatabaseEntry, jobject) 32 33%{ 34typedef struct __dbt_locked { 35 JNIEnv *jenv; 36 jobject jdbt; 37 DBT dbt; 38 jobject jdata_nio; 39 jbyteArray jarr; 40 jint offset; 41 int reuse; 42 u_int32_t orig_size; 43 jsize array_len; 44} DBT_LOCKED; 45 46static int __dbj_dbt_memcopy(DBT *dbt, u_int32_t offset, void *buf, u_int32_t size, u_int32_t flags) { 47 DBT_LOCKED *ldbt = dbt->app_data; 48 JNIEnv *jenv = ldbt->jenv; 49 50 if (size == 0) 51 return (0); 52 else if (!F_ISSET(dbt, DB_DBT_USERCOPY)) { 53 /* 54 * For simplicity, the Java API calls this function directly, 55 * so it needs to work with regular DBTs. 56 */ 57 switch (flags) { 58 case DB_USERCOPY_GETDATA: 59 memcpy(buf, (u_int8_t *)dbt->data + offset, size); 60 return (0); 61 case DB_USERCOPY_SETDATA: 62 memcpy((u_int8_t *)dbt->data + offset, buf, size); 63 return (0); 64 default: 65 return (EINVAL); 66 } 67 } 68 69 switch (flags) { 70 case DB_USERCOPY_GETDATA: 71 (*jenv)->GetByteArrayRegion(jenv, ldbt->jarr, ldbt->offset + 72 offset, size, buf); 73 break; 74 case DB_USERCOPY_SETDATA: 75 /* 76 * Check whether this is the first time through the callback by relying 77 * on the offset being zero. 78 */ 79 if (offset == 0 && (!ldbt->reuse || 80 (jsize)(ldbt->offset + dbt->size) > ldbt->array_len)) { 81 if (ldbt->jarr != NULL) 82 (*jenv)->DeleteLocalRef(jenv, ldbt->jarr); 83 ldbt->jarr = (*jenv)->NewByteArray(jenv, (jsize)dbt->size); 84 if (ldbt->jarr == NULL) 85 return (ENOMEM); 86 (*jenv)->SetObjectField(jenv, ldbt->jdbt, dbt_data_fid, ldbt->jarr); 87 /* We've allocated a new array, start from the beginning. */ 88 ldbt->offset = 0; 89 } 90 (*jenv)->SetByteArrayRegion(jenv, ldbt->jarr, ldbt->offset + 91 offset, size, buf); 92 break; 93 default: 94 return (EINVAL); 95 } 96 return ((*jenv)->ExceptionOccurred(jenv) ? EINVAL : 0); 97} 98 99static void __dbj_dbt_copyout( 100 JNIEnv *jenv, const DBT *dbt, jbyteArray *jarr, jobject jdbt) 101{ 102 jbyteArray newarr = (*jenv)->NewByteArray(jenv, (jsize)dbt->size); 103 if (newarr == NULL) 104 return; /* An exception is pending */ 105 (*jenv)->SetByteArrayRegion(jenv, newarr, 0, (jsize)dbt->size, 106 (jbyte *)dbt->data); 107 (*jenv)->SetObjectField(jenv, jdbt, dbt_data_fid, newarr); 108 (*jenv)->SetIntField(jenv, jdbt, dbt_offset_fid, 0); 109 (*jenv)->SetIntField(jenv, jdbt, dbt_size_fid, (jint)dbt->size); 110 if (jarr != NULL) 111 *jarr = newarr; 112 else 113 (*jenv)->DeleteLocalRef(jenv, newarr); 114} 115 116static int __dbj_dbt_copyin( 117 JNIEnv *jenv, DBT_LOCKED *ldbt, DBT **dbtp, jobject jdbt, int allow_null) 118{ 119 DBT *dbt; 120 jlong capacity; 121 122 memset(ldbt, 0, sizeof (*ldbt)); 123 ldbt->jenv = jenv; 124 ldbt->jdbt = jdbt; 125 126 if (jdbt == NULL) { 127 if (allow_null) { 128 *dbtp = NULL; 129 return (0); 130 } else { 131 return (__dbj_throw(jenv, EINVAL, 132 "DatabaseEntry must not be null", NULL, NULL)); 133 } 134 } 135 136 dbt = &ldbt->dbt; 137 if (dbtp != NULL) 138 *dbtp = dbt; 139 140 ldbt->jdata_nio = (*jenv)->GetObjectField(jenv, jdbt, dbt_data_nio_fid); 141 if (ldbt->jdata_nio != NULL) 142 F_SET(dbt, DB_DBT_USERMEM); 143 else 144 ldbt->jarr = (jbyteArray)(*jenv)->GetObjectField(jenv, jdbt, dbt_data_fid); 145 ldbt->offset = (*jenv)->GetIntField(jenv, jdbt, dbt_offset_fid); 146 dbt->size = (*jenv)->GetIntField(jenv, jdbt, dbt_size_fid); 147 ldbt->orig_size = dbt->size; 148 dbt->flags = (*jenv)->GetIntField(jenv, jdbt, dbt_flags_fid); 149 150 if (F_ISSET(dbt, DB_DBT_USERMEM)) 151 dbt->ulen = (*jenv)->GetIntField(jenv, jdbt, dbt_ulen_fid); 152 if (F_ISSET(dbt, DB_DBT_PARTIAL)) { 153 dbt->dlen = (*jenv)->GetIntField(jenv, jdbt, dbt_dlen_fid); 154 dbt->doff = (*jenv)->GetIntField(jenv, jdbt, dbt_doff_fid); 155 156 if ((jint)dbt->doff < 0) 157 return (__dbj_throw(jenv, EINVAL, "DatabaseEntry doff illegal", 158 NULL, NULL)); 159 } 160 161 /* 162 * We don't support DB_DBT_REALLOC - map anything that's not USERMEM to 163 * MALLOC. 164 */ 165 if (!F_ISSET(dbt, DB_DBT_USERMEM)) { 166 ldbt->reuse = !F_ISSET(dbt, DB_DBT_MALLOC); 167 F_CLR(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC); 168 } 169 170 /* Verify parameters before allocating or locking data. */ 171 if (ldbt->jdata_nio != NULL) { 172 capacity = (*jenv)->GetDirectBufferCapacity(jenv, 173 ldbt->jdata_nio); 174 if (capacity > (jlong)UINT32_MAX) 175 return (__dbj_throw(jenv, EINVAL, 176 "DirectBuffer may not be larger than 4GB", 177 NULL, NULL)); 178 ldbt->array_len = (u_int32_t)capacity; 179 } else if (ldbt->jarr == NULL) { 180 /* 181 * Some code makes the assumption that if a DBT's size or ulen 182 * is non-zero, there is data to copy from dbt->data. 183 * 184 * Clean up the dbt fields so we don't run into trouble. 185 * (Note that doff, dlen, and flags all may contain 186 * meaningful values.) 187 */ 188 dbt->data = NULL; 189 ldbt->array_len = ldbt->offset = dbt->size = dbt->ulen = 0; 190 } else 191 ldbt->array_len = (*jenv)->GetArrayLength(jenv, ldbt->jarr); 192 193 if (F_ISSET(dbt, DB_DBT_USERMEM)) { 194 if (ldbt->offset < 0) 195 return (__dbj_throw(jenv, EINVAL, 196 "offset cannot be negative", 197 NULL, NULL)); 198 if (dbt->size > dbt->ulen) 199 return (__dbj_throw(jenv, EINVAL, 200 "size must be less than or equal to ulen", 201 NULL, NULL)); 202 if ((jsize)(ldbt->offset + dbt->ulen) > ldbt->array_len) 203 return (__dbj_throw(jenv, EINVAL, 204 "offset + ulen greater than array length", 205 NULL, NULL)); 206 } 207 208 if (ldbt->jdata_nio) { 209 dbt->data = (*jenv)->GetDirectBufferAddress(jenv, 210 ldbt->jdata_nio); 211 dbt->data = (u_int8_t *)dbt->data + ldbt->offset; 212 } else if (F_ISSET(dbt, DB_DBT_USERMEM)) { 213 if (ldbt->jarr != NULL && 214 (dbt->data = (*jenv)->GetByteArrayElements(jenv, 215 ldbt->jarr, NULL)) == NULL) 216 return (EINVAL); /* an exception will be pending */ 217 dbt->data = (u_int8_t *)dbt->data + ldbt->offset; 218 } else 219 F_SET(dbt, DB_DBT_USERCOPY); 220 dbt->app_data = ldbt; 221 222 return (0); 223} 224 225static void __dbj_dbt_release( 226 JNIEnv *jenv, jobject jdbt, DBT *dbt, DBT_LOCKED *ldbt) { 227 jthrowable t; 228 229 if (dbt == NULL) 230 return; 231 232 if (dbt->size != ldbt->orig_size) 233 (*jenv)->SetIntField(jenv, jdbt, dbt_size_fid, (jint)dbt->size); 234 235 if (F_ISSET(dbt, DB_DBT_USERMEM)) { 236 if (ldbt->jarr != NULL) 237 (*jenv)->ReleaseByteArrayElements(jenv, ldbt->jarr, 238 (jbyte *)dbt->data - ldbt->offset, 0); 239 240 if (dbt->size > dbt->ulen && 241 (t = (*jenv)->ExceptionOccurred(jenv)) != NULL && 242 (*jenv)->IsInstanceOf(jenv, t, memex_class)) { 243 (*jenv)->CallNonvirtualVoidMethod(jenv, t, memex_class, 244 memex_update_method, jdbt); 245 /* 246 * We have to rethrow the exception because calling 247 * into Java clears it. 248 */ 249 (*jenv)->Throw(jenv, t); 250 } 251 } 252} 253%} 254 255%typemap(in) DBT * (DBT_LOCKED ldbt) %{ 256 if (__dbj_dbt_copyin(jenv, &ldbt, &$1, $input, 0) != 0) { 257 return $null; /* An exception will be pending. */ 258 }%} 259 260/* Special cases for DBTs that may be null: DbEnv.rep_start and Db.compact */ 261%typemap(in) DBT *data_or_null (DBT_LOCKED ldbt) %{ 262 if (__dbj_dbt_copyin(jenv, &ldbt, &$1, $input, 1) != 0) { 263 return $null; /* An exception will be pending. */ 264 }%} 265 266%apply DBT *data_or_null {DBT *cdata, DBT *start, DBT *stop, DBT *end}; 267 268%typemap(freearg) DBT * %{ __dbj_dbt_release(jenv, $input, $1, &ldbt$argnum); %} 269 270/* DbLsn handling */ 271JAVA_TYPEMAP(DB_LSN *, com.sleepycat.db.LogSequenceNumber, jobject) 272 273%typemap(check) DB_LSN *lsn_or_null "" 274 275%typemap(check) DB_LSN * %{ 276 if ($1 == NULL) { 277 __dbj_throw(jenv, EINVAL, "null LogSequenceNumber", NULL, NULL); 278 return $null; 279 } 280%} 281 282%typemap(in) DB_LSN * (DB_LSN lsn) %{ 283 if ($input == NULL) { 284 $1 = NULL; 285 } else { 286 $1 = &lsn; 287 $1->file = (*jenv)->GetIntField(jenv, $input, dblsn_file_fid); 288 $1->offset = (*jenv)->GetIntField(jenv, $input, 289 dblsn_offset_fid); 290 } 291%} 292 293%typemap(freearg) DB_LSN * %{ 294 if ($input != NULL) { 295 (*jenv)->SetIntField(jenv, $input, dblsn_file_fid, $1->file); 296 (*jenv)->SetIntField(jenv, $input, 297 dblsn_offset_fid, $1->offset); 298 } 299%} 300 301/* Various typemaps */ 302JAVA_TYPEMAP(time_t, long, jlong) 303JAVA_TYPEMAP(time_t *, long, jlong) 304%typemap(in) time_t * (time_t time) %{ 305 time = (time_t)$input; 306 $1 = &time; 307%} 308 309JAVA_TYPEMAP(DB_KEY_RANGE *, com.sleepycat.db.KeyRange, jobject) 310%typemap(in) DB_KEY_RANGE * (DB_KEY_RANGE range) { 311 $1 = ⦥ 312} 313%typemap(argout) DB_KEY_RANGE * { 314 (*jenv)->SetDoubleField(jenv, $input, kr_less_fid, $1->less); 315 (*jenv)->SetDoubleField(jenv, $input, kr_equal_fid, $1->equal); 316 (*jenv)->SetDoubleField(jenv, $input, kr_greater_fid, $1->greater); 317} 318 319JAVA_TYPEMAP(DBC **, Dbc[], jobjectArray) 320%typemap(in) DBC ** { 321 int i, count, err; 322 323 count = (*jenv)->GetArrayLength(jenv, $input); 324 if ((err = __os_malloc(NULL, (count + 1) * sizeof(DBC *), &$1)) != 0) { 325 __dbj_throw(jenv, err, NULL, NULL, DB2JDBENV); 326 return $null; 327 } 328 for (i = 0; i < count; i++) { 329 jobject jobj = (*jenv)->GetObjectArrayElement(jenv, $input, i); 330 /* 331 * A null in the array is treated as an endpoint. 332 */ 333 if (jobj == NULL) { 334 $1[i] = NULL; 335 break; 336 } else { 337 jlong jptr = (*jenv)->GetLongField(jenv, jobj, 338 dbc_cptr_fid); 339 $1[i] = *(DBC **)(void *)&jptr; 340 } 341 } 342 $1[count] = NULL; 343} 344 345%typemap(freearg) DBC ** %{ 346 __os_free(NULL, $1); 347%} 348 349JAVA_TYPEMAP(u_int8_t *gid, byte[], jbyteArray) 350%typemap(check) u_int8_t *gid %{ 351 if ((*jenv)->GetArrayLength(jenv, $input) < DB_XIDDATASIZE) { 352 __dbj_throw(jenv, EINVAL, 353 "DbTxn.prepare gid array must be >= 128 bytes", NULL, 354 TXN2JDBENV); 355 return $null; 356 } 357%} 358 359%typemap(in) u_int8_t *gid %{ 360 $1 = (u_int8_t *)(*jenv)->GetByteArrayElements(jenv, $input, NULL); 361%} 362 363%typemap(freearg) u_int8_t *gid %{ 364 (*jenv)->ReleaseByteArrayElements(jenv, $input, (jbyte *)$1, 0); 365%} 366 367%define STRING_ARRAY_OUT 368 int i, len; 369 370 len = 0; 371 while ($1[len] != NULL) 372 len++; 373 if (($result = (*jenv)->NewObjectArray(jenv, (jsize)len, string_class, 374 NULL)) == NULL) 375 return $null; /* an exception is pending */ 376 for (i = 0; i < len; i++) { 377 jstring str = (*jenv)->NewStringUTF(jenv, $1[i]); 378 (*jenv)->SetObjectArrayElement(jenv, $result, (jsize)i, str); 379 } 380%enddef 381 382JAVA_TYPEMAP(char **, String[], jobjectArray) 383%typemap(out) const char ** { 384 if ($1 != NULL) { 385 STRING_ARRAY_OUT 386 } 387} 388%typemap(out) char ** { 389 if ($1 != NULL) { 390 STRING_ARRAY_OUT 391 __os_ufree(NULL, $1); 392 } 393} 394 395JAVA_TYPEMAP(struct __db_lk_conflicts, byte[][], jobjectArray) 396%typemap(in) struct __db_lk_conflicts { 397 int i, len, err; 398 size_t bytesize; 399 400 len = $1.lk_modes = (*jenv)->GetArrayLength(jenv, $input); 401 bytesize = sizeof(u_char) * len * len; 402 403 if ((err = __os_malloc(NULL, bytesize, &$1.lk_conflicts)) != 0) { 404 __dbj_throw(jenv, err, NULL, NULL, JDBENV); 405 return $null; 406 } 407 408 for (i = 0; i < len; i++) { 409 jobject sub_array = (*jenv)->GetObjectArrayElement(jenv, 410 $input, i); 411 (*jenv)->GetByteArrayRegion(jenv,(jbyteArray)sub_array, 0, len, 412 (jbyte *)&$1.lk_conflicts[i * len]); 413 } 414} 415 416%typemap(freearg) struct __db_lk_conflicts %{ 417 __os_free(NULL, $1.lk_conflicts); 418%} 419 420%typemap(out) struct __db_lk_conflicts { 421 int i; 422 jbyteArray bytes; 423 424 $result = (*jenv)->NewObjectArray(jenv, 425 (jsize)$1.lk_modes, bytearray_class, NULL); 426 if ($result == NULL) 427 return $null; /* an exception is pending */ 428 for (i = 0; i < $1.lk_modes; i++) { 429 bytes = (*jenv)->NewByteArray(jenv, (jsize)$1.lk_modes); 430 if (bytes == NULL) 431 return $null; /* an exception is pending */ 432 (*jenv)->SetByteArrayRegion(jenv, bytes, 0, (jsize)$1.lk_modes, 433 (jbyte *)($1.lk_conflicts + i * $1.lk_modes)); 434 (*jenv)->SetObjectArrayElement(jenv, $result, (jsize)i, bytes); 435 } 436} 437 438%{ 439struct __dbj_verify_data { 440 JNIEnv *jenv; 441 jobject streamobj; 442 jbyteArray bytes; 443 int nbytes; 444}; 445 446static int __dbj_verify_callback(void *handle, const void *str_arg) { 447 char *str; 448 struct __dbj_verify_data *vd; 449 int len; 450 JNIEnv *jenv; 451 452 str = (char *)str_arg; 453 vd = (struct __dbj_verify_data *)handle; 454 jenv = vd->jenv; 455 len = strlen(str) + 1; 456 if (len > vd->nbytes) { 457 vd->nbytes = len; 458 if (vd->bytes != NULL) 459 (*jenv)->DeleteLocalRef(jenv, vd->bytes); 460 if ((vd->bytes = (*jenv)->NewByteArray(jenv, (jsize)len)) 461 == NULL) 462 return (ENOMEM); 463 } 464 465 if (vd->bytes != NULL) { 466 (*jenv)->SetByteArrayRegion(jenv, vd->bytes, 0, (jsize)len, 467 (jbyte*)str); 468 (*jenv)->CallVoidMethod(jenv, vd->streamobj, 469 outputstream_write_method, vd->bytes, 0, len - 1); 470 } 471 472 if ((*jenv)->ExceptionOccurred(jenv) != NULL) 473 return (EIO); 474 475 return (0); 476} 477%} 478 479JAVA_TYPEMAP(struct __db_out_stream, java.io.OutputStream, jobject) 480%typemap(in) struct __db_out_stream (struct __dbj_verify_data data) { 481 data.jenv = jenv; 482 data.streamobj = $input; 483 data.bytes = NULL; 484 data.nbytes = 0; 485 $1.handle = &data; 486 $1.callback = __dbj_verify_callback; 487} 488 489JAVA_TYPEMAP(DB_PREPLIST *, com.sleepycat.db.PreparedTransaction[], 490 jobjectArray) 491%typemap(out) DB_PREPLIST * { 492 int i, len; 493 494 len = 0; 495 while ($1[len].txn != NULL) 496 len++; 497 $result = (*jenv)->NewObjectArray(jenv, (jsize)len, dbpreplist_class, 498 NULL); 499 if ($result == NULL) 500 return $null; /* an exception is pending */ 501 for (i = 0; i < len; i++) { 502 jobject jtxn = (*jenv)->NewObject(jenv, dbtxn_class, 503 dbtxn_construct, $1[i].txn, JNI_FALSE); 504 jobject bytearr = (*jenv)->NewByteArray(jenv, 505 (jsize)sizeof($1[i].gid)); 506 jobject obj = (*jenv)->NewObject(jenv, dbpreplist_class, 507 dbpreplist_construct, jtxn, bytearr); 508 509 if (jtxn == NULL || bytearr == NULL || obj == NULL) 510 return $null; /* An exception is pending */ 511 512 (*jenv)->SetByteArrayRegion(jenv, bytearr, 0, 513 (jsize)sizeof($1[i].gid), (jbyte *)$1[i].gid); 514 (*jenv)->SetObjectArrayElement(jenv, $result, i, obj); 515 } 516 __os_ufree(NULL, $1); 517} 518 519JAVA_TYPEMAP(DB_LOCKREQ *, com.sleepycat.db.LockRequest[], jobjectArray) 520 521%native(DbEnv_lock_vec) void DbEnv_lock_vec(DB_ENV *dbenv, u_int32_t locker, 522 u_int32_t flags, DB_LOCKREQ *list, int offset, int nlist); 523%{ 524SWIGEXPORT void JNICALL 525Java_com_sleepycat_db_internal_db_1javaJNI_DbEnv_1lock_1vec(JNIEnv *jenv, 526 jclass jcls, jlong jdbenvp, jobject jdbenv, jint locker, jint flags, 527 jobjectArray list, jint offset, jint count) { 528 DB_ENV *dbenv; 529 DB_LOCKREQ *lockreq; 530 DB_LOCKREQ *prereq; /* preprocessed requests */ 531 DB_LOCKREQ *failedreq; 532 DB_LOCK *lockp; 533 DBT_LOCKED *locked_dbts; 534 DBT *obj; 535 ENV *env; 536 int err, alloc_err, i; 537 size_t bytesize, ldbtsize; 538 jobject jlockreq; 539 db_lockop_t op; 540 jobject jobj, jlock; 541 jlong jlockp; 542 int completed; 543 544 COMPQUIET(jcls, NULL); 545 dbenv = *(DB_ENV **)(void *)&jdbenvp; 546 env = dbenv->env; 547 548 if (dbenv == NULL) { 549 __dbj_throw(jenv, EINVAL, "null object", NULL, jdbenv); 550 return; 551 } 552 553 if ((*jenv)->GetArrayLength(jenv, list) < offset + count) { 554 __dbj_throw(jenv, EINVAL, 555 "DbEnv.lock_vec array not large enough", NULL, jdbenv); 556 goto out0; 557 } 558 559 bytesize = sizeof(DB_LOCKREQ) * count; 560 if ((err = __os_malloc(env, bytesize, &lockreq)) != 0) { 561 __dbj_throw(jenv, err, NULL, NULL, jdbenv); 562 goto out0; 563 } 564 memset(lockreq, 0, bytesize); 565 566 ldbtsize = sizeof(DBT_LOCKED) * count; 567 if ((err = __os_malloc(env, ldbtsize, &locked_dbts)) != 0) { 568 __dbj_throw(jenv, err, NULL, NULL, jdbenv); 569 goto out1; 570 } 571 memset(locked_dbts, 0, ldbtsize); 572 prereq = &lockreq[0]; 573 574 /* fill in the lockreq array */ 575 for (i = 0, prereq = &lockreq[0]; i < count; i++, prereq++) { 576 jlockreq = (*jenv)->GetObjectArrayElement(jenv, list, 577 offset + i); 578 if (jlockreq == NULL) { 579 __dbj_throw(jenv, EINVAL, 580 "DbEnv.lock_vec list entry is null", NULL, jdbenv); 581 goto out2; 582 } 583 op = (*jenv)->GetIntField(jenv, jlockreq, lockreq_op_fid); 584 prereq->op = op; 585 586 switch (op) { 587 case DB_LOCK_GET_TIMEOUT: 588 /* Needed: mode, timeout, obj. Returned: lock. */ 589 prereq->op = (*jenv)->GetIntField(jenv, jlockreq, 590 lockreq_timeout_fid); 591 /* FALLTHROUGH */ 592 case DB_LOCK_GET: 593 /* Needed: mode, obj. Returned: lock. */ 594 prereq->mode = (*jenv)->GetIntField(jenv, jlockreq, 595 lockreq_modeflag_fid); 596 jobj = (*jenv)->GetObjectField(jenv, jlockreq, 597 lockreq_obj_fid); 598 if ((err = __dbj_dbt_copyin(jenv, 599 &locked_dbts[i], &obj, jobj, 0)) != 0 || 600 (err = 601 __os_umalloc(env, obj->size, &obj->data)) != 0 || 602 (err = __dbj_dbt_memcopy(obj, 0, 603 obj->data, obj->size, DB_USERCOPY_GETDATA)) != 0) 604 goto out2; 605 prereq->obj = obj; 606 break; 607 case DB_LOCK_PUT: 608 /* Needed: lock. Ignored: mode, obj. */ 609 jlock = (*jenv)->GetObjectField(jenv, jlockreq, 610 lockreq_lock_fid); 611 if (jlock == NULL || 612 (jlockp = (*jenv)->GetLongField(jenv, jlock, 613 lock_cptr_fid)) == 0L) { 614 __dbj_throw(jenv, EINVAL, 615 "LockRequest lock field is NULL", NULL, 616 jdbenv); 617 goto out2; 618 } 619 lockp = *(DB_LOCK **)(void *)&jlockp; 620 prereq->lock = *lockp; 621 break; 622 case DB_LOCK_PUT_ALL: 623 case DB_LOCK_TIMEOUT: 624 /* Needed: (none). Ignored: lock, mode, obj. */ 625 break; 626 case DB_LOCK_PUT_OBJ: 627 /* Needed: obj. Ignored: lock, mode. */ 628 jobj = (*jenv)->GetObjectField(jenv, jlockreq, 629 lockreq_obj_fid); 630 if ((err = __dbj_dbt_copyin(jenv, 631 &locked_dbts[i], &obj, jobj, 0)) != 0 || 632 (err = 633 __os_umalloc(env, obj->size, &obj->data)) != 0 || 634 (err = __dbj_dbt_memcopy(obj, 0, 635 obj->data, obj->size, DB_USERCOPY_GETDATA)) != 0) 636 goto out2; 637 prereq->obj = obj; 638 break; 639 default: 640 __dbj_throw(jenv, EINVAL, 641 "DbEnv.lock_vec bad op value", NULL, jdbenv); 642 goto out2; 643 } 644 } 645 646 err = dbenv->lock_vec(dbenv, (u_int32_t)locker, (u_int32_t)flags, 647 lockreq, count, &failedreq); 648 if (err == 0) 649 completed = count; 650 else 651 completed = failedreq - lockreq; 652 653 /* do post processing for any and all requests that completed */ 654 for (i = 0; i < completed; i++) { 655 op = lockreq[i].op; 656 if (op == DB_LOCK_PUT) { 657 /* 658 * After a successful put, the DbLock can no longer be 659 * used, so we release the storage related to it. 660 */ 661 jlockreq = (*jenv)->GetObjectArrayElement(jenv, 662 list, i + offset); 663 jlock = (*jenv)->GetObjectField(jenv, jlockreq, 664 lockreq_lock_fid); 665 jlockp = (*jenv)->GetLongField(jenv, jlock, 666 lock_cptr_fid); 667 lockp = *(DB_LOCK **)(void *)&jlockp; 668 __os_free(NULL, lockp); 669 (*jenv)->SetLongField(jenv, jlock, lock_cptr_fid, 670 (jlong)0); 671 } 672 else if (op == DB_LOCK_GET) { 673 /* 674 * Store the lock that was obtained. We need to create 675 * storage for it since the lockreq array only exists 676 * during this method call. 677 */ 678 if ((alloc_err = 679 __os_malloc(env, sizeof(DB_LOCK), &lockp)) != 0) { 680 __dbj_throw(jenv, alloc_err, NULL, NULL, 681 jdbenv); 682 goto out2; 683 } 684 685 *lockp = lockreq[i].lock; 686 *(DB_LOCK **)(void *)&jlockp = lockp; 687 688 jlockreq = (*jenv)->GetObjectArrayElement(jenv, 689 list, i + offset); 690 jlock = (*jenv)->NewObject(jenv, lock_class, 691 lock_construct, jlockp, JNI_TRUE); 692 if (jlock == NULL) 693 goto out2; /* An exception is pending */ 694 (*jenv)->SetLongField(jenv, jlock, lock_cptr_fid, 695 jlockp); 696 (*jenv)->SetObjectField(jenv, jlockreq, 697 lockreq_lock_fid, jlock); 698 } 699 } 700 701 /* If one of the locks was not granted, build the exception now. */ 702 if (err == DB_LOCK_NOTGRANTED && i < count) { 703 jlockreq = (*jenv)->GetObjectArrayElement(jenv, list, 704 i + offset); 705 jobj = (*jenv)->GetObjectField(jenv, jlockreq, 706 lockreq_obj_fid); 707 jlock = (*jenv)->GetObjectField(jenv, jlockreq, 708 lockreq_lock_fid); 709 (*jenv)->Throw(jenv, 710 (*jenv)->NewObject(jenv, lockex_class, lockex_construct, 711 (*jenv)->NewStringUTF(jenv, "DbEnv.lock_vec incomplete"), 712 lockreq[i].op, lockreq[i].mode, jobj, jlock, i, jdbenv)); 713 } else if (err != 0) 714 __dbj_throw(jenv, err, NULL, NULL, jdbenv); 715 716out2: __os_free(env, locked_dbts); 717out1: for (i = 0, prereq = &lockreq[0]; i < count; i++, prereq++) 718 if ((prereq->op == DB_LOCK_GET || prereq->op == DB_LOCK_PUT) && 719 prereq->obj->data != NULL) 720 __os_ufree(env, prereq->obj->data); 721 __os_free(env, lockreq); 722out0: return; 723} 724%} 725 726JAVA_TYPEMAP(struct __db_repmgr_sites, 727 com.sleepycat.db.ReplicationManagerSiteInfo[], jobjectArray) 728%typemap(out) struct __db_repmgr_sites 729{ 730 int i, len; 731 jobject jrep_addr, jrep_info; 732 733 len = $1.nsites; 734 $result = (*jenv)->NewObjectArray(jenv, (jsize)len, repmgr_siteinfo_class, 735 NULL); 736 if ($result == NULL) 737 return $null; /* an exception is pending */ 738 for (i = 0; i < len; i++) { 739 jstring addr_host = (*jenv)->NewStringUTF(jenv, $1.sites[i].host); 740 if (addr_host == NULL) 741 return $null; /* An exception is pending */ 742 jrep_addr = (*jenv)->NewObject(jenv, 743 rephost_class, rephost_construct, addr_host, $1.sites[i].port); 744 if (jrep_addr == NULL) 745 return $null; /* An exception is pending */ 746 747 jrep_info = (*jenv)->NewObject(jenv, 748 repmgr_siteinfo_class, repmgr_siteinfo_construct, jrep_addr, $1.sites[i].eid); 749 (*jenv)->SetIntField(jenv, jrep_info, repmgr_siteinfo_status_fid, 750 $1.sites[i].status); 751 if (jrep_info == NULL) 752 return $null; /* An exception is pending */ 753 754 (*jenv)->SetObjectArrayElement(jenv, $result, i, jrep_info); 755 } 756 __os_ufree(NULL, $1.sites); 757} 758 759JAVA_TYPEMAP(void *, Object, jobject) 760