Ejemplo n.º 1
0
        public void IntBigEndian()
        {
            ByteArraySegment byteArraySegment = new ByteArraySegment(new byte[4]);

            byteArraySegment.PutInteger(Endianness.Big, 1, 0);

            Assert.AreEqual(1, byteArraySegment[3]);
            Assert.AreEqual(0, byteArraySegment[0]);

            long num = byteArraySegment.GetInteger(Endianness.Big, 0);

            Assert.AreEqual(1, num);

            byteArraySegment.PutInteger(Endianness.Big, 16777216, 0);

            Assert.AreEqual(1, byteArraySegment[0]);
            Assert.AreEqual(0, byteArraySegment[3]);

            num = byteArraySegment.GetInteger(Endianness.Big, 0);

            Assert.AreEqual(16777216, num);
        }
Ejemplo n.º 2
0
        public void LongLittleEndian()
        {
            ByteArraySegment byteArraySegment = new ByteArraySegment(new byte[8]);

            byteArraySegment.PutLong(Endianness.Little, 1, 0);

            Assert.AreEqual(byteArraySegment[0], 1);
            Assert.AreEqual(0, byteArraySegment[7]);

            long num = byteArraySegment.GetLong(Endianness.Little, 0);

            Assert.AreEqual(1, num);

            byteArraySegment.PutLong(Endianness.Little, 72057594037927936, 0);

            Assert.AreEqual(1, byteArraySegment[7]);
            Assert.AreEqual(0, byteArraySegment[0]);

            num = byteArraySegment.GetLong(Endianness.Little, 0);

            Assert.AreEqual(72057594037927936, num);
        }
