Exemple #1
0
        public static InboundFrame ReadFrom(Stream reader)
        {
            int type;

            try
            {
                type = reader.ReadByte();
                if (type == -1)
                {
                    throw new EndOfStreamException("Reached the end of the stream. Possible authentication failure.");
                }
            }
            catch (IOException ioe) when
                (ioe.InnerException != null &&
                (ioe.InnerException is SocketException) &&
                ((SocketException)ioe.InnerException).SocketErrorCode == SocketError.TimedOut)
            {
                throw ioe.InnerException;
            }

            if (type == 'A')
            {
                // Probably an AMQP protocol header, otherwise meaningless
                ProcessProtocolHeader(reader);
            }

            using IMemoryOwner <byte> headerMemory = MemoryPool <byte> .Shared.Rent(6);

            Memory <byte> headerSlice = headerMemory.Memory.Slice(0, 6);

            reader.Read(headerSlice);
            int channel                 = NetworkOrderDeserializer.ReadUInt16(headerSlice);
            int payloadSize             = NetworkOrderDeserializer.ReadInt32(headerSlice.Slice(2)); // FIXME - throw exn on unreasonable value
            IMemoryOwner <byte> payload = MemoryPool <byte> .Shared.Rent(payloadSize);

            int bytesRead = 0;

            try
            {
                while (bytesRead < payloadSize)
                {
                    bytesRead += reader.Read(payload.Memory[bytesRead..payloadSize]);
Exemple #2
0
        public static object ReadFieldValue(ReadOnlySpan <byte> span, out int bytesRead)
        {
            switch ((char)span[0])
            {
            case 'S':
                bytesRead = 1 + ReadLongstr(span.Slice(1), out var bytes);
                return(bytes);

            case 't':
                bytesRead = 2;
                return(span[1] != 0 ? TrueBoolean : FalseBoolean);

            case 'I':
                bytesRead = 5;
                return(NetworkOrderDeserializer.ReadInt32(span.Slice(1)));

            case 'V':
                bytesRead = 1;
                return(null);

            default:
                return(ReadFieldValueSlow(span, out bytesRead));
            }
 public void TestReadInt32()
 {
     Assert.Equal(0x12345678, NetworkOrderDeserializer.ReadInt32(new byte[] { 0x12, 0x34, 0x56, 0x78 }.AsSpan()));
 }
Exemple #4
0
        internal static InboundFrame ReadFrom(Stream reader)
        {
            int type;

            try
            {
                type = reader.ReadByte();
                if (type == -1)
                {
                    throw new EndOfStreamException("Reached the end of the stream. Possible authentication failure.");
                }
            }
            catch (IOException ioe)
            {
                // If it's a WSAETIMEDOUT SocketException, unwrap it.
                // This might happen when the limit of half-open connections is
                // reached.
                if (ioe.InnerException == null ||
                    !(ioe.InnerException is SocketException) ||
                    ((SocketException)ioe.InnerException).SocketErrorCode != SocketError.TimedOut)
                {
                    throw ioe;
                }
                throw ioe.InnerException;
            }

            if (type == 'A')
            {
                // Probably an AMQP protocol header, otherwise meaningless
                ProcessProtocolHeader(reader);
            }

            using (IMemoryOwner <byte> headerMemory = MemoryPool <byte> .Shared.Rent(6))
            {
                Memory <byte> headerSlice = headerMemory.Memory.Slice(0, 6);
                reader.Read(headerSlice);
                int channel                 = NetworkOrderDeserializer.ReadUInt16(headerSlice);
                int payloadSize             = NetworkOrderDeserializer.ReadInt32(headerSlice.Slice(2)); // FIXME - throw exn on unreasonable value
                IMemoryOwner <byte> payload = MemoryPool <byte> .Shared.Rent(payloadSize);

                int bytesRead = 0;
                try
                {
                    while (bytesRead < payloadSize)
                    {
                        bytesRead += reader.Read(payload.Memory.Slice(bytesRead, payloadSize - bytesRead));
                    }
                }
                catch (Exception)
                {
                    // Early EOF.
                    throw new MalformedFrameException($"Short frame - expected to read {payloadSize} bytes, only got {bytesRead} bytes");
                }

                int frameEndMarker = reader.ReadByte();
                if (frameEndMarker != Constants.FrameEnd)
                {
                    throw new MalformedFrameException("Bad frame end marker: " + frameEndMarker);
                }

                return(new InboundFrame((FrameType)type, channel, payload, payloadSize));
            }
        }
        public static object ReadFieldValue(ReadOnlyMemory <byte> memory, out int bytesRead)
        {
            bytesRead = 1;
            ReadOnlyMemory <byte> slice = memory.Slice(1);

            switch ((char)memory.Span[0])
            {
            case 'S':
                byte[] result = ReadLongstr(slice);
                bytesRead += result.Length + 4;
                return(result);

            case 'I':
                bytesRead += 4;
                return(NetworkOrderDeserializer.ReadInt32(slice));

            case 'i':
                bytesRead += 4;
                return(NetworkOrderDeserializer.ReadUInt32(slice));

            case 'D':
                bytesRead += 5;
                return(ReadDecimal(slice));

            case 'T':
                bytesRead += 8;
                return(ReadTimestamp(slice));

            case 'F':
                IDictionary <string, object> tableResult = ReadTable(slice, out int tableBytesRead);
                bytesRead += tableBytesRead;
                return(tableResult);

            case 'A':
                IList arrayResult = ReadArray(slice, out int arrayBytesRead);
                bytesRead += arrayBytesRead;
                return(arrayResult);

            case 'B':
                bytesRead += 1;
                return(slice.Span[0]);

            case 'b':
                bytesRead += 1;
                return((sbyte)slice.Span[0]);

            case 'd':
                bytesRead += 8;
                return(NetworkOrderDeserializer.ReadDouble(slice));

            case 'f':
                bytesRead += 4;
                return(NetworkOrderDeserializer.ReadSingle(slice));

            case 'l':
                bytesRead += 8;
                return(NetworkOrderDeserializer.ReadInt64(slice));

            case 's':
                bytesRead += 2;
                return(NetworkOrderDeserializer.ReadInt16(slice));

            case 't':
                bytesRead += 1;
                return(slice.Span[0] != 0);

            case 'x':
                byte[] binaryTableResult = ReadLongstr(slice);
                bytesRead += binaryTableResult.Length + 4;
                return(new BinaryTableValue(binaryTableResult));

            case 'V':
                return(null);

            default:
                throw new SyntaxError($"Unrecognised type in table: {(char)memory.Span[0]}");
            }
        }
Exemple #6
0
        public static object ReadFieldValue(ReadOnlySpan <byte> span, out int bytesRead)
        {
            bytesRead = 1;
            switch ((char)span[0])
            {
            case 'S':
                bytesRead += ReadLongstr(span.Slice(1), out var bytes);
                return(bytes);

            case 'I':
                bytesRead += 4;
                return(NetworkOrderDeserializer.ReadInt32(span.Slice(1)));

            case 'i':
                bytesRead += 4;
                return(NetworkOrderDeserializer.ReadUInt32(span.Slice(1)));

            case 'D':
                bytesRead += 5;
                return(ReadDecimal(span.Slice(1)));

            case 'T':
                bytesRead += ReadTimestamp(span.Slice(1), out var timestamp);
                return(timestamp);

            case 'F':
                bytesRead += ReadDictionary(span.Slice(1), out var dictionary);
                return(dictionary);

            case 'A':
                IList arrayResult = ReadArray(span.Slice(1), out int arrayBytesRead);
                bytesRead += arrayBytesRead;
                return(arrayResult);

            case 'B':
                bytesRead += 1;
                return(span[1]);

            case 'b':
                bytesRead += 1;
                return((sbyte)span[1]);

            case 'd':
                bytesRead += 8;
                return(NetworkOrderDeserializer.ReadDouble(span.Slice(1)));

            case 'f':
                bytesRead += 4;
                return(NetworkOrderDeserializer.ReadSingle(span.Slice(1)));

            case 'l':
                bytesRead += 8;
                return(NetworkOrderDeserializer.ReadInt64(span.Slice(1)));

            case 's':
                bytesRead += 2;
                return(NetworkOrderDeserializer.ReadInt16(span.Slice(1)));

            case 't':
                bytesRead += 1;
                return(span[1] != 0);

            case 'x':
                bytesRead += ReadLongstr(span.Slice(1), out var binaryTableResult);
                return(new BinaryTableValue(binaryTableResult));

            case 'V':
                return(null);

            default:
                throw new SyntaxErrorException($"Unrecognised type in table: {(char)span[0]}");
            }
        }
        internal static InboundFrame ReadFrom(Stream reader, byte[] frameHeaderBuffer)
        {
            int type = default;

            try
            {
                type = reader.ReadByte();
            }
            catch (IOException ioe)
            {
                // If it's a WSAETIMEDOUT SocketException, unwrap it.
                // This might happen when the limit of half-open connections is
                // reached.
                if (ioe.InnerException == null ||
                    !(ioe.InnerException is SocketException) ||
                    ((SocketException)ioe.InnerException).SocketErrorCode != SocketError.TimedOut)
                {
                    throw;
                }

                ExceptionDispatchInfo.Capture(ioe.InnerException).Throw();
            }

            switch (type)
            {
            case -1:
                throw new EndOfStreamException("Reached the end of the stream. Possible authentication failure.");

            case 'A':
                // Probably an AMQP protocol header, otherwise meaningless
                ProcessProtocolHeader(reader);
                break;
            }

            reader.Read(frameHeaderBuffer, 0, frameHeaderBuffer.Length);
            int channel     = NetworkOrderDeserializer.ReadUInt16(new ReadOnlySpan <byte>(frameHeaderBuffer));
            int payloadSize = NetworkOrderDeserializer.ReadInt32(new ReadOnlySpan <byte>(frameHeaderBuffer, 2, 4)); // FIXME - throw exn on unreasonable value

            const int EndMarkerLength = 1;
            // Is returned by InboundFrame.ReturnPayload in Connection.MainLoopIteration
            var readSize = payloadSize + EndMarkerLength;

            byte[] payloadBytes = ArrayPool <byte> .Shared.Rent(readSize);

            int bytesRead = 0;

            try
            {
                while (bytesRead < readSize)
                {
                    bytesRead += reader.Read(payloadBytes, bytesRead, readSize - bytesRead);
                }
            }
            catch (Exception)
            {
                // Early EOF.
                ArrayPool <byte> .Shared.Return(payloadBytes);

                throw new MalformedFrameException($"Short frame - expected to read {readSize} bytes, only got {bytesRead} bytes");
            }

            if (payloadBytes[payloadSize] != Constants.FrameEnd)
            {
                ArrayPool <byte> .Shared.Return(payloadBytes);

                throw new MalformedFrameException($"Bad frame end marker: {payloadBytes[payloadSize]}");
            }

            return(new InboundFrame((FrameType)type, channel, new Memory <byte>(payloadBytes, 0, payloadSize), payloadBytes));
        }
        internal static InboundFrame ReadFrom(Stream reader)
        {
            int type = default;

            try
            {
                type = reader.ReadByte();
                if (type == -1)
                {
                    throw new EndOfStreamException("Reached the end of the stream. Possible authentication failure.");
                }
            }
            catch (IOException ioe)
            {
                // If it's a WSAETIMEDOUT SocketException, unwrap it.
                // This might happen when the limit of half-open connections is
                // reached.
                if (ioe.InnerException == null ||
                    !(ioe.InnerException is SocketException) ||
                    ((SocketException)ioe.InnerException).SocketErrorCode != SocketError.TimedOut)
                {
                    throw;
                }

                ExceptionDispatchInfo.Capture(ioe.InnerException).Throw();
            }

            if (type == 'A')
            {
                // Probably an AMQP protocol header, otherwise meaningless
                ProcessProtocolHeader(reader);
            }

            Span <byte> headerBytes = stackalloc byte[6];

            reader.Read(headerBytes);
            int channel     = NetworkOrderDeserializer.ReadUInt16(headerBytes);
            int payloadSize = NetworkOrderDeserializer.ReadInt32(headerBytes.Slice(2)); // FIXME - throw exn on unreasonable value

            // Is returned by InboundFrame.Dispose in Connection.MainLoopIteration
            byte[] payloadBytes = ArrayPool <byte> .Shared.Rent(payloadSize);

            Memory <byte> payload   = new Memory <byte>(payloadBytes, 0, payloadSize);
            int           bytesRead = 0;

            try
            {
                while (bytesRead < payloadSize)
                {
                    bytesRead += reader.Read(payload.Slice(bytesRead, payloadSize - bytesRead));
                }
            }
            catch (Exception)
            {
                // Early EOF.
                ArrayPool <byte> .Shared.Return(payloadBytes);

                throw new MalformedFrameException($"Short frame - expected to read {payloadSize} bytes, only got {bytesRead} bytes");
            }

            int frameEndMarker = reader.ReadByte();

            if (frameEndMarker != Constants.FrameEnd)
            {
                ArrayPool <byte> .Shared.Return(payloadBytes);

                throw new MalformedFrameException($"Bad frame end marker: {frameEndMarker}");
            }

            return(new InboundFrame((FrameType)type, channel, payload));
        }