/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 *
 * @author Mladen Turk
 * @version $Revision$, $Date$
 */

#include "tcn.h"

#ifdef TCN_DO_STATISTICS

#include "apr_atomic.h"

static volatile apr_uint32_t sp_created  = 0;
static volatile apr_uint32_t sp_closed   = 0;
static volatile apr_uint32_t sp_cleared  = 0;
static volatile apr_uint32_t sp_accepted = 0;
static volatile apr_uint32_t sp_max_send = 0;
static volatile apr_uint32_t sp_min_send = 10000000;
static volatile apr_uint32_t sp_num_send = 0;
static volatile apr_off_t    sp_tot_send = 0;
static volatile apr_uint32_t sp_max_recv = 0;
static volatile apr_uint32_t sp_min_recv = 10000000;
static volatile apr_uint32_t sp_num_recv = 0;
static volatile apr_off_t    sp_tot_recv = 0;
static volatile apr_uint32_t sp_err_recv = 0;
static volatile apr_uint32_t sp_tmo_recv = 0;
static volatile apr_uint32_t sp_rst_recv = 0;
static volatile apr_status_t sp_erl_recv = 0;

static volatile apr_size_t   sf_max_send = 0;
static volatile apr_size_t   sf_min_send = 10000000;
static volatile apr_uint32_t sf_num_send = 0;
static volatile apr_off_t    sf_tot_send = 0;

void sp_network_dump_statistics()
{
    fprintf(stderr, "Network Statistics ......\n");
    fprintf(stderr, "Sockets created         : %d\n", sp_created);
    fprintf(stderr, "Sockets accepted        : %d\n", sp_accepted);
    fprintf(stderr, "Sockets closed          : %d\n", sp_closed);
    fprintf(stderr, "Sockets cleared         : %d\n", sp_cleared);
    fprintf(stderr, "Total send calls        : %d\n", sp_num_send);
    fprintf(stderr, "Minimum send length     : %d\n", sp_min_send);
    fprintf(stderr, "Maximum send length     : %d\n", sp_max_send);
    fprintf(stderr, "Average send length     : %.2f\n", (double)sp_tot_send/(double)sp_num_send);
    fprintf(stderr, "Total recv calls        : %d\n", sp_num_recv);
    fprintf(stderr, "Minimum recv length     : %d\n", sp_min_recv);
    fprintf(stderr, "Maximum recv length     : %d\n", sp_max_recv);
    fprintf(stderr, "Average recv length     : %.2f\n", (double)sp_tot_recv/(double)sp_num_recv);
    fprintf(stderr, "Receive timeouts        : %d\n", sp_tmo_recv);
    fprintf(stderr, "Receive errors          : %d\n", sp_err_recv);
    fprintf(stderr, "Receive resets          : %d\n", sp_rst_recv);
    fprintf(stderr, "Last receive error      : %d\n", sp_erl_recv);

    fprintf(stderr, "Total sendfile calls    : %d\n", sf_num_send);
    fprintf(stderr, "Minimum sendfile lenght : %" APR_SIZE_T_FMT "\n", sf_min_send);
    fprintf(stderr, "Maximum sendfile lenght : %" APR_SIZE_T_FMT "\n", sf_max_send);

}

#endif /* TCN_DO_STATISTICS */

static apr_status_t sp_socket_cleanup(void *data)
{
    tcn_socket_t *s = (tcn_socket_t *)data;

    if (s->net && s->net->cleanup)
        (*s->net->cleanup)(s->opaque);
    if (s->sock) {
        apr_socket_t *as = s->sock;
        s->sock = NULL;
        apr_socket_close(as);
    }
#ifdef TCN_DO_STATISTICS
    apr_atomic_inc32(&sp_cleared);
#endif
    return APR_SUCCESS;
}

