GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / jurt / source / pipe / com_sun_star_lib_connections_pipe_PipeConnection.c
blob15c1d96e378979206e13f4f8ebace1ba081fbaaf
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 dependencies on any other URE DLLs, as
25 Java System.LoadLibrary could otherwise not load it. Therefore, on Windows,
26 this code goes into a jpipx.dll that the jpipe.dll wrapper loads with
27 LoadLibraryEx(LOAD_WITH_ALTERED_SEARCH_PATH). The function names in this
28 wrapped code are truncated from the long JNICALL names, as JNICALL causes
29 some "@N" with different numeric values for N (and probably different across
30 32 and 64 bit) to be added to the symbol names, which the calls to
31 GetProcAddress in wrapper/wrapper.c would otheriwse have to take into
32 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 AQUIRED,
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 /* aquire pipe */
374 osl_acquirePipe( npipe );
375 state = AQUIRED;
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 >= AQUIRED )
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 case INMONITOR:
436 (*env)->MonitorExit(env, obj_this);
437 case START:
438 default:
439 break;
441 return -1;
444 /*****************************************************************************/
446 * Class: com_sun_star_lib_connections_pipe_PipeConnection
447 * Method: writeJNI
448 * Signature: ([B)V
450 SAL_DLLPUBLIC_EXPORT void
451 #if defined WNT
452 PipeConnection_write
453 #else
454 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI
455 #endif
456 (JNIEnv * env, jobject obj_this, jbyteArray buffer)
458 enum {
459 START = 0,
460 INMONITOR,
461 GOTBUFFER
464 short state = START;
465 oslPipe npipe; /* native pipe */
466 long count; /* number of bytes has been written */
467 jsize nwrite; /* number of bytes to write */
468 jbyte * nbuff = NULL; /* native buffer */
470 if ((*env)->MonitorEnter(env, obj_this) != 0)
472 ThrowException(env,
473 "java/lang/RuntimeException",
474 "native pipe cannot synchronize on the object");
475 goto error;
477 state = INMONITOR;
479 /* check connection state */
480 npipe = getPipe(env, obj_this);
481 if ((*env)->ExceptionOccurred(env) != NULL)
482 goto error;
483 if (npipe == NULL)
485 ThrowException(env,
486 "com/sun/star/io/IOException",
487 "native pipe is not connected");
488 goto error;
491 nwrite = (*env)->GetArrayLength(env, buffer);
492 if (nwrite > 0)
494 nbuff = (*env)->GetByteArrayElements(env, buffer, NULL);
495 if (nbuff == NULL)
497 ThrowException(env,
498 "java/lang/RuntimeException",
499 "native pipe out of memory");
500 goto error;
502 state = GOTBUFFER;
504 (*env)->MonitorExit(env, obj_this);
505 /* writing */
506 count = osl_writePipe(npipe, nbuff, nwrite);
507 if ((*env)->MonitorEnter(env, obj_this) != 0)
509 ThrowException(env,
510 "java/lang/RuntimeException",
511 "native pipe cannot synchronize on the object");
512 goto error;
514 if (count != nwrite)
516 ThrowException(env,
517 "com/sun/star/io/IOException",
518 "native pipe is failed to write");
519 goto error;
522 /* done */
523 (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
524 (*env)->MonitorExit(env, obj_this);
525 return;
527 error:
528 switch (state)
530 case GOTBUFFER:
531 (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
532 case INMONITOR:
533 (*env)->MonitorExit(env, obj_this);
534 case START:
535 default:
536 break;
538 return;
541 /*****************************************************************************/
543 * Class: com_sun_star_lib_connections_pipe_PipeConnection
544 * Method: flushJNI
545 * Signature: ()V
547 SAL_DLLPUBLIC_EXPORT void
548 #if defined WNT
549 PipeConnection_flush
550 #else
551 JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI
552 #endif
553 (JNIEnv * env, jobject obj_this)
555 (void) env; /* not used */
556 (void) obj_this; /* not used */
557 return;
560 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */