INLINE size_t IOStreamTCP::tryReadImpl()

in src/dxapi/native/io/tcp.cpp [136:202]


INLINE size_t IOStreamTCP::tryReadImpl(byte *to, size_t maxSize, timeval &timeout)
{
    if (inputClosed_) {
        THROW_DBGLOG_IO(IOStreamException, ENOTCONN, "IOStreamTCP::tryRead(): ERR: closed");
    }

    if (0 != maxSize) {
        if (NULL == to) {
            THROW_DBGLOG("IOStreamTCP::tryRead(): 'to' parameter is NULL with non-zero maxSize = %llu", (ulonglong)maxSize);
        }
    }

    fd_set r, e;
    
    int result, error;

    FD_ZERO(&r);
    FD_ZERO(&e);
    FD_SET(socket_, &r);
    FD_SET(socket_, &e);

    if (SOCKET_ERROR == (result = select((int)socket_ + 1, &r, NULL, &e, &timeout))) {
        if (result < 0) {
            error = socket_errno();

            if (WSAESHUTDOWN != error) {
                std::string out;
                int errorCode;
                DBGLOGERR(&out, "%s", last_socket_error(&errorCode, "IOStreamTCP::tryRead() select()").c_str());
                invokeDisconnectionCallback(out, true);
                throw IOStreamException(errorCode, out);
            }
        }
    }

    if (0 == result)
        return 0;

    if (FD_ISSET(socket_, &r)) {
        if (0 == maxSize) {
            size_t n = nBytesAvailable();
            if (0 == n) {
                const char *err = "tryRead(): input stream disconnected";
                DBGLOG(err);
                //invokeDisconnectionCallback(out, true);
                throw IOStreamDisconnectException();
            }
            else {
                return 0;
            }
        }
        else {
            return read(to, 1, maxSize);
        }
    }

    // If we are here, error flag must be set
    assert(FD_ISSET(socket_, &e));

    socklen_t len = sizeof(error);
    if (0 != getsockopt(socket_, SOL_SOCKET, SO_ERROR, (char *)&error, &len)) {
        THROW_DBGLOG("%s", last_socket_error(nullptr, "IOStreamTCP::tryRead() getsockopt(SO_ERROR)").c_str());
    }
    else {
        THROW_DBGLOG("%s", format_socket_error(error, "IOStreamTCP::tryRead() select()").c_str());
    }
}