Update ooo320-m1
[ooovba.git] / jurt / source / pipe / com_sun_star_lib_connections_pipe_PipeConnection.c
blob3ad1b992080ab538c62a34df898ff7660cfa15a8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: com_sun_star_lib_connections_pipe_PipeConnection.c,v $
10 * $Revision: 1.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "osl/security.h"
32 #include <osl/pipe.h>
34 #include "com_sun_star_lib_connections_pipe_PipeConnection.h"
36 /*****************************************************************************/
37 /* exception macros */
39 static void ThrowException(JNIEnv * env, char const * type, char const * msg) {
40 jclass c;
41 (*env)->ExceptionClear(env);
42 c = (*env)->FindClass(env, type);
43 if (c == NULL) {
44 (*env)->ExceptionClear(env);
45 (*env)->FatalError(env, "JNI FindClass failed");
47 if ((*env)->ThrowNew(env, c, msg) != 0) {
48 (*env)->ExceptionClear(env);
49 (*env)->FatalError(env, "JNI ThrowNew failed");
53 /*****************************************************************************/
54 /* helper functions prototypes */
56 static oslPipe getPipe(JNIEnv * env, jobject obj_this);
57 static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr);
59 /*****************************************************************************/
60 /* get pipe */
62 static oslPipe getPipe(JNIEnv * env, jobject obj_this)
64 jclass tclass;
65 jfieldID fid;
66 tclass = (*env)->GetObjectClass(env, obj_this);
67 if (tclass == NULL)
69 ThrowException(env,
70 "java/lang/RuntimeException",
71 "native pipe cannot find class");
72 return NULL;
75 fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
76 if (fid == NULL)
78 ThrowException(env,
79 "java/lang/RuntimeException",
80 "native pipe cannot find field");
81 return NULL;
83 return (oslPipe) SAL_INT_CAST(
84 sal_IntPtr, (*env)->GetLongField(env, obj_this, fid));
87 /*****************************************************************************/
88 /* convert jstring to rtl_uString */
90 static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr)
92 const char * cstr;
93 rtl_uString * ustr = NULL;
94 cstr = (*env)->GetStringUTFChars(env, jstr, NULL);
95 rtl_uString_newFromAscii(&ustr, cstr);
96 (*env)->ReleaseStringUTFChars(env, jstr, cstr);
97 return ustr;
100 /*****************************************************************************/
102 * Class: com_sun_star_lib_connections_pipe_PipeConnection
103 * Method: connect
104 * Signature: (Lcom/sun/star/beans/NativeService;)V
106 JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_createJNI
107 (JNIEnv * env, jobject obj_this, jstring name)
109 enum {
110 START = 0,
111 INMONITOR,
112 GOTNAME,
113 CREATED
116 short state = START;
118 jclass tclass;
119 jfieldID fid;
121 oslSecurity psec = osl_getCurrentSecurity();
122 oslPipe npipe = NULL;
123 rtl_uString * pname = NULL;
124 if ((*env)->MonitorEnter(env, obj_this) != 0)
126 ThrowException(env,
127 "java/lang/RuntimeException",
128 "native pipe cannot synchronize on the object");
129 goto error;
131 state = INMONITOR;
133 /* check connection state */
134 npipe = getPipe(env, obj_this);
135 if ((*env)->ExceptionOccurred(env) != NULL)
136 goto error;
137 if (npipe != NULL)
139 ThrowException(env,
140 "com/sun/star/io/IOException",
141 "native pipe is already connected");
142 goto error;
145 /* save the pipe name */
146 tclass = (*env)->GetObjectClass(env, obj_this);
147 if (tclass == NULL)
149 ThrowException(env,
150 "java/lang/RuntimeException",
151 "native pipe cannot find class");
152 goto error;
155 fid = (*env)->GetFieldID(env, tclass,
156 "_aDescription", "Ljava/lang/String;");
157 if (fid == NULL)
159 ThrowException(env,
160 "java/lang/RuntimeException",
161 "native pipe cannot find field");
162 goto error;
165 (*env)->SetObjectField(env, obj_this, fid, (jobject)name);
167 /* convert pipe name to rtl_uString */
168 pname = jstring2ustring(env, name);
169 if (pname == NULL)
171 ThrowException(env,
172 "java/lang/RuntimeException",
173 "native pipe cannot convert name");
174 goto error;
176 state = GOTNAME;
178 /* try to connect */
179 npipe = osl_createPipe(pname, osl_Pipe_OPEN, psec);
180 if (npipe == NULL)
182 ThrowException(env,
183 "java/lang/RuntimeException",
184 "cannot create native pipe");
185 goto error;
187 state = CREATED;
189 /* save the pipe */
190 tclass = (*env)->GetObjectClass(env, obj_this);
191 if (tclass == NULL)
193 ThrowException(env,
194 "java/lang/RuntimeException",
195 "native pipe cannot find class");
196 goto error;
199 fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
200 if (fid == NULL)
202 ThrowException(env,
203 "java/lang/RuntimeException",
204 "native pipe cannot find field");
205 goto error;
207 (*env)->SetLongField(
208 env, obj_this, fid, SAL_INT_CAST(jlong, (sal_IntPtr) npipe));
210 /* done */
211 rtl_uString_release(pname);
212 (*env)->MonitorExit(env, obj_this);
213 osl_freeSecurityHandle(psec);
214 return;
216 error:
217 switch (state)
219 case CREATED:
220 osl_closePipe(npipe);
221 osl_releasePipe(npipe);
222 case GOTNAME:
223 rtl_uString_release(pname);
224 case INMONITOR:
225 (*env)->MonitorExit(env, obj_this);
226 case START:
227 osl_freeSecurityHandle(psec);
228 default:
229 break;
231 return;
234 /*****************************************************************************/
236 * Class: com_sun_star_lib_connections_pipe_PipeConnection
237 * Method: closeJNI
238 * Signature: ()V
240 JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_closeJNI
241 (JNIEnv * env, jobject obj_this)
243 enum {
244 START = 0,
245 INMONITOR
248 short state = START;
249 oslPipe npipe; /* native pipe */
250 jclass tclass; /* this class */
251 jfieldID fid; /* a field identifier */
253 if ((*env)->MonitorEnter(env, obj_this) != 0)
255 ThrowException(env,
256 "java/lang/RuntimeException",
257 "native pipe cannot synchronize on the object");
258 goto error;
260 state = INMONITOR;
262 /* check connection state */
263 npipe = getPipe(env, obj_this);
264 if ((*env)->ExceptionOccurred(env) != NULL)
265 goto error;
266 if (npipe == NULL)
268 ThrowException(env,
269 "com/sun/star/io/IOException",
270 "native pipe is not connected");
271 goto error;
274 /* remove the reference to the pipe */
275 tclass = (*env)->GetObjectClass(env, obj_this);
276 if (tclass == NULL)
278 ThrowException(env,
279 "java/lang/RuntimeException",
280 "native pipe cannot find class");
281 goto error;
284 fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
285 if (fid == NULL)
287 ThrowException(env,
288 "java/lang/RuntimeException",
289 "native pipe cannot find field");
290 goto error;
293 (*env)->SetLongField(env, obj_this, fid, (jlong)0);
295 /* release the pipe */
296 osl_closePipe(npipe);
297 osl_releasePipe(npipe);
299 /* done */
300 (*env)->MonitorExit(env, obj_this);
301 return;
303 error:
304 switch (state)
306 case INMONITOR:
307 (*env)->MonitorExit(env, obj_this);
308 case START:
309 default:
310 break;
312 return;
315 /*****************************************************************************/
317 * Class: com_sun_star_lib_connections_pipe_PipeConnection
318 * Method: readJNI
319 * Signature: ([[BI)I
321 JNIEXPORT jint JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_readJNI
322 (JNIEnv * env, jobject obj_this, jobjectArray buffer, jint len)
324 enum {
325 START = 0,
326 INMONITOR,
327 AQUIRED,
328 GOTBUFFER
331 short state = START;
332 oslPipe npipe; /* native pipe */
333 void * nbuff = NULL; /* native read buffer */
334 jbyteArray bytes; /* java read buffer */
335 jint nread; /* number of bytes has been read */
337 /* enter monitor */
338 if ((*env)->MonitorEnter(env, obj_this) != 0)
340 ThrowException(env,
341 "java/lang/RuntimeException",
342 "native pipe cannot synchronize on the object");
343 goto error;
345 state = INMONITOR;
347 /* check connection state */
348 npipe = getPipe(env, obj_this);
349 if ((*env)->ExceptionOccurred(env) != NULL)
350 goto error;
351 if (npipe == NULL)
353 ThrowException(env,
354 "com/sun/star/io/IOException",
355 "native pipe is not connected");
356 goto error;
359 /* aquire pipe */
360 osl_acquirePipe( npipe );
361 state = AQUIRED;
363 /* allocate a buffer */
364 if ((nbuff = malloc(len)) == NULL)
366 ThrowException(env,
367 "java/lang/RuntimeException",
368 "native pipe out of memory");
369 goto error;
372 state = GOTBUFFER;
374 /* exit monitor */
375 (*env)->MonitorExit(env, obj_this);
377 /* reading */
378 nread = osl_readPipe(npipe, nbuff, len);
380 /* enter monitor again */
381 if ((*env)->MonitorEnter(env, obj_this) != 0)
383 ThrowException(env,
384 "java/lang/RuntimeException",
385 "native pipe cannot synchronize on the object");
386 goto error;
389 /* copy buffer */
390 if (nread >= 0)
392 bytes = (*env)->NewByteArray(env, len);
393 if (bytes == NULL)
395 ThrowException(env,
396 "java/lang/RuntimeException",
397 "native pipe out of memory");
398 goto error;
401 /* save the data */
402 (*env)->SetByteArrayRegion(env, bytes, 0, len, nbuff);
403 (*env)->SetObjectArrayElement(env, buffer, 0, bytes);
404 (*env)->DeleteLocalRef(env, bytes);
407 /* done */
408 free(nbuff);
409 if ( state >= AQUIRED )
410 osl_releasePipe( npipe );
412 /* exit monitor */
413 (*env)->MonitorExit(env, obj_this);
414 return nread;
416 error:
417 switch (state)
419 case GOTBUFFER:
420 free(nbuff);
421 case INMONITOR:
422 (*env)->MonitorExit(env, obj_this);
423 case START:
424 default:
425 break;
427 return -1;
430 /*****************************************************************************/
432 * Class: com_sun_star_lib_connections_pipe_PipeConnection
433 * Method: writeJNI
434 * Signature: ([B)V
436 JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI
437 (JNIEnv * env, jobject obj_this, jbyteArray buffer)
439 enum {
440 START = 0,
441 INMONITOR,
442 GOTBUFFER
445 short state = START;
446 oslPipe npipe; /* native pipe */
447 long count; /* number of bytes has been written */
448 jsize nwrite; /* number of bytes to write */
449 jbyte * nbuff = NULL; /* native buffer */
451 if ((*env)->MonitorEnter(env, obj_this) != 0)
453 ThrowException(env,
454 "java/lang/RuntimeException",
455 "native pipe cannot synchronize on the object");
456 goto error;
458 state = INMONITOR;
460 /* check connection state */
461 npipe = getPipe(env, obj_this);
462 if ((*env)->ExceptionOccurred(env) != NULL)
463 goto error;
464 if (npipe == NULL)
466 ThrowException(env,
467 "com/sun/star/io/IOException",
468 "native pipe is not connected");
469 goto error;
472 nwrite = (*env)->GetArrayLength(env, buffer);
473 if (nwrite > 0)
475 nbuff = (*env)->GetByteArrayElements(env, buffer, NULL);
476 if (nbuff == NULL)
478 ThrowException(env,
479 "java/lang/RuntimeException",
480 "native pipe out of memory");
481 goto error;
483 state = GOTBUFFER;
485 (*env)->MonitorExit(env, obj_this);
486 /* writing */
487 count = osl_writePipe(npipe, nbuff, nwrite);
488 if ((*env)->MonitorEnter(env, obj_this) != 0)
490 ThrowException(env,
491 "java/lang/RuntimeException",
492 "native pipe cannot synchronize on the object");
493 goto error;
495 if (count != nwrite)
497 ThrowException(env,
498 "com/sun/star/io/IOException",
499 "native pipe is failed to write");
500 goto error;
503 /* done */
504 (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
505 (*env)->MonitorExit(env, obj_this);
506 return;
508 error:
509 switch (state)
511 case GOTBUFFER:
512 (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
513 case INMONITOR:
514 (*env)->MonitorExit(env, obj_this);
515 case START:
516 default:
517 break;
519 return;
522 /*****************************************************************************/
524 * Class: com_sun_star_lib_connections_pipe_PipeConnection
525 * Method: flushJNI
526 * Signature: ()V
528 JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI
529 (JNIEnv * env, jobject obj_this)
531 (void) env; /* not used */
532 (void) obj_this; /* not used */
533 return;