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]);
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())); }
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]}"); } }
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)); }