• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
3  * Copyright 2009, The Android Open Source Project
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef _JNI_UTILITY_H_
28 #define _JNI_UTILITY_H_
29 
30 #include <JavaVM/jni.h>
31 #include "npruntime.h"
32 
33 // The order of these items can not be modified as they are tightly
34 // bound with the JVM on Mac OSX. If new types need to be added, they
35 // should be added to the end. It is used in jni_obc.mm when calling
36 // through to the JVM. Newly added items need to be made compatible
37 // in that file.
38 typedef enum {
39     invalid_type = 0,
40     void_type,
41     object_type,
42     boolean_type,
43     byte_type,
44     char_type,
45     short_type,
46     int_type,
47     long_type,
48     float_type,
49     double_type,
50     array_type
51 } JNIType;
52 
53 namespace JSC {
54 
55 namespace Bindings {
56 
57 const char *getCharactersFromJString(jstring aJString);
58 void releaseCharactersForJString(jstring aJString, const char *s);
59 
60 const char *getCharactersFromJStringInEnv(JNIEnv *env, jstring aJString);
61 void releaseCharactersForJStringInEnv(JNIEnv *env, jstring aJString, const char *s);
62 const jchar *getUCharactersFromJStringInEnv(JNIEnv *env, jstring aJString);
63 void releaseUCharactersForJStringInEnv(JNIEnv *env, jstring aJString, const jchar *s);
64 
65 JNIType JNITypeFromClassName(const char *name);
66 JNIType JNITypeFromPrimitiveType(char type);
67 const char *signatureFromPrimitiveType(JNIType type);
68 
69 jvalue convertNPVariantToJValue(NPVariant, JNIType, const char* javaClassName);
70 void convertJValueToNPVariant(jvalue, JNIType, const char* javaClassName, NPVariant*);
71 
72 jvalue getJNIField(jobject obj, JNIType type, const char *name, const char *signature);
73 
74 jmethodID getMethodID(jobject obj, const char *name, const char *sig);
75 JNIEnv* getJNIEnv();
76 JavaVM* getJavaVM();
77 void setJavaVM(JavaVM*);
78 
79 
80 template <typename T> struct JNICaller;
81 
82 template<> struct JNICaller<void> {
83     static void callA(jobject obj, jmethodID mid, jvalue* args)
84     {
85         return getJNIEnv()->CallVoidMethodA(obj, mid, args);
86     }
87     static void callV(jobject obj, jmethodID mid, va_list args)
88     {
89         return getJNIEnv()->CallVoidMethodV(obj, mid, args);
90     }
91 };
92 
93 template<> struct JNICaller<jobject> {
94     static jobject callA(jobject obj, jmethodID mid, jvalue* args)
95     {
96         return getJNIEnv()->CallObjectMethodA(obj, mid, args);
97     }
98     static jobject callV(jobject obj, jmethodID mid, va_list args)
99     {
100         return getJNIEnv()->CallObjectMethodV(obj, mid, args);
101     }
102 };
103 
104 template<> struct JNICaller<jboolean> {
105     static jboolean callA(jobject obj, jmethodID mid, jvalue* args)
106     {
107         return getJNIEnv()->CallBooleanMethodA(obj, mid, args);
108     }
109     static jboolean callV(jobject obj, jmethodID mid, va_list args)
110     {
111         return getJNIEnv()->CallBooleanMethodV(obj, mid, args);
112     }
113     static jboolean callStaticV(jclass cls, jmethodID mid, va_list args)
114     {
115         return getJNIEnv()->CallStaticBooleanMethod(cls, mid, args);
116     }
117 
118 };
119 
120 template<> struct JNICaller<jbyte> {
121     static jbyte callA(jobject obj, jmethodID mid, jvalue* args)
122     {
123         return getJNIEnv()->CallByteMethodA(obj, mid, args);
124     }
125     static jbyte callV(jobject obj, jmethodID mid, va_list args)
126     {
127         return getJNIEnv()->CallByteMethodV(obj, mid, args);
128     }
129 };
130 
131 template<> struct JNICaller<jchar> {
132     static jchar callA(jobject obj, jmethodID mid, jvalue* args)
133     {
134         return getJNIEnv()->CallCharMethodA(obj, mid, args);
135     }
136     static jchar callV(jobject obj, jmethodID mid, va_list args)
137     {
138         return getJNIEnv()->CallCharMethodV(obj, mid, args);
139     }
140 };
141 
142 template<> struct JNICaller<jshort> {
143     static jshort callA(jobject obj, jmethodID mid, jvalue* args)
144     {
145         return getJNIEnv()->CallShortMethodA(obj, mid, args);
146     }
147     static jshort callV(jobject obj, jmethodID mid, va_list args)
148     {
149         return getJNIEnv()->CallShortMethodV(obj, mid, args);
150     }
151 };
152 
153 template<> struct JNICaller<jint> {
154     static jint callA(jobject obj, jmethodID mid, jvalue* args)
155     {
156         return getJNIEnv()->CallIntMethodA(obj, mid, args);
157     }
158     static jint callV(jobject obj, jmethodID mid, va_list args)
159     {
160         return getJNIEnv()->CallIntMethodV(obj, mid, args);
161     }
162 };
163 
164 template<> struct JNICaller<jlong> {
165     static jlong callA(jobject obj, jmethodID mid, jvalue* args)
166     {
167         return getJNIEnv()->CallLongMethodA(obj, mid, args);
168     }
169     static jlong callV(jobject obj, jmethodID mid, va_list args)
170     {
171         return getJNIEnv()->CallLongMethodV(obj, mid, args);
172     }
173 };
174 
175 template<> struct JNICaller<jfloat> {
176     static jfloat callA(jobject obj, jmethodID mid, jvalue* args)
177     {
178         return getJNIEnv()->CallFloatMethodA(obj, mid, args);
179     }
180     static jfloat callV(jobject obj, jmethodID mid, va_list args)
181     {
182         return getJNIEnv()->CallFloatMethodV(obj, mid, args);
183     }
184 };
185 
186 template<> struct JNICaller<jdouble> {
187     static jdouble callA(jobject obj, jmethodID mid, jvalue* args)
188     {
189         return getJNIEnv()->CallDoubleMethodA(obj, mid, args);
190     }
191     static jdouble callV(jobject obj, jmethodID mid, va_list args)
192     {
193         return getJNIEnv()->CallDoubleMethodV(obj, mid, args);
194     }
195 };
196 
197 template<typename T> T callJNIMethodIDA(jobject obj, jmethodID mid, jvalue *args)
198 {
199     return JNICaller<T>::callA(obj, mid, args);
200 }
201 
202 template<typename T>
203 static T callJNIMethodV(jobject obj, const char *name, const char *sig, va_list args)
204 {
205     JavaVM *jvm = getJavaVM();
206     JNIEnv *env = getJNIEnv();
207 
208     if ( obj != NULL && jvm != NULL && env != NULL) {
209         jclass cls = env->GetObjectClass(obj);
210         if ( cls != NULL ) {
211             jmethodID mid = env->GetMethodID(cls, name, sig);
212             if ( mid != NULL )
213             {
214                 env->DeleteLocalRef(cls);
215                 return JNICaller<T>::callV(obj, mid, args);
216             }
217             else
218             {
219                 fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj);
220                 env->ExceptionDescribe();
221                 env->ExceptionClear();
222                 fprintf (stderr, "\n");
223             }
224 
225             env->DeleteLocalRef(cls);
226         }
227         else {
228             fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, obj);
229         }
230     }
231 
232     return 0;
233 }
234 
235 template<typename T>
236 T callJNIMethod(jobject obj, const char* methodName, const char* methodSignature, ...)
237 {
238     va_list args;
239     va_start(args, methodSignature);
240 
241     T result= callJNIMethodV<T>(obj, methodName, methodSignature, args);
242 
243     va_end(args);
244 
245     return result;
246 }
247 
248 template<typename T>
249 T callJNIStaticMethod(jclass cls, const char* methodName, const char* methodSignature, ...)
250 {
251     JavaVM *jvm = getJavaVM();
252     JNIEnv *env = getJNIEnv();
253     va_list args;
254 
255     va_start(args, methodSignature);
256 
257     T result = 0;
258 
259     if (cls != NULL && jvm != NULL && env != NULL) {
260         jmethodID mid = env->GetStaticMethodID(cls, methodName, methodSignature);
261         if (mid != NULL)
262             result = JNICaller<T>::callStaticV(cls, mid, args);
263         else {
264             fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, methodName, cls);
265             env->ExceptionDescribe();
266             env->ExceptionClear();
267             fprintf (stderr, "\n");
268         }
269     }
270 
271     va_end(args);
272 
273     return result;
274 }
275 
276 } // namespace Bindings
277 
278 } // namespace JSC
279 
280 #endif // _JNI_UTILITY_H_
281