private bool OneByteSizeReady() { m_tmpbuf.Reset(); // First byte of size is read. If it is 0xff read 8-byte size. // Otherwise allocate the buffer for message data and read the // message data into it. byte first = m_tmpbuf[0]; if (first == 0xff) { NextStep(m_tmpbuf, 8, EightByteSizeReadyState); } else { // There has to be at least one byte (the flags) in the message). if (first == 0) { DecodingError(); return(false); } // in_progress is initialised at this point so in theory we should // close it before calling zmq_msg_init_size, however, it's a 0-byte // message and thus we can treat it as uninitialised... if (m_maxmsgsize >= 0 && (long)(first - 1) > m_maxmsgsize) { DecodingError(); return(false); } else { m_inProgress = new Msg(first - 1); } NextStep(m_tmpbuf, 1, FlagsReadyState); } return(true); }
public void InEvent() { if (m_pendingBytes > 0) { return; } // Get new batch of data. // Note the workaround made not to break strict-aliasing rules. data.Reset(); int received = 0; try { received = m_handle.Receive((byte[])data); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.WouldBlock) { return; //break; } else { m_joined = false; Error(); return; } } // No data to process. This may happen if the packet received is // neither ODATA nor ODATA. if (received == 0) { return; } // Read the offset of the fist message in the current packet. Debug.Assert(received >= sizeof(ushort)); ushort offset = data.GetUnsignedShort(m_options.Endian, 0); data.AdvanceOffset(sizeof(ushort)); received -= sizeof(ushort); // Join the stream if needed. if (!m_joined) { // There is no beginning of the message in current packet. // Ignore the data. if (offset == 0xffff) { return; } Debug.Assert(offset <= received); Debug.Assert(m_decoder == null); // We have to move data to the begining of the first message. data.AdvanceOffset(offset); received -= offset; // Mark the stream as joined. m_joined = true; // Create and connect decoder for the peer. m_decoder = new Decoder(0, m_options.Maxmsgsize, m_options.Endian); m_decoder.SetMsgSink(m_session); } // Push all the data to the decoder. int processed = m_decoder.ProcessBuffer(data, received); if (processed < received) { // Save some state so we can resume the decoding process later. m_pendingBytes = received - processed; m_pendingData = new ByteArraySegment(data, processed); // Stop polling. m_ioObject.ResetPollin(m_handle); return; } m_session.Flush(); }