/**
 * Internal utility to read from a socket, synchronously.
 *
 * @param handle the open socket handle
 * @param buf the buffer into which to read
 * @param len the number of bytes to attempt to read
 * 
 * @return -1 if error, otherwise the number of bytes actually read
 */
static int
utilRead(
    void *handle,
    unsigned char *buf,
    int len)
{
    int status;
    int nread;
    void *context;

    status = pcsl_socket_read_start(
	handle, buf, len, &nread, &context);

    if (status == PCSL_NET_SUCCESS) {
	return nread;
    }

    if (status == PCSL_NET_WOULDBLOCK) {
	if (wait_on_handle(handle, 1)) {
	    status =
		pcsl_socket_read_finish(handle, buf, len, &nread, context);
	    if (status == PCSL_NET_SUCCESS) {
		return nread;
	    }
	}
    }

    return -1;
}
static int do_pcsl_read(void *handle, char *buffer, int length) {
  void *context;
  int nread;
  int status = pcsl_socket_read_start(
	handle, (unsigned char*)buffer, length, &nread, &context);
  if (status == PCSL_NET_WOULDBLOCK) {
    do {
      status = pcsl_socket_read_finish(handle, (unsigned char*) buffer, length,
                                       &nread, context);
    } while (status == PCSL_NET_WOULDBLOCK);
  }

  if (status == PCSL_NET_SUCCESS && nread > 0) {
    return nread;
  } else {
    return -1;
  }
}
Exemple #3
0
/**
 * Reads from the open socket connection.
 * <p>
 * Java declaration:
 * <pre>
 *     read0([BII)I
 * </pre>
 *
 * @param b the buffer into which the data is read.
 * @param off the start offset in array <code>b</code>
 *            at which the data is written.
 * @param len the maximum number of bytes to read.
 *
 * @return the total number of bytes read into the buffer, or
 *         <tt>-1</tt> if there is no more data because the end of
 *         the stream has been reached.
 */
KNIEXPORT KNI_RETURNTYPE_INT
Java_com_sun_midp_io_j2me_socket_Protocol_read0(void) {
    int length;
    int offset;
    void *pcslHandle;
    int bytesRead = -1;
    int status = PCSL_NET_INVALID;
    void* context = NULL;
    MidpReentryData* info;

    length = (int)KNI_GetParameterAsInt(3);
    offset = (int)KNI_GetParameterAsInt(2);

    KNI_StartHandles(2);
    
    KNI_DeclareHandle(bufferObject);
    KNI_DeclareHandle(thisObject);
    KNI_GetThisPointer(thisObject);
    KNI_GetParameterAsObject(1, bufferObject);
    
    pcslHandle = (void *)(getMidpSocketProtocolPtr(thisObject)->handle);

    REPORT_INFO3(LC_PROTOCOL, "socket::read0 o=%d l=%d fd=%d\n", 
                 offset, length, (int)pcslHandle);

    info = (MidpReentryData*)SNI_GetReentryData(NULL);

    START_NETWORK_INDICATOR;

    if (info == NULL) {   /* First invocation */
        if (INVALID_HANDLE == pcslHandle) {
            KNI_ThrowNew(midpIOException, "invalid handle during socket::read");
        } else {
            INC_NETWORK_INDICATOR;
            SNI_BEGIN_RAW_POINTERS;
            status = pcsl_socket_read_start(pcslHandle, 
                           (unsigned char*)&(JavaByteArray(bufferObject)[offset]),
                           length, &bytesRead, &context);
            SNI_END_RAW_POINTERS;
        }
    } else {  /* Reinvocation after unblocking the thread */
        if (INVALID_HANDLE == pcslHandle) {
            /* closed by another thread */
            KNI_ThrowNew(midpInterruptedIOException, 
                         "Interrupted IO error during socket::read");
            DEC_NETWORK_INDICATOR;
        } else {
            if ((void *)info->descriptor != pcslHandle) {
                REPORT_CRIT2(LC_PROTOCOL, 
                             "socket::read Handles mismatched 0x%x != 0x%x\n", 
                             pcslHandle,
                             info->descriptor);
            }
            context = info->pResult;
            SNI_BEGIN_RAW_POINTERS;
            status = pcsl_socket_read_finish(pcslHandle, 
                       (unsigned char*)&(JavaByteArray(bufferObject)[offset]),
                       length, &bytesRead, context);
            SNI_END_RAW_POINTERS;
        }
    }

    REPORT_INFO1(LC_PROTOCOL, "socket::read0 bytesRead=%d\n", bytesRead);

    if (INVALID_HANDLE != pcslHandle) {
        if (status == PCSL_NET_SUCCESS) {
            if (bytesRead == 0) {
                /* end of stream */
                bytesRead = -1;
            }
            DEC_NETWORK_INDICATOR;
        } else {
            REPORT_INFO1(LC_PROTOCOL, "socket::read error=%d\n", 
                         pcsl_network_error(pcslHandle));

            if (status == PCSL_NET_WOULDBLOCK) {
                midp_thread_wait(NETWORK_READ_SIGNAL, (int)pcslHandle, context);
            } else if (status == PCSL_NET_INTERRUPTED) {
                midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,
                        "Interrupted IO error %d during socket::read ", 
                        pcsl_network_error(pcslHandle));
                KNI_ThrowNew(midpInterruptedIOException, gKNIBuffer);
                DEC_NETWORK_INDICATOR;
            } else {
                midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,
                        "Unknown error %d during socket::read ", 
                        pcsl_network_error(pcslHandle));
                KNI_ThrowNew(midpIOException, gKNIBuffer);
                DEC_NETWORK_INDICATOR;
            }
        }
    }

    STOP_NETWORK_INDICATOR;

    KNI_EndHandles();
    KNI_ReturnInt((jint)bytesRead);
}