void AsioSessionState::onAppReadWriteCompleted( size_t bytesTransferred) { RCF_ASSERT(!mReflecting); switch(mState) { case ReadingDataCount: case ReadingData: if (mTransport.mCustomFraming) { doCustomFraming(bytesTransferred); } else { doRegularFraming(bytesTransferred); } break; case WritingData: RCF_ASSERT_LTEQ(bytesTransferred , mWriteBufferRemaining); mWriteBufferRemaining -= bytesTransferred; if (mWriteBufferRemaining > 0) { beginWrite(); } else { if (mCloseAfterWrite) { // For TCP sockets, call shutdown() so client receives // the message before we close the connection. implCloseAfterWrite(); } else { mState = Ready; mSlicedWriteByteBuffers.resize(0); mWriteByteBuffers.resize(0); mTransport.getSessionManager().onWriteCompleted( getSessionPtr()); } } break; default: RCF_ASSERT(0); } }
void AsioSessionState::doRegularFraming(size_t bytesTransferred) { RCF_ASSERT_LTEQ(bytesTransferred , mReadBufferRemaining); mReadBufferRemaining -= bytesTransferred; if (mReadBufferRemaining > 0) { beginRead(); } else if (mReadBufferRemaining == 0 && mIssueZeroByteRead) { if (!mAppReadBufferPtr || !mAppReadBufferPtr.unique()) { mAppReadBufferPtr = getObjectPool().getReallocBufferPtr(); } mAppReadBufferPtr->resize(4); mReadBufferRemaining = 4; mIssueZeroByteRead = false; beginRead(); } else { RCF_ASSERT_EQ(mReadBufferRemaining , 0); if (mState == ReadingDataCount) { ReallocBuffer & readBuffer = *mAppReadBufferPtr; RCF_ASSERT_EQ(readBuffer.size() , 4); unsigned int packetLength = 0; memcpy(&packetLength, &readBuffer[0], 4); networkToMachineOrder(&packetLength, 4, 1); if ( mTransport.getMaxMessageLength() && packetLength > mTransport.getMaxMessageLength()) { sendServerError(RcfError_ServerMessageLength); } else { readBuffer.resize(packetLength); mReadBufferRemaining = packetLength; mState = ReadingData; beginRead(); } } else if (mState == ReadingData) { mState = Ready; mTransport.getSessionManager().onReadCompleted( getSessionPtr()); } } }
void AsioSessionState::doCustomFraming(size_t bytesTransferred) { RCF_ASSERT_LTEQ(bytesTransferred , mReadBufferRemaining); mReadBufferRemaining -= bytesTransferred; if (mReadBufferRemaining > 0) { beginRead(); } else if (mReadBufferRemaining == 0 && mIssueZeroByteRead) { if (!mAppReadBufferPtr || !mAppReadBufferPtr.unique()) { mAppReadBufferPtr = getObjectPool().getReallocBufferPtr(); } mAppReadBufferPtr->resize(4); mReadBufferRemaining = 4; mIssueZeroByteRead = false; beginRead(); } else { RCF_ASSERT_EQ(mReadBufferRemaining , 0); if (mState == ReadingDataCount) { ReallocBuffer & readBuffer = *mAppReadBufferPtr; RCF_ASSERT_EQ(readBuffer.size() , 4); std::size_t messageLength = mTransportFilters[0]->getFrameSize(); if ( mTransport.getMaxMessageLength() && messageLength > mTransport.getMaxMessageLength()) { sendServerError(RcfError_ServerMessageLength); } else { RCF_ASSERT( messageLength > 4 ); readBuffer.resize(messageLength); mReadBufferRemaining = messageLength - 4; mState = ReadingData; beginRead(); } } else if (mState == ReadingData) { mState = Ready; mTransport.getSessionManager().onReadCompleted( getSessionPtr()); } } }
void AsioSessionState::onReadWrite( size_t bytesTransferred, const boost::system::error_code& error) { RCF_ASSERT(!error); RCF_ASSERT(!mReflecting); { switch(mState) { case ReadingDataCount: case ReadingData: RCF_ASSERT( bytesTransferred <= mReadBufferRemaining) (bytesTransferred)(mReadBufferRemaining); mReadBufferRemaining -= bytesTransferred; if (mReadBufferRemaining > 0) { invokeAsyncRead(); } else { RCF_ASSERT(mReadBufferRemaining == 0)(mReadBufferRemaining); if (mState == ReadingDataCount) { std::vector<char> &readBuffer = getReadBuffer(); RCF_ASSERT(readBuffer.size() == 4)(readBuffer.size()); unsigned int packetLength = 0; memcpy(&packetLength, &readBuffer[0], 4); networkToMachineOrder(&packetLength, 4, 1); if (packetLength <= mTransport.getMaxMessageLength()) { readBuffer.resize(packetLength); mReadBufferRemaining = packetLength; mState = ReadingData; invokeAsyncRead(); } else { sendServerError(RcfError_ServerMessageLength); } } else if (mState == ReadingData) { mState = Ready; mTransport.getSessionManager().onReadCompleted( getSessionPtr()); if (mTransport.mInterrupt) { mTransport.mInterrupt = false; mTransport.mDemuxerPtr->stop(); } } } break; case WritingData: RCF_ASSERT( bytesTransferred <= mWriteBufferRemaining) (bytesTransferred)(mWriteBufferRemaining); mWriteBufferRemaining -= bytesTransferred; if (mWriteBufferRemaining > 0) { invokeAsyncWrite(); } else { if (mCloseAfterWrite) { int fd = implGetNative(); const int BufferSize = 8*1024; char buffer[BufferSize]; while (recv(fd, buffer, BufferSize, 0) > 0); } else { mState = Ready; mSlicedWriteByteBuffers.resize(0); mWriteByteBuffers.resize(0); mTransport.getSessionManager().onWriteCompleted( getSessionPtr()); if (mTransport.mInterrupt) { mTransport.mInterrupt = false; mTransport.mDemuxerPtr->stop(); } } } break; default: RCF_ASSERT(0); } } }