LCOV - code coverage report
Current view: top level - jurt/source/pipe - com_sun_star_lib_connections_pipe_PipeConnection.c (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 121 191 63.4 %
Date: 2014-04-11 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          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             : #include "jni.h"
      21             : #include "osl/security.h"
      22             : #include <osl/pipe.h>
      23             : 
      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.
      33             : */
      34             : 
      35             : /*****************************************************************************/
      36             : /* exception macros */
      37             : 
      38         329 : static void ThrowException(JNIEnv * env, char const * type, char const * msg) {
      39             :     jclass c;
      40         329 :     (*env)->ExceptionClear(env);
      41         329 :     c = (*env)->FindClass(env, type);
      42         329 :     if (c == NULL) {
      43           0 :         (*env)->ExceptionClear(env);
      44           0 :         (*env)->FatalError(env, "JNI FindClass failed");
      45             :     }
      46         329 :     if ((*env)->ThrowNew(env, c, msg) != 0) {
      47           0 :         (*env)->ExceptionClear(env);
      48           0 :         (*env)->FatalError(env, "JNI ThrowNew failed");
      49             :     }
      50         329 : }
      51             : 
      52             : /*****************************************************************************/
      53             : /* helper functions prototypes */
      54             : 
      55             : static oslPipe getPipe(JNIEnv * env, jobject obj_this);
      56             : static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr);
      57             : 
      58             : /*****************************************************************************/
      59             : /* get pipe */
      60             : 
      61     4177322 : static oslPipe getPipe(JNIEnv * env, jobject obj_this)
      62             : {
      63             :     jclass      tclass;
      64             :     jfieldID    fid;
      65     4177322 :     tclass  = (*env)->GetObjectClass(env, obj_this);
      66     4177322 :     if (tclass == NULL)
      67             :     {
      68           0 :         ThrowException(env,
      69             :                        "java/lang/RuntimeException",
      70             :                        "native pipe cannot find class");
      71           0 :         return NULL;
      72             :     }
      73             : 
      74     4177322 :     fid     = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
      75     4177322 :     if (fid == NULL)
      76             :     {
      77           0 :         ThrowException(env,
      78             :                        "java/lang/RuntimeException",
      79             :                        "native pipe cannot find field");
      80           0 :         return NULL;
      81             :     }
      82     4177322 :     return (oslPipe) SAL_INT_CAST(
      83             :         sal_IntPtr, (*env)->GetLongField(env, obj_this, fid));
      84             : }
      85             : 
      86             : /*****************************************************************************/
      87             : /* convert jstring to rtl_uString */
      88             : 
      89         376 : static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr)
      90             : {
      91             :     const char *    cstr;
      92         376 :     rtl_uString *   ustr    = NULL;
      93         376 :     cstr    = (*env)->GetStringUTFChars(env, jstr, NULL);
      94         376 :     rtl_uString_newFromAscii(&ustr, cstr);
      95         376 :     (*env)->ReleaseStringUTFChars(env, jstr, cstr);
      96         376 :     return ustr;
      97             : }
      98             : 
      99             : /*****************************************************************************/
     100             : /*
     101             :  * Class:     com_sun_star_lib_connections_pipe_PipeConnection
     102             :  * Method:    connect
     103             :  * Signature: (Lcom/sun/star/beans/NativeService;)V
     104             :  */
     105             : SAL_DLLPUBLIC_EXPORT void
     106             : #if defined WNT
     107             : PipeConnection_create
     108             : #else
     109         376 : JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_createJNI
     110             : #endif
     111             :   (JNIEnv * env, jobject obj_this, jstring name)
     112             : {
     113             :     enum {
     114             :         START   = 0,
     115             :         INMONITOR,
     116             :         GOTNAME,
     117             :         CREATED
     118             :     };
     119             : 
     120         376 :     short       state   = START;
     121             : 
     122             :     jclass      tclass;
     123             :     jfieldID    fid;
     124             : 
     125         376 :     oslSecurity     psec    = osl_getCurrentSecurity();
     126         376 :     oslPipe         npipe   = NULL;
     127         376 :     rtl_uString *   pname   = NULL;
     128         376 :     if ((*env)->MonitorEnter(env, obj_this) != 0)
     129             :     {
     130           0 :         ThrowException(env,
     131             :                        "java/lang/RuntimeException",
     132             :                        "native pipe cannot synchronize on the object");
     133           0 :         goto error;
     134             :     }
     135         376 :     state   = INMONITOR;
     136             : 
     137             :     /* check connection state */
     138         376 :     npipe   = getPipe(env, obj_this);
     139         376 :     if ((*env)->ExceptionOccurred(env) != NULL)
     140           0 :         goto error;
     141         376 :     if (npipe != NULL)
     142             :     {
     143           0 :         ThrowException(env,
     144             :                        "com/sun/star/io/IOException",
     145             :                        "native pipe is already connected");
     146           0 :         goto error;
     147             :     }
     148             : 
     149             :     /* save the pipe name */
     150         376 :     tclass  = (*env)->GetObjectClass(env, obj_this);
     151         376 :     if (tclass == NULL)
     152             :     {
     153           0 :         ThrowException(env,
     154             :                        "java/lang/RuntimeException",
     155             :                        "native pipe cannot find class");
     156           0 :         goto error;
     157             :     }
     158             : 
     159         376 :     fid     = (*env)->GetFieldID(env, tclass,
     160             :                                  "_aDescription", "Ljava/lang/String;");
     161         376 :     if (fid == NULL)
     162             :     {
     163           0 :         ThrowException(env,
     164             :                        "java/lang/RuntimeException",
     165             :                        "native pipe cannot find field");
     166           0 :         goto error;
     167             :     }
     168             : 
     169         376 :     (*env)->SetObjectField(env, obj_this, fid, (jobject)name);
     170             : 
     171             :     /* convert pipe name to rtl_uString */
     172         376 :     pname   = jstring2ustring(env, name);
     173         376 :     if (pname == NULL)
     174             :     {
     175           0 :         ThrowException(env,
     176             :                        "java/lang/RuntimeException",
     177             :                        "native pipe cannot convert name");
     178           0 :         goto error;
     179             :     }
     180         376 :     state   = GOTNAME;
     181             : 
     182             :     /* try to connect */
     183         376 :     npipe   = osl_createPipe(pname, osl_Pipe_OPEN, psec);
     184         376 :     if (npipe == NULL)
     185             :     {
     186         329 :         ThrowException(env,
     187             :                        "java/lang/RuntimeException",
     188             :                        "cannot create native pipe");
     189         329 :         goto error;
     190             :     }
     191          47 :     state   = CREATED;
     192             : 
     193             :     /* save the pipe */
     194          47 :     tclass  = (*env)->GetObjectClass(env, obj_this);
     195          47 :     if (tclass == NULL)
     196             :     {
     197           0 :         ThrowException(env,
     198             :                        "java/lang/RuntimeException",
     199             :                        "native pipe cannot find class");
     200           0 :         goto error;
     201             :     }
     202             : 
     203          47 :     fid     = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
     204          47 :     if (fid == NULL)
     205             :     {
     206           0 :         ThrowException(env,
     207             :                        "java/lang/RuntimeException",
     208             :                        "native pipe cannot find field");
     209           0 :         goto error;
     210             :     }
     211          94 :     (*env)->SetLongField(
     212          47 :         env, obj_this, fid, SAL_INT_CAST(jlong, (sal_IntPtr) npipe));
     213             : 
     214             :     /* done */
     215          47 :     rtl_uString_release(pname);
     216          47 :     (*env)->MonitorExit(env, obj_this);
     217          47 :     osl_freeSecurityHandle(psec);
     218          47 :     return;
     219             : 
     220             :  error:
     221         329 :     switch (state)
     222             :     {
     223             :         case CREATED:
     224           0 :             osl_closePipe(npipe);
     225           0 :             osl_releasePipe(npipe);
     226             :         case GOTNAME:
     227         329 :             rtl_uString_release(pname);
     228             :         case INMONITOR:
     229         329 :             (*env)->MonitorExit(env, obj_this);
     230             :         case START:
     231         329 :             osl_freeSecurityHandle(psec);
     232             :         default:
     233         329 :             break;
     234             :     }
     235         329 :     return;
     236             : }
     237             : 
     238             : /*****************************************************************************/
     239             : /*
     240             :  * Class:     com_sun_star_lib_connections_pipe_PipeConnection
     241             :  * Method:    closeJNI
     242             :  * Signature: ()V
     243             :  */
     244             : SAL_DLLPUBLIC_EXPORT void
     245             : #if defined WNT
     246             : PipeConnection_close
     247             : #else
     248          47 : JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_closeJNI
     249             : #endif
     250             :   (JNIEnv * env, jobject obj_this)
     251             : {
     252             :     enum {
     253             :         START   = 0,
     254             :         INMONITOR
     255             :     };
     256             : 
     257          47 :     short       state   = START;
     258             :     oslPipe     npipe;      /* native pipe */
     259             :     jclass      tclass;     /* this class */
     260             :     jfieldID    fid;        /* a field identifier */
     261             : 
     262          47 :     if ((*env)->MonitorEnter(env, obj_this) != 0)
     263             :     {
     264           0 :         ThrowException(env,
     265             :                        "java/lang/RuntimeException",
     266             :                        "native pipe cannot synchronize on the object");
     267           0 :         goto error;
     268             :     }
     269          47 :     state   = INMONITOR;
     270             : 
     271             :     /* check connection state */
     272          47 :     npipe   = getPipe(env, obj_this);
     273          47 :     if ((*env)->ExceptionOccurred(env) != NULL)
     274           0 :         goto error;
     275          47 :     if (npipe == NULL)
     276             :     {
     277           0 :         ThrowException(env,
     278             :                        "com/sun/star/io/IOException",
     279             :                        "native pipe is not connected");
     280           0 :         goto error;
     281             :     }
     282             : 
     283             :     /* remove the reference to the pipe */
     284          47 :     tclass  = (*env)->GetObjectClass(env, obj_this);
     285          47 :     if (tclass == NULL)
     286             :     {
     287           0 :         ThrowException(env,
     288             :                        "java/lang/RuntimeException",
     289             :                        "native pipe cannot find class");
     290           0 :         goto error;
     291             :     }
     292             : 
     293          47 :     fid     = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J");
     294          47 :     if (fid == NULL)
     295             :     {
     296           0 :         ThrowException(env,
     297             :                        "java/lang/RuntimeException",
     298             :                        "native pipe cannot find field");
     299           0 :         goto error;
     300             :     }
     301             : 
     302          47 :     (*env)->SetLongField(env, obj_this, fid, (jlong)0);
     303             : 
     304             :     /* release the pipe */
     305          47 :     osl_closePipe(npipe);
     306          47 :     osl_releasePipe(npipe);
     307             : 
     308             :     /* done */
     309          47 :     (*env)->MonitorExit(env, obj_this);
     310          47 :     return;
     311             : 
     312             :  error:
     313           0 :     switch (state)
     314             :     {
     315             :         case INMONITOR:
     316           0 :             (*env)->MonitorExit(env, obj_this);
     317             :         case START:
     318             :         default:
     319           0 :             break;
     320             :     }
     321           0 :     return;
     322             : }
     323             : 
     324             : /*****************************************************************************/
     325             : /*
     326             :  * Class:     com_sun_star_lib_connections_pipe_PipeConnection
     327             :  * Method:    readJNI
     328             :  * Signature: ([[BI)I
     329             :  */
     330             : SAL_DLLPUBLIC_EXPORT jint
     331             : #if defined WNT
     332             : PipeConnection_read
     333             : #else
     334     1864997 : JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_readJNI
     335             : #endif
     336             :   (JNIEnv * env, jobject obj_this, jobjectArray buffer, jint len)
     337             : {
     338             :     enum {
     339             :         START   = 0,
     340             :         INMONITOR,
     341             :         AQUIRED,
     342             :         GOTBUFFER
     343             :     };
     344             : 
     345     1864997 :     short       state   = START;
     346             :     oslPipe     npipe;          /* native pipe */
     347     1864997 :     void *      nbuff = NULL;   /* native read buffer */
     348             :     jbyteArray  bytes;          /* java read buffer */
     349             :     jint        nread;          /* number of bytes has been read */
     350             : 
     351             :     /* enter monitor */
     352     1864997 :     if ((*env)->MonitorEnter(env, obj_this) != 0)
     353             :     {
     354           0 :         ThrowException(env,
     355             :                        "java/lang/RuntimeException",
     356             :                        "native pipe cannot synchronize on the object");
     357           0 :         goto error;
     358             :     }
     359     1864997 :     state = INMONITOR;
     360             : 
     361             :     /* check connection state */
     362     1864997 :     npipe   = getPipe(env, obj_this);
     363     1864997 :     if ((*env)->ExceptionOccurred(env) != NULL)
     364           0 :         goto error;
     365     1864997 :     if (npipe == NULL)
     366             :     {
     367           0 :         ThrowException(env,
     368             :                        "com/sun/star/io/IOException",
     369             :                        "native pipe is not connected");
     370           0 :         goto error;
     371             :     }
     372             : 
     373             :     /* aquire pipe */
     374     1864997 :     osl_acquirePipe( npipe );
     375     1864997 :     state = AQUIRED;
     376             : 
     377             :     /* allocate a buffer */
     378     1864997 :     if ((nbuff = malloc(len)) == NULL)
     379             :     {
     380           0 :         ThrowException(env,
     381             :                        "java/lang/RuntimeException",
     382             :                        "native pipe out of memory");
     383           0 :         goto error;
     384             :     }
     385             : 
     386     1864997 :     state = GOTBUFFER;
     387             : 
     388             :     /* exit monitor */
     389     1864997 :     (*env)->MonitorExit(env, obj_this);
     390             : 
     391             :     /* reading */
     392     1864997 :     nread = osl_readPipe(npipe, nbuff, len);
     393             : 
     394             :     /* enter monitor again */
     395     1864997 :     if ((*env)->MonitorEnter(env, obj_this) != 0)
     396             :     {
     397           0 :         ThrowException(env,
     398             :                        "java/lang/RuntimeException",
     399             :                        "native pipe cannot synchronize on the object");
     400           0 :         goto error;
     401             :     }
     402             : 
     403             :     /* copy buffer */
     404     1864997 :     if (nread >= 0)
     405             :     {
     406     1864997 :         bytes   = (*env)->NewByteArray(env, len);
     407     1864997 :         if (bytes == NULL)
     408             :         {
     409           0 :             ThrowException(env,
     410             :                            "java/lang/RuntimeException",
     411             :                            "native pipe out of memory");
     412           0 :             goto error;
     413             :         }
     414             : 
     415             :         /* save the data */
     416     1864997 :         (*env)->SetByteArrayRegion(env, bytes, 0, len, nbuff);
     417     1864997 :         (*env)->SetObjectArrayElement(env, buffer, 0, bytes);
     418     1864997 :         (*env)->DeleteLocalRef(env, bytes);
     419             :     }
     420             : 
     421             :     /* done */
     422     1864997 :     free(nbuff);
     423     1864997 :     if ( state >= AQUIRED )
     424     1864997 :         osl_releasePipe( npipe );
     425             : 
     426             :     /* exit monitor */
     427     1864997 :     (*env)->MonitorExit(env, obj_this);
     428     1864997 :     return nread;
     429             : 
     430             :  error:
     431           0 :     switch (state)
     432             :     {
     433             :         case GOTBUFFER:
     434           0 :             free(nbuff);
     435             :         case INMONITOR:
     436           0 :             (*env)->MonitorExit(env, obj_this);
     437             :         case START:
     438             :         default:
     439           0 :             break;
     440             :     }
     441           0 :     return -1;
     442             : }
     443             : 
     444             : /*****************************************************************************/
     445             : /*
     446             :  * Class:     com_sun_star_lib_connections_pipe_PipeConnection
     447             :  * Method:    writeJNI
     448             :  * Signature: ([B)V
     449             :  */
     450             : SAL_DLLPUBLIC_EXPORT void
     451             : #if defined WNT
     452             : PipeConnection_write
     453             : #else
     454     2311902 : JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI
     455             : #endif
     456             :   (JNIEnv * env, jobject obj_this, jbyteArray buffer)
     457             : {
     458             :     enum {
     459             :         START   = 0,
     460             :         INMONITOR,
     461             :         GOTBUFFER
     462             :     };
     463             : 
     464     2311902 :     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     2311902 :     jbyte * nbuff = NULL;   /* native buffer */
     469             : 
     470     2311902 :     if ((*env)->MonitorEnter(env, obj_this) != 0)
     471             :     {
     472           0 :         ThrowException(env,
     473             :                        "java/lang/RuntimeException",
     474             :                        "native pipe cannot synchronize on the object");
     475           0 :         goto error;
     476             :     }
     477     2311902 :     state   = INMONITOR;
     478             : 
     479             :     /* check connection state */
     480     2311902 :     npipe   = getPipe(env, obj_this);
     481     2311902 :     if ((*env)->ExceptionOccurred(env) != NULL)
     482           0 :         goto error;
     483     2311902 :     if (npipe == NULL)
     484             :     {
     485           0 :         ThrowException(env,
     486             :                        "com/sun/star/io/IOException",
     487             :                        "native pipe is not connected");
     488           0 :         goto error;
     489             :     }
     490             : 
     491     2311902 :     nwrite  = (*env)->GetArrayLength(env, buffer);
     492     2311902 :     if (nwrite > 0)
     493             :     {
     494     2311902 :         nbuff   = (*env)->GetByteArrayElements(env, buffer, NULL);
     495     2311902 :         if (nbuff == NULL)
     496             :         {
     497           0 :             ThrowException(env,
     498             :                            "java/lang/RuntimeException",
     499             :                            "native pipe out of memory");
     500           0 :             goto error;
     501             :         }
     502     2311902 :         state   = GOTBUFFER;
     503             : 
     504     2311902 :         (*env)->MonitorExit(env, obj_this);
     505             :         /* writing */
     506     2311902 :         count   = osl_writePipe(npipe, nbuff, nwrite);
     507     2311902 :         if ((*env)->MonitorEnter(env, obj_this) != 0)
     508             :         {
     509           0 :             ThrowException(env,
     510             :                            "java/lang/RuntimeException",
     511             :                            "native pipe cannot synchronize on the object");
     512           0 :             goto error;
     513             :         }
     514     2311902 :         if (count != nwrite)
     515             :         {
     516           0 :             ThrowException(env,
     517             :                            "com/sun/star/io/IOException",
     518             :                            "native pipe: failed to write");
     519           0 :             goto error;
     520             :         }
     521             :     }
     522             :     /* done */
     523     2311902 :     (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
     524     2311902 :     (*env)->MonitorExit(env, obj_this);
     525     2311902 :     return;
     526             : 
     527             :  error:
     528           0 :     switch (state)
     529             :     {
     530             :         case GOTBUFFER:
     531           0 :             (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT);
     532             :         case INMONITOR:
     533           0 :             (*env)->MonitorExit(env, obj_this);
     534             :         case START:
     535             :         default:
     536           0 :             break;
     537             :     }
     538           0 :     return;
     539             : }
     540             : 
     541             : /*****************************************************************************/
     542             : /*
     543             :  * Class:     com_sun_star_lib_connections_pipe_PipeConnection
     544             :  * Method:    flushJNI
     545             :  * Signature: ()V
     546             :  */
     547             : SAL_DLLPUBLIC_EXPORT void
     548             : #if defined WNT
     549             : PipeConnection_flush
     550             : #else
     551      202772 : JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI
     552             : #endif
     553             :   (JNIEnv * env, jobject obj_this)
     554             : {
     555             :     (void) env; /* not used */
     556             :     (void) obj_this; /* not used */
     557      202772 :     return;
     558             : }
     559             : 
     560             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10