Stream::StreamID ASIOReadBuffer::processPartialChunk(uint8* dataBuffer, uint32 packetLength, uint32 &bufferReceived, Chunk&retval) { unsigned int headerLength=bufferReceived; Stream::StreamID retid; retid.unserialize(dataBuffer,headerLength); assert(headerLength<=bufferReceived&&"High water mark must be greater than maximum StreamID size"); bufferReceived-=headerLength; assert(headerLength<=packetLength&&"High water mark must be greater than maximum StreamID size"); retval.resize(packetLength-headerLength); if (packetLength>headerLength) { std::memcpy(&*retval.begin(),dataBuffer+headerLength,bufferReceived); } return retid; }
Stream::ReceivedResponse MultiplexedSocket::receiveFullChunk(unsigned int whichSocket, Stream::StreamID id,Chunk&newChunk){ Stream::ReceivedResponse retval = Stream::AcceptedData; if (id==Stream::StreamID()) {//control packet if(newChunk.size()) { unsigned int controlCode=*newChunk.begin(); switch (controlCode) { case TCPStream::TCPStreamCloseStream: case TCPStream::TCPStreamAckCloseStream: if (newChunk.size()>1) { unsigned int avail_len=newChunk.size()-1; id.unserialize((const uint8*)&(newChunk[1]),avail_len); if (avail_len+1>newChunk.size()) { SILOG(tcpsst,warning,"Control Chunk too short"); } } if (id!=Stream::StreamID()) { std::tr1::unordered_map<Stream::StreamID,unsigned int>::iterator where=mAckedClosingStreams.find(id); if (where!=mAckedClosingStreams.end()){ where->second++; int how_much=where->second; if (where->second==mSockets.size()) { mAckedClosingStreams.erase(where); shutDownClosedStream(controlCode,id); if (controlCode==TCPStream::TCPStreamCloseStream) { closeStream(getSharedPtr(),id,TCPStream::TCPStreamAckCloseStream); } } }else{ if (mSockets.size()==1) { shutDownClosedStream(controlCode,id); if (controlCode==TCPStream::TCPStreamCloseStream) { closeStream(getSharedPtr(),id,TCPStream::TCPStreamAckCloseStream); } }else { mAckedClosingStreams[id]=1; } } } break; default: break; } } }else { std::deque<StreamIDCallbackPair> registrations; CommitCallbacks(registrations,CONNECTED,false); CallbackMap::iterator where=mCallbacks.find(id); if (where!=mCallbacks.end()) { retval=where->second->mBytesReceivedCallback(newChunk); }else if (mOneSidedClosingStreams.find(id)==mOneSidedClosingStreams.end()) { //new substream TCPStream*newStream=new TCPStream(getSharedPtr(),id); TCPSetCallbacks setCallbackFunctor(this,newStream); mNewSubstreamCallback(newStream,setCallbackFunctor); if (setCallbackFunctor.mCallbacks != NULL) { CommitCallbacks(registrations,CONNECTED,false);//make sure bytes are received retval=setCallbackFunctor.mCallbacks->mBytesReceivedCallback(newChunk); }else { closeStream(getSharedPtr(),id); } }else { //IGNORED MESSAGE } } return retval; }