Ejemplo n.º 3
0
 protected void NextStep(ByteArraySegment readPos, int toRead, int state)
 {
     m_readPos = readPos;
     m_toRead = toRead;
     this.State = state;
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns a buffer to be filled with binary data.
        /// </summary>
        public void GetBuffer(out ByteArraySegment data, out int size)
        {
            // If we are expected to read large message, we'll opt for zero-
            // copy, i.e. we'll ask caller to fill the data directly to the
            // message. Note that subsequent read(s) are non-blocking, thus
            // each single read reads at most SO_RCVBUF bytes at once not
            // depending on how large is the chunk returned from here.
            // As a consequence, large messages being received won't block
            // other engines running in the same I/O thread for excessive
            // amounts of time.

            if (m_toRead >= m_bufsize)
            {
                data = m_readPos.Clone();
                size = m_toRead;
                return;
            }

            data = new ByteArraySegment(m_buf);
            size = m_bufsize;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Processes the data in the buffer previously allocated using
        /// get_buffer function. size argument specifies the number of bytes
        /// actually filled into the buffer. Function returns number of
        /// bytes actually processed.
        /// </summary>
        public int ProcessBuffer(ByteArraySegment data, int size)
        {
            // Check if we had an error in previous attempt.
            if (State < 0)
            {
                return -1;
            }

            // In case of zero-copy simply adjust the pointers, no copying
            // is required. Also, run the state machine in case all the data
            // were processed.
            if (data != null && data.Equals(m_readPos))
            {
                m_readPos.AdvanceOffset(size);
                m_toRead -= size;

                while (m_toRead == 0)
                {
                    if (!Next())
                    {
                        if (State < 0)
                        {
                            return -1;
                        }
                        return size;
                    }
                }
                return size;
            }

            int pos = 0;
            while (true)
            {

                // Try to get more space in the message to fill in.
                // If none is available, return.
                while (m_toRead == 0)
                {
                    if (!Next())
                    {
                        if (State < 0)
                        {
                            return -1;
                        }

                        return pos;
                    }
                }

                // If there are no more data in the buffer, return.
                if (pos == size)
                    return pos;

                // Copy the data from buffer to the message.
                int toCopy = Math.Min(m_toRead, size - pos);
                data.CopyTo(pos, m_readPos, 0, toCopy);
                m_readPos.AdvanceOffset(toCopy);
                pos += toCopy;
                m_toRead -= toCopy;
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Write the bytes of this ByteArraySegment to the specified destination-ByteArraySegment.
 /// </summary>
 /// <param name="fromOffset">an offset within this source buffer to start copying from</param>
 /// <param name="dest">the destination-ByteArraySegment</param>
 /// <param name="destOffset">an offset within the destination buffer to start copying to</param>
 /// <param name="toCopy">the number of bytes to copy</param>
 public void CopyTo(int fromOffset, ByteArraySegment dest, int destOffset, int toCopy)
 {
     Buffer.BlockCopy(m_innerBuffer, Offset + fromOffset, dest.m_innerBuffer, dest.Offset + destOffset, toCopy);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Write the bytes of this ByteArraySegment to the specified destination-ByteArraySegment.
 /// </summary>
 /// <param name="otherSegment">the destination-ByteArraySegment</param>
 /// <param name="toCopy">the number of bytes to copy</param>
 public void CopyTo( ByteArraySegment otherSegment, int toCopy)
 {
     CopyTo(0, otherSegment, 0, toCopy);
 }
Ejemplo n.º 8
0
        private void HandleHandshake(Action action, SocketError socketError, int bytesTransferred)
        {
            int bytesSent;
            int bytesReceived;

            switch (m_handshakeState)
            {
            case HandshakeState.Closed:
                switch (action)
                {
                case Action.Start:
                    // Send the 'length' and 'flags' fields of the identity message.
                    // The 'length' field is encoded in the long format.

                    m_greetingOutputBuffer[m_outsize++] = ((byte)0xff);
                    m_greetingOutputBuffer.PutLong(m_options.Endian, (long)m_options.IdentitySize + 1, 1);
                    m_outsize += 8;
                    m_greetingOutputBuffer[m_outsize++] = ((byte)0x7f);

                    m_outpos = new ByteArraySegment(m_greetingOutputBuffer);

                    m_handshakeState = HandshakeState.SendingGreeting;

                    BeginWrite(m_outpos, m_outsize);
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
                break;

            case HandshakeState.SendingGreeting:
                switch (action)
                {
                case Action.OutCompleted:
                    bytesSent = EndWrite(socketError, bytesTransferred);

                    if (bytesSent == -1)
                    {
                        Error();
                    }
                    else
                    {
                        m_outpos.AdvanceOffset(bytesSent);
                        m_outsize -= bytesSent;

                        if (m_outsize > 0)
                        {
                            BeginWrite(m_outpos, m_outsize);
                        }
                        else
                        {
                            m_greetingBytesRead = 0;

                            var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);

                            m_handshakeState = HandshakeState.ReceivingGreeting;

                            BeginRead(greetingSegment, PreambleSize);
                        }
                    }
                    break;

                case Action.ActivateIn:
                case Action.ActivateOut:
                    // nothing to do
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
                break;

            case HandshakeState.ReceivingGreeting:
                switch (action)
                {
                case Action.InCompleted:
                    bytesReceived = EndRead(socketError, bytesTransferred);

                    if (bytesReceived == -1)
                    {
                        Error();
                    }
                    else
                    {
                        m_greetingBytesRead += bytesReceived;

                        // check if it is an unversioned protocol
                        if (m_greeting[0] != 0xff || (m_greetingBytesRead == 10 && (m_greeting[9] & 0x01) == 0))
                        {
                            m_encoder = new V1Encoder(Config.OutBatchSize, m_options.Endian);
                            m_encoder.SetMsgSource(m_session);

                            m_decoder = new V1Decoder(Config.InBatchSize, m_options.MaxMessageSize, m_options.Endian);
                            m_decoder.SetMsgSink(m_session);

                            // We have already sent the message header.
                            // Since there is no way to tell the encoder to
                            // skip the message header, we simply throw that
                            // header data away.
                            int headerSize = m_options.IdentitySize + 1 >= 255 ? 10 : 2;
                            var tmp        = new byte[10];
                            var bufferp    = new ByteArraySegment(tmp);

                            int bufferSize = headerSize;

                            m_encoder.GetData(ref bufferp, ref bufferSize);

                            Debug.Assert(bufferSize == headerSize);

                            // Make sure the decoder sees the data we have already received.
                            m_inpos  = new ByteArraySegment(m_greeting);
                            m_insize = m_greetingBytesRead;

                            // To allow for interoperability with peers that do not forward
                            // their subscriptions, we inject a phony subscription
                            // message into the incoming message stream. To put this
                            // message right after the identity message, we temporarily
                            // divert the message stream from session to ourselves.
                            if (m_options.SocketType == ZmqSocketType.Pub || m_options.SocketType == ZmqSocketType.Xpub)
                            {
                                m_decoder.SetMsgSink(this);
                            }

                            // handshake is done
                            Activate();
                        }
                        else if (m_greetingBytesRead < 10)
                        {
                            var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);
                            BeginRead(greetingSegment, PreambleSize - m_greetingBytesRead);
                        }
                        else
                        {
                            // The peer is using versioned protocol.
                            // Send the rest of the greeting.
                            m_outpos[m_outsize++] = 1;         // Protocol version
                            m_outpos[m_outsize++] = (byte)m_options.SocketType;

                            m_handshakeState = HandshakeState.SendingRestOfGreeting;

                            BeginWrite(m_outpos, m_outsize);
                        }
                    }
                    break;

                case Action.ActivateIn:
                case Action.ActivateOut:
                    // nothing to do
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
                break;

            case HandshakeState.SendingRestOfGreeting:
                switch (action)
                {
                case Action.OutCompleted:
                    bytesSent = EndWrite(socketError, bytesTransferred);

                    if (bytesSent == -1)
                    {
                        Error();
                    }
                    else
                    {
                        m_outpos.AdvanceOffset(bytesSent);
                        m_outsize -= bytesSent;

                        if (m_outsize > 0)
                        {
                            BeginWrite(m_outpos, m_outsize);
                        }
                        else
                        {
                            var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);

                            m_handshakeState = HandshakeState.ReceivingRestOfGreeting;
                            BeginRead(greetingSegment, GreetingSize - m_greetingBytesRead);
                        }
                    }
                    break;

                case Action.ActivateIn:
                case Action.ActivateOut:
                    // nothing to do
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
                break;

            case HandshakeState.ReceivingRestOfGreeting:
                switch (action)
                {
                case Action.InCompleted:
                    bytesReceived = EndRead(socketError, bytesTransferred);

                    if (bytesReceived == -1)
                    {
                        Error();
                    }
                    else
                    {
                        m_greetingBytesRead += bytesReceived;

                        if (m_greetingBytesRead < GreetingSize)
                        {
                            var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);
                            BeginRead(greetingSegment, GreetingSize - m_greetingBytesRead);
                        }
                        else
                        {
                            if (m_greeting[VersionPos] == 0)
                            {
                                // ZMTP/1.0 framing.
                                m_encoder = new V1Encoder(Config.OutBatchSize, m_options.Endian);
                                m_encoder.SetMsgSource(m_session);

                                m_decoder = new V1Decoder(Config.InBatchSize, m_options.MaxMessageSize, m_options.Endian);
                                m_decoder.SetMsgSink(m_session);
                            }
                            else
                            {
                                // v1 framing protocol.
                                m_encoder = new V2Encoder(Config.OutBatchSize, m_session, m_options.Endian);
                                m_decoder = new V2Decoder(Config.InBatchSize, m_options.MaxMessageSize, m_session, m_options.Endian);
                            }

                            // handshake is done
                            Activate();
                        }
                    }
                    break;

                case Action.ActivateIn:
                case Action.ActivateOut:
                    // nothing to do
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
                break;

            default:
                Debug.Assert(false);
                break;
            }
        }
Ejemplo n.º 9
0
        public int Encode(ref ByteArraySegment?data, int size)
        {
            ByteArraySegment buffer = data ?? new ByteArraySegment(m_buffer);
            int bufferSize          = data == null ? m_bufferSize : size;

            if (!m_hasMessage)
            {
                return(0);
            }

            int pos = 0;

            while (pos < bufferSize)
            {
                // If there are no more data to return, run the state machine.
                // If there are still no data, return what we already have
                // in the buffer.
                if (m_toWrite == 0)
                {
                    if (m_newMsgFlag)
                    {
                        m_inProgress.Close();
                        m_inProgress.InitEmpty();
                        m_hasMessage = false;
                        break;
                    }

                    Next();
                }

                // If there are no data in the buffer yet and we are able to
                // fill whole buffer in a single go, let's use zero-copy.
                // There's no disadvantage to it as we cannot stuck multiple
                // messages into the buffer anyway. Note that subsequent
                // write(s) are non-blocking, thus each single write writes
                // at most SO_SNDBUF bytes at once not depending on how large
                // is the chunk returned from here.
                // As a consequence, large messages being sent won't block
                // other engines running in the same I/O thread for excessive
                // amounts of time.
                if (pos == 0 && data == null && m_toWrite >= bufferSize)
                {
                    data = m_writePos;
                    pos  = m_toWrite;

                    m_writePos = null;
                    m_toWrite  = 0;
                    return(pos);
                }

                // Copy data to the buffer. If the buffer is full, return.
                int toCopy = Math.Min(m_toWrite, bufferSize - pos);

                if (toCopy != 0)
                {
                    Assumes.NotNull(m_writePos);

                    m_writePos.CopyTo(0, buffer, pos, toCopy);
                    pos += toCopy;
                    m_writePos.AdvanceOffset(toCopy);
                    m_toWrite -= toCopy;
                }
            }

            data = buffer;
            return(pos);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Processes the data in the buffer previously allocated using
        /// get_buffer function. size argument specifies the number of bytes
        /// actually filled into the buffer. Function returns number of
        /// bytes actually processed.
        /// </summary>
        public int ProcessBuffer(ByteArraySegment data, int size)
        {
            // Check if we had an error in previous attempt.
            if (State < 0)
            {
                return(-1);
            }

            // In case of zero-copy simply adjust the pointers, no copying
            // is required. Also, run the state machine in case all the data
            // were processed.
            if (data != null && data.Equals(m_readPos))
            {
                m_readPos.AdvanceOffset(size);
                m_toRead -= size;

                while (m_toRead == 0)
                {
                    if (!Next())
                    {
                        if (State < 0)
                        {
                            return(-1);
                        }
                        return(size);
                    }
                }
                return(size);
            }

            int pos = 0;

            while (true)
            {
                // Try to get more space in the message to fill in.
                // If none is available, return.
                while (m_toRead == 0)
                {
                    if (!Next())
                    {
                        if (State < 0)
                        {
                            return(-1);
                        }

                        return(pos);
                    }
                }

                // If there are no more data in the buffer, return.
                if (pos == size)
                {
                    return(pos);
                }

                // Copy the data from buffer to the message.
                int toCopy = Math.Min(m_toRead, size - pos);
                data.CopyTo(pos, m_readPos, 0, toCopy);
                m_readPos.AdvanceOffset(toCopy);
                pos      += toCopy;
                m_toRead -= toCopy;
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// This returns a batch of binary data. The data
        /// are filled to a supplied buffer. If no buffer is supplied (data_
        /// points to NULL) decoder object will provide buffer of its own.
        /// </summary>
        public void GetData(ref ByteArraySegment data, ref int size)
        {
            int offset = -1;

            GetData(ref data, ref size, ref offset);
        }
Ejemplo n.º 12
0
 private void BeginRead( ByteArraySegment data, int size)
 {
     try
     {
         m_handle.Receive((byte[])data, data.Offset, size, SocketFlags.None);
     }
     catch (SocketException ex)
     {
         EnqueueAction(Action.InCompleted, ex.SocketErrorCode, 0);
     }
 }
Ejemplo n.º 13
0
        public void UnsignedShortBigEndian()
        {
            ByteArraySegment byteArraySegment = new ByteArraySegment(new byte[2]);

            byteArraySegment.PutUnsignedShort(Endianness.Big, 1, 0);

            Assert.AreEqual(1, byteArraySegment[1]);
            Assert.AreEqual(0, byteArraySegment[0]);

            long num = byteArraySegment.GetUnsignedShort(Endianness.Big, 0);

            Assert.AreEqual(1, num);

            byteArraySegment.PutUnsignedShort(Endianness.Big, 256, 0);

            Assert.AreEqual(1, byteArraySegment[0]);
            Assert.AreEqual(0, byteArraySegment[1]);

            num = byteArraySegment.GetUnsignedShort(Endianness.Big, 0);

            Assert.AreEqual(256, num);
        }
Ejemplo n.º 14
0
        private void ProcessInput()
        {
            bool disconnection = false;
            int processed;

            if (m_insize == -1)
            {
                m_insize = 0;
                disconnection = true;
            }

            if (m_options.RawSocket)
            {
                if (m_insize == 0 || !m_decoder.MessageReadySize(m_insize))
                {
                    processed = 0;
                }
                else
                {
                    processed = m_decoder.ProcessBuffer(m_inpos, m_insize);
                }
            }
            else
            {
                // Push the data to the decoder.
                processed = m_decoder.ProcessBuffer(m_inpos, m_insize);
            }

            if (processed == -1)
            {
                disconnection = true;
            }
            else
            {
                // Stop polling for input if we got stuck.
                if (processed < m_insize)
                {
                    m_receivingState = ReceiveState.Stuck;

                    m_inpos.AdvanceOffset(processed);
                    m_insize -= processed;
                }
                else
                {
                    m_inpos = null;
                    m_insize = 0;
                }
            }

            // Flush all messages the decoder may have produced.
            m_session.Flush();

            // An input error has occurred. If the last decoded message
            // has already been accepted, we terminate the engine immediately.
            // Otherwise, we stop waiting for socket events and postpone
            // the termination until after the message is accepted.
            if (disconnection)
            {
                if (m_decoder.Stalled())
                {
                    m_ioObject.RemoveSocket(m_handle);
                    m_ioEnabled = false;
                    m_state = State.Stalled;
                }
                else
                {
                    Error();
                }
            }
            else if (m_receivingState != ReceiveState.Stuck)
            {
                m_decoder.GetBuffer(out m_inpos, out m_insize);
                BeginRead(m_inpos, m_insize);
            }
        }
Ejemplo n.º 15
0
        private void HandleHandshake(Action action, SocketError socketError, int bytesTransferred)
        {
            int bytesSent;
            int bytesReceived;

            switch (m_handshakeState)
            {
                case HandshakeState.Closed:
                    switch (action)
                    {
                        case Action.Start:
                            // Send the 'length' and 'flags' fields of the identity message.
                            // The 'length' field is encoded in the long format.

                            m_greetingOutputBuffer[m_outsize++] = ((byte)0xff);
                            m_greetingOutputBuffer.PutLong(m_options.Endian, (long)m_options.IdentitySize + 1, 1);
                            m_outsize += 8;
                            m_greetingOutputBuffer[m_outsize++] = ((byte)0x7f);

                            m_outpos = new ByteArraySegment(m_greetingOutputBuffer);

                            m_handshakeState = HandshakeState.SendingGreeting;

                            BeginWrite(m_outpos, m_outsize);
                            break;
                        default:
                            Debug.Assert(false);
                            break;
                    }
                    break;
                case HandshakeState.SendingGreeting:
                    switch (action)
                    {
                        case Action.OutCompleted:
                            bytesSent = EndWrite(socketError, bytesTransferred);

                            if (bytesSent == -1)
                            {
                                Error();
                            }
                            else
                            {
                                m_outpos.AdvanceOffset(bytesSent);
                                m_outsize -= bytesSent;

                                if (m_outsize > 0)
                                {
                                    BeginWrite(m_outpos, m_outsize);
                                }
                                else
                                {
                                    m_greetingBytesRead = 0;

                                    var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);

                                    m_handshakeState = HandshakeState.ReceivingGreeting;

                                    BeginRead(greetingSegment, PreambleSize);
                                }
                            }
                            break;
                        case Action.ActivateIn:
                        case Action.ActivateOut:
                            // nothing to do
                            break;
                        default:
                            Debug.Assert(false);
                            break;
                    }
                    break;
                case HandshakeState.ReceivingGreeting:
                    switch (action)
                    {
                        case Action.InCompleted:
                            bytesReceived = EndRead(socketError, bytesTransferred);

                            if (bytesReceived == -1)
                            {
                                Error();
                            }
                            else
                            {
                                m_greetingBytesRead += bytesReceived;

                                // check if it is an unversioned protocol
                                if (m_greeting[0] != 0xff || (m_greetingBytesRead == 10 && (m_greeting[9] & 0x01) == 0))
                                {
                                    m_encoder = new V1Encoder(Config.OutBatchSize, m_options.Endian);
                                    m_encoder.SetMsgSource(m_session);

                                    m_decoder = new V1Decoder(Config.InBatchSize, m_options.MaxMessageSize, m_options.Endian);
                                    m_decoder.SetMsgSink(m_session);

                                    // We have already sent the message header.
                                    // Since there is no way to tell the encoder to
                                    // skip the message header, we simply throw that
                                    // header data away.
                                    int headerSize = m_options.IdentitySize + 1 >= 255 ? 10 : 2;
                                    var tmp = new byte[10];
                                    var bufferp = new ByteArraySegment(tmp);

                                    int bufferSize = headerSize;

                                    m_encoder.GetData(ref bufferp, ref bufferSize);

                                    Debug.Assert(bufferSize == headerSize);

                                    // Make sure the decoder sees the data we have already received.
                                    m_inpos = new ByteArraySegment(m_greeting);
                                    m_insize = m_greetingBytesRead;

                                    // To allow for interoperability with peers that do not forward
                                    // their subscriptions, we inject a phony subscription
                                    // message into the incoming message stream. To put this
                                    // message right after the identity message, we temporarily
                                    // divert the message stream from session to ourselves.
                                    if (m_options.SocketType == ZmqSocketType.Pub || m_options.SocketType == ZmqSocketType.Xpub)
                                        m_decoder.SetMsgSink(this);

                                    ActivateOut();
                                }
                                else if (m_greetingBytesRead < 10)
                                {
                                    var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);
                                    BeginRead(greetingSegment, PreambleSize - m_greetingBytesRead);
                                }
                                else
                                {
                                    // The peer is using versioned protocol.
                                    // Send the rest of the greeting.
                                    m_outpos[m_outsize++] = 1; // Protocol version
                                    m_outpos[m_outsize++] = (byte)m_options.SocketType;

                                    m_handshakeState = HandshakeState.SendingRestOfGreeting;

                                    BeginWrite(m_outpos, m_outsize);
                                }
                            }
                            break;
                        case Action.ActivateIn:
                        case Action.ActivateOut:
                            // nothing to do
                            break;
                        default:
                            Debug.Assert(false);
                            break;
                    }
                    break;
                case HandshakeState.SendingRestOfGreeting:
                    switch (action)
                    {
                        case Action.OutCompleted:
                            bytesSent = EndWrite(socketError, bytesTransferred);

                            if (bytesSent == -1)
                            {
                                Error();
                            }
                            else
                            {
                                m_outpos.AdvanceOffset(bytesSent);
                                m_outsize -= bytesSent;

                                if (m_outsize > 0)
                                {
                                    BeginWrite(m_outpos, m_outsize);
                                }
                                else
                                {
                                    var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);

                                    m_handshakeState = HandshakeState.ReceivingRestOfGreeting;
                                    BeginRead(greetingSegment, GreetingSize - m_greetingBytesRead);
                                }
                            }
                            break;
                        case Action.ActivateIn:
                        case Action.ActivateOut:
                            // nothing to do
                            break;
                        default:
                            Debug.Assert(false);
                            break;
                    }
                    break;
                case HandshakeState.ReceivingRestOfGreeting:
                    switch (action)
                    {
                        case Action.InCompleted:
                            bytesReceived = EndRead(socketError, bytesTransferred);

                            if (bytesReceived == -1)
                            {
                                Error();
                            }
                            else
                            {
                                m_greetingBytesRead += bytesReceived;

                                if (m_greetingBytesRead < GreetingSize)
                                {
                                    var greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);
                                    BeginRead(greetingSegment, GreetingSize - m_greetingBytesRead);
                                }
                                else
                                {
                                    if (m_greeting[VersionPos] == 0)
                                    {
                                        // ZMTP/1.0 framing.
                                        m_encoder = new V1Encoder(Config.OutBatchSize, m_options.Endian);
                                        m_encoder.SetMsgSource(m_session);

                                        m_decoder = new V1Decoder(Config.InBatchSize, m_options.MaxMessageSize, m_options.Endian);
                                        m_decoder.SetMsgSink(m_session);
                                    }
                                    else
                                    {
                                        // v1 framing protocol.
                                        m_encoder = new V2Encoder(Config.OutBatchSize, m_session, m_options.Endian);
                                        m_decoder = new V2Decoder(Config.InBatchSize, m_options.MaxMessageSize, m_session, m_options.Endian);
                                    }

                                    // handshake is done
                                    Activate();
                                }
                            }
                            break;
                        case Action.ActivateIn:
                        case Action.ActivateOut:
                            // nothing to do
                            break;
                        default:
                            Debug.Assert(false);
                            break;
                    }
                    break;
                default:
                    Debug.Assert(false);
                    break;
            }
        }
Ejemplo n.º 16
0
        private void BeginSending()
        {
            if (m_outsize == 0)
            {
                m_outpos = null;
                m_encoder.GetData(ref m_outpos, ref m_outsize);

                if (m_outsize == 0)
                {
                    m_sendingState = SendState.Idle;
                }
                else
                {
                    BeginWrite(m_outpos, m_outsize);
                }
            }
            else
            {
                BeginWrite(m_outpos, m_outsize);
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Create a new ByteArraySegment that is a shallow-copy of the given ByteArraySegment (with a reference to the same buffer)
 /// but with a different offset.
 /// </summary>
 /// <param name="otherSegment">the source-ByteArraySegment to make a copy of</param>
 /// <param name="offset">a value for the Offset property that is distinct from that of the source ByteArraySegment</param>
 public ByteArraySegment( ByteArraySegment otherSegment, int offset)
 {
     m_innerBuffer = otherSegment.m_innerBuffer;
     Offset = otherSegment.Offset + offset;
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Write the bytes of this ByteArraySegment to the specified destination-ByteArraySegment.
 /// </summary>
 /// <param name="fromOffset">an offset within this source buffer to start copying from</param>
 /// <param name="dest">the destination-ByteArraySegment</param>
 /// <param name="destOffset">an offset within the destination buffer to start copying to</param>
 /// <param name="toCopy">the number of bytes to copy</param>
 public void CopyTo(int fromOffset,  ByteArraySegment dest, int destOffset, int toCopy)
 {
     Buffer.BlockCopy(m_innerBuffer, Offset + fromOffset, dest.m_innerBuffer, dest.Offset + destOffset, toCopy);
 }
Ejemplo n.º 19
0
 protected void NextStep(ByteArraySegment readPos, int toRead, int state)
 {
     m_readPos  = readPos;
     m_toRead   = toRead;
     this.State = state;
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Create a new ByteArraySegment that is a shallow-copy of the given ByteArraySegment (with a reference to the same buffer).
 /// </summary>
 /// <param name="otherSegment">the source-ByteArraySegment to make a copy of</param>
 public ByteArraySegment([NotNull] ByteArraySegment otherSegment)
 {
     m_innerBuffer = otherSegment.m_innerBuffer;
     Offset        = otherSegment.Offset;
 }
Ejemplo n.º 21
0
        public void GetData(ref ByteArraySegment data, ref int size, ref int offset)
        {
            ByteArraySegment buffer = data ?? new ByteArraySegment(m_buffer);
            int bufferSize          = data == null ? m_bufferSize : size;

            int pos = 0;

            while (pos < bufferSize)
            {
                // If there are no more data to return, run the state machine.
                // If there are still no data, return what we already have
                // in the buffer.
                if (m_toWrite == 0)
                {
                    // If we are to encode the beginning of a new message,
                    // adjust the message offset.

                    if (m_beginning)
                    {
                        if (offset == -1)
                        {
                            offset = pos;
                        }
                    }

                    if (!Next())
                    {
                        break;
                    }
                }

                // If there are no data in the buffer yet and we are able to
                // fill whole buffer in a single go, let's use zero-copy.
                // There's no disadvantage to it as we cannot stuck multiple
                // messages into the buffer anyway. Note that subsequent
                // write(s) are non-blocking, thus each single write writes
                // at most SO_SNDBUF bytes at once not depending on how large
                // is the chunk returned from here.
                // As a consequence, large messages being sent won't block
                // other engines running in the same I/O thread for excessive
                // amounts of time.
                if (pos == 0 && data == null && m_toWrite >= bufferSize)
                {
                    data = m_writePos;
                    size = m_toWrite;

                    m_writePos = null;
                    m_toWrite  = 0;
                    return;
                }

                // Copy data to the buffer. If the buffer is full, return.
                int toCopy = Math.Min(m_toWrite, bufferSize - pos);

                if (toCopy != 0)
                {
                    m_writePos.CopyTo(0, buffer, pos, toCopy);
                    pos += toCopy;
                    m_writePos.AdvanceOffset(toCopy);
                    m_toWrite -= toCopy;
                }
            }

            data = buffer;
            size = pos;
        }
Ejemplo n.º 22
0
        /// <summary>
        /// This returns a batch of binary data. The data
        /// are filled to a supplied buffer. If no buffer is supplied (data_
        /// points to NULL) decoder object will provide buffer of its own.
        /// </summary>
        public void GetData(ref ByteArraySegment data, ref int size)
        {
            int offset = -1;

            GetData(ref data, ref size, ref offset);
        }
Ejemplo n.º 23
0
        private void ProcessInput()
        {
            bool disconnection = false;
            int  processed;

            if (m_insize == -1)
            {
                m_insize      = 0;
                disconnection = true;
            }

            if (m_options.RawSocket)
            {
                if (m_insize == 0 || !m_decoder.MessageReadySize(m_insize))
                {
                    processed = 0;
                }
                else
                {
                    processed = m_decoder.ProcessBuffer(m_inpos, m_insize);
                }
            }
            else
            {
                // Push the data to the decoder.
                processed = m_decoder.ProcessBuffer(m_inpos, m_insize);
            }

            if (processed == -1)
            {
                disconnection = true;
            }
            else
            {
                // Stop polling for input if we got stuck.
                if (processed < m_insize)
                {
                    m_receivingState = ReceiveState.Stuck;

                    m_inpos.AdvanceOffset(processed);
                    m_insize -= processed;
                }
                else
                {
                    m_inpos  = null;
                    m_insize = 0;
                }
            }

            // Flush all messages the decoder may have produced.
            m_session.Flush();

            // An input error has occurred. If the last decoded message
            // has already been accepted, we terminate the engine immediately.
            // Otherwise, we stop waiting for socket events and postpone
            // the termination until after the message is accepted.
            if (disconnection)
            {
                if (m_decoder.Stalled())
                {
                    m_ioObject.RemoveSocket(m_handle);
                    m_ioEnabled = false;
                    m_state     = State.Stalled;
                }
                else
                {
                    Error();
                }
            }
            else if (m_receivingState != ReceiveState.Stuck)
            {
                m_decoder.GetBuffer(out m_inpos, out m_insize);
                BeginRead(m_inpos, m_insize);
            }
        }
Ejemplo n.º 24
0
        public void GetData(ref ByteArraySegment data, ref int size, ref int offset)
        {
            ByteArraySegment buffer = data ?? new ByteArraySegment(m_buffer);
            int bufferSize = data == null ? m_bufferSize : size;

            int pos = 0;

            while (pos < bufferSize)
            {
                // If there are no more data to return, run the state machine.
                // If there are still no data, return what we already have
                // in the buffer.
                if (m_toWrite == 0)
                {
                    // If we are to encode the beginning of a new message,
                    // adjust the message offset.

                    if (m_beginning)
                    {
                        if (offset == -1)
                        {
                            offset = pos;
                        }
                    }

                    if (!Next())
                        break;
                }

                // If there are no data in the buffer yet and we are able to
                // fill whole buffer in a single go, let's use zero-copy.
                // There's no disadvantage to it as we cannot stuck multiple
                // messages into the buffer anyway. Note that subsequent
                // write(s) are non-blocking, thus each single write writes
                // at most SO_SNDBUF bytes at once not depending on how large
                // is the chunk returned from here.
                // As a consequence, large messages being sent won't block
                // other engines running in the same I/O thread for excessive
                // amounts of time.
                if (pos == 0 && data == null && m_toWrite >= bufferSize)
                {
                    data = m_writePos;
                    size = m_toWrite;

                    m_writePos = null;
                    m_toWrite = 0;
                    return;
                }

                // Copy data to the buffer. If the buffer is full, return.
                int toCopy = Math.Min(m_toWrite, bufferSize - pos);

                if (toCopy != 0)
                {
                    m_writePos.CopyTo(0, buffer, pos, toCopy);
                    pos += toCopy;
                    m_writePos.AdvanceOffset(toCopy);
                    m_toWrite -= toCopy;
                }
            }

            data = buffer;
            size = pos;
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Write the bytes of this ByteArraySegment to the specified destination-ByteArraySegment.
 /// </summary>
 /// <param name="otherSegment">the destination-ByteArraySegment</param>
 /// <param name="toCopy">the number of bytes to copy</param>
 public void CopyTo(ByteArraySegment otherSegment, int toCopy)
 {
     CopyTo(0, otherSegment, 0, toCopy);
 }
Ejemplo n.º 26
0
 //protected void next_step (Msg msg_, int state_, bool beginning_) {
 //    if (msg_ == null)
 //        next_step((ByteBuffer) null, 0, state_, beginning_);
 //    else
 //        next_step(msg_.data(), msg_.size(), state_, beginning_);
 //}
 protected void NextStep(ByteArraySegment writePos, int toWrite, int state, bool beginning)
 {
     m_writePos = writePos;
     m_toWrite = toWrite;
     State = state;
     m_beginning = beginning;
 }
Ejemplo n.º 27
0
 /// <summary>
 /// Create a new ByteArraySegment that is a shallow-copy of the given ByteArraySegment (with a reference to the same buffer)
 /// but with a different offset.
 /// </summary>
 /// <param name="otherSegment">the source-ByteArraySegment to make a copy of</param>
 /// <param name="offset">a value for the Offset property that is distinct from that of the source ByteArraySegment</param>
 public ByteArraySegment(ByteArraySegment otherSegment, int offset)
 {
     m_innerBuffer = otherSegment.m_innerBuffer;
     Offset        = otherSegment.Offset + offset;
 }
Ejemplo n.º 28
0
 public override void GetBuffer(out ByteArraySegment data, out int size)
 {
     data = new ByteArraySegment(m_buffer);
     size = m_buffer.Length;
 }