1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wunknown-attributes"
30 #pragma clang diagnostic pop
33 #include <osl/security.h>
36 /* On Windows, jpipe.dll must not have static dependencies on any other URE DLLs
37 (sal3.dll, uwinapi.dll), as Java System.LoadLibrary could otherwise not load
38 it. Therefore, on Windows, this code goes into a jpipx.dll that the jpipe.dll
39 wrapper loads with LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH).
40 The function names in this wrapped code are truncated from the long JNICALL
41 names, as JNICALL causes some "@N" with different numeric values for
42 N (and probably different across 32 and 64 bit) to be added to the symbol
43 names, which the calls to GetProcAddress in wrapper/wrapper.c would otherwise
44 have to take into account.
47 /*****************************************************************************/
48 /* exception macros */
50 static void ThrowException(JNIEnv
* env
, char const * type
, char const * msg
) {
52 (*env
)->ExceptionClear(env
);
53 c
= (*env
)->FindClass(env
, type
);
55 (*env
)->ExceptionClear(env
);
56 (*env
)->FatalError(env
, "JNI FindClass failed");
58 if ((*env
)->ThrowNew(env
, c
, msg
) != 0) {
59 (*env
)->ExceptionClear(env
);
60 (*env
)->FatalError(env
, "JNI ThrowNew failed");
64 /*****************************************************************************/
65 /* helper functions prototypes */
67 static oslPipe
getPipe(JNIEnv
* env
, jobject obj_this
);
68 static rtl_uString
* jstring2ustring(JNIEnv
* env
, jstring jstr
);
70 /*****************************************************************************/
73 static oslPipe
getPipe(JNIEnv
* env
, jobject obj_this
)
77 tclass
= (*env
)->GetObjectClass(env
, obj_this
);
81 "java/lang/RuntimeException",
82 "native pipe cannot find class");
86 fid
= (*env
)->GetFieldID(env
, tclass
, "_nPipeHandle", "J");
90 "java/lang/RuntimeException",
91 "native pipe cannot find field");
94 return (oslPipe
) SAL_INT_CAST(
95 sal_IntPtr
, (*env
)->GetLongField(env
, obj_this
, fid
));
98 /*****************************************************************************/
99 /* convert jstring to rtl_uString */
101 static rtl_uString
* jstring2ustring(JNIEnv
* env
, jstring jstr
)
104 rtl_uString
* ustr
= NULL
;
105 cstr
= (*env
)->GetStringUTFChars(env
, jstr
, NULL
);
106 rtl_uString_newFromAscii(&ustr
, cstr
);
107 (*env
)->ReleaseStringUTFChars(env
, jstr
, cstr
);
111 /*****************************************************************************/
113 * Class: com_sun_star_lib_connections_pipe_PipeConnection
115 * Signature: (Lcom/sun/star/beans/NativeService;)V
117 SAL_DLLPUBLIC_EXPORT
void
119 PipeConnection_create
121 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_createJNI
123 (JNIEnv
* env
, jobject obj_this
, jstring name
)
137 oslSecurity psec
= osl_getCurrentSecurity();
138 oslPipe npipe
= NULL
;
139 rtl_uString
* pname
= NULL
;
140 if ((*env
)->MonitorEnter(env
, obj_this
) != 0)
143 "java/lang/RuntimeException",
144 "native pipe cannot synchronize on the object");
149 /* check connection state */
150 npipe
= getPipe(env
, obj_this
);
151 if ((*env
)->ExceptionOccurred(env
) != NULL
)
156 "com/sun/star/io/IOException",
157 "native pipe is already connected");
161 /* save the pipe name */
162 tclass
= (*env
)->GetObjectClass(env
, obj_this
);
166 "java/lang/RuntimeException",
167 "native pipe cannot find class");
171 fid
= (*env
)->GetFieldID(env
, tclass
,
172 "_aDescription", "Ljava/lang/String;");
176 "java/lang/RuntimeException",
177 "native pipe cannot find field");
181 (*env
)->SetObjectField(env
, obj_this
, fid
, (jobject
)name
);
183 /* convert pipe name to rtl_uString */
184 pname
= jstring2ustring(env
, name
);
188 "java/lang/RuntimeException",
189 "native pipe cannot convert name");
195 npipe
= osl_createPipe(pname
, osl_Pipe_OPEN
, psec
);
199 "java/lang/RuntimeException",
200 "cannot create native pipe");
206 tclass
= (*env
)->GetObjectClass(env
, obj_this
);
210 "java/lang/RuntimeException",
211 "native pipe cannot find class");
215 fid
= (*env
)->GetFieldID(env
, tclass
, "_nPipeHandle", "J");
219 "java/lang/RuntimeException",
220 "native pipe cannot find field");
223 (*env
)->SetLongField(
224 env
, obj_this
, fid
, SAL_INT_CAST(jlong
, (sal_IntPtr
) npipe
));
227 rtl_uString_release(pname
);
228 (*env
)->MonitorExit(env
, obj_this
);
229 osl_freeSecurityHandle(psec
);
236 osl_closePipe(npipe
);
237 osl_releasePipe(npipe
);
240 rtl_uString_release(pname
);
243 (*env
)->MonitorExit(env
, obj_this
);
246 osl_freeSecurityHandle(psec
);
253 /*****************************************************************************/
255 * Class: com_sun_star_lib_connections_pipe_PipeConnection
259 SAL_DLLPUBLIC_EXPORT
void
263 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_closeJNI
265 (JNIEnv
* env
, jobject obj_this
)
274 oslPipe npipe
= NULL
; /* native pipe */
275 jclass tclass
; /* this class */
276 jfieldID fid
; /* a field identifier */
278 if ((*env
)->MonitorEnter(env
, obj_this
) != 0)
281 "java/lang/RuntimeException",
282 "native pipe cannot synchronize on the object");
287 /* check connection state */
288 npipe
= getPipe(env
, obj_this
);
289 if ((*env
)->ExceptionOccurred(env
) != NULL
)
294 "com/sun/star/io/IOException",
295 "native pipe is not connected");
300 /* remove the reference to the pipe */
301 tclass
= (*env
)->GetObjectClass(env
, obj_this
);
305 "java/lang/RuntimeException",
306 "native pipe cannot find class");
310 fid
= (*env
)->GetFieldID(env
, tclass
, "_nPipeHandle", "J");
314 "java/lang/RuntimeException",
315 "native pipe cannot find field");
319 (*env
)->SetLongField(env
, obj_this
, fid
, (jlong
)0);
327 /* release the pipe */
328 osl_closePipe(npipe
);
329 osl_releasePipe(npipe
);
332 (*env
)->MonitorExit(env
, obj_this
);
341 /*****************************************************************************/
343 * Class: com_sun_star_lib_connections_pipe_PipeConnection
347 SAL_DLLPUBLIC_EXPORT jint
351 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_readJNI
353 (JNIEnv
* env
, jobject obj_this
, jobjectArray buffer
, jint len
)
363 oslPipe npipe
= NULL
; /* native pipe */
364 void * nbuff
= NULL
; /* native read buffer */
365 jbyteArray bytes
; /* java read buffer */
366 jint nread
; /* number of bytes has been read */
367 jint nreturn
= -1; /* actual return value */
370 if ((*env
)->MonitorEnter(env
, obj_this
) != 0)
373 "java/lang/RuntimeException",
374 "native pipe cannot synchronize on the object");
379 /* check connection state */
380 npipe
= getPipe(env
, obj_this
);
381 if ((*env
)->ExceptionOccurred(env
) != NULL
)
386 "com/sun/star/io/IOException",
387 "native pipe is not connected");
392 osl_acquirePipe( npipe
);
395 /* allocate a buffer */
396 if ((nbuff
= malloc(len
)) == NULL
)
399 "java/lang/RuntimeException",
400 "native pipe out of memory");
407 (*env
)->MonitorExit(env
, obj_this
);
410 nread
= osl_readPipe(npipe
, nbuff
, len
);
412 /* enter monitor again */
413 if ((*env
)->MonitorEnter(env
, obj_this
) != 0)
416 "java/lang/RuntimeException",
417 "native pipe cannot synchronize on the object");
424 bytes
= (*env
)->NewByteArray(env
, len
);
428 "java/lang/RuntimeException",
429 "native pipe out of memory");
434 (*env
)->SetByteArrayRegion(env
, bytes
, 0, len
, nbuff
);
435 (*env
)->SetObjectArrayElement(env
, buffer
, 0, bytes
);
436 (*env
)->DeleteLocalRef(env
, bytes
);
449 osl_releasePipe(npipe
);
452 (*env
)->MonitorExit(env
, obj_this
);
461 /*****************************************************************************/
463 * Class: com_sun_star_lib_connections_pipe_PipeConnection
467 SAL_DLLPUBLIC_EXPORT
void
471 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI
473 (JNIEnv
* env
, jobject obj_this
, jbyteArray buffer
)
482 oslPipe npipe
; /* native pipe */
483 sal_Int32 count
; /* number of bytes has been written */
484 jsize nwrite
; /* number of bytes to write */
485 jbyte
* nbuff
= NULL
; /* native buffer */
487 if ((*env
)->MonitorEnter(env
, obj_this
) != 0)
490 "java/lang/RuntimeException",
491 "native pipe cannot synchronize on the object");
496 /* check connection state */
497 npipe
= getPipe(env
, obj_this
);
498 if ((*env
)->ExceptionOccurred(env
) != NULL
)
503 "com/sun/star/io/IOException",
504 "native pipe is not connected");
508 nwrite
= (*env
)->GetArrayLength(env
, buffer
);
511 nbuff
= (*env
)->GetByteArrayElements(env
, buffer
, NULL
);
515 "java/lang/RuntimeException",
516 "native pipe out of memory");
521 (*env
)->MonitorExit(env
, obj_this
);
523 count
= osl_writePipe(npipe
, nbuff
, nwrite
);
524 if ((*env
)->MonitorEnter(env
, obj_this
) != 0)
527 "java/lang/RuntimeException",
528 "native pipe cannot synchronize on the object");
534 "com/sun/star/io/IOException",
535 "native pipe: failed to write");
545 (*env
)->ReleaseByteArrayElements(env
, buffer
, nbuff
, JNI_ABORT
);
548 (*env
)->MonitorExit(env
, obj_this
);
557 /*****************************************************************************/
559 * Class: com_sun_star_lib_connections_pipe_PipeConnection
563 SAL_DLLPUBLIC_EXPORT
void
567 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI
569 (JNIEnv
* env
, jobject obj_this
)
571 (void) env
; /* not used */
572 (void) obj_this
; /* not used */
576 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */