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_BRIDGES_SOURCE_JNI_UNO_JNI_BASE_H
21 : #define INCLUDED_BRIDGES_SOURCE_JNI_UNO_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 : #include "sal/log.hxx"
35 :
36 : #include "uno/environment.h"
37 : #include "typelib/typedescription.h"
38 :
39 :
40 : namespace jni_uno
41 : {
42 :
43 : class JNI_info;
44 :
45 0 : struct BridgeRuntimeError
46 : {
47 : OUString m_message;
48 :
49 0 : inline BridgeRuntimeError( OUString const & message )
50 0 : : m_message( message )
51 0 : {}
52 : };
53 :
54 :
55 : class JNI_context
56 : {
57 : JNI_info const * m_jni_info;
58 : JNIEnv * m_env;
59 : jobject m_class_loader;
60 :
61 : JNI_context( JNI_context & ) SAL_DELETED_FUNCTION;
62 : void operator = ( JNI_context ) SAL_DELETED_FUNCTION;
63 :
64 : void java_exc_occurred() const;
65 : public:
66 128 : inline explicit JNI_context(
67 : JNI_info const * jni_info, JNIEnv * env, jobject class_loader )
68 : : m_jni_info( jni_info ),
69 : m_env( env ),
70 128 : m_class_loader( class_loader )
71 128 : {}
72 :
73 211 : inline JNI_info const * get_info() const
74 211 : { return m_jni_info; }
75 :
76 1894 : inline JNIEnv * operator -> () const
77 1894 : { return m_env; }
78 0 : inline JNIEnv * get_jni_env() const
79 0 : { return m_env; }
80 :
81 : // does not handle exceptions, *classClass will be null if exception
82 : // occurred:
83 : void getClassForName(jclass * classClass, jmethodID * methodForName) const;
84 :
85 : // if inException, does not handle exceptions, in which case returned value
86 : // will be null if exception occurred:
87 : jclass findClass(
88 : char const * name, jclass classClass, jmethodID methodForName,
89 : bool inException) const;
90 :
91 : inline void ensure_no_exception() const; // throws BridgeRuntimeError
92 : inline bool assert_no_exception() const; // asserts and clears exception
93 :
94 : OUString get_stack_trace( jobject jo_exc = 0 ) const;
95 : };
96 :
97 768 : inline void JNI_context::ensure_no_exception() const
98 : {
99 768 : if (m_env->ExceptionCheck())
100 : {
101 0 : java_exc_occurred();
102 : }
103 768 : }
104 :
105 0 : inline bool JNI_context::assert_no_exception() const
106 : {
107 0 : if (m_env->ExceptionCheck())
108 : {
109 : SAL_WARN("bridges", "unexpected java exception occurred");
110 : #if OSL_DEBUG_LEVEL > 0
111 : m_env->ExceptionDescribe();
112 : #endif
113 0 : m_env->ExceptionClear();
114 0 : return false;
115 : }
116 0 : return true;
117 : }
118 :
119 :
120 100 : class JNI_guarded_context
121 : : private ::jvmaccess::VirtualMachine::AttachGuard,
122 : public JNI_context
123 : {
124 : JNI_guarded_context( JNI_guarded_context & ) SAL_DELETED_FUNCTION;
125 : void operator = ( JNI_guarded_context ) SAL_DELETED_FUNCTION;
126 :
127 : public:
128 100 : inline explicit JNI_guarded_context(
129 : JNI_info const * jni_info,
130 : rtl::Reference<jvmaccess::UnoVirtualMachine> const & vm_access)
131 : : AttachGuard( vm_access->getVirtualMachine() ),
132 : JNI_context(
133 : jni_info, AttachGuard::getEnvironment(),
134 100 : static_cast< jobject >(vm_access->getClassLoader()) )
135 100 : {}
136 : };
137 :
138 :
139 : class JLocalAutoRef
140 : {
141 : JNI_context const & m_jni;
142 : jobject m_jo;
143 :
144 : public:
145 132 : inline JLocalAutoRef( JNI_context const & jni )
146 : : m_jni( jni ),
147 132 : m_jo( 0 )
148 132 : {}
149 503 : inline explicit JLocalAutoRef( JNI_context const & jni, jobject jo )
150 : : m_jni( jni ),
151 503 : m_jo( jo )
152 503 : {}
153 : inline JLocalAutoRef( JLocalAutoRef & auto_ref );
154 : inline ~JLocalAutoRef();
155 :
156 931 : inline jobject get() const
157 931 : { return m_jo; }
158 151 : inline bool is() const
159 151 : { return (0 != m_jo); }
160 : inline jobject release();
161 : inline void reset();
162 : inline void reset( jobject jo );
163 : inline JLocalAutoRef & operator = ( JLocalAutoRef & auto_ref );
164 : };
165 :
166 635 : inline JLocalAutoRef::~JLocalAutoRef()
167 : {
168 635 : if (0 != m_jo)
169 526 : m_jni->DeleteLocalRef( m_jo );
170 635 : }
171 :
172 : inline JLocalAutoRef::JLocalAutoRef( JLocalAutoRef & auto_ref )
173 : : m_jni( auto_ref.m_jni ),
174 : m_jo( auto_ref.m_jo )
175 : {
176 : auto_ref.m_jo = 0;
177 : }
178 :
179 32 : inline jobject JLocalAutoRef::release()
180 : {
181 32 : jobject jo = m_jo;
182 32 : m_jo = 0;
183 32 : return jo;
184 : }
185 :
186 : inline void JLocalAutoRef::reset()
187 : {
188 : if (0 != m_jo)
189 : m_jni->DeleteLocalRef( m_jo );
190 : m_jo = 0;
191 : }
192 :
193 62 : inline void JLocalAutoRef::reset( jobject jo )
194 : {
195 62 : if (jo != m_jo)
196 : {
197 62 : if (0 != m_jo)
198 4 : m_jni->DeleteLocalRef( m_jo );
199 62 : m_jo = jo;
200 : }
201 62 : }
202 :
203 : inline JLocalAutoRef & JLocalAutoRef::operator = ( JLocalAutoRef & auto_ref )
204 : {
205 : assert( m_jni.get_jni_env() == auto_ref.m_jni.get_jni_env() );
206 : reset( auto_ref.m_jo );
207 : auto_ref.m_jo = 0;
208 : return *this;
209 : }
210 :
211 :
212 :
213 : struct rtl_mem
214 : {
215 : inline static void * operator new ( size_t nSize )
216 : { return rtl_allocateMemory( nSize ); }
217 0 : inline static void operator delete ( void * mem )
218 0 : { if (mem) rtl_freeMemory( mem ); }
219 : inline static void * operator new ( size_t, void * mem )
220 : { return mem; }
221 : inline static void operator delete ( void *, void * )
222 : {}
223 :
224 : static inline rtl_mem * allocate( ::std::size_t bytes );
225 : };
226 :
227 92 : inline rtl_mem * rtl_mem::allocate( ::std::size_t bytes )
228 : {
229 92 : void * p = rtl_allocateMemory( bytes );
230 92 : if (0 == p)
231 0 : throw BridgeRuntimeError( "out of memory!" );
232 92 : return static_cast<rtl_mem *>(p);
233 : }
234 :
235 :
236 : class TypeDescr
237 : {
238 : typelib_TypeDescription * m_td;
239 :
240 : TypeDescr( TypeDescr & ) SAL_DELETED_FUNCTION;
241 : void operator = ( TypeDescr ) SAL_DELETED_FUNCTION;
242 :
243 : public:
244 : inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref );
245 230 : inline ~TypeDescr()
246 230 : { TYPELIB_DANGER_RELEASE( m_td ); }
247 :
248 464 : inline typelib_TypeDescription * get() const
249 464 : { return m_td; }
250 : };
251 :
252 230 : inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref )
253 230 : : m_td( 0 )
254 : {
255 230 : TYPELIB_DANGER_GET( &m_td, td_ref );
256 230 : if (0 == m_td)
257 : {
258 : throw BridgeRuntimeError(
259 0 : "cannot get comprehensive type description for " +
260 0 : OUString::unacquired( &td_ref->pTypeName ) );
261 : }
262 230 : }
263 :
264 : }
265 :
266 : #endif
267 :
268 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|