#if defined(DEBUG) || defined(_DEBUG)
static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
{
    return apr_socket_send(sock, buf, len);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
{
    return apr_socket_recv(sock, buf, len);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_sendv(apr_socket_t *sock, const struct iovec *vec,
                 apr_int32_t nvec, apr_size_t *len)
{
    return apr_socket_sendv(sock, vec, nvec, len);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
{
    return apr_socket_shutdown(sock, how);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
{
    return apr_socket_timeout_set(sock, t);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
{
    return apr_socket_timeout_get(sock, t);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
{
    return apr_socket_opt_set(sock, opt, on);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
{
    return apr_socket_opt_get(sock, opt, on);
}

#else
#define APR_socket_send         apr_socket_send
#define APR_socket_recv         apr_socket_recv
#define APR_socket_sendv        apr_socket_sendv
#define APR_socket_shutdown     apr_socket_shutdown
#define APR_socket_timeout_set  apr_socket_timeout_set
#define APR_socket_timeout_get  apr_socket_timeout_get
#define APR_socket_opt_set      apr_socket_opt_set
#define APR_socket_opt_get      apr_socket_opt_get
#endif

static tcn_nlayer_t apr_socket_layer = {
    TCN_SOCKET_APR,
    NULL,
    NULL,
    APR_socket_shutdown,
    APR_socket_opt_get,
    APR_socket_opt_set,
    APR_socket_timeout_get,
    APR_socket_timeout_set,
    APR_socket_send,
    APR_socket_sendv,
    APR_socket_recv
};

TCN_IMPLEMENT_CALL(jlong, Socket, create)(TCN_STDARGS, jint family,
                                          jint type, jint protocol,
                                          jlong pool)
{
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    apr_pool_t *c = NULL;
    apr_socket_t *s = NULL;
    tcn_socket_t *a = NULL;
    apr_int32_t f, t;

    UNREFERENCED(o);
    TCN_ASSERT(pool != 0);
    GET_S_FAMILY(f, family);
    GET_S_TYPE(t, type);

    TCN_THROW_IF_ERR(apr_pool_create(&c, p), c);

    a = (tcn_socket_t *)apr_pcalloc(c, sizeof(tcn_socket_t));
    TCN_CHECK_ALLOCATED(a);
    TCN_THROW_IF_ERR(apr_pool_create(&a->child, c), a->child);
    a->pool = c;

    if (family >= 0) {
        a->net = &apr_socket_layer;
        TCN_THROW_IF_ERR(apr_socket_create(&s,
                         f, t, protocol, c), a);
    }
    apr_pool_cleanup_register(c, (const void *)a,
                              sp_socket_cleanup,
                              apr_pool_cleanup_null);

#ifdef TCN_DO_STATISTICS
    sp_created++;
#endif
    a->sock = s;
    if (family >= 0)
        a->net = &apr_socket_layer;
    a->opaque   = s;

    return P2J(a);
cleanup:
    if (c)
        apr_pool_destroy(c);
    return 0;

}

TCN_IMPLEMENT_CALL(void, Socket, destroy)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_socket_t *as;
    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);

    as = s->sock;
    s->sock = NULL;
    apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
    if (s->net && s->net->cleanup) {
        (*s->net->cleanup)(s->opaque);
        s->net = NULL;
    }
    if (as) {
        apr_socket_close(as);
    }

    apr_pool_destroy(s->pool);
}

TCN_IMPLEMENT_CALL(jlong, Socket, pool)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_pool_t *n;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_THROW_IF_ERR(apr_pool_create(&n, s->pool), n);
cleanup:
    return P2J(n);
}

TCN_IMPLEMENT_CALL(jlong, Socket, get)(TCN_STDARGS, jlong sock, jint what)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);

    switch (what) {
        case TCN_SOCKET_GET_POOL:
            return P2J(s->pool);
        break;
        case TCN_SOCKET_GET_IMPL:
            return P2J(s->opaque);
        break;
        case TCN_SOCKET_GET_APRS:
            return P2J(s->sock);
        break;
        case TCN_SOCKET_GET_TYPE:
            return (jlong)(s->net->type);
        break;
    }
    return 0;
}

TCN_IMPLEMENT_CALL(jint, Socket, shutdown)(TCN_STDARGS, jlong sock,
                                           jint how)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    return (jint)(*s->net->shutdown)(s->opaque, how);
}

TCN_IMPLEMENT_CALL(jint, Socket, close)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    jint rv = APR_SUCCESS;
    apr_socket_t *as;
    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);

    as = s->sock;
    s->sock = NULL;
    apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
    if (s->child) {
        apr_pool_clear(s->child);
    }
