1 /* Copyright (C) 2005-2011 Fabio Riccardi */
2 
3 /*
4  * JavaAppLauncher: a simple Java application launcher for Mac OS X.
5  * LC_JNIUtils.h
6  *
7  * Paul J. Lucas [paul@lightcrafts.com]
8  */
9 
10 #ifndef LC_JNIUtils_H
11 #define LC_JNIUtils_H
12 
13 // standard
14 #include <jni.h>                        /* for JNIEnv */
15 
16 #ifdef  __cplusplus
17 extern "C" {
18 #endif
19 
20 /**
21  * Attach to the current JVM thread.
22  */
23 JNIEnv* LC_attachCurrentThread();
24 
25 /**
26  * Check to see if Java threw an exception: if so, report it, then clear it.
27  */
28 bool LC_exceptionOccurred( JNIEnv* );
29 
30 
31 /**
32  * Gets the JNI env for the current thread.
33  */
34 JNIEnv* LC_getJNIEnv( int *mustDetach );
35 
36 extern JavaVM *g_jvm;
37 
38 #ifdef  __cplusplus
39 }
40 
41 // local
42 #include <LC_CPPUtils.h>
43 
44 namespace LightCrafts {
45 
46     /**
47      * Ensure we detach from the current JVM thread.
48      */
49     class auto_JNIEnv {
50     public:
auto_JNIEnv()51         auto_JNIEnv() : m_env( LC_getJNIEnv( &m_mustDetach ) ) { }
~auto_JNIEnv()52         ~auto_JNIEnv() {
53             if ( m_mustDetach )
54                 g_jvm->DetachCurrentThread();
55         }
56         operator JNIEnv*() const {
57             return m_env;
58         }
59         JNIEnv* operator->() const {
60             return m_env;
61         }
62     private:
63         JNIEnv *const m_env;
64         int m_mustDetach;
65     };
66 
67     /**
68      * Ensure a Java local reference is destroyed.
69      */
70     template<typename T> class auto_local_ref {
71     public:
72         typedef T value_type;
73 
auto_local_ref(JNIEnv * env,value_type ref)74         auto_local_ref( JNIEnv *env, value_type ref ) :
75             m_env( env ), m_ref( ref )
76         {
77         }
78 
79         auto_local_ref& operator=( value_type ref ) {
80             if ( ref != m_ref ) {
81                 m_env->DeleteLocalRef( m_ref );
82                 m_ref = ref;
83             }
84             return *this;
85         }
86 
release()87         void release() {
88             m_env->DeleteLocalRef( m_ref );
89             m_ref = 0;
90         }
91 
~auto_local_ref()92         ~auto_local_ref() {
93             release();
94         }
95 
value_type()96         operator value_type() const {
97             return m_ref;
98         }
99 
100         bool operator!() const {
101             return !m_ref;
102         }
103     private:
104         JNIEnv *const m_env;
105         value_type m_ref;
106     };
107 
108     /**
109      * Get an jobject's jclass and ensure the local reference thereto is
110      * destroyed.
111      */
112     class auto_jclass : public auto_local_ref<jclass> {
113     public:
114         typedef auto_local_ref<jclass> base_type;
115 
auto_jclass(JNIEnv * env,jobject jObject)116         auto_jclass( JNIEnv *env, jobject jObject ) :
117             base_type( env, env->GetObjectClass( jObject ) )
118         {
119         }
120     };
121 
122     /**
123      * Ensure a jstring is destroyed.
124      */
125     typedef auto_local_ref<jstring> auto_jstring;
126 
127 } // namespace
128 
129 #endif  /* __cplusplus */
130 
131 #endif  /* LC_JNIUtils_H */
132 /* vim:set et sw=4 ts=4: */
133