void AsioSessionState::read(
        const ByteBuffer &byteBuffer,
        std::size_t bytesRequested)
    {

        RCF2_TRACE("")(this);

        if (byteBuffer.getLength() == 0)
        {
            std::vector<char> &vec = getUniqueReadBufferSecondary();
            vec.resize(bytesRequested);
            mTempByteBuffer = getReadByteBufferSecondary();
        }
        else
        {
            mTempByteBuffer = ByteBuffer(byteBuffer, 0, bytesRequested);
        }

        RCF_ASSERT(
            bytesRequested <= mTempByteBuffer.getLength())
            (bytesRequested)(mTempByteBuffer.getLength());

        char *buffer = mTempByteBuffer.getPtr();
        std::size_t bufferLen = mTempByteBuffer.getLength();

        Lock lock(mMutex);
        if (!mHasBeenClosed)
        {
            implRead(buffer, bufferLen);
        }
    }
void AsioSessionState::read(
    const ByteBuffer &byteBuffer,
    std::size_t bytesRequested)
{
    if (byteBuffer.getLength() == 0 && bytesRequested > 0)
    {
        if (!mNetworkReadBufferPtr || mNetworkReadBufferPtr.unique())
        {
            mNetworkReadBufferPtr = getObjectPool().getReallocBufferPtr();
        }
        mNetworkReadBufferPtr->resize(bytesRequested);
        mNetworkReadByteBuffer = ByteBuffer(mNetworkReadBufferPtr);
    }
    else
    {
        mNetworkReadByteBuffer = ByteBuffer(byteBuffer, 0, bytesRequested);
    }

    RCF_ASSERT_LTEQ(bytesRequested, mNetworkReadByteBuffer.getLength());

    char *buffer = mNetworkReadByteBuffer.getPtr();
    std::size_t bufferLen = mNetworkReadByteBuffer.getLength();

    Lock lock(mSessionPtr->mDisableIoMutex);
    if (!mSessionPtr->mDisableIo)
    {
        if (mSocketOpsMutexPtr)
        {
            Lock lock(*mSocketOpsMutexPtr);
            implRead(buffer, bufferLen);
        }
        else
        {
            implRead(buffer, bufferLen);
        }
    }
}
void AsioSessionState::onReflectedReadWriteCompleted(
    const AsioErrorCode & error,
    size_t bytesTransferred)
{
    RCF_UNUSED_VARIABLE(error);

    RCF_ASSERT(
        mState == ReadingData ||
        mState == ReadingDataCount ||
        mState == WritingData)
    (mState);

    RCF_ASSERT(mReflecting);

    if (bytesTransferred == 0)
    {
        // Previous operation was aborted for some reason (probably because
        // of a thread exiting). Reissue the operation.

        mState = (mState == WritingData) ? ReadingData : WritingData;
    }

    if (mState == WritingData)
    {
        mState = ReadingData;
        ReallocBuffer & readBuffer = *mAppReadBufferPtr;
        readBuffer.resize(8*1024);

        char *buffer = &readBuffer[0];
        std::size_t bufferLen = readBuffer.size();

        Lock lock(mSessionPtr->mDisableIoMutex);
        if (!mSessionPtr->mDisableIo)
        {
            if (mSocketOpsMutexPtr)
            {
                Lock lock(*mSocketOpsMutexPtr);
                implRead(buffer, bufferLen);
            }
            else
            {
                implRead(buffer, bufferLen);
            }
        }
    }
    else if (
        mState == ReadingData ||
        mState == ReadingDataCount)
    {
        mState = WritingData;
        ReallocBuffer & readBuffer = *mAppReadBufferPtr;

        char *buffer = &readBuffer[0];
        std::size_t bufferLen = bytesTransferred;

        // mReflecteePtr will be nulled in onWriteCompletion(), otherwise
        // we could easily end up with a cycle
        RCF_ASSERT(!mReflecteePtr);
        mReflecteePtr = mReflecteeWeakPtr.lock();
        if (mReflecteePtr)
        {
            RCF_ASSERT(mReflecteePtr->mReflecting);

            Lock lock(mReflecteePtr->mSessionPtr->mDisableIoMutex);
            if (!mReflecteePtr->mSessionPtr->mDisableIo)
            {
                // TODO: if this can throw, then we need a scope_guard
                // to reset mReflecteePtr

                if (mReflecteePtr->mSocketOpsMutexPtr)
                {
                    Lock lock(*mReflecteePtr->mSocketOpsMutexPtr);
                    mReflecteePtr->implWrite(*this, buffer, bufferLen);
                }
                else
                {
                    mReflecteePtr->implWrite(*this, buffer, bufferLen);
                }
            }
        }
    }
}
    void AsioSessionState::onReflectedReadWrite(
        const boost::system::error_code& error,
        size_t bytesTransferred)
    {
        RCF2_TRACE("")(this);
        RCF_UNUSED_VARIABLE(error);

        RCF_ASSERT(
            mState == ReadingData ||
            mState == ReadingDataCount ||
            mState == WritingData)
            (mState);

        RCF_ASSERT(mReflecting);

        if (bytesTransferred == 0)
        {
            // Previous operation was aborted for some reason (probably because
            // of a thread exiting). Reissue the operation.

            mState = (mState == WritingData) ? ReadingData : WritingData;
        }

        if (mState == WritingData)
        {
            mState = ReadingData;
            std::vector<char> &readBuffer = getReadBuffer();
            readBuffer.resize(8*1024);

            char *buffer = &readBuffer[0];
            std::size_t bufferLen = readBuffer.size();

            Lock lock(mMutex);
            if (!mHasBeenClosed)
            {
                implRead(buffer, bufferLen);
            }
        }
        else if (
            mState == ReadingData ||
            mState == ReadingDataCount)
        {
            mState = WritingData;
            std::vector<char> &readBuffer = getReadBuffer();

            char *buffer = &readBuffer[0];
            std::size_t bufferLen = bytesTransferred;

            // mReflecteePtr will be nulled in onWriteCompletion(), otherwise 
            // we could easily end up with a cycle
            RCF_ASSERT(!mReflecteePtr);
            mReflecteePtr = mReflecteeWeakPtr.lock();
            if (mReflecteePtr)
            {
                RCF_ASSERT(mReflecteePtr->mReflecting);

                Lock lock(mReflecteePtr->mMutex);
                if (!mReflecteePtr->mHasBeenClosed)
                {
                    // TODO: if this can throw, then we need a scope_guard
                    // to reset mReflecteePtr
                    mReflecteePtr->implWrite(*this, buffer, bufferLen);
                }
            }
        }
    }