#ifdef TCN_DO_STATISTICS
    apr_atomic_inc32(&sp_closed);
#endif
    if (s->net && s->net->close) {
        rv = (*s->net->close)(s->opaque);
        s->net = NULL;
    }
    if (as) {
        rv = (jint)apr_socket_close(as);
    }
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Socket, bind)(TCN_STDARGS, jlong sock,
                                       jlong sa)
{
    jint rv = APR_SUCCESS;
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *a = J2P(sa, apr_sockaddr_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);
    rv = (jint)apr_socket_bind(s->sock, a);
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Socket, listen)(TCN_STDARGS, jlong sock,
                                         jint backlog)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);
    return (jint)apr_socket_listen(s->sock, backlog);
}

TCN_IMPLEMENT_CALL(jlong, Socket, acceptx)(TCN_STDARGS, jlong sock,
                                           jlong pool)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_pool_t   *p = J2P(pool, apr_pool_t *);
    apr_socket_t *n = NULL;
    tcn_socket_t *a = NULL;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    if (s->net->type == TCN_SOCKET_APR) {
        TCN_ASSERT(s->sock != NULL);
        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
        TCN_CHECK_ALLOCATED(a);
        a->pool   = p;
        apr_pool_cleanup_register(a->pool, (const void *)a,
                                  sp_socket_cleanup,
                                  apr_pool_cleanup_null);

        TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
    }
    else {
        tcn_ThrowAPRException(e, APR_ENOTIMPL);
        goto cleanup;
    }
    if (n) {
#ifdef TCN_DO_STATISTICS
        apr_atomic_inc32(&sp_accepted);
#endif
        a->net    = &apr_socket_layer;
        a->sock   = n;
        a->opaque = n;
    }

cleanup:
    return P2J(a);
}

TCN_IMPLEMENT_CALL(jlong, Socket, accept)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_pool_t   *p = NULL;
    apr_socket_t *n = NULL;
    tcn_socket_t *a = NULL;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    TCN_THROW_IF_ERR(apr_pool_create(&p, s->child), p);
    if (s->net->type == TCN_SOCKET_APR) {
        TCN_ASSERT(s->sock != NULL);
        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
        TCN_CHECK_ALLOCATED(a);
        TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);

        a->pool = p;
        apr_pool_cleanup_register(a->pool, (const void *)a,
                                  sp_socket_cleanup,
                                  apr_pool_cleanup_null);

    }
    else {
        tcn_ThrowAPRException(e, APR_ENOTIMPL);
        goto cleanup;
    }
    if (n) {
#ifdef TCN_DO_STATISTICS
        apr_atomic_inc32(&sp_accepted);
#endif
        a->net    = &apr_socket_layer;
        a->sock   = n;
        a->opaque = n;
    }
    return P2J(a);
cleanup:
    if (p && s->sock)
        apr_pool_destroy(p);
    return 0;
}

TCN_IMPLEMENT_CALL(jint, Socket, connect)(TCN_STDARGS, jlong sock,
                                          jlong sa)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *a = J2P(sa, apr_sockaddr_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);
    return (jint)apr_socket_connect(s->sock, a);
}

TCN_IMPLEMENT_CALL(jint, Socket, send)(TCN_STDARGS, jlong sock,
                                      jbyteArray buf, jint offset, jint tosend)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)tosend;
    apr_status_t ss;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(s->opaque != NULL);
#ifdef TCN_DO_STATISTICS
    sp_max_send = TCN_MAX(sp_max_send, nbytes);
    sp_min_send = TCN_MIN(sp_min_send, nbytes);
    sp_tot_send += nbytes;
    sp_num_send++;
