Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_JNI_BASE_H
21 : #define INCLUDED_JNI_BASE_H
22 :
23 : #include <sal/config.h>
24 :
25 : #include <cassert>
26 :
27 : #include "jvmaccess/unovirtualmachine.hxx"
28 : #include "jvmaccess/virtualmachine.hxx"
29 :
30 : #include "osl/diagnose.h"
31 :
32 : #include "rtl/alloc.h"
33 : #include "rtl/ustring.hxx"
34 :
35 : #include "uno/environment.h"
36 : #include "typelib/typedescription.h"
37 :
38 :
39 : namespace jni_uno
40 : {
41 :
42 : class JNI_info;
43 :
44 0 : struct BridgeRuntimeError
45 : {
46 : OUString m_message;
47 :
48 0 : inline BridgeRuntimeError( OUString const & message )
49 0 : : m_message( message )
50 0 : {}
51 : };
52 :
53 :
54 : class JNI_context
55 : {
56 : JNI_info const * m_jni_info;
57 : JNIEnv * m_env;
58 : jobject m_class_loader;
59 :
60 : JNI_context( JNI_context & ); // not impl
61 : void operator = ( JNI_context ); // not impl
62 :
63 : void java_exc_occurred() const;
64 : public:
65 0 : inline explicit JNI_context(
66 : JNI_info const * jni_info, JNIEnv * env, jobject class_loader )
67 : : m_jni_info( jni_info ),
68 : m_env( env ),
69 0 : m_class_loader( class_loader )
70 0 : {}
71 :
72 0 : inline JNI_info const * get_info() const
73 0 : { return m_jni_info; }
74 :
75 0 : inline JNIEnv * operator -> () const
76 0 : { return m_env; }
77 0 : inline JNIEnv * get_jni_env() const
78 0 : { return m_env; }
79 :
80 : // does not handle exceptions, *classClass will be null if exception
81 : // occurred:
82 : void getClassForName(jclass * classClass, jmethodID * methodForName) const;
83 :
84 : // if inException, does not handle exceptions, in which case returned value
85 : // will be null if exception occurred:
86 : jclass findClass(
87 : char const * name, jclass classClass, jmethodID methodForName,
88 : bool inException) const;
89 :
90 : inline void ensure_no_exception() const; // throws BridgeRuntimeError
91 : inline bool assert_no_exception() const; // asserts and clears exception
92 :
93 : OUString get_stack_trace( jobject jo_exc = 0 ) const;
94 : };
95 :
96 0 : inline void JNI_context::ensure_no_exception() const
97 : {
98 0 : if (JNI_FALSE != m_env->ExceptionCheck())
99 : {
100 0 : java_exc_occurred();
101 : }
102 0 : }
103 :
104 0 : inline bool JNI_context::assert_no_exception() const
105 : {
106 0 : if (JNI_FALSE != m_env->ExceptionCheck())
107 : {
108 : SAL_WARN("bridges", "unexpected java exception occurred");
109 : #if OSL_DEBUG_LEVEL > 0
110 : m_env->ExceptionDescribe();
111 : #endif
112 0 : m_env->ExceptionClear();
113 0 : return false;
114 : }
115 0 : return true;
116 : }
117 :
118 :
119 0 : class JNI_guarded_context
120 : : private ::jvmaccess::VirtualMachine::AttachGuard,
121 : public JNI_context
122 : {
123 : JNI_guarded_context( JNI_guarded_context & ); // not impl
124 : void operator = ( JNI_guarded_context ); // not impl
125 :
126 : public:
127 0 : inline explicit JNI_guarded_context(
128 : JNI_info const * jni_info, ::jvmaccess::UnoVirtualMachine * vm_access )
129 : : AttachGuard( vm_access->getVirtualMachine() ),
130 : JNI_context(
131 : jni_info, AttachGuard::getEnvironment(),
132 0 : static_cast< jobject >(vm_access->getClassLoader()) )
133 0 : {}
134 : };
135 :
136 :
137 : class JLocalAutoRef
138 : {
139 : JNI_context const & m_jni;
140 : jobject m_jo;
141 :
142 : public:
143 0 : inline JLocalAutoRef( JNI_context const & jni )
144 : : m_jni( jni ),
145 0 : m_jo( 0 )
146 0 : {}
147 0 : inline explicit JLocalAutoRef( JNI_context const & jni, jobject jo )
148 : : m_jni( jni ),
149 0 : m_jo( jo )
150 0 : {}
151 : inline JLocalAutoRef( JLocalAutoRef & auto_ref );
152 : inline ~JLocalAutoRef() SAL_THROW(());
153 :
154 0 : inline jobject get() const
155 0 : { return m_jo; }
156 0 : inline bool is() const
157 0 : { return (0 != m_jo); }
158 : inline jobject release();
159 : inline void reset();
160 : inline void reset( jobject jo );
161 : inline JLocalAutoRef & operator = ( JLocalAutoRef & auto_ref );
162 : };
163 :
164 0 : inline JLocalAutoRef::~JLocalAutoRef() SAL_THROW(())
165 : {
166 0 : if (0 != m_jo)
167 0 : m_jni->DeleteLocalRef( m_jo );
168 0 : }
169 :
170 : inline JLocalAutoRef::JLocalAutoRef( JLocalAutoRef & auto_ref )
171 : : m_jni( auto_ref.m_jni ),
172 : m_jo( auto_ref.m_jo )
173 : {
174 : auto_ref.m_jo = 0;
175 : }
176 :
177 0 : inline jobject JLocalAutoRef::release()
178 : {
179 0 : jobject jo = m_jo;
180 0 : m_jo = 0;
181 0 : return jo;
182 : }
183 :
184 : inline void JLocalAutoRef::reset()
185 : {
186 : if (0 != m_jo)
187 : m_jni->DeleteLocalRef( m_jo );
188 : m_jo = 0;
189 : }
190 :
191 0 : inline void JLocalAutoRef::reset( jobject jo )
192 : {
193 0 : if (jo != m_jo)
194 : {
195 0 : if (0 != m_jo)
196 0 : m_jni->DeleteLocalRef( m_jo );
197 0 : m_jo = jo;
198 : }
199 0 : }
200 :
201 : inline JLocalAutoRef & JLocalAutoRef::operator = ( JLocalAutoRef & auto_ref )
202 : {
203 : assert( m_jni.get_jni_env() == auto_ref.m_jni.get_jni_env() );
204 : reset( auto_ref.m_jo );
205 : auto_ref.m_jo = 0;
206 : return *this;
207 : }
208 :
209 :
210 :
211 : struct rtl_mem
212 : {
213 : inline static void * operator new ( size_t nSize )
214 : { return rtl_allocateMemory( nSize ); }
215 0 : inline static void operator delete ( void * mem )
216 0 : { if (mem) rtl_freeMemory( mem ); }
217 : inline static void * operator new ( size_t, void * mem )
218 : { return mem; }
219 : inline static void operator delete ( void *, void * )
220 : {}
221 :
222 : static inline rtl_mem * allocate( ::std::size_t bytes );
223 : };
224 :
225 0 : inline rtl_mem * rtl_mem::allocate( ::std::size_t bytes )
226 : {
227 0 : void * p = rtl_allocateMemory( bytes );
228 0 : if (0 == p)
229 0 : throw BridgeRuntimeError( "out of memory!" );
230 0 : return (rtl_mem *)p;
231 : }
232 :
233 :
234 : class TypeDescr
235 : {
236 : typelib_TypeDescription * m_td;
237 :
238 : TypeDescr( TypeDescr & ); // not impl
239 : void operator = ( TypeDescr ); // not impl
240 :
241 : public:
242 : inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref );
243 0 : inline ~TypeDescr() SAL_THROW(())
244 0 : { TYPELIB_DANGER_RELEASE( m_td ); }
245 :
246 0 : inline typelib_TypeDescription * get() const
247 0 : { return m_td; }
248 : };
249 :
250 0 : inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref )
251 0 : : m_td( 0 )
252 : {
253 0 : TYPELIB_DANGER_GET( &m_td, td_ref );
254 0 : if (0 == m_td)
255 : {
256 : throw BridgeRuntimeError(
257 0 : "cannot get comprehensive type description for " +
258 0 : OUString::unacquired( &td_ref->pTypeName ) );
259 : }
260 0 : }
261 :
262 : }
263 :
264 : #endif
265 :
266 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|