Return-Path: Delivered-To: apmail-lucene-commits-archive@www.apache.org Received: (qmail 10134 invoked from network); 9 Jan 2009 03:29:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 9 Jan 2009 03:29:43 -0000 Received: (qmail 93736 invoked by uid 500); 9 Jan 2009 03:29:42 -0000 Mailing-List: contact commits-help@lucene.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@lucene.apache.org Delivered-To: mailing list commits@lucene.apache.org Received: (qmail 93726 invoked by uid 99); 9 Jan 2009 03:29:42 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Jan 2009 19:29:42 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED,FB_WORD1_END_DOLLAR X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 09 Jan 2009 03:29:38 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id D1E3C2388B47; Thu, 8 Jan 2009 19:28:52 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r732916 [6/14] - in /lucene/pylucene/trunk: ./ java/ java/org/ java/org/osafoundation/ java/org/osafoundation/lucene/ java/org/osafoundation/lucene/analysis/ java/org/osafoundation/lucene/queryParser/ java/org/osafoundation/lucene/search/ j... Date: Fri, 09 Jan 2009 03:28:41 -0000 To: commits@lucene.apache.org From: vajda@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090109032852.D1E3C2388B47@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: lucene/pylucene/trunk/jcc/jcc/sources/JArray.h URL: http://svn.apache.org/viewvc/lucene/pylucene/trunk/jcc/jcc/sources/JArray.h?rev=732916&view=auto ============================================================================== --- lucene/pylucene/trunk/jcc/jcc/sources/JArray.h (added) +++ lucene/pylucene/trunk/jcc/jcc/sources/JArray.h Thu Jan 8 19:28:33 2009 @@ -0,0 +1,1593 @@ +/* + * Copyright (c) 2007-2008 Open Source Applications Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _JArray_H +#define _JArray_H + +#ifdef PYTHON +#include +#include "macros.h" + +extern jobjectArray fromPySequence(jclass cls, PyObject *sequence); +extern PyObject *PyErr_SetJavaError(jthrowable throwable); + +extern PyTypeObject *JArrayObjectType; +extern PyTypeObject *JArrayStringType; +extern PyTypeObject *JArrayBoolType; +extern PyTypeObject *JArrayByteType; +extern PyTypeObject *JArrayCharType; +extern PyTypeObject *JArrayDoubleType; +extern PyTypeObject *JArrayFloatType; +extern PyTypeObject *JArrayIntType; +extern PyTypeObject *JArrayLongType; +extern PyTypeObject *JArrayShortType; + +#endif + +#include "JCCEnv.h" +#include "java/lang/Object.h" + + +template class JArray : public java::lang::Object { +public: + int length; + + explicit JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jobjectArray) this$) : 0; + } + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(fromPySequence(T::initializeClass(), sequence)) { + length = this$ ? env->getArrayLength((jobjectArray) this$) : 0; + } + + JArray(jclass cls, PyObject *sequence) : java::lang::Object(fromPySequence(cls, sequence)) { + length = this$ ? env->getArrayLength((jobjectArray) this$) : 0; + } + + PyObject *toSequence(PyObject *(*wrapfn)(const T&)) + { + if (this$ == NULL) + Py_RETURN_NONE; + + PyObject *list = PyList_New(length); + + for (int i = 0; i < length; i++) + PyList_SET_ITEM(list, i, (*wrapfn)((*this)[i])); + + return list; + } + + PyObject *get(int n, PyObject *(*wrapfn)(const T&)) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + return (*wrapfn)((*this)[n]); + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } +#endif + + T operator[](int n) { + return T(env->getObjectArrayElement((jobjectArray) this$, n)); + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + JArray(jclass cls, int n) : java::lang::Object(env->get_vm_env()->NewObjectArray(n, cls, NULL)) { + length = env->getArrayLength((jobjectArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jobjectArray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + +#ifdef PYTHON + JArray(jclass cls, PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewObjectArray(PySequence_Length(sequence), cls, NULL)) { + length = env->getArrayLength((jobjectArray) this$); + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (obj == NULL) + break; + + if (!PyObject_TypeCheck(obj, &JObjectType)) + { + PyErr_SetObject(PyExc_TypeError, obj); + break; + } + + jobject jobj = ((t_JObject *) obj)->object.this$; + + Py_DECREF(obj); + try { + env->setObjectArrayElement((jobjectArray) this$, i, jobj); + } catch (JCCEnv::exception e) { + PyErr_SetJavaError(e.throwable); + } + } + } + + PyObject *toSequence(PyObject *(*wrapfn)(const jobject&)) + { + return toSequence(0, length, wrapfn); + } + + PyObject *toSequence(int lo, int hi, PyObject *(*wrapfn)(const jobject&)) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + + if (!wrapfn) + wrapfn = java::lang::t_Object::wrap_jobject; + + for (int i = lo; i < hi; i++) { + jobject jobj = env->getObjectArrayElement((jobjectArray) this$, i); + PyObject *obj = (*wrapfn)(jobj); + + PyList_SET_ITEM(list, i - lo, obj); + } + + return list; + } + + PyObject *get(int n, PyObject *(*wrapfn)(const jobject&)) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!wrapfn) + wrapfn = java::lang::t_Object::wrap_jobject; + + jobject jobj = + env->getObjectArrayElement((jobjectArray) this$, n); + + return (*wrapfn)(jobj); + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyObject_TypeCheck(obj, &JObjectType)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + + jobject jobj = ((t_JObject *) obj)->object.this$; + + try { + env->setObjectArrayElement((jobjectArray) this$, n, jobj); + } catch (JCCEnv::exception e) { + PyErr_SetJavaError(e.throwable); + return -1; + } + + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(PyObject *(*wrapfn)(const jobject&)); +#endif + + jobject operator[](int n) { + return (jobject) env->getObjectArrayElement((jobjectArray) this$, n); + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jobjectArray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewObjectArray(n, env->findClass("java/lang/String"), NULL)) { + length = env->getArrayLength((jobjectArray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewObjectArray(PySequence_Length(sequence), env->findClass("java/lang/String"), NULL)) { + length = env->getArrayLength((jobjectArray) this$); + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (obj == NULL) + break; + + jstring str = env->fromPyString(obj); + + Py_DECREF(obj); + if (PyErr_Occurred()) + break; + + env->setObjectArrayElement((jobjectArray) this$, i, str); + env->get_vm_env()->DeleteLocalRef(str); + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + + for (int i = lo; i < hi; i++) { + jstring value = (jstring) + env->getObjectArrayElement((jobjectArray) this$, i); + PyObject *obj = env->fromJString(value); + + PyList_SET_ITEM(list, i - lo, obj); + } + + return list; + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + jstring str = (jstring) + env->getObjectArrayElement((jobjectArray) this$, n); + + return env->fromJString(str); + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + jstring str = env->fromPyString(obj); + + if (PyErr_Occurred()) + return -1; + + env->setObjectArrayElement((jobjectArray) this$, n, str); + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jstring operator[](int n) { + return (jstring) env->getObjectArrayElement((jobjectArray) this$, n); + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jbooleanArray array; + jboolean *elts; + public: + arrayElements(jbooleanArray array) { + this->array = array; + elts = env->get_vm_env()->GetBooleanArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseBooleanArrayElements(array, elts, isCopy); + } + operator jboolean *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jbooleanArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewBooleanArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewBooleanArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jboolean *buf = (jboolean *) elts; + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (obj == Py_True || obj == Py_False) + { + buf[i] = (jboolean) (obj == Py_True); + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + arrayElements elts = elements(); + jboolean *buf = (jboolean *) elts; + + for (int i = lo; i < hi; i++) { + jboolean value = buf[i]; + PyObject *obj = value ? Py_True : Py_False; + + Py_INCREF(obj); + PyList_SET_ITEM(list, i - lo, obj); + } + + return list; + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + Py_RETURN_BOOL(elements()[n]); + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + elements()[n] = (jboolean) PyObject_IsTrue(obj); + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jboolean operator[](int n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jboolean *elts = (jboolean *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jboolean value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jbyteArray array; + jbyte *elts; + public: + arrayElements(jbyteArray array) { + this->array = array; + elts = env->get_vm_env()->GetByteArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseByteArrayElements(array, elts, isCopy); + } + operator jbyte *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jbyteArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewByteArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewByteArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jbyte *buf = (jbyte *) elts; + + if (PyString_Check(sequence)) + memcpy(buf, PyString_AS_STRING(sequence), length); + else + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (PyString_Check(obj) && (PyString_GET_SIZE(obj) == 1)) + { + buf[i] = (jbyte) PyString_AS_STRING(obj)[0]; + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + char getType() + { + return 'Z'; + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + arrayElements elts = elements(); + jbyte *buf = (jbyte *) elts; + + return PyString_FromStringAndSize((char *) buf + lo, hi - lo); + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + jbyte b = (*this)[n]; + return PyString_FromStringAndSize((char *) &b, 1); + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyString_Check(obj)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + if (PyString_GET_SIZE(obj) != 1) + { + PyErr_SetObject(PyExc_ValueError, obj); + return -1; + } + + elements()[n] = (jbyte) PyString_AS_STRING(obj)[0]; + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jbyte operator[](int n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jbyte *elts = (jbyte *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jbyte value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jcharArray array; + jchar *elts; + public: + arrayElements(jcharArray array) { + this->array = array; + elts = env->get_vm_env()->GetCharArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseCharArrayElements(array, elts, isCopy); + } + operator jchar *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jcharArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewCharArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewCharArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jchar *buf = (jchar *) elts; + + if (PyUnicode_Check(sequence)) + { + if (sizeof(Py_UNICODE) == sizeof(jchar)) + memcpy(buf, PyUnicode_AS_UNICODE(sequence), + length * sizeof(jchar)); + else + { + Py_UNICODE *pchars = PyUnicode_AS_UNICODE(sequence); + for (int i = 0; i < length; i++) + buf[i] = (jchar) pchars[i]; + } + } + else + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (PyUnicode_Check(obj) && (PyUnicode_GET_SIZE(obj) == 1)) + { + buf[i] = (jchar) PyUnicode_AS_UNICODE(obj)[0]; + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + arrayElements elts = elements(); + jchar *buf = (jchar *) elts; + + if (sizeof(Py_UNICODE) == sizeof(jchar)) + return PyUnicode_FromUnicode((const Py_UNICODE *) buf + lo, + hi - lo); + else + { + PyObject *string = PyUnicode_FromUnicode(NULL, hi - lo); + Py_UNICODE *pchars = PyUnicode_AS_UNICODE(string); + + for (int i = lo; i < hi; i++) + pchars[i - lo] = (Py_UNICODE) buf[i]; + + return string; + } + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + jchar c = (*this)[n]; + + if (sizeof(Py_UNICODE) == sizeof(jchar)) + return PyUnicode_FromUnicode((const Py_UNICODE *) &c, 1); + else + { + PyObject *string = PyUnicode_FromUnicode(NULL, 1); + Py_UNICODE *pchars = PyUnicode_AS_UNICODE(string); + + pchars[0] = (Py_UNICODE) c; + + return string; + } + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyUnicode_Check(obj)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + if (PyUnicode_GET_SIZE(obj) != 1) + { + PyErr_SetObject(PyExc_ValueError, obj); + return -1; + } + + elements()[n] = (jchar) PyUnicode_AS_UNICODE(obj)[0]; + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jchar operator[](int n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jchar *elts = (jchar *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jchar value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jdoubleArray array; + jdouble *elts; + public: + arrayElements(jdoubleArray array) { + this->array = array; + elts = env->get_vm_env()->GetDoubleArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseDoubleArrayElements(array, elts, isCopy); + } + operator jdouble *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jdoubleArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewDoubleArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewDoubleArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jdouble *buf = (jdouble *) elts; + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (PyFloat_Check(obj)) + { + buf[i] = (jdouble) PyFloat_AS_DOUBLE(obj); + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + arrayElements elts = elements(); + jdouble *buf = (jdouble *) elts; + + for (int i = lo; i < hi; i++) + PyList_SET_ITEM(list, i - lo, PyFloat_FromDouble((double) buf[i])); + + return list; + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + return PyFloat_FromDouble((double) (*this)[n]); + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyFloat_Check(obj)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + + elements()[n] = (jdouble) PyFloat_AS_DOUBLE(obj); + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jdouble operator[](int n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jdouble *elts = (jdouble *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jdouble value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jfloatArray array; + jfloat *elts; + public: + arrayElements(jfloatArray array) { + this->array = array; + elts = env->get_vm_env()->GetFloatArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseFloatArrayElements(array, elts, isCopy); + } + operator jfloat *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jfloatArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewFloatArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewFloatArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jfloat *buf = (jfloat *) elts; + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (PyFloat_Check(obj)) + { + buf[i] = (jfloat) PyFloat_AS_DOUBLE(obj); + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + arrayElements elts = elements(); + jfloat *buf = (jfloat *) elts; + + for (int i = lo; i < hi; i++) + PyList_SET_ITEM(list, i - lo, PyFloat_FromDouble((double) buf[i])); + + return list; + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + return PyFloat_FromDouble((double) (*this)[n]); + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyFloat_Check(obj)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + + elements()[n] = (jfloat) PyFloat_AS_DOUBLE(obj); + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jfloat operator[](int n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jfloat *elts = (jfloat *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jfloat value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jintArray array; + jint *elts; + public: + arrayElements(jintArray array) { + this->array = array; + elts = env->get_vm_env()->GetIntArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseIntArrayElements(array, elts, isCopy); + } + operator jint *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jintArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewIntArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewIntArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jint *buf = (jint *) elts; + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (PyInt_Check(obj)) + { + buf[i] = (jint) PyInt_AS_LONG(obj); + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + arrayElements elts = elements(); + jint *buf = (jint *) elts; + + for (int i = lo; i < hi; i++) + PyList_SET_ITEM(list, i - lo, PyInt_FromLong(buf[i])); + + return list; + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + return PyInt_FromLong((*this)[n]); + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyInt_Check(obj)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + + elements()[n] = (jint) PyInt_AS_LONG(obj); + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jint operator[](int n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jint *elts = (jint *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jint value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jlongArray array; + jlong *elts; + public: + arrayElements(jlongArray array) { + this->array = array; + elts = env->get_vm_env()->GetLongArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseLongArrayElements(array, elts, isCopy); + } + operator jlong *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jlongArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewLongArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewLongArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jlong *buf = (jlong *) elts; + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (PyLong_Check(obj)) + { + buf[i] = (jlong) PyLong_AsLongLong(obj); + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + arrayElements elts = elements(); + jlong *buf = (jlong *) elts; + + for (int i = lo; i < hi; i++) + PyList_SET_ITEM(list, i - lo, PyLong_FromLongLong((long long) buf[i])); + + return list; + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + return PyLong_FromLongLong((long long) (*this)[n]); + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyLong_Check(obj)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + + elements()[n] = (jlong) PyLong_AsLongLong(obj); + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jlong operator[](long n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jlong *elts = (jlong *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jlong value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +template<> class JArray : public java::lang::Object { + public: + int length; + + class arrayElements { + private: + jboolean isCopy; + jshortArray array; + jshort *elts; + public: + arrayElements(jshortArray array) { + this->array = array; + elts = env->get_vm_env()->GetShortArrayElements(array, &isCopy); + } + virtual ~arrayElements() { + env->get_vm_env()->ReleaseShortArrayElements(array, elts, isCopy); + } + operator jshort *() { + return elts; + } + }; + + arrayElements elements() { + return arrayElements((jshortArray) this$); + } + + JArray(jobject obj) : java::lang::Object(obj) { + length = this$ ? env->getArrayLength((jarray) this$) : 0; + } + + JArray(const JArray& obj) : java::lang::Object(obj) { + length = obj.length; + } + + JArray(int n) : java::lang::Object(env->get_vm_env()->NewShortArray(n)) { + length = env->getArrayLength((jarray) this$); + } + +#ifdef PYTHON + JArray(PyObject *sequence) : java::lang::Object(env->get_vm_env()->NewShortArray(PySequence_Length(sequence))) { + length = env->getArrayLength((jarray) this$); + arrayElements elts = elements(); + jshort *buf = (jshort *) elts; + + for (int i = 0; i < length; i++) { + PyObject *obj = PySequence_GetItem(sequence, i); + + if (!obj) + break; + + if (PyInt_Check(obj)) + { + buf[i] = (jshort) PyInt_AS_LONG(obj); + Py_DECREF(obj); + } + else + { + PyErr_SetObject(PyExc_TypeError, obj); + Py_DECREF(obj); + break; + } + } + } + + PyObject *toSequence() + { + return toSequence(0, length); + } + + PyObject *toSequence(int lo, int hi) + { + if (this$ == NULL) + Py_RETURN_NONE; + + if (lo < 0) lo = length + lo; + if (lo < 0) lo = 0; + else if (lo > length) lo = length; + if (hi < 0) hi = length + hi; + if (hi < 0) hi = 0; + else if (hi > length) hi = length; + if (lo > hi) lo = hi; + + PyObject *list = PyList_New(hi - lo); + arrayElements elts = elements(); + jshort *buf = (jshort *) elts; + + for (int i = lo; i < hi; i++) + PyList_SET_ITEM(list, i - lo, PyInt_FromLong(buf[i])); + + return list; + } + + PyObject *get(int n) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + return PyInt_FromLong((long) (*this)[n]); + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + int set(int n, PyObject *obj) + { + if (this$ != NULL) + { + if (n < 0) + n = length + n; + + if (n >= 0 && n < length) + { + if (!PyInt_Check(obj)) + { + PyErr_SetObject(PyExc_TypeError, obj); + return -1; + } + + elements()[n] = (jshort) PyInt_AS_LONG(obj); + return 0; + } + } + + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + PyObject *wrap(); +#endif + + jshort operator[](int n) { + JNIEnv *vm_env = env->get_vm_env(); + jboolean isCopy = 0; + jshort *elts = (jshort *) + vm_env->GetPrimitiveArrayCritical((jarray) this$, &isCopy); + jshort value = elts[n]; + + vm_env->ReleasePrimitiveArrayCritical((jarray) this$, elts, isCopy); + + return value; + } +}; + +#ifdef PYTHON + +template class t_jarray { +public: + PyObject_HEAD + JArray array; +}; + +#endif + +#endif /* _JArray_H */ Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JArray.h ------------------------------------------------------------------------------ svn:eol-style = native Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JArray.h ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.cpp URL: http://svn.apache.org/viewvc/lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.cpp?rev=732916&view=auto ============================================================================== --- lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.cpp (added) +++ lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.cpp Thu Jan 8 19:28:33 2009 @@ -0,0 +1,680 @@ +/* + * Copyright (c) 2007-2008 Open Source Applications Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "JCCEnv.h" + +extern JCCEnv *env; + +#if defined(_MSC_VER) || defined(__WIN32) +_DLL_EXPORT DWORD VM_ENV = 0; +#else +pthread_key_t JCCEnv::VM_ENV = (pthread_key_t) NULL; +#endif + +#if defined(_MSC_VER) || defined(__WIN32) + +static CRITICAL_SECTION *mutex = NULL; + +class lock { +public: + lock() { + EnterCriticalSection(mutex); + } + virtual ~lock() { + LeaveCriticalSection(mutex); + } +}; + +#else + +static pthread_mutex_t *mutex = NULL; + +class lock { +public: + lock() { + pthread_mutex_lock(mutex); + } + virtual ~lock() { + pthread_mutex_unlock(mutex); + } +}; + +#endif + +JCCEnv::JCCEnv(JavaVM *vm, JNIEnv *vm_env) +{ +#if defined(_MSC_VER) || defined(__WIN32) + if (!mutex) + { + mutex = new CRITICAL_SECTION(); + InitializeCriticalSection(mutex); + } +#else + if (!mutex) + { + mutex = new pthread_mutex_t(); + pthread_mutex_init(mutex, NULL); + } +#endif + + this->vm = vm; + set_vm_env(vm_env); + env = this; + + _sys = (jclass) vm_env->NewGlobalRef(vm_env->FindClass("java/lang/System")); + _obj = (jclass) vm_env->NewGlobalRef(vm_env->FindClass("java/lang/Object")); +#ifdef _jcc_lib + _thr = (jclass) vm_env->NewGlobalRef(vm_env->FindClass("org/osafoundation/jcc/PythonException")); +#else + _thr = (jclass) vm_env->NewGlobalRef(vm_env->FindClass("java/lang/RuntimeException")); +#endif + _mids = new jmethodID[max_mid]; + + _mids[mid_sys_identityHashCode] = + vm_env->GetStaticMethodID(_sys, "identityHashCode", + "(Ljava/lang/Object;)I"); + _mids[mid_sys_setProperty] = + vm_env->GetStaticMethodID(_sys, "setProperty", + "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); + _mids[mid_obj_toString] = + vm_env->GetMethodID(_obj, "toString", + "()Ljava/lang/String;"); + _mids[mid_obj_hashCode] = + vm_env->GetMethodID(_obj, "hashCode", + "()I"); + _mids[mid_obj_getClass] = + vm_env->GetMethodID(_obj, "getClass", + "()Ljava/lang/Class;"); +} + +#if defined(_MSC_VER) || defined(__WIN32) + +void JCCEnv::set_vm_env(JNIEnv *vm_env) +{ + if (!VM_ENV) + VM_ENV = TlsAlloc(); + TlsSetValue(VM_ENV, (LPVOID) vm_env); +} + +#else + +void JCCEnv::set_vm_env(JNIEnv *vm_env) +{ + if (!VM_ENV) + pthread_key_create(&VM_ENV, NULL); + pthread_setspecific(VM_ENV, (void *) vm_env); +} + +#endif + +jclass JCCEnv::findClass(const char *className) +{ + jclass cls = NULL; + + if (env) + cls = get_vm_env()->FindClass(className); + + reportException(); + + return cls; +} + +void JCCEnv::registerNatives(jclass cls, JNINativeMethod *methods, int n) +{ + get_vm_env()->RegisterNatives(cls, methods, n); +} + +jobject JCCEnv::newGlobalRef(jobject obj, int id) +{ + if (obj) + { + if (id) /* zero when weak global ref is desired */ + { + lock locked; + + for (std::multimap::iterator iter = refs.find(id); + iter != refs.end(); + iter++) { + if (iter->first != id) + break; + if (isSame(obj, iter->second.global)) + { + /* If it's in the table but not the same reference, + * it must be a local reference and must be deleted. + */ + if (obj != iter->second.global) + get_vm_env()->DeleteLocalRef(obj); + + iter->second.count += 1; + return iter->second.global; + } + } + + JNIEnv *vm_env = get_vm_env(); + countedRef ref; + + ref.global = vm_env->NewGlobalRef(obj); + ref.count = 1; + refs.insert(std::pair(id, ref)); + vm_env->DeleteLocalRef(obj); + + return ref.global; + } + else + return (jobject) get_vm_env()->NewWeakGlobalRef(obj); + } + + return NULL; +} + +jobject JCCEnv::deleteGlobalRef(jobject obj, int id) +{ + if (obj) + { + if (id) /* zero when obj is weak global ref */ + { + lock locked; + + for (std::multimap::iterator iter = refs.find(id); + iter != refs.end(); + iter++) { + if (iter->first != id) + break; + if (isSame(obj, iter->second.global)) + { + if (iter->second.count == 1) + { + get_vm_env()->DeleteGlobalRef(iter->second.global); + refs.erase(iter); + } + else + iter->second.count -= 1; + + return NULL; + } + } + + printf("deleting non-existent ref: 0x%x\n", id); + } + else + get_vm_env()->DeleteWeakGlobalRef((jweak) obj); + } + + return NULL; +} + +jobject JCCEnv::newObject(jclass (*initializeClass)(), jmethodID **mids, + int m, ...) +{ + jclass cls; + jobject obj; + va_list ap; + + va_start(ap, m); + cls = (*initializeClass)(); + obj = get_vm_env()->NewObjectV(cls, (*mids)[m], ap); + va_end(ap); + + reportException(); + + return obj; +} + +jobjectArray JCCEnv::newObjectArray(jclass cls, int size) +{ + jobjectArray array = get_vm_env()->NewObjectArray(size, cls, NULL); + + reportException(); + return array; +} + +void JCCEnv::setObjectArrayElement(jobjectArray array, int n, jobject obj) +{ + get_vm_env()->SetObjectArrayElement(array, n, obj); + reportException(); +} + +jobject JCCEnv::getObjectArrayElement(jobjectArray array, int n) +{ + jobject obj = get_vm_env()->GetObjectArrayElement(array, n); + + reportException(); + return obj; +} + +int JCCEnv::getArrayLength(jarray array) +{ + int len = get_vm_env()->GetArrayLength(array); + + reportException(); + return len; +} + +jclass JCCEnv::getPythonExceptionClass() +{ + return _thr; +} + +void JCCEnv::reportException() +{ + JNIEnv *vm_env = get_vm_env(); + jthrowable throwable = vm_env->ExceptionOccurred(); + + if (throwable) + { + //vm_env->ExceptionDescribe(); + vm_env->ExceptionClear(); + +#ifdef PYTHON +#ifndef _jcc_lib + PythonGIL gil; + + if (PyErr_Occurred()) + { +#endif + /* _thr is PythonException ifdef _jcc_lib (shared mode) + * if not shared mode, _thr is RuntimeException + */ + jobject cls = (jobject) vm_env->GetObjectClass(throwable); + + if (vm_env->IsSameObject(cls, _thr)) + throw pythonError(throwable); +#ifndef _jcc_lib + } +#endif +#endif + + throw exception(throwable); + } +} + + +#define DEFINE_CALL(jtype, Type) \ + jtype JCCEnv::call##Type##Method(jobject obj, \ + jmethodID mid, ...) \ + { \ + va_list ap; \ + jtype result; \ + \ + va_start(ap, mid); \ + result = get_vm_env()->Call##Type##MethodV(obj, mid, ap); \ + va_end(ap); \ + \ + reportException(); \ + \ + return result; \ + } + +#define DEFINE_NONVIRTUAL_CALL(jtype, Type) \ + jtype JCCEnv::callNonvirtual##Type##Method(jobject obj, jclass cls, \ + jmethodID mid, ...) \ + { \ + va_list ap; \ + jtype result; \ + \ + va_start(ap, mid); \ + result = get_vm_env()->CallNonvirtual##Type##MethodV(obj, cls, \ + mid, ap); \ + va_end(ap); \ + \ + reportException(); \ + \ + return result; \ + } + +#define DEFINE_STATIC_CALL(jtype, Type) \ + jtype JCCEnv::callStatic##Type##Method(jclass cls, \ + jmethodID mid, ...) \ + { \ + va_list ap; \ + jtype result; \ + \ + va_start(ap, mid); \ + result = get_vm_env()->CallStatic##Type##MethodV(cls, mid, ap); \ + va_end(ap); \ + \ + reportException(); \ + \ + return result; \ + } + +DEFINE_CALL(jobject, Object) +DEFINE_CALL(jboolean, Boolean) +DEFINE_CALL(jbyte, Byte) +DEFINE_CALL(jchar, Char) +DEFINE_CALL(jdouble, Double) +DEFINE_CALL(jfloat, Float) +DEFINE_CALL(jint, Int) +DEFINE_CALL(jlong, Long) +DEFINE_CALL(jshort, Short) + +DEFINE_NONVIRTUAL_CALL(jobject, Object) +DEFINE_NONVIRTUAL_CALL(jboolean, Boolean) +DEFINE_NONVIRTUAL_CALL(jbyte, Byte) +DEFINE_NONVIRTUAL_CALL(jchar, Char) +DEFINE_NONVIRTUAL_CALL(jdouble, Double) +DEFINE_NONVIRTUAL_CALL(jfloat, Float) +DEFINE_NONVIRTUAL_CALL(jint, Int) +DEFINE_NONVIRTUAL_CALL(jlong, Long) +DEFINE_NONVIRTUAL_CALL(jshort, Short) + +DEFINE_STATIC_CALL(jobject, Object) +DEFINE_STATIC_CALL(jboolean, Boolean) +DEFINE_STATIC_CALL(jbyte, Byte) +DEFINE_STATIC_CALL(jchar, Char) +DEFINE_STATIC_CALL(jdouble, Double) +DEFINE_STATIC_CALL(jfloat, Float) +DEFINE_STATIC_CALL(jint, Int) +DEFINE_STATIC_CALL(jlong, Long) +DEFINE_STATIC_CALL(jshort, Short) + +void JCCEnv::callVoidMethod(jobject obj, jmethodID mid, ...) +{ + va_list ap; + + va_start(ap, mid); + get_vm_env()->CallVoidMethodV(obj, mid, ap); + va_end(ap); + + reportException(); +} + +void JCCEnv::callNonvirtualVoidMethod(jobject obj, jclass cls, + jmethodID mid, ...) +{ + va_list ap; + + va_start(ap, mid); + get_vm_env()->CallNonvirtualVoidMethodV(obj, cls, mid, ap); + va_end(ap); + + reportException(); +} + +void JCCEnv::callStaticVoidMethod(jclass cls, jmethodID mid, ...) +{ + va_list ap; + + va_start(ap, mid); + get_vm_env()->CallStaticVoidMethodV(cls, mid, ap); + va_end(ap); + + reportException(); +} + + +jmethodID JCCEnv::getMethodID(jclass cls, const char *name, + const char *signature) +{ + jmethodID id = get_vm_env()->GetMethodID(cls, name, signature); + + reportException(); + + return id; +} + +jfieldID JCCEnv::getFieldID(jclass cls, const char *name, + const char *signature) +{ + jfieldID id = get_vm_env()->GetFieldID(cls, name, signature); + + reportException(); + + return id; +} + + +jmethodID JCCEnv::getStaticMethodID(jclass cls, const char *name, + const char *signature) +{ + jmethodID id = get_vm_env()->GetStaticMethodID(cls, name, signature); + + reportException(); + + return id; +} + +jobject JCCEnv::getStaticObjectField(jclass cls, const char *name, + const char *signature) +{ + JNIEnv *vm_env = get_vm_env(); + jfieldID id = vm_env->GetStaticFieldID(cls, name, signature); + + reportException(); + + return vm_env->GetStaticObjectField(cls, id); +} + +#define DEFINE_GET_STATIC_FIELD(jtype, Type, signature) \ + jtype JCCEnv::getStatic##Type##Field(jclass cls, const char *name) \ + { \ + JNIEnv *vm_env = get_vm_env(); \ + jfieldID id = vm_env->GetStaticFieldID(cls, name, #signature); \ + reportException(); \ + return vm_env->GetStatic##Type##Field(cls, id); \ + } + +DEFINE_GET_STATIC_FIELD(jboolean, Boolean, Z) +DEFINE_GET_STATIC_FIELD(jbyte, Byte, B) +DEFINE_GET_STATIC_FIELD(jchar, Char, C) +DEFINE_GET_STATIC_FIELD(jdouble, Double, D) +DEFINE_GET_STATIC_FIELD(jfloat, Float, F) +DEFINE_GET_STATIC_FIELD(jint, Int, I) +DEFINE_GET_STATIC_FIELD(jlong, Long, J) +DEFINE_GET_STATIC_FIELD(jshort, Short, S) + +#define DEFINE_GET_FIELD(jtype, Type) \ + jtype JCCEnv::get##Type##Field(jobject obj, jfieldID id) \ + { \ + jtype value = get_vm_env()->Get##Type##Field(obj, id); \ + reportException(); \ + return value; \ + } + +DEFINE_GET_FIELD(jobject, Object) +DEFINE_GET_FIELD(jboolean, Boolean) +DEFINE_GET_FIELD(jbyte, Byte) +DEFINE_GET_FIELD(jchar, Char) +DEFINE_GET_FIELD(jdouble, Double) +DEFINE_GET_FIELD(jfloat, Float) +DEFINE_GET_FIELD(jint, Int) +DEFINE_GET_FIELD(jlong, Long) +DEFINE_GET_FIELD(jshort, Short) + +#define DEFINE_SET_FIELD(jtype, Type) \ + void JCCEnv::set##Type##Field(jobject obj, jfieldID id, jtype value) \ + { \ + get_vm_env()->Set##Type##Field(obj, id, value); \ + reportException(); \ + } + +DEFINE_SET_FIELD(jobject, Object) +DEFINE_SET_FIELD(jboolean, Boolean) +DEFINE_SET_FIELD(jbyte, Byte) +DEFINE_SET_FIELD(jchar, Char) +DEFINE_SET_FIELD(jdouble, Double) +DEFINE_SET_FIELD(jfloat, Float) +DEFINE_SET_FIELD(jint, Int) +DEFINE_SET_FIELD(jlong, Long) +DEFINE_SET_FIELD(jshort, Short) + +void JCCEnv::setClassPath(const char *classPath) +{ + JNIEnv *vm_env = get_vm_env(); + jclass _ucl = (jclass) vm_env->FindClass("java/net/URLClassLoader"); + jclass _fil = (jclass) vm_env->FindClass("java/io/File"); + jmethodID mid = vm_env->GetStaticMethodID(_ucl, "getSystemClassLoader", + "()Ljava/lang/ClassLoader;"); + jobject classLoader = vm_env->CallStaticObjectMethod(_ucl, mid); + jmethodID mf = vm_env->GetMethodID(_fil, "", "(Ljava/lang/String;)V"); + jmethodID mu = vm_env->GetMethodID(_fil, "toURL", "()Ljava/net/URL;"); + jmethodID ma = vm_env->GetMethodID(_ucl, "addURL", "(Ljava/net/URL;)V"); +#ifdef WINDOWS + char *pathsep = ";"; +#else + char *pathsep = ":"; +#endif + char *path = strdup(classPath); + + for (char *cp = strtok(path, pathsep); + cp != NULL; + cp = strtok(NULL, pathsep)) { + jstring string = vm_env->NewStringUTF(cp); + jobject file = vm_env->NewObject(_fil, mf, string); + jobject url = vm_env->CallObjectMethod(file, mu); + + vm_env->CallVoidMethod(classLoader, ma, url); + } + free(path); +} + +jstring JCCEnv::fromUTF(const char *bytes) +{ + jstring str = get_vm_env()->NewStringUTF(bytes); + + reportException(); + + return str; +} + +char *JCCEnv::toUTF(jstring str) +{ + JNIEnv *vm_env = get_vm_env(); + int len = vm_env->GetStringUTFLength(str); + char *bytes = new char[len + 1]; + jboolean isCopy = 0; + const char *utf = vm_env->GetStringUTFChars(str, &isCopy); + + if (!bytes) + return NULL; + + memcpy(bytes, utf, len); + bytes[len] = '\0'; + + vm_env->ReleaseStringUTFChars(str, utf); + + return bytes; +} + +char *JCCEnv::toString(jobject obj) +{ + return obj + ? toUTF((jstring) callObjectMethod(obj, _mids[mid_obj_toString])) + : NULL; +} + +char *JCCEnv::getClassName(jobject obj) +{ + return obj + ? toString(callObjectMethod(obj, _mids[mid_obj_getClass])) + : NULL; +} + +#ifdef PYTHON + +jstring JCCEnv::fromPyString(PyObject *object) +{ + if (object == Py_None) + return NULL; + else if (PyUnicode_Check(object)) + { + if (sizeof(Py_UNICODE) == sizeof(jchar)) + { + jchar *buf = (jchar *) PyUnicode_AS_UNICODE(object); + jsize len = (jsize) PyUnicode_GET_SIZE(object); + + return get_vm_env()->NewString(buf, len); + } + else + { + jsize len = PyUnicode_GET_SIZE(object); + Py_UNICODE *pchars = PyUnicode_AS_UNICODE(object); + jchar *jchars = new jchar[len]; + jstring str; + + for (int i = 0; i < len; i++) + jchars[i] = (jchar) pchars[i]; + + str = get_vm_env()->NewString(jchars, len); + delete jchars; + + return str; + } + } + else if (PyString_Check(object)) + return fromUTF(PyString_AS_STRING(object)); + else + { + PyObject *tuple = Py_BuildValue("(sO)", "expected a string", object); + + PyErr_SetObject(PyExc_TypeError, tuple); + Py_DECREF(tuple); + + return NULL; + } +} + +PyObject *JCCEnv::fromJString(jstring js) +{ + if (!js) + Py_RETURN_NONE; + + JNIEnv *vm_env = get_vm_env(); + + if (sizeof(Py_UNICODE) == sizeof(jchar)) + { + jboolean isCopy; + const jchar *buf = vm_env->GetStringChars(js, &isCopy); + jsize len = vm_env->GetStringLength(js); + PyObject *string = PyUnicode_FromUnicode((const Py_UNICODE *) buf, len); + + vm_env->ReleaseStringChars(js, buf); + return string; + } + else + { + jsize len = vm_env->GetStringLength(js); + PyObject *string = PyUnicode_FromUnicode(NULL, len); + + if (!string) + return NULL; + + jboolean isCopy; + const jchar *jchars = vm_env->GetStringChars(js, &isCopy); + Py_UNICODE *pchars = PyUnicode_AS_UNICODE(string); + + for (int i = 0; i < len; i++) + pchars[i] = (Py_UNICODE) jchars[i]; + + vm_env->ReleaseStringChars(js, jchars); + return string; + } +} + +/* may be called from finalizer thread which has no vm_env thread local */ +void JCCEnv::finalizeObject(JNIEnv *jenv, PyObject *obj) +{ + PythonGIL gil; + + set_vm_env(jenv); + Py_DECREF(obj); +} + +#endif /* PYTHON */ Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.cpp ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.h URL: http://svn.apache.org/viewvc/lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.h?rev=732916&view=auto ============================================================================== --- lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.h (added) +++ lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.h Thu Jan 8 19:28:33 2009 @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2007-2008 Open Source Applications Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _JCCEnv_H +#define _JCCEnv_H + +#include +#if defined(_MSC_VER) || defined(__WIN32) +#define _DLL_IMPORT __declspec(dllimport) +#define _DLL_EXPORT __declspec(dllexport) +#include +#undef MAX_PRIORITY +#undef MIN_PRIORITY +#else +#include +#define _DLL_IMPORT +#define _DLL_EXPORT +#endif + +#ifdef __SUNPRO_CC +#undef DEFAULT_TYPE +#endif + +#ifdef TRUE +#undef TRUE +#endif +#ifdef FALSE +#undef FALSE +#endif + +#include + +#ifdef PYTHON +#include +#endif + +#undef EOF + +class JCCEnv; + +#if defined(_MSC_VER) || defined(__WIN32) + +#ifdef _jcc_shared +_DLL_IMPORT extern JCCEnv *env; +_DLL_IMPORT extern DWORD VM_ENV; +#else +_DLL_EXPORT extern JCCEnv *env; +_DLL_EXPORT extern DWORD VM_ENV; +#endif + +#else + +extern JCCEnv *env; + +#endif + + +class countedRef { +public: + jobject global; + int count; +}; + +class _DLL_EXPORT JCCEnv { +protected: + jclass _sys, _obj, _thr; + jmethodID *_mids; + + enum { + mid_sys_identityHashCode, + mid_sys_setProperty, + mid_obj_toString, + mid_obj_hashCode, + mid_obj_getClass, + max_mid + }; + +public: + JavaVM *vm; + std::multimap refs; + + class exception { + public: + jthrowable throwable; + exception(jthrowable throwable) { + this->throwable = throwable; + } + }; + +#ifdef PYTHON + class pythonError { + public: + jthrowable throwable; + pythonError(jthrowable throwable) { + this->throwable = throwable; + } + }; +#endif + + explicit JCCEnv(JavaVM *vm, JNIEnv *env); + virtual ~JCCEnv() {}; + +#if defined(_MSC_VER) || defined(__WIN32) + inline JNIEnv *get_vm_env() + { + return (JNIEnv *) TlsGetValue(VM_ENV); + } +#else + static pthread_key_t VM_ENV; + + inline JNIEnv *get_vm_env() + { + return (JNIEnv *) pthread_getspecific(VM_ENV); + } +#endif + virtual void set_vm_env(JNIEnv *vm_env); + + virtual jclass findClass(const char *className); + virtual void registerNatives(jclass cls, JNINativeMethod *methods, int n); + virtual jobject newGlobalRef(jobject obj, int id); + virtual jobject deleteGlobalRef(jobject obj, int id); + + virtual jobject newObject(jclass (*initializeClass)(), jmethodID **mids, + int m, ...); + + virtual jobjectArray newObjectArray(jclass cls, int size); + virtual void setObjectArrayElement(jobjectArray a, int n, jobject obj); + virtual jobject getObjectArrayElement(jobjectArray a, int n); + virtual int getArrayLength(jarray a); + + virtual jclass getPythonExceptionClass(); + virtual void reportException(); + + virtual jobject callObjectMethod(jobject obj, jmethodID mid, ...); + virtual jboolean callBooleanMethod(jobject obj, jmethodID mid, ...); + virtual jbyte callByteMethod(jobject obj, jmethodID mid, ...); + virtual jchar callCharMethod(jobject obj, jmethodID mid, ...); + virtual jdouble callDoubleMethod(jobject obj, jmethodID mid, ...); + virtual jfloat callFloatMethod(jobject obj, jmethodID mid, ...); + virtual jint callIntMethod(jobject obj, jmethodID mid, ...); + virtual jlong callLongMethod(jobject obj, jmethodID mid, ...); + virtual jshort callShortMethod(jobject obj, jmethodID mid, ...); + virtual void callVoidMethod(jobject obj, jmethodID mid, ...); + + virtual jobject callNonvirtualObjectMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jboolean callNonvirtualBooleanMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jbyte callNonvirtualByteMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jchar callNonvirtualCharMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jdouble callNonvirtualDoubleMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jfloat callNonvirtualFloatMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jint callNonvirtualIntMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jlong callNonvirtualLongMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual jshort callNonvirtualShortMethod(jobject obj, jclass cls, jmethodID mid, ...); + virtual void callNonvirtualVoidMethod(jobject obj, jclass cls, jmethodID mid, ...); + + virtual jobject callStaticObjectMethod(jclass cls, jmethodID mid, ...); + virtual jboolean callStaticBooleanMethod(jclass cls, jmethodID mid, ...); + virtual jbyte callStaticByteMethod(jclass cls, jmethodID mid, ...); + virtual jchar callStaticCharMethod(jclass cls, jmethodID mid, ...); + virtual jdouble callStaticDoubleMethod(jclass cls, jmethodID mid, ...); + virtual jfloat callStaticFloatMethod(jclass cls, jmethodID mid, ...); + virtual jint callStaticIntMethod(jclass cls, jmethodID mid, ...); + virtual jlong callStaticLongMethod(jclass cls, jmethodID mid, ...); + virtual jshort callStaticShortMethod(jclass cls, jmethodID mid, ...); + virtual void callStaticVoidMethod(jclass cls, jmethodID mid, ...); + + virtual jmethodID getMethodID(jclass cls, const char *name, + const char *signature); + virtual jfieldID getFieldID(jclass cls, const char *name, + const char *signature); + virtual jmethodID getStaticMethodID(jclass cls, const char *name, + const char *signature); + + virtual jobject getStaticObjectField(jclass cls, const char *name, + const char *signature); + virtual jboolean getStaticBooleanField(jclass cls, const char *name); + virtual jbyte getStaticByteField(jclass cls, const char *name); + virtual jchar getStaticCharField(jclass cls, const char *name); + virtual jdouble getStaticDoubleField(jclass cls, const char *name); + virtual jfloat getStaticFloatField(jclass cls, const char *name); + virtual jint getStaticIntField(jclass cls, const char *name); + virtual jlong getStaticLongField(jclass cls, const char *name); + virtual jshort getStaticShortField(jclass cls, const char *name); + + virtual jobject getObjectField(jobject obj, jfieldID id); + virtual jboolean getBooleanField(jobject obj, jfieldID id); + virtual jbyte getByteField(jobject obj, jfieldID id); + virtual jchar getCharField(jobject obj, jfieldID id); + virtual jdouble getDoubleField(jobject obj, jfieldID id); + virtual jfloat getFloatField(jobject obj, jfieldID id); + virtual jint getIntField(jobject obj, jfieldID id); + virtual jlong getLongField(jobject obj, jfieldID id); + virtual jshort getShortField(jobject obj, jfieldID id); + + virtual void setObjectField(jobject obj, jfieldID id, jobject value); + virtual void setBooleanField(jobject obj, jfieldID id, jboolean value); + virtual void setByteField(jobject obj, jfieldID id, jbyte value); + virtual void setCharField(jobject obj, jfieldID id, jchar value); + virtual void setDoubleField(jobject obj, jfieldID id, jdouble value); + virtual void setFloatField(jobject obj, jfieldID id, jfloat value); + virtual void setIntField(jobject obj, jfieldID id, jint value); + virtual void setLongField(jobject obj, jfieldID id, jlong value); + virtual void setShortField(jobject obj, jfieldID id, jshort value); + + int id(jobject obj) { + return obj + ? get_vm_env()->CallStaticIntMethod(_sys, + _mids[mid_sys_identityHashCode], + obj) + : 0; + } + + int hash(jobject obj) { + return obj + ? get_vm_env()->CallIntMethod(obj, _mids[mid_obj_hashCode]) + : 0; + } + + virtual void setClassPath(const char *classPath); + virtual jstring fromUTF(const char *bytes); + virtual char *toUTF(jstring str); + virtual char *toString(jobject obj); + virtual char *getClassName(jobject obj); +#ifdef PYTHON + virtual jstring fromPyString(PyObject *object); + virtual PyObject *fromJString(jstring js); + virtual void finalizeObject(JNIEnv *jenv, PyObject *obj); +#endif + + virtual inline int isSame(jobject o1, jobject o2) + { + return o1 == o2 || get_vm_env()->IsSameObject(o1, o2); + } +}; + +#ifdef PYTHON + +class PythonGIL { + private: + PyGILState_STATE state; + public: + PythonGIL() + { + state = PyGILState_Ensure(); + } + PythonGIL(JNIEnv *vm_env) + { + state = PyGILState_Ensure(); + env->set_vm_env(vm_env); + } + ~PythonGIL() + { + PyGILState_Release(state); + } +}; + +class PythonThreadState { + private: + PyThreadState *state; + public: + PythonThreadState() + { + state = PyEval_SaveThread(); + } + ~PythonThreadState() + { + PyEval_RestoreThread(state); + } +}; + +#endif + +#endif /* _JCCEnv_H */ Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.h ------------------------------------------------------------------------------ svn:eol-style = native Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JCCEnv.h ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: lucene/pylucene/trunk/jcc/jcc/sources/JObject.cpp URL: http://svn.apache.org/viewvc/lucene/pylucene/trunk/jcc/jcc/sources/JObject.cpp?rev=732916&view=auto ============================================================================== --- lucene/pylucene/trunk/jcc/jcc/sources/JObject.cpp (added) +++ lucene/pylucene/trunk/jcc/jcc/sources/JObject.cpp Thu Jan 8 19:28:33 2009 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2007-2008 Open Source Applications Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "JCCEnv.h" + +#ifdef PYTHON + +#include +#include "structmember.h" + +#include "JObject.h" +#include "macros.h" + + +/* JObject */ + +static void t_JObject_dealloc(t_JObject *self); +static PyObject *t_JObject_new(PyTypeObject *type, + PyObject *args, PyObject *kwds); + +static PyObject *t_JObject_richcmp(t_JObject *, PyObject *o2, int op); +static PyObject *t_JObject_str(t_JObject *self); +static PyObject *t_JObject_repr(t_JObject *self); +static int t_JObject_hash(t_JObject *self); +static PyObject *t_JObject__getJObject(t_JObject *self, void *data); + +static PyMemberDef t_JObject_members[] = { + { NULL, 0, 0, 0, NULL } +}; + +static PyMethodDef t_JObject_methods[] = { + { NULL, NULL, 0, NULL } +}; + +static PyGetSetDef t_JObject_properties[] = { + { "_jobject", (getter) t_JObject__getJObject, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL } +}; + +PyTypeObject JObjectType = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "jcc.JObject", /* tp_name */ + sizeof(t_JObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)t_JObject_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc)t_JObject_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)t_JObject_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)t_JObject_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + (Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE), /* tp_flags */ + "t_JObject objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)t_JObject_richcmp, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + t_JObject_methods, /* tp_methods */ + t_JObject_members, /* tp_members */ + t_JObject_properties, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)t_JObject_new, /* tp_new */ +}; + + +static void t_JObject_dealloc(t_JObject *self) +{ + self->object = JObject(NULL); + self->ob_type->tp_free((PyObject *) self); +} + +static PyObject *t_JObject_new(PyTypeObject *type, + PyObject *args, PyObject *kwds) +{ + t_JObject *self = (t_JObject *) type->tp_alloc(type, 0); + + self->object = JObject(NULL); + + return (PyObject *) self; +} + +static PyObject *t_JObject_richcmp(t_JObject *self, PyObject *arg, int op) +{ + int b = 0; + + switch (op) { + case Py_EQ: + case Py_NE: + if (PyObject_TypeCheck(arg, &JObjectType)) + b = self->object == ((t_JObject *) arg)->object; + if (op == Py_EQ) + Py_RETURN_BOOL(b); + Py_RETURN_BOOL(!b); + case Py_LT: + PyErr_SetString(PyExc_NotImplementedError, "<"); + return NULL; + case Py_LE: + PyErr_SetString(PyExc_NotImplementedError, "<="); + return NULL; + case Py_GT: + PyErr_SetString(PyExc_NotImplementedError, ">"); + return NULL; + case Py_GE: + PyErr_SetString(PyExc_NotImplementedError, ">="); + return NULL; + } + + return NULL; +} + +static PyObject *t_JObject_str(t_JObject *self) +{ + if (self->object.this$) + { + char *utf = env->toString(self->object.this$); + PyObject *unicode = PyUnicode_DecodeUTF8(utf, strlen(utf), "strict"); + + delete utf; + return unicode; + } + + return PyString_FromString(""); +} + +static PyObject *t_JObject_repr(t_JObject *self) +{ + PyObject *name = PyObject_GetAttrString((PyObject *) self->ob_type, + "__name__"); + PyObject *str = self->ob_type->tp_str((PyObject *) self); +#if PY_VERSION_HEX < 0x02040000 + PyObject *args = Py_BuildValue("(OO)", name, str); +#else + PyObject *args = PyTuple_Pack(2, name, str); +#endif + PyObject *format = PyString_FromString("<%s: %s>"); + PyObject *repr = PyString_Format(format, args); + + Py_DECREF(name); + Py_DECREF(str); + Py_DECREF(args); + Py_DECREF(format); + + return repr; +} + +static int t_JObject_hash(t_JObject *self) +{ + return env->hash(self->object.this$); +} + +static PyObject *t_JObject__getJObject(t_JObject *self, void *data) +{ + return PyCObject_FromVoidPtr((void *) self->object.this$, NULL); +} + +#endif /* PYTHON */ Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JObject.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JObject.cpp ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: lucene/pylucene/trunk/jcc/jcc/sources/JObject.h URL: http://svn.apache.org/viewvc/lucene/pylucene/trunk/jcc/jcc/sources/JObject.h?rev=732916&view=auto ============================================================================== --- lucene/pylucene/trunk/jcc/jcc/sources/JObject.h (added) +++ lucene/pylucene/trunk/jcc/jcc/sources/JObject.h Thu Jan 8 19:28:33 2009 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2007-2008 Open Source Applications Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _JObject_H +#define _JObject_H + +#include +#include "JCCEnv.h" + +class JObject { +public: + jobject this$; + int id; /* zero when this$ is a weak ref */ + + inline explicit JObject(jobject obj) + { + id = env->id(obj); + this$ = env->newGlobalRef(obj, id); + } + + inline JObject(const JObject& obj) + { + id = obj.id ? obj.id : env->id(obj.this$); + this$ = env->newGlobalRef(obj.this$, id); + } + + virtual ~JObject() + { + this$ = env->deleteGlobalRef(this$, id); + } + + JObject& weaken$() + { + if (id) + { + jobject ref = env->newGlobalRef(this$, 0); + + env->deleteGlobalRef(this$, id); + id = 0; + this$ = ref; + } + + return *this; + } + + inline int operator!() const + { + return env->isSame(this$, NULL); + } + + inline int operator==(const JObject& obj) const + { + return env->isSame(this$, obj.this$); + } + + JObject& operator=(const JObject& obj) + { + jobject prev = this$; + int objid = obj.id ? obj.id : env->id(obj.this$); + + this$ = env->newGlobalRef(obj.this$, objid); + env->deleteGlobalRef(prev, id); + id = objid; + + return *this; + } +}; + + +#ifdef PYTHON + +#include + +class t_JObject { +public: + PyObject_HEAD + JObject object; +}; + +extern PyTypeObject JObjectType; + +#endif /* PYTHON */ + + +#endif /* _JObject_H */ Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JObject.h ------------------------------------------------------------------------------ svn:eol-style = native Propchange: lucene/pylucene/trunk/jcc/jcc/sources/JObject.h ------------------------------------------------------------------------------ svn:mime-type = text/plain