#endif

    if (tosend <= TCN_BUFFER_SZ) {
        jbyte sb[TCN_BUFFER_SZ];
        (*e)->GetByteArrayRegion(e, buf, offset, tosend, &sb[0]);
        ss = (*s->net->send)(s->opaque, (const char *)&sb[0], &nbytes);
    }
    else {
        jbyte *sb = (jbyte *)malloc(nbytes);
        if (sb == NULL)
            return -APR_ENOMEM;
        (*e)->GetByteArrayRegion(e, buf, offset, tosend, sb);
        ss = (*s->net->send)(s->opaque, (const char *)sb, &nbytes);
        free(sb);
    }
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(void, Socket, setsbb)(TCN_STDARGS, jlong sock,
                                         jobject buf)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return;
    }
    TCN_ASSERT(s->opaque != NULL);
    if (buf)
        s->jsbbuff = (char *)(*e)->GetDirectBufferAddress(e, buf);
    else
        s->jsbbuff = NULL;
}

TCN_IMPLEMENT_CALL(void, Socket, setrbb)(TCN_STDARGS, jlong sock,
                                         jobject buf)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return;
    }
    TCN_ASSERT(s->opaque != NULL);
    if (buf)
        s->jrbbuff = (char *)(*e)->GetDirectBufferAddress(e, buf);
    else
        s->jrbbuff = NULL;
}

TCN_IMPLEMENT_CALL(jint, Socket, sendb)(TCN_STDARGS, jlong sock,
                                        jobject buf, jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)len;
    apr_size_t sent = 0;
    char *bytes;
    apr_status_t ss = APR_SUCCESS;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(buf != NULL);
#ifdef TCN_DO_STATISTICS
    sp_max_send = TCN_MAX(sp_max_send, nbytes);
    sp_min_send = TCN_MIN(sp_min_send, nbytes);
    sp_tot_send += nbytes;
    sp_num_send++;
#endif

    bytes  = (char *)(*e)->GetDirectBufferAddress(e, buf);

    while (sent < nbytes) {
        apr_size_t wr = nbytes - sent;
        ss = (*s->net->send)(s->opaque, bytes + offset + sent, &wr);
        if (ss != APR_SUCCESS)
            break;
        sent += wr;
    }

    if (ss == APR_SUCCESS)
        return (jint)sent;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, sendbb)(TCN_STDARGS, jlong sock,
                                         jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)len;
    apr_size_t sent = 0;
    apr_status_t ss = APR_SUCCESS;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(s->jsbbuff != NULL);
#ifdef TCN_DO_STATISTICS
    sp_max_send = TCN_MAX(sp_max_send, nbytes);
    sp_min_send = TCN_MIN(sp_min_send, nbytes);
    sp_tot_send += nbytes;
    sp_num_send++;
#endif

    while (sent < nbytes) {
        apr_size_t wr = nbytes - sent;
        ss = (*s->net->send)(s->opaque, s->jsbbuff + offset + sent, &wr);
        if (ss != APR_SUCCESS)
            break;
        sent += wr;
    }
    if (ss == APR_SUCCESS)
        return (jint)sent;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, sendv)(TCN_STDARGS, jlong sock,
                                        jobjectArray bufs)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    jsize nvec;
    jsize i;
    struct iovec vec[APR_MAX_IOVEC_SIZE];
    jobject ba[APR_MAX_IOVEC_SIZE];
    apr_size_t written = 0;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);

    nvec = (*e)->GetArrayLength(e, bufs);
    if (nvec >= APR_MAX_IOVEC_SIZE)
        return (jint)(-APR_ENOMEM);

    for (i = 0; i < nvec; i++) {
        ba[i] = (*e)->GetObjectArrayElement(e, bufs, i);
        vec[i].iov_len  = (*e)->GetArrayLength(e, ba[i]);
        vec[i].iov_base = (*e)->GetByteArrayElements(e, ba[i], NULL);
    }

    ss = (*s->net->sendv)(s->opaque, vec, nvec, &written);

    for (i = 0; i < nvec; i++) {
        (*e)->ReleaseByteArrayElements(e, ba[i], vec[i].iov_base, JNI_ABORT);
    }
    if (ss == APR_SUCCESS)
        return (jint)written;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, sendto)(TCN_STDARGS, jlong sock,
                                         jlong where, jint flag,
                                         jbyteArray buf, jint offset, jint tosend)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *w = J2P(where, apr_sockaddr_t *);
    apr_size_t nbytes = (apr_size_t)tosend;
    jbyte *bytes;
    apr_int32_t nb;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);

    bytes = (*e)->GetByteArrayElements(e, buf, NULL);
    TCN_ASSERT(bytes != NULL);
    apr_socket_opt_get(s->sock, APR_SO_NONBLOCK, &nb);
    if (nb)
         bytes = (*e)->GetPrimitiveArrayCritical(e, buf, NULL);
    else
         bytes = (*e)->GetByteArrayElements(e, buf, NULL);
    ss = apr_socket_sendto(s->sock, w, flag, (char *)(bytes + offset), &nbytes);

    if (nb)
        (*e)->ReleasePrimitiveArrayCritical(e, buf, bytes, 0);
    else
        (*e)->ReleaseByteArrayElements(e, buf, bytes, JNI_ABORT);
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recv)(TCN_STDARGS, jlong sock,
                                       jbyteArray buf, jint offset, jint toread)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)toread;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);

    if (toread <= TCN_BUFFER_SZ) {
        char sb[TCN_BUFFER_SZ];

        if ((ss = (*s->net->recv)(s->opaque, sb, &nbytes)) == APR_SUCCESS)
            (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, (jbyte*)&sb[0]);
    }
    else {
        jbyte *bytes = (*e)->GetByteArrayElements(e, buf, NULL);
        if ((ss = (*s->net->recv)(s->opaque, (char*)(bytes + offset),
                                  &nbytes)) == APR_SUCCESS)
            (*e)->ReleaseByteArrayElements(e, buf, bytes,
                                           nbytes ? 0 : JNI_ABORT);
    }
#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvt)(TCN_STDARGS, jlong sock,
                                        jbyteArray buf, jint offset,
                                        jint toread, jlong timeout)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)toread;
    apr_status_t ss;
    apr_interval_time_t pt;
    apr_interval_time_t nt = J2T(timeout);

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(buf != NULL);

    if ((ss = (*s->net->timeout_get)(s->opaque, &pt)) != APR_SUCCESS) {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
    if (pt != nt) {
        if ((ss = (*s->net->timeout_set)(s->opaque, nt)) != APR_SUCCESS)
            goto cleanup;
    }
    if (toread <= TCN_BUFFER_SZ) {
        jbyte sb[TCN_BUFFER_SZ];
        if ((ss = (*s->net->recv)(s->opaque, (char *)&sb[0], &nbytes)) == APR_SUCCESS)
            (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, &sb[0]);
    }
    else {
        jbyte *sb = (jbyte *)malloc(nbytes);
        if (sb == NULL)
            return -APR_ENOMEM;
        if ((ss = (*s->net->recv)(s->opaque, (char *)sb, &nbytes)) == APR_SUCCESS)
            (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, &sb[0]);
        free(sb);
    }
    if (pt != nt) {
        if ((ss = (*s->net->timeout_set)(s->opaque, pt)) != APR_SUCCESS)
            goto cleanup;
    }

#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
cleanup:
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvb)(TCN_STDARGS, jlong sock,
                                        jobject buf, jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_status_t ss;
    apr_size_t nbytes = (apr_size_t)len;
    char *bytes;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(buf != NULL);

    bytes  = (char *)(*e)->GetDirectBufferAddress(e, buf);
    TCN_ASSERT(bytes != NULL);
    ss = (*s->net->recv)(s->opaque, bytes + offset, &nbytes);
#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvbb)(TCN_STDARGS, jlong sock,
                                         jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_status_t ss;
    apr_size_t nbytes = (apr_size_t)len;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(s->jrbbuff != NULL);

    ss = (*s->net->recv)(s->opaque, s->jrbbuff + offset, &nbytes);
#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvbt)(TCN_STDARGS, jlong sock,
                                         jobject buf, jint offset,
                                         jint len, jlong timeout)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_status_t ss;
    apr_size_t nbytes = (apr_size_t)len;
    char *bytes;
    apr_interval_time_t pt;
    apr_interval_time_t nt = J2T(timeout);

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(buf != NULL);
    TCN_ASSERT(s->opaque != NULL);

    bytes  = (char *)(*e)->GetDirectBufferAddress(e, buf);
    TCN_ASSERT(bytes != NULL);

    if ((ss = (*s->net->timeout_get)(s->opaque, &pt)) != APR_SUCCESS) {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
    if (pt != nt) {
        if ((ss = (*s->net->timeout_set)(s->opaque, nt)) != APR_SUCCESS) {
            TCN_ERROR_WRAP(ss);
            return -(jint)ss;
        }
    }
    ss = (*s->net->recv)(s->opaque, bytes + offset, &nbytes);
    if (pt != nt) {
        if ((ss = (*s->net->timeout_set)(s->opaque, pt)) != APR_SUCCESS) {
            TCN_ERROR_WRAP(ss);
            return -(jint)ss;
        }
    }

#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvbbt)(TCN_STDARGS, jlong sock,
                                          jint offset,
                                          jint len, jlong timeout)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_status_t ss;
    apr_size_t nbytes = (apr_size_t)len;
    apr_interval_time_t pt;
    apr_interval_time_t nt = J2T(timeout);

    UNREFERENCED_STDARGS;
    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(s->jrbbuff != NULL);
    TCN_ASSERT(s->opaque != NULL);


    if ((ss = (*s->net->timeout_get)(s->opaque, &pt)) != APR_SUCCESS) {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
    if (pt != nt) {
        if ((ss = (*s->net->timeout_set)(s->opaque, nt)) != APR_SUCCESS) {
            TCN_ERROR_WRAP(ss);
            return -(jint)ss;
        }
    }
    ss = (*s->net->recv)(s->opaque, s->jrbbuff + offset, &nbytes);
    if (pt != nt) {
        if ((ss = (*s->net->timeout_set)(s->opaque, pt)) != APR_SUCCESS) {
            TCN_ERROR_WRAP(ss);
            return -(jint)ss;
        }
    }

#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvfrom)(TCN_STDARGS, jlong from,
                                          jlong sock, jint flags,
                                          jbyteArray buf, jint offset, jint toread)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *f = J2P(from, apr_sockaddr_t *);
    apr_size_t nbytes = (apr_size_t)toread;
    jbyte *bytes = (*e)->GetByteArrayElements(e, buf, NULL);
    apr_status_t ss;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(s->sock != NULL);
    TCN_ASSERT(buf != NULL);
    ss = apr_socket_recvfrom(f, s->sock, (apr_int32_t)flags, (char*)(bytes + offset), &nbytes);

    (*e)->ReleaseByteArrayElements(e, buf, bytes,
                                   nbytes ? 0 : JNI_ABORT);
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, optSet)(TCN_STDARGS, jlong sock,
                                         jint opt, jint on)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);

    UNREFERENCED(o);
    if (!s->sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return APR_ENOTSOCK;
    }
    else
        return (jint)(*s->net->opt_set)(s->opaque, (apr_int32_t)opt, (apr_int32_t)on);
}

TCN_IMPLEMENT_CALL(jint, Socket, optGet)(TCN_STDARGS, jlong sock,
                                         jint opt)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_int32_t on = 0;

    UNREFERENCED(o);
    if (s->sock)
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
    else {
        TCN_THROW_IF_ERR((*s->net->opt_get)(s->opaque, (apr_int32_t)opt,
                                            &on), on);
    }
cleanup:
    return (jint)on;
}

TCN_IMPLEMENT_CALL(jint, Socket, timeoutSet)(TCN_STDARGS, jlong sock,
                                             jlong timeout)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);

    UNREFERENCED(o);
    TCN_ASSERT(s->opaque != NULL);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return APR_ENOTSOCK;
    }
    return (jint)(*s->net->timeout_set)(s->opaque, J2T(timeout));
}

