fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / jurt / source / pipe / com_sun_star_lib_connections_pipe_PipeConnection.c
blob6cdb2d1c1e4f22ccc72a95412bb2a5a1f7f93cc3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "jni.h"
21 #include "osl/security.h"
22 #include <osl/pipe.h>
24 /* On Windows, jpipe.dll must not have static dependencies on any other URE DLLs
25 (sal3.dll, uwinapi.dll), as Java System.LoadLibrary could otherwise not load
26 it. Therefore, on Windows, this code goes into a jpipx.dll that the jpipe.dll
27 wrapper loads with LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH).
28 The function names in this wrapped code are truncated from the long JNICALL
29 names, as JNICALL causes some "@N" with different numeric values for
30 N (and probably different across 32 and 64 bit) to be added to the symbol
31 names, which the calls to GetProcAddress in wrapper/wrapper.c would otherwise
32 have to take into account.
35 /*****************************************************************************/
36 /* exception macros */
38 static void ThrowException(JNIEnv * env, char const * type, char const * msg) {
39 jclass c;
40 (*env)->ExceptionClear(env);
41 c = (*env)->FindClass(env, type);
42 if (c == NULL) {
43 (*env)->ExceptionClear(env);
44 (*env)->FatalError(env, "JNI FindClass failed");
46 if ((*env)->ThrowNew(env, c, msg) != 0) {
47 (*env)->ExceptionClear(env);
48 (*env)->FatalError(env, "JNI ThrowNew failed");
52 /*****************************************************************************/
53 /* helper functions prototypes */
55 static oslPipe getPipe(JNIEnv * env, jobject obj_this);
56 static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr);
58 /*****************************************************************************/
59 /* get pipe */
61 static oslPipe getPipe(JNIEnv * env, jobject obj_this)
63 jclass tclass;
64 jfieldID fid;
65 tclass = (*env)->GetObjectClass(env, obj_this);
66 if (tclass == NULL)
68 ThrowException(env,
69 "java/lang/RuntimeException",
70 "native pipe cannot find class");
71 return NULL;
74 fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
75 if (fid == NULL)
77 ThrowException(env,
78 "java/lang/RuntimeException",
79 "native pipe cannot find field");
80 return NULL;
82 return (oslPipe) SAL_INT_CAST(
83 sal_IntPtr, (*env)->GetLongField(env, obj_this, fid));
86 /*****************************************************************************/
87 /* convert jstring to rtl_uString */
89 static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr)
91 const char * cstr;
92 rtl_uString * ustr = NULL;
93 cstr = (*env)->GetStringUTFChars(env, jstr, NULL);
94 rtl_uString_newFromAscii(&ustr, cstr);
95 (*env)->ReleaseStringUTFChars(env, jstr, cstr);
96 return ustr;
99 /*****************************************************************************/
101 * Class: com_sun_star_lib_connections_pipe_PipeConnection
102 * Method: connect
103 * Signature: (Lcom/sun/star/beans/NativeService;)V
105 SAL_DLLPUBLIC_EXPORT void
106 #if defined WNT
107 PipeConnection_create
108 #else
109 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_createJNI
110 #endif
111 (JNIEnv * env, jobject obj_this, jstring name)
113 enum {
114 START = 0,
115 INMONITOR,
116 GOTNAME,
117 CREATED
120 short state = START;
122 jclass tclass;
123 jfieldID fid;
125 oslSecurity psec = osl_getCurrentSecurity();
126 oslPipe npipe = NULL;
127 rtl_uString * pname = NULL;
128 if ((*env)->MonitorEnter(env, obj_this) != 0)
130 ThrowException(env,
131 "java/lang/RuntimeException",
132 "native pipe cannot synchronize on the object");
133 goto error;
135 state = INMONITOR;
137 /* check connection state */
138 npipe = getPipe(env, obj_this);
139 if ((*env)->ExceptionOccurred(env) != NULL)
140 goto error;
141 if (npipe != NULL)
143 ThrowException(env,
144 "com/sun/star/io/IOException",
145 "native pipe is already connected");
146 goto error;
149 /* save the pipe name */
150 tclass = (*env)->GetObjectClass(env, obj_this);
151 if (tclass == NULL)
153 ThrowException(env,
154 "java/lang/RuntimeException",
155 "native pipe cannot find class");
156 goto error;
159 fid = (*env)->GetFieldID(env, tclass,
160 "_aDescription", "Ljava/lang/String;");
161 if (fid == NULL)
163 ThrowException(env,
164 "java/lang/RuntimeException",
165 "native pipe cannot find field");
166 goto error;
169 (*env)->SetObjectField(env, obj_this, fid, (jobject)name);
171 /* convert pipe name to rtl_uString */
172 pname = jstring2ustring(env, name);
173 if (pname == NULL)
175 ThrowException(env,
176 "java/lang/RuntimeException",
177 "native pipe cannot convert name");
178 goto error;
180 state = GOTNAME;
182 /* try to connect */
183 npipe = osl_createPipe(pname, osl_Pipe_OPEN, psec);
184 if (npipe == NULL)
186 ThrowException(env,
187 "java/lang/RuntimeException",
188 "cannot create native pipe");
189 goto error;
191 state = CREATED;
193 /* save the pipe */
194 tclass = (*env)->GetObjectClass(env, obj_this);
195 if (tclass == NULL)
197 ThrowException(env,
198 "java/lang/RuntimeException",
199 "native pipe cannot find class");
200 goto error;
203 fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
204 if (fid == NULL)
206 ThrowException(env,
207 "java/lang/RuntimeException",
208 "native pipe cannot find field");
209 goto error;
211 (*env)->SetLongField(
212 env, obj_this, fid, SAL_INT_CAST(jlong, (sal_IntPtr) npipe));
214 /* done */
215 rtl_uString_release(pname);
216 (*env)->MonitorExit(env, obj_this);
217 osl_freeSecurityHandle(psec);
218 return;
220 error:
221 switch (state)
223 case CREATED:
224 osl_closePipe(npipe);
225 osl_releasePipe(npipe);
226 case GOTNAME:
227 rtl_uString_release(pname);
228 case INMONITOR:
229 (*env)->MonitorExit(env, obj_this);
230 case START:
231 osl_freeSecurityHandle(psec);
232 default:
233 break;
235 return;
238 /*****************************************************************************/
240 * Class: com_sun_star_lib_connections_pipe_PipeConnection
241 * Method: closeJNI
242 * Signature: ()V
244 SAL_DLLPUBLIC_EXPORT void
245 #if defined WNT
246 PipeConnection_close
247 #else
248 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_closeJNI
249 #endif
250 (JNIEnv * env, jobject obj_this)
252 enum {
253 START = 0,
254 INMONITOR
257 short state = START;
258 oslPipe npipe; /* native pipe */
259 jclass tclass; /* this class */
260 jfieldID fid; /* a field identifier */
262 if ((*env)->MonitorEnter(env, obj_this) != 0)
264 ThrowException(env,
265 "java/lang/RuntimeException",
266 "native pipe cannot synchronize on the object");
267 goto error;
269 state = INMONITOR;
271 /* check connection state */
272 npipe = getPipe(env, obj_this);
273 if ((*env)->ExceptionOccurred(env) != NULL)
274 goto error;
275 if (npipe == NULL)
277 ThrowException(env,
278 "com/sun/star/io/IOException",
279 "native pipe is not connected");
280 goto error;
283 /* remove the reference to the pipe */
284 tclass = (*env)->GetObjectClass(env, obj_this);
285 if (tclass == NULL)
287 ThrowException(env,
288 "java/lang/RuntimeException",
289 "native pipe cannot find class");
290 goto error;
293 fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
294 if (fid == NULL)
296 ThrowException(env,
297 "java/lang/RuntimeException",
298 "native pipe cannot find field");
299 goto error;
302 (*env)->SetLongField(env, obj_this, fid, (jlong)0);
304 /* release the pipe */
305 osl_closePipe(npipe);
306 osl_releasePipe(npipe);
308 /* done */
309 (*env)->MonitorExit(env, obj_this);
310 return;
312 error:
313 switch (state)
315 case INMONITOR:
316 (*env)->MonitorExit(env, obj_this);
317 case START:
318 default:
319 break;
321 return;
324 /*****************************************************************************/
326 * Class: com_sun_star_lib_connections_pipe_PipeConnection
327 * Method: readJNI
328 * Signature: ([[BI)I
330 SAL_DLLPUBLIC_EXPORT jint
331 #if defined WNT
332 PipeConnection_read
333 #else
334 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_readJNI
335 #endif
336 (JNIEnv * env, jobject obj_this, jobjectArray buffer, jint len)
338 enum {
339 START = 0,
340 INMONITOR,
341 ACQUIRED,
342 GOTBUFFER
345 short state = START;
346 oslPipe npipe; /* native pipe */
347 void * nbuff = NULL; /* native read buffer */
348 jbyteArray bytes; /* java read buffer */
349 jint nread; /* number of bytes has been read */
351 /* enter monitor */
352 if ((*env)->MonitorEnter(env, obj_this) != 0)
354 ThrowException(env,
355 "java/lang/RuntimeException",
356 "native pipe cannot synchronize on the object");
357 goto error;
359 state = INMONITOR;
361 /* check connection state */
362 npipe = getPipe(env, obj_this);
363 if ((*env)->ExceptionOccurred(env) != NULL)
364 goto error;
365 if (npipe == NULL)
367 ThrowException(env,
368 "com/sun/star/io/IOException",
369 "native pipe is not connected");
370 goto error;
373 /* acquire pipe */
374 osl_acquirePipe( npipe );
375 state = ACQUIRED;
377 /* allocate a buffer */
378 if ((nbuff = malloc(len)) == NULL)
380 ThrowException(env,
381 "java/lang/RuntimeException",
382 "native pipe out of memory");
383 goto error;
386 state = GOTBUFFER;
388 /* exit monitor */
389 (*env)->MonitorExit(env, obj_this);
391 /* reading */
392 nread = osl_readPipe(npipe, nbuff, len);
394 /* enter monitor again */
395 if ((*env)->MonitorEnter(env, obj_this) != 0)
397 ThrowException(env,
398 "java/lang/RuntimeException",
399 "native pipe cannot synchronize on the object");
400 goto error;
403 /* copy buffer */
404 if (nread >= 0)
406 bytes = (*env)->NewByteArray(env, len);
407 if (bytes == NULL)
409 ThrowException(env,
410 "java/lang/RuntimeException",
411 "native pipe out of memory");
412 goto error;
415 /* save the data */
416 (*env)->SetByteArrayRegion(env, bytes, 0, len, nbuff);
417 (*env)->SetObjectArrayElement(env, buffer, 0, bytes);
418 (*env)->DeleteLocalRef(env, bytes);
421 /* done */
422 free(nbuff);
423 if ( state >= ACQUIRED )
424 osl_releasePipe( npipe );
426 /* exit monitor */
427 (*env)->MonitorExit(env, obj_this);
428 return nread;
430 error:
431 switch (state)
433 case GOTBUFFER:
434 free(nbuff);
435 /* fall-through */
436 case INMONITOR:
437 (*env)->MonitorExit(env, obj_this);
438 case START:
439 default:
440 break;
442 return -1;
445 /*****************************************************************************/
447 * Class: com_sun_star_lib_connections_pipe_PipeConnection
448 * Method: writeJNI
449 * Signature: ([B)V
451 SAL_DLLPUBLIC_EXPORT void
452 #if defined WNT
453 PipeConnection_write
454 #else
455 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI
456 #endif
457 (JNIEnv * env, jobject obj_this, jbyteArray buffer)
459 enum {
460 START = 0,
461 INMONITOR,
462 GOTBUFFER
465 short state = START;
466 oslPipe npipe; /* native pipe */
467 long count; /* number of bytes has been written */
468 jsize nwrite; /* number of bytes to write */
469 jbyte * nbuff = NULL; /* native buffer */
471 if ((*env)->MonitorEnter(env, obj_this) != 0)
473 ThrowException(env,
474 "java/lang/RuntimeException",
475 "native pipe cannot synchronize on the object");
476 goto error;
478 state = INMONITOR;
480 /* check connection state */
481 npipe = getPipe(env, obj_this);
482 if ((*env)->ExceptionOccurred(env) != NULL)
483 goto error;
484 if (npipe == NULL)
486 ThrowException(env,
487 "com/sun/star/io/IOException",
488 "native pipe is not connected");
489 goto error;
492 nwrite = (*env)->GetArrayLength(env, buffer);
493 if (nwrite > 0)
495 nbuff = (*env)->GetByteArrayElements(env, buffer, NULL);
496 if (nbuff == NULL)
498 ThrowException(env,
499 "java/lang/RuntimeException",
500 "native pipe out of memory");
501 goto error;
503 state = GOTBUFFER;
505 (*env)->MonitorExit(env, obj_this);
506 /* writing */
507 count = osl_writePipe(npipe, nbuff, nwrite);
508 if ((*env)->MonitorEnter(env, obj_this) != 0)
510 ThrowException(env,
511 "java/lang/RuntimeException",
512 "native pipe cannot synchronize on the object");
513 goto error;
515 if (count != nwrite)
517 ThrowException(env,
518 "com/sun/star/io/IOException",
519 "native pipe: failed to write");
520 goto error;
523 /* done */
524 (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
525 (*env)->MonitorExit(env, obj_this);
526 return;
528 error:
529 switch (state)
531 case GOTBUFFER:
532 (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
533 case INMONITOR:
534 (*env)->MonitorExit(env, obj_this);
535 case START:
536 default:
537 break;
539 return;
542 /*****************************************************************************/
544 * Class: com_sun_star_lib_connections_pipe_PipeConnection
545 * Method: flushJNI
546 * Signature: ()V
548 SAL_DLLPUBLIC_EXPORT void
549 #if defined WNT
550 PipeConnection_flush
551 #else
552 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI
553 #endif
554 (JNIEnv * env, jobject obj_this)
556 (void) env; /* not used */
557 (void) obj_this; /* not used */
558 return;
561 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */