示例#1
0
文件: buffer.c 项目: blakawk/Aio4c
JNIEXPORT jbyteArray JNICALL Java_com_aio4c_buffer_Buffer_array__(JNIEnv* jvm, jobject buffer) {
    Buffer* _buffer = NULL;
    jbyteArray array = NULL;
    aio4c_byte_t* data = NULL;

    _buffer = _GetBuffer(jvm, buffer);
    data = BufferGetBytes(_buffer);

    array = (*jvm)->NewByteArray(jvm, BufferRemaining(_buffer));
    (*jvm)->SetByteArrayRegion(jvm, array, 0, BufferRemaining(_buffer), (jbyte*)&data[BufferGetPosition(_buffer)]);

    return array;
}
示例#2
0
bool ConnectionWrite(Connection* connection) {
    ssize_t nbWrite = 0;
    Buffer* buffer = connection->writeBuffer;
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;
    bool pendingCloseMemorized = false;
    aio4c_byte_t* data = NULL;

    if (!connection->canWrite) {
        code.expected = AIO4C_CONNECTION_STATE_CONNECTED;
        _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_DEBUG, AIO4C_CONNECTION_STATE_ERROR, &code);
        return false;
    }

    if (connection->state == AIO4C_CONNECTION_STATE_PENDING_CLOSE) {
        pendingCloseMemorized = true;
    }

    if (!BufferHasRemaining(buffer)) {
        BufferReset(buffer);
        _ConnectionEventHandle(connection, AIO4C_WRITE_EVENT);
        BufferFlip(buffer);
    }

    if (BufferGetLimit(buffer) - BufferGetPosition(buffer) < 0) {
        code.buffer = buffer;
        _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_BUFFER_UNDERFLOW_ERROR, &code);
        return false;
    }

    data = BufferGetBytes(buffer);
    if ((nbWrite = send(connection->socket, (void*)&data[BufferGetPosition(buffer)], BufferRemaining(buffer), MSG_NOSIGNAL)) < 0) {
#ifndef AIO4C_WIN32
        code.error = errno;
#else /* AIO4C_WIN32 */
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_WRITE_ERROR, &code);
        return false;
    }

    ProbeSize(AIO4C_PROBE_NETWORK_WRITE_SIZE, nbWrite);

    BufferPosition(buffer, BufferGetPosition(buffer) + nbWrite);

    if (BufferHasRemaining(connection->writeBuffer)) {
        return true;
    } else if (pendingCloseMemorized) {
        ConnectionShutdown(connection);
    }

    return false;
}
示例#3
0
void TransportRx::HandleReceive(const boost::uint8_t* apData, size_t aNumBytes)
{
	switch(aNumBytes) {
	case(1):
		ERROR_BLOCK(LEV_WARNING, "Received tpdu with no payload", TLERR_NO_PAYLOAD);
		return;
	case(0):
		throw ArgumentException(LOCATION, "Zero length invalid");
	default:
		if(aNumBytes > TL_MAX_TPDU_LENGTH) {
			ostringstream oss;
			oss << "Illegal arg: " << aNumBytes << " exceeds max tpdu size of " << TL_MAX_TPDU_LENGTH;
			throw ArgumentException(LOCATION, oss.str());
		}
	}

	boost::uint8_t hdr = apData[0];
	LOG_BLOCK(LEV_INTERPRET, "<- " << TransportLayer::ToString(hdr));
	bool first = (hdr & TL_HDR_FIR) != 0;
	bool last = (hdr & TL_HDR_FIN) != 0;
	int seq = hdr & TL_HDR_SEQ;
	size_t payload_len = aNumBytes - 1;

	if(this->ValidateHeader(first, last, seq, payload_len)) {
		if(BufferRemaining() < payload_len) {
			ERROR_BLOCK(LEV_WARNING, "Exceeded the buffer size before a complete fragment was read", TLERR_BUFFER_FULL);
			mNumBytesRead = 0;
		}
		else { //passed all validation
			memcpy(mBuffer + mNumBytesRead, apData + 1, payload_len);
			mNumBytesRead += payload_len;
			mSeq = (mSeq + 1) % 64;

			if(last) {
				size_t tmp = mNumBytesRead;
				mNumBytesRead = 0;
				mpContext->ReceiveAPDU(mBuffer, tmp);
			}
		}
	}
}
示例#4
0
文件: buffer.c 项目: blakawk/Aio4c
JNIEXPORT void JNICALL Java_com_aio4c_buffer_Buffer_array___3B(JNIEnv* jvm, jobject buffer, jbyteArray array) {
    Buffer* _buffer = _GetBuffer(jvm, buffer);
    aio4c_byte_t* data = BufferGetBytes(_buffer);

    (*jvm)->GetByteArrayRegion(jvm, array, 0, BufferRemaining(_buffer), (jbyte*)&data[BufferGetPosition(_buffer)]);
}
示例#5
0
文件: buffer.c 项目: blakawk/Aio4c
int main(int argc, char* argv[]) {
    Buffer* a = NULL;
    aio4c_byte_t* data = NULL;
    aio4c_byte_t b = 0;
    char* s = NULL;
    int i = 0;
    int d = 12345;
    size_t len = 0;
    Aio4cInit(argc, argv, NULL, NULL);

    s = aio4c_malloc(strlen(TEST_STRING) + 1);
    assert(s != NULL);
    memcpy(s, TEST_STRING, strlen(TEST_STRING) + 1);

    a = NewBuffer(BUFFER_SIZE);
    assert(a != NULL);
    assert(BufferGetCapacity(a) == BUFFER_SIZE);
    assert(BufferGetLimit(a) == BUFFER_SIZE);
    assert(BufferGetPosition(a) == 0);
    assert(BufferHasRemaining(a) == true);
    assert(BufferRemaining(a) == BUFFER_SIZE);
    assert((data = BufferGetBytes(a)) != NULL);
    for(i = 0; i < BUFFER_SIZE; i++) {
        assert(data[i] == 0);
    }
    assert(BufferPutInt(a, &d) == true);
    assert(BufferGetPosition(a) == sizeof(int));
    assert(BufferFlip(a) == a);
    assert(BufferGetPosition(a) == 0);
    assert(BufferGetLimit(a) == sizeof(int));
    d = 0;
    assert(BufferGetInt(a, &d) == true);
    assert(d == 12345);
    d = 45678;
    assert(BufferGetInt(a, &d) == false);
    assert(d == 45678);
    assert(BufferPutInt(a, &d) == false);
    assert(BufferReset(a) == a);
    assert(BufferPutString(a, s) == true);
    assert(BufferGetPosition(a) == (int)(strlen(s) + 1));
    assert(BufferFlip(a) == a);
    assert(BufferGetPosition(a) == 0);
    assert(BufferGetLimit(a) == (int)(strlen(s) + 1));
    for(i = 0; i < (int)(strlen(s) + 1); i++) {
        assert(BufferGetByte(a, &b) == true);
        assert(b == s[i]);
        assert(BufferGetPosition(a) == (i + 1));
    }
    assert(BufferGetByte(a, &b) == false);
    assert(BufferHasRemaining(a) == false);
    assert(BufferReset(a) == a);
    assert(BufferGetCapacity(a) == BUFFER_SIZE);
    assert(BufferGetLimit(a) == BUFFER_SIZE);
    assert(BufferGetPosition(a) == 0);
    assert(BufferHasRemaining(a) == true);
    assert((data = BufferGetBytes(a)) != NULL);
    assert(BufferLimit(a, strlen(s) + 1) == a);
    assert(BufferGetLimit(a) == (int)(strlen(s) + 1));
    len = strlen(s);
    s[len] = '0';
    for(i = 0; i < BUFFER_SIZE; i++) {
        assert(data[i] == 0);
    }
    assert(BufferPutString(a, s) == false);
    for(i = 0; i < BUFFER_SIZE; i++) {
        assert(data[i] == 0);
    }
    s[len] = '\0';
    assert(BufferPutString(a, s) == true);
    assert(BufferFlip(a) == a);
    for(i = 0; i < (int)(strlen(s) + 1); i++) {
        assert(BufferGetByte(a, &b) == true);
        assert(b == s[i]);
        assert(BufferGetPosition(a) == (i + 1));
    }
    assert(BufferHasRemaining(a) == false);
    Aio4cEnd();
    return 0;
}
示例#6
0
Connection* ConnectionInit(Connection* connection) {
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;

#ifndef AIO4C_WIN32
    if ((connection->socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    if ((connection->socket = socket(PF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_SOCKET_ERROR, &code);
    }

#ifndef AIO4C_WIN32
    if (fcntl(connection->socket, F_SETFL, O_NONBLOCK) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    unsigned long ioctl = 1;
    if (ioctlsocket(connection->socket, FIONBIO, &ioctl) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_FCNTL_ERROR, &code);
    }

    ConnectionState(connection, AIO4C_CONNECTION_STATE_INITIALIZED);

    return connection;
}

Connection* ConnectionConnect(Connection* connection) {
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;
    ConnectionState newState = AIO4C_CONNECTION_STATE_CONNECTING;

    if (connection->state != AIO4C_CONNECTION_STATE_INITIALIZED) {
        code.expected = AIO4C_CONNECTION_STATE_INITIALIZED;
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_DEBUG, AIO4C_CONNECTION_STATE_ERROR, &code);
    }

    if (connect(connection->socket, AddressGetAddr(connection->address), AddressGetAddrSize(connection->address)) == -1) {
#ifndef AIO4C_WIN32
        code.error = errno;
        if (errno == EINPROGRESS) {
#else /* AIO4C_WIN32 */
        int error = WSAGetLastError();
        code.source = AIO4C_ERRNO_SOURCE_WSA;
        if (error == WSAEINPROGRESS || error == WSAEALREADY || error == WSAEWOULDBLOCK) {
#endif /* AIO4C_WIN32 */
            newState = AIO4C_CONNECTION_STATE_CONNECTING;
        } else {
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_CONNECT_ERROR, &code);
        }
    } else {
        newState = AIO4C_CONNECTION_STATE_CONNECTED;
    }

    ConnectionState(connection, newState);

    return connection;
}

Connection* ConnectionFinishConnect(Connection* connection) {
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;
    int soError = 0;
    socklen_t soSize = sizeof(int);

#ifdef AIO4C_HAVE_POLL
    aio4c_poll_t polls[1] = { { .fd = connection->socket, .events = POLLOUT, .revents = 0 } };

#ifndef AIO4C_WIN32
    if (poll(polls, 1, -1) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    if (WSAPoll(polls, 1, -1) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_POLL_ERROR, &code);
    }

    if (polls[0].revents > 0) {
#else /* AIO4C_HAVE_POLL */
    fd_set writeSet;
    fd_set errorSet;

    FD_ZERO(&writeSet);
    FD_ZERO(&errorSet);
    FD_SET(connection->socket, &writeSet);
    FD_SET(connection->socket, &errorSet);

#ifndef AIO4C_WIN32
    if (select(connection->socket + 1, NULL, &writeSet, &errorSet, NULL) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    if (select(connection->socket + 1, NULL, &writeSet, &errorSet, NULL) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_SELECT_ERROR, &code);
    }

    if (FD_ISSET(connection->socket, &writeSet) || FD_ISSET(connection->socket, &errorSet)) {
#endif /* AIO4C_HAVE_POLL */

#ifndef AIO4C_WIN32
        if (getsockopt(connection->socket, SOL_SOCKET, SO_ERROR, &soError, &soSize) != 0) {
            code.error = errno;
#else /* AI4OC_WIN32 */
        if (getsockopt(connection->socket, SOL_SOCKET, SO_ERROR, (char*)&soError, &soSize) == SOCKET_ERROR) {
            code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_GETSOCKOPT_ERROR, &code);
        }

        if (soError != 0) {
#ifndef AIO4C_WIN32
            code.error = soError;
#else /* AIO4C_WIN32 */
            code.source = AIO4C_ERRNO_SOURCE_SOE;
            code.soError = soError;
#endif /* AIO4C_WIN32 */
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_FINISH_CONNECT_ERROR, &code);
        }
    }

    return connection;
}

Connection* ConnectionRead(Connection* connection) {
    Buffer* buffer = NULL;
    ssize_t nbRead = 0;
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;
    aio4c_byte_t* data = NULL;

    buffer = connection->readBuffer;

    if (!BufferHasRemaining(buffer)) {
        code.buffer = buffer;
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_BUFFER_OVERFLOW_ERROR, &code);
    }

    data = BufferGetBytes(buffer);
    if ((nbRead = recv(connection->socket, (void*)&data[BufferGetPosition(buffer)], BufferRemaining(buffer), 0)) < 0) {
#ifndef AIO4C_WIN32
        code.error = errno;
#else /* AIO4C_WIN32 */
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_READ_ERROR, &code);
    }

    ProbeSize(AIO4C_PROBE_NETWORK_READ_SIZE, nbRead);

    if (nbRead == 0) {
        if (connection->state == AIO4C_CONNECTION_STATE_PENDING_CLOSE) {
            ConnectionState(connection, AIO4C_CONNECTION_STATE_CLOSED);
            return connection;
        } else {
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_INFO, AIO4C_CONNECTION_DISCONNECTED, &code);
        }
    }

    if (!connection->canRead) {
        Log(AIO4C_LOG_LEVEL_WARN, "received data on connection %s when reading is not allowed", connection->string);
        BufferReset(buffer);
        return connection;
    }

    BufferPosition(buffer, BufferGetPosition(buffer) + nbRead);

    _ConnectionEventHandle(connection, AIO4C_INBOUND_DATA_EVENT);

    return connection;
}