TCN_IMPLEMENT_CALL(jlong, Socket, timeoutGet)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_interval_time_t timeout;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return 0;
    }
    TCN_ASSERT(s->opaque != NULL);

    TCN_THROW_IF_ERR((*s->net->timeout_get)(s->opaque, &timeout), timeout);
cleanup:
    return (jlong)timeout;
}

TCN_IMPLEMENT_CALL(jboolean, Socket, atmark)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_int32_t mark;

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);

    if (apr_socket_atmark(s->sock, &mark) != APR_SUCCESS)
        return JNI_FALSE;
    return mark ? JNI_TRUE : JNI_FALSE;
}

#if APR_HAS_SENDFILE

TCN_IMPLEMENT_CALL(jlong, Socket, sendfile)(TCN_STDARGS, jlong sock,
                                            jlong file,
                                            jobjectArray headers,
                                            jobjectArray trailers,
                                            jlong offset, jlong len,
                                            jint flags)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_file_t *f = J2P(file, apr_file_t *);
    jsize nh = 0;
    jsize nt = 0;
    jsize i;
    struct iovec hvec[APR_MAX_IOVEC_SIZE];
    struct iovec tvec[APR_MAX_IOVEC_SIZE];
    jobject hba[APR_MAX_IOVEC_SIZE];
    jobject tba[APR_MAX_IOVEC_SIZE];
    apr_off_t off = (apr_off_t)offset;
    apr_size_t written = (apr_size_t)len;
    apr_hdtr_t hdrs;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(file != 0);

    if (s->net->type != TCN_SOCKET_APR)
        return (jint)(-APR_ENOTIMPL);
    if (headers)
        nh = (*e)->GetArrayLength(e, headers);
    if (trailers)
        nt = (*e)->GetArrayLength(e, trailers);
    /* Check for overflow */
    if (nh >= APR_MAX_IOVEC_SIZE || nt >= APR_MAX_IOVEC_SIZE)
        return (jint)(-APR_ENOMEM);

    for (i = 0; i < nh; i++) {
        hba[i] = (*e)->GetObjectArrayElement(e, headers, i);
        hvec[i].iov_len  = (*e)->GetArrayLength(e, hba[i]);
        hvec[i].iov_base = (*e)->GetByteArrayElements(e, hba[i], NULL);
    }
    for (i = 0; i < nt; i++) {
        tba[i] = (*e)->GetObjectArrayElement(e, trailers, i);
        tvec[i].iov_len  = (*e)->GetArrayLength(e, tba[i]);
        tvec[i].iov_base = (*e)->GetByteArrayElements(e, tba[i], NULL);
    }
    hdrs.headers = &hvec[0];
    hdrs.numheaders = nh;
    hdrs.trailers = &tvec[0];
    hdrs.numtrailers = nt;


    ss = apr_socket_sendfile(s->sock, f, &hdrs, &off, &written, (apr_int32_t)flags);

#ifdef TCN_DO_STATISTICS
    sf_max_send = TCN_MAX(sf_max_send, written);
    sf_min_send = TCN_MIN(sf_min_send, written);
    sf_tot_send += written;
    sf_num_send++;
#endif

    for (i = 0; i < nh; i++) {
        (*e)->ReleaseByteArrayElements(e, hba[i], hvec[i].iov_base, JNI_ABORT);
    }

    for (i = 0; i < nt; i++) {
        (*e)->ReleaseByteArrayElements(e, tba[i], tvec[i].iov_base, JNI_ABORT);
    }
    /* Return Number of bytes actually sent,
     * including headers, file, and trailers
     */
    if (ss == APR_SUCCESS)
        return (jlong)written;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jlong)ss;
    }
}

