openldap_read_function(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
    Connection *conn = NULL;
    /* copy up to bytes_to_read bytes into the caller's buffer, return the number of bytes copied */
    ber_slen_t bytes_to_copy = 0;
    char *readbuf; /* buffer to "read" from */
    size_t max;    /* number of bytes currently stored in the buffer */
    size_t offset; /* offset to the location of new data in the buffer */

    PR_ASSERT(sbiod);
    PR_ASSERT(sbiod->sbiod_pvt);

    conn = (Connection *)sbiod->sbiod_pvt;

    if (CONNECTION_BUFFER_OFF == conn->c_private->use_buffer) {
        bytes_to_copy = PR_Recv(conn->c_prfd, buf, len, 0, PR_INTERVAL_NO_WAIT);
        goto done;
    }

    PR_ASSERT(conn->c_private->c_buffer);

    readbuf = conn->c_private->c_buffer;
    max = conn->c_private->c_buffer_bytes;
    offset = conn->c_private->c_buffer_offset;

    if (len <= (max - offset)) {
        bytes_to_copy = len; /* we have enough buffered data */
    } else {
        bytes_to_copy = max - offset; /* just return what we have */
    }

    if (bytes_to_copy <= 0) {
        bytes_to_copy = 0; /* never return a negative result */
                           /* in this case, we don't have enough data to satisfy the
           caller, so we have to let it know we need more */
#if defined(EWOULDBLOCK)
        errno = EWOULDBLOCK;
#elif defined(EAGAIN)
        errno = EAGAIN;
#endif
        PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
    } else {
        /* copy buffered data into output buf */
        SAFEMEMCPY(buf, readbuf + offset, bytes_to_copy);
        conn->c_private->c_buffer_offset += bytes_to_copy;
    }
done:
    return bytes_to_copy;
}
openldap_read_function(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
    Connection *conn = NULL;
     
    ber_slen_t bytes_to_copy = 0;
    char *readbuf;  
    size_t max;     
    size_t offset;  

    PR_ASSERT(sbiod);
    PR_ASSERT(sbiod->sbiod_pvt);

    conn = (Connection *)sbiod->sbiod_pvt;

    if (CONNECTION_BUFFER_OFF == conn->c_private->use_buffer) {
        bytes_to_copy = PR_Recv(conn->c_prfd, buf, len, 0, PR_INTERVAL_NO_WAIT);
        goto done;
    }

    PR_ASSERT(conn->c_private->c_buffer);

    readbuf = conn->c_private->c_buffer;
    max = conn->c_private->c_buffer_bytes;
    offset = conn->c_private->c_buffer_offset;

    if (len <= (max - offset)) {
        bytes_to_copy = len;  
    } else {
        bytes_to_copy = max - offset;  
    }

    if (bytes_to_copy <= 0) {
        bytes_to_copy = 0;  
                            
#if defined(EWOULDBLOCK)
        errno = EWOULDBLOCK;
#elif defined(EAGAIN)
        errno = EAGAIN;
#endif
        PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
    } else {
         
        SAFEMEMCPY(buf, readbuf + offset, bytes_to_copy);
        conn->c_private->c_buffer_offset += bytes_to_copy;
    }
done:
    return bytes_to_copy;
}