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; }
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; }
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); } } } }
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)]); }
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; }
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; }