TCN_IMPLEMENT_CALL(jlong, Socket, sendfilen)(TCN_STDARGS, jlong sock,
                                             jlong file,
                                             jlong offset, jlong len,
                                             jint flags)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_file_t *f = J2P(file, apr_file_t *);
    apr_off_t off = (apr_off_t)offset;
    apr_size_t written = (apr_size_t)len;
    apr_hdtr_t hdrs;
    apr_status_t ss;

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(file != 0);

    if (s->net->type != TCN_SOCKET_APR)
        return (jint)(-APR_ENOTIMPL);

    hdrs.headers = NULL;
    hdrs.numheaders = 0;
    hdrs.trailers = NULL;
    hdrs.numtrailers = 0;


    ss = apr_socket_sendfile(s->sock, f, &hdrs, &off, &written, (apr_int32_t)flags);

#ifdef TCN_DO_STATISTICS
    sf_max_send = TCN_MAX(sf_max_send, written);
    sf_min_send = TCN_MIN(sf_min_send, written);
    sf_tot_send += written;
    sf_num_send++;
#endif

    /* Return Number of bytes actually sent,
     * including headers, file, and trailers
     */
    if (ss == APR_SUCCESS)
        return (jlong)written;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jlong)ss;
    }
}

#else /* APR_HAS_SENDIFLE */

TCN_IMPLEMENT_CALL(jlong, Socket, sendfile)(TCN_STDARGS, jlong sock,
                                            jlong file,
                                            jobjectArray headers,
                                            jobjectArray trailers,
                                            jlong offset, jlong len,
                                            jint flags)
{

    UNREFERENCED_STDARGS;
    UNREFERENCED(sock);
    UNREFERENCED(file);
    UNREFERENCED(headers);
    UNREFERENCED(trailers);
    UNREFERENCED(offset);
    UNREFERENCED(len);
    UNREFERENCED(flags);
    return -(jlong)APR_ENOTIMPL;
}

TCN_IMPLEMENT_CALL(jlong, Socket, sendfilen)(TCN_STDARGS, jlong sock,
                                             jlong file,
                                             jlong offset, jlong len,
                                             jint flags)
{
    UNREFERENCED_STDARGS;
    UNREFERENCED(sock);
    UNREFERENCED(file);
    UNREFERENCED(offset);
    UNREFERENCED(len);
    UNREFERENCED(flags);
    return -(jlong)APR_ENOTIMPL;
}

#endif  /* APR_HAS_SENDIFLE */


TCN_IMPLEMENT_CALL(jint, Socket, acceptfilter)(TCN_STDARGS,
                                               jlong sock,
                                               jstring name,
                                               jstring args)
{
#if APR_HAS_SO_ACCEPTFILTER
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    TCN_ALLOC_CSTRING(name);
    TCN_ALLOC_CSTRING(args);
    apr_status_t rv;


    UNREFERENCED(o);
    rv = apr_socket_accept_filter(s->sock, J2S(name),
                                  J2S(args) ? J2S(args) : "");
    TCN_FREE_CSTRING(name);
    TCN_FREE_CSTRING(args);
    return (jint)rv;
#else
    UNREFERENCED_STDARGS;
    UNREFERENCED(sock);
    UNREFERENCED(name);
    UNREFERENCED(args);
    return (jint)APR_ENOTIMPL;
#endif
}

TCN_IMPLEMENT_CALL(jint, Socket, dataSet)(TCN_STDARGS, jlong sock,
                                          jstring key, jobject data)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_status_t rv = APR_SUCCESS;
    TCN_ALLOC_CSTRING(key);

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    rv = apr_socket_data_set(s->sock, data, J2S(key), NULL);
    TCN_FREE_CSTRING(key);
    return rv;
}

TCN_IMPLEMENT_CALL(jobject, Socket, dataGet)(TCN_STDARGS, jlong socket,
                                             jstring key)
{
    tcn_socket_t *s = J2P(socket, tcn_socket_t *);
    TCN_ALLOC_CSTRING(key);
    void *rv = NULL;

    UNREFERENCED(o);
    TCN_ASSERT(socket != 0);

    if (apr_socket_data_get(&rv, J2S(key), s->sock) != APR_SUCCESS) {
        rv = NULL;
    }
    TCN_FREE_CSTRING(key);
    return rv;
}
