java_locked.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: java_locked.c,v 11.11 2000/10/25 19:54:55 dda Exp $";
  10. #endif /* not lint */
  11. #include <jni.h>
  12. #include <errno.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "db.h"
  16. #include "java_util.h"
  17. /****************************************************************
  18.  *
  19.  * Implementation of class LockedDBT
  20.  *
  21.  */
  22. int
  23. jdbt_lock(JDBT *jdbt, JNIEnv *jnienv, jobject obj, OpKind kind)
  24. {
  25. DBT *dbt;
  26. jdbt->obj_ = obj;
  27. jdbt->do_realloc_ = 0;
  28. jdbt->kind_ = kind;
  29. jdbt->java_array_len_= 0;
  30. jdbt->java_data_ = 0;
  31. jdbt->before_data_ = 0;
  32. jdbt->has_error_ = 0;
  33. jdbt->dbt = (DBT_JAVAINFO *)get_private_dbobj(jnienv, name_DBT, obj);
  34. if (!verify_non_null(jnienv, jdbt->dbt)) {
  35. jdbt->has_error_ = 1;
  36. return (EINVAL);
  37. }
  38. dbt = &jdbt->dbt->dbt;
  39. if (kind == outOp &&
  40.     (dbt->flags & (DB_DBT_USERMEM | DB_DBT_MALLOC | DB_DBT_REALLOC)) == 0) {
  41. report_exception(jnienv,
  42.  "Dbt.flags must be set to Db.DB_DBT_USERMEM, "
  43.  "Db.DB_DBT_MALLOC or Db.DB_DBT_REALLOC",
  44.  0, 0);
  45. jdbt->has_error_ = 1;
  46. return (EINVAL);
  47. }
  48. /* If this is requested to be realloc, we cannot use the
  49.  * underlying realloc, because the array we will pass in
  50.  * is not allocated by us, but the Java VM, so it cannot
  51.  * be successfully realloced.  We simulate the reallocation,
  52.  * by using USERMEM and reallocating the java array when a
  53.  * ENOMEM error occurs.  We change the flags during the operation,
  54.  * and they are reset when the operation completes (in the
  55.  * LockedDBT destructor.
  56.  */
  57. if ((dbt->flags & DB_DBT_REALLOC) != 0) {
  58. dbt->flags &= ~DB_DBT_REALLOC;
  59. dbt->flags |= DB_DBT_USERMEM;
  60. jdbt->do_realloc_ = 1;
  61. }
  62. if ((dbt->flags & DB_DBT_USERMEM) || kind != outOp) {
  63. /* If writing with DB_DBT_USERMEM/REALLOC
  64.  * or it's a set (or get/set) operation,
  65.  * then the data should point to a java array.
  66.  * Note that outOp means data is coming out of the database
  67.  * (it's a get).  inOp means data is going into the database
  68.  * (either a put, or a key input).
  69.  */
  70. if (!jdbt->dbt->array_) {
  71. report_exception(jnienv, "Dbt.data is null", 0, 0);
  72. jdbt->has_error_ = 1;
  73. return (EINVAL);
  74. }
  75. /* Verify other parameters */
  76. jdbt->java_array_len_ = (*jnienv)->GetArrayLength(jnienv, jdbt->dbt->array_);
  77. if (jdbt->dbt->offset_ < 0 ) {
  78. report_exception(jnienv, "Dbt.offset illegal", 0, 0);
  79. jdbt->has_error_ = 1;
  80. return (EINVAL);
  81. }
  82. if (dbt->ulen + jdbt->dbt->offset_ > jdbt->java_array_len_) {
  83. report_exception(jnienv,
  84.  "Dbt.ulen + Dbt.offset greater than array length", 0, 0);
  85. jdbt->has_error_ = 1;
  86. return (EINVAL);
  87. }
  88. jdbt->java_data_ = (*jnienv)->GetByteArrayElements(jnienv, jdbt->dbt->array_,
  89.   (jboolean *)0);
  90. dbt->data = jdbt->before_data_ = jdbt->java_data_ + jdbt->dbt->offset_;
  91. }
  92. else {
  93. /* If writing with DB_DBT_MALLOC, then the data is
  94.  * allocated by DB.
  95.  */
  96. dbt->data = jdbt->before_data_ = 0;
  97. }
  98. return (0);
  99. }
  100. /* The LockedDBT destructor is called when the java handler returns
  101.  * to the user, since that's when the LockedDBT objects go out of scope.
  102.  * Since it is thus called after any call to the underlying database,
  103.  * it copies any information from temporary structures back to user
  104.  * accessible arrays, and of course must free memory and remove references.
  105.  */
  106. void
  107. jdbt_unlock(JDBT *jdbt, JNIEnv *jnienv)
  108. {
  109. DBT *dbt;
  110. dbt = &jdbt->dbt->dbt;
  111. /* Fix up the flags if we changed them. */
  112. if (jdbt->do_realloc_) {
  113. dbt->flags &= ~DB_DBT_USERMEM;
  114. dbt->flags |= DB_DBT_REALLOC;
  115. }
  116. if ((dbt->flags & (DB_DBT_USERMEM | DB_DBT_REALLOC)) ||
  117.     jdbt->kind_ == inOp) {
  118. /* If writing with DB_DBT_USERMEM/REALLOC or it's a set
  119.  * (or get/set) operation, then the data may be already in
  120.  * the java array, in which case, we just need to release it.
  121.  * If DB didn't put it in the array (indicated by the
  122.  * dbt->data changing), we need to do that
  123.  */
  124. if (jdbt->before_data_ != jdbt->java_data_) {
  125. (*jnienv)->SetByteArrayRegion(jnienv,
  126.       jdbt->dbt->array_,
  127.       jdbt->dbt->offset_,
  128.       dbt->ulen,
  129.       jdbt->before_data_);
  130. }
  131. (*jnienv)->ReleaseByteArrayElements(jnienv, jdbt->dbt->array_, jdbt->java_data_, 0);
  132. dbt->data = 0;
  133. }
  134. if ((dbt->flags & DB_DBT_MALLOC) && jdbt->kind_ != inOp) {
  135. /* If writing with DB_DBT_MALLOC, then the data was allocated
  136.  * by DB.  If dbt->data is zero, it means an error occurred
  137.  * (and should have been already reported).
  138.  */
  139. if (dbt->data) {
  140. /* Release any old references. */
  141. dbjit_release(jdbt->dbt, jnienv);
  142. /* In the case of SET_RANGE, the key is inOutOp
  143.  * and when not found, its data will be left as
  144.  * its original value.  Only copy and free it
  145.  * here if it has been allocated by DB
  146.  * (dbt->data has changed).
  147.  */
  148. if (dbt->data != jdbt->before_data_) {
  149. jdbt->dbt->array_ = (jbyteArray)
  150. NEW_GLOBAL_REF(jnienv,
  151.    (*jnienv)->NewByteArray(jnienv,
  152.    dbt->size));
  153. jdbt->dbt->offset_ = 0;
  154. (*jnienv)->SetByteArrayRegion(jnienv,
  155.       jdbt->dbt->array_, 0, dbt->size,
  156.       (jbyte *)dbt->data);
  157. free(dbt->data);
  158. dbt->data = 0;
  159. }
  160. }
  161. }
  162. }
  163. /* Realloc the java array to receive data if the DBT was marked
  164.  * for realloc, and the last operation set the size field to an
  165.  * amount greater than ulen.
  166.  */
  167. int jdbt_realloc(JDBT *jdbt, JNIEnv *jnienv)
  168. {
  169. DBT *dbt;
  170. dbt = &jdbt->dbt->dbt;
  171. if (!jdbt->do_realloc_ || jdbt->has_error_ || dbt->size <= dbt->ulen)
  172. return (0);
  173. (*jnienv)->ReleaseByteArrayElements(jnienv, jdbt->dbt->array_, jdbt->java_data_, 0);
  174. dbjit_release(jdbt->dbt, jnienv);
  175. /* We allocate a new array of the needed size.
  176.  * We'll set the offset to 0, as the old offset
  177.  * really doesn't make any sense.
  178.  */
  179. jdbt->java_array_len_ = dbt->ulen = dbt->size;
  180. jdbt->dbt->offset_ = 0;
  181. jdbt->dbt->array_ = (jbyteArray)
  182. NEW_GLOBAL_REF(jnienv, (*jnienv)->NewByteArray(jnienv, dbt->size));
  183. jdbt->java_data_ = (*jnienv)->GetByteArrayElements(jnienv,
  184.      jdbt->dbt->array_,
  185.      (jboolean *)0);
  186. dbt->data = jdbt->before_data_ = jdbt->java_data_;
  187. return (1);
  188. }
  189. /****************************************************************
  190.  *
  191.  * Implementation of class JSTR
  192.  *
  193.  */
  194. int
  195. jstr_lock(JSTR *js, JNIEnv *jnienv, jstring jstr)
  196. {
  197. js->jstr_ = jstr;
  198. if (jstr == 0)
  199. js->string = 0;
  200. else
  201. js->string = (*jnienv)->GetStringUTFChars(jnienv, jstr,
  202.   (jboolean *)0);
  203. return (0);
  204. }
  205. void jstr_unlock(JSTR *js, JNIEnv *jnienv)
  206. {
  207. if (js->jstr_)
  208. (*jnienv)->ReleaseStringUTFChars(jnienv, js->jstr_, js->string);
  209. }
  210. /****************************************************************
  211.  *
  212.  * Implementation of class JSTRARRAY
  213.  *
  214.  */
  215. int
  216. jstrarray_lock(JSTRARRAY *jsa, JNIEnv *jnienv, jobjectArray arr)
  217. {
  218. int i;
  219. jsa->arr_ = arr;
  220. jsa->array = 0;
  221. if (arr != 0) {
  222. int count = (*jnienv)->GetArrayLength(jnienv, arr);
  223. const char **new_array =
  224. (const char **)malloc((sizeof(const char *))*(count+1));
  225. for (i=0; i<count; i++) {
  226. jstring jstr = (jstring)(*jnienv)->GetObjectArrayElement(jnienv, arr, i);
  227. if (jstr == 0) {
  228. /*
  229.  * An embedded null in the string array
  230.  * is treated as an endpoint.
  231.  */
  232. new_array[i] = 0;
  233. break;
  234. }
  235. else {
  236. new_array[i] =
  237. (*jnienv)->GetStringUTFChars(jnienv, jstr, (jboolean *)0);
  238. }
  239. }
  240. new_array[count] = 0;
  241. jsa->array = new_array;
  242. }
  243. return (0);
  244. }
  245. void jstrarray_unlock(JSTRARRAY *jsa, JNIEnv *jnienv)
  246. {
  247. int i;
  248. jstring jstr;
  249. if (jsa->arr_) {
  250. int count = (*jnienv)->GetArrayLength(jnienv, jsa->arr_);
  251. for (i=0; i<count; i++) {
  252. if (jsa->array[i] == 0)
  253. break;
  254. jstr = (jstring)(*jnienv)->GetObjectArrayElement(jnienv, jsa->arr_, i);
  255. (*jnienv)->ReleaseStringUTFChars(jnienv, jstr, jsa->array[i]);
  256. }
  257. free((void*)jsa->array);
  258. }
  259. }