diff --git a/projects/client/RabbitMQ.Client/RabbitMQ.Client.csproj b/projects/client/RabbitMQ.Client/RabbitMQ.Client.csproj index e87f0117e3..bc5af1d38d 100755 --- a/projects/client/RabbitMQ.Client/RabbitMQ.Client.csproj +++ b/projects/client/RabbitMQ.Client/RabbitMQ.Client.csproj @@ -53,6 +53,7 @@ + diff --git a/projects/client/RabbitMQ.Client/src/client/content/BytesWireFormatting.cs b/projects/client/RabbitMQ.Client/src/client/content/BytesWireFormatting.cs index 010a616afd..fd7ca6414c 100644 --- a/projects/client/RabbitMQ.Client/src/client/content/BytesWireFormatting.cs +++ b/projects/client/RabbitMQ.Client/src/client/content/BytesWireFormatting.cs @@ -38,6 +38,7 @@ // Copyright (c) 2007-2020 VMware, Inc. All rights reserved. //--------------------------------------------------------------------------- +using System.Buffers; using System.Text; using RabbitMQ.Util; @@ -67,7 +68,7 @@ public static byte[] ReadBytes(NetworkBinaryReader reader, int count) public static char ReadChar(NetworkBinaryReader reader) { - return (char) reader.ReadUInt16(); + return (char)reader.ReadUInt16(); } public static double ReadDouble(NetworkBinaryReader reader) @@ -119,7 +120,7 @@ public static void WriteBytes(NetworkBinaryWriter writer, byte[] source) public static void WriteChar(NetworkBinaryWriter writer, char value) { - writer.Write((ushort) value); + writer.Write((ushort)value); } public static void WriteDouble(NetworkBinaryWriter writer, double value) @@ -149,9 +150,18 @@ public static void WriteSingle(NetworkBinaryWriter writer, float value) public static void WriteString(NetworkBinaryWriter writer, string value) { - byte[] bytes = Encoding.UTF8.GetBytes(value); - writer.Write((ushort) bytes.Length); - writer.Write(bytes); + int maxLength = Encoding.UTF8.GetMaxByteCount(value.Length); + byte[] bytes = ArrayPool.Shared.Rent(maxLength); + try + { + int bytesUsed = Encoding.UTF8.GetBytes(value, 0, value.Length, bytes, 0); + writer.Write((ushort)bytesUsed); + writer.Write(bytes, 0, bytesUsed); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } } } diff --git a/projects/client/RabbitMQ.Client/src/client/content/StreamWireFormatting.cs b/projects/client/RabbitMQ.Client/src/client/content/StreamWireFormatting.cs index 34e563359c..f7cb53eaf1 100644 --- a/projects/client/RabbitMQ.Client/src/client/content/StreamWireFormatting.cs +++ b/projects/client/RabbitMQ.Client/src/client/content/StreamWireFormatting.cs @@ -38,6 +38,7 @@ // Copyright (c) 2007-2020 VMware, Inc. All rights reserved. //--------------------------------------------------------------------------- +using System.Buffers; using System.IO; using System.Text; @@ -75,11 +76,11 @@ public static bool ReadBool(NetworkBinaryReader reader) object value = ReadNonnullObject("bool", reader); if (value is bool) { - return (bool) value; + return (bool)value; } if (value is string) { - return PrimitiveParser.ParseBool((string) value); + return PrimitiveParser.ParseBool((string)value); } throw PrimitiveParser.CreateProtocolViolationException("bool", value); } @@ -89,11 +90,11 @@ public static byte ReadByte(NetworkBinaryReader reader) object value = ReadNonnullObject("byte", reader); if (value is byte) { - return (byte) value; + return (byte)value; } if (value is string) { - return PrimitiveParser.ParseByte((string) value); + return PrimitiveParser.ParseByte((string)value); } throw PrimitiveParser.CreateProtocolViolationException("byte", value); } @@ -107,7 +108,7 @@ public static byte[] ReadBytes(NetworkBinaryReader reader) } if (value is byte[]) { - return (byte[]) value; + return (byte[])value; } throw PrimitiveParser.CreateProtocolViolationException("byte[]", value); } @@ -117,7 +118,7 @@ public static char ReadChar(NetworkBinaryReader reader) object value = ReadNonnullObject("char", reader); if (value is char) { - return (char) value; + return (char)value; } throw PrimitiveParser.CreateProtocolViolationException("char", value); } @@ -127,11 +128,11 @@ public static double ReadDouble(NetworkBinaryReader reader) object value = ReadNonnullObject("double", reader); if (value is double || value is float) { - return (double) value; + return (double)value; } if (value is string) { - return PrimitiveParser.ParseDouble((string) value); + return PrimitiveParser.ParseDouble((string)value); } throw PrimitiveParser.CreateProtocolViolationException("double", value); } @@ -141,11 +142,11 @@ public static short ReadInt16(NetworkBinaryReader reader) object value = ReadNonnullObject("short", reader); if (value is short || value is byte) { - return (short) value; + return (short)value; } if (value is string) { - return PrimitiveParser.ParseShort((string) value); + return PrimitiveParser.ParseShort((string)value); } throw PrimitiveParser.CreateProtocolViolationException("short", value); } @@ -155,11 +156,11 @@ public static int ReadInt32(NetworkBinaryReader reader) object value = ReadNonnullObject("int", reader); if (value is int || value is short || value is byte) { - return (int) value; + return (int)value; } if (value is string) { - return PrimitiveParser.ParseInt((string) value); + return PrimitiveParser.ParseInt((string)value); } throw PrimitiveParser.CreateProtocolViolationException("int", value); } @@ -169,11 +170,11 @@ public static long ReadInt64(NetworkBinaryReader reader) object value = ReadNonnullObject("long", reader); if (value is long || value is int || value is short || value is byte) { - return (long) value; + return (long)value; } if (value is string) { - return PrimitiveParser.ParseLong((string) value); + return PrimitiveParser.ParseLong((string)value); } throw PrimitiveParser.CreateProtocolViolationException("long", value); } @@ -195,71 +196,73 @@ public static object ReadNonnullObject(string target, NetworkBinaryReader reader public static object ReadObject(NetworkBinaryReader reader) { int typeTag = reader.ReadByte(); - switch (typeTag) + if (typeTag == -1) { - case -1: - throw new EndOfStreamException("End of StreamMessage reached"); + throw new EndOfStreamException("End of StreamMessage reached"); + } - case (int) StreamWireFormattingTag.Bool: - { - byte value = reader.ReadByte(); - switch (value) + switch ((StreamWireFormattingTag)typeTag) + { + case StreamWireFormattingTag.Bool: { - case 0x00: - return false; - case 0x01: - return true; - default: + byte value = reader.ReadByte(); + switch (value) { - string message = - string.Format("Invalid boolean value in StreamMessage: {0}", value); - throw new ProtocolViolationException(message); + case 0x00: + return false; + case 0x01: + return true; + default: + { + string message = + string.Format("Invalid boolean value in StreamMessage: {0}", value); + throw new ProtocolViolationException(message); + } } } - } - case (int) StreamWireFormattingTag.Byte: + case StreamWireFormattingTag.Byte: return reader.ReadByte(); - case (int) StreamWireFormattingTag.Bytes: - { - int length = reader.ReadInt32(); - if (length == -1) + case StreamWireFormattingTag.Bytes: { - return null; + int length = reader.ReadInt32(); + if (length == -1) + { + return null; + } + return reader.ReadBytes(length); } - return reader.ReadBytes(length); - } - case (int) StreamWireFormattingTag.Int16: + case StreamWireFormattingTag.Int16: return reader.ReadInt16(); - case (int) StreamWireFormattingTag.Char: - return (char) reader.ReadUInt16(); + case StreamWireFormattingTag.Char: + return (char)reader.ReadUInt16(); - case (int) StreamWireFormattingTag.Int32: + case StreamWireFormattingTag.Int32: return reader.ReadInt32(); - case (int) StreamWireFormattingTag.Int64: + case StreamWireFormattingTag.Int64: return reader.ReadInt64(); - case (int) StreamWireFormattingTag.Single: + case StreamWireFormattingTag.Single: return reader.ReadSingle(); - case (int) StreamWireFormattingTag.Double: + case StreamWireFormattingTag.Double: return reader.ReadDouble(); - case (int) StreamWireFormattingTag.String: + case StreamWireFormattingTag.String: return ReadUntypedString(reader); - case (int) StreamWireFormattingTag.Null: + case StreamWireFormattingTag.Null: return null; default: - { - string message = string.Format("Invalid type tag in StreamMessage: {0}", typeTag); - throw new ProtocolViolationException(message); - } + { + string message = string.Format("Invalid type tag in StreamMessage: {0}", typeTag); + throw new ProtocolViolationException(message); + } } } @@ -268,11 +271,11 @@ public static float ReadSingle(NetworkBinaryReader reader) object value = ReadNonnullObject("float", reader); if (value is float) { - return (float) value; + return (float)value; } if (value is string) { - return PrimitiveParser.ParseFloat((string) value); + return PrimitiveParser.ParseFloat((string)value); } throw PrimitiveParser.CreateProtocolViolationException("float", value); } @@ -308,13 +311,13 @@ public static string ReadUntypedString(NetworkBinaryReader reader) public static void WriteBool(NetworkBinaryWriter writer, bool value) { - writer.Write((byte) StreamWireFormattingTag.Bool); - writer.Write(value ? (byte) 0x01 : (byte) 0x00); + writer.Write((byte)StreamWireFormattingTag.Bool); + writer.Write(value ? (byte)0x01 : (byte)0x00); } public static void WriteByte(NetworkBinaryWriter writer, byte value) { - writer.Write((byte) StreamWireFormattingTag.Byte); + writer.Write((byte)StreamWireFormattingTag.Byte); writer.Write(value); } @@ -323,7 +326,7 @@ public static void WriteBytes(NetworkBinaryWriter writer, int offset, int length) { - writer.Write((byte) StreamWireFormattingTag.Bytes); + writer.Write((byte)StreamWireFormattingTag.Bytes); writer.Write(length); writer.Write(value, offset, length); } @@ -335,31 +338,31 @@ public static void WriteBytes(NetworkBinaryWriter writer, byte[] value) public static void WriteChar(NetworkBinaryWriter writer, char value) { - writer.Write((byte) StreamWireFormattingTag.Char); - writer.Write((ushort) value); + writer.Write((byte)StreamWireFormattingTag.Char); + writer.Write((ushort)value); } public static void WriteDouble(NetworkBinaryWriter writer, double value) { - writer.Write((byte) StreamWireFormattingTag.Double); + writer.Write((byte)StreamWireFormattingTag.Double); writer.Write(value); } public static void WriteInt16(NetworkBinaryWriter writer, short value) { - writer.Write((byte) StreamWireFormattingTag.Int16); + writer.Write((byte)StreamWireFormattingTag.Int16); writer.Write(value); } public static void WriteInt32(NetworkBinaryWriter writer, int value) { - writer.Write((byte) StreamWireFormattingTag.Int32); + writer.Write((byte)StreamWireFormattingTag.Int32); writer.Write(value); } public static void WriteInt64(NetworkBinaryWriter writer, long value) { - writer.Write((byte) StreamWireFormattingTag.Int64); + writer.Write((byte)StreamWireFormattingTag.Int64); writer.Write(value); } @@ -368,48 +371,48 @@ public static void WriteObject(NetworkBinaryWriter writer, object value) { if (value is bool) { - WriteBool(writer, (bool) value); + WriteBool(writer, (bool)value); } else if (value is int) { - WriteInt32(writer, (int) value); + WriteInt32(writer, (int)value); } else if (value is short) { - WriteInt16(writer, (short) value); + WriteInt16(writer, (short)value); } else if (value is byte) { - WriteByte(writer, (byte) value); + WriteByte(writer, (byte)value); } else if (value is char) { - WriteChar(writer, (char) value); + WriteChar(writer, (char)value); } else if (value is long) { - WriteInt64(writer, (long) value); + WriteInt64(writer, (long)value); } else if (value is float) { - WriteSingle(writer, (float) value); + WriteSingle(writer, (float)value); } else if (value is double) { - WriteDouble(writer, (double) value); + WriteDouble(writer, (double)value); } else if (value is byte[]) { - WriteBytes(writer, (byte[]) value); + WriteBytes(writer, (byte[])value); } else if (value is BinaryTableValue) { WriteBytes(writer, - ((BinaryTableValue) value).Bytes); + ((BinaryTableValue)value).Bytes); } else if (value is string) { - WriteString(writer, (string) value); + WriteString(writer, (string)value); } else { @@ -420,20 +423,30 @@ public static void WriteObject(NetworkBinaryWriter writer, object value) public static void WriteSingle(NetworkBinaryWriter writer, float value) { - writer.Write((byte) StreamWireFormattingTag.Single); + writer.Write((byte)StreamWireFormattingTag.Single); writer.Write(value); } public static void WriteString(NetworkBinaryWriter writer, string value) { - writer.Write((byte) StreamWireFormattingTag.String); + writer.Write((byte)StreamWireFormattingTag.String); WriteUntypedString(writer, value); } public static void WriteUntypedString(NetworkBinaryWriter writer, string value) { - writer.Write(Encoding.UTF8.GetBytes(value)); - writer.Write((byte) 0); + int maxLength = Encoding.UTF8.GetMaxByteCount(value.Length); + byte[] bytes = ArrayPool.Shared.Rent(maxLength + 1); + try + { + int bytesUsed = Encoding.UTF8.GetBytes(value, 0, value.Length, bytes, 0); + bytes[bytesUsed] = 0; + writer.Write(bytes, 0, bytesUsed + 1); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } } } diff --git a/projects/client/RabbitMQ.Client/src/client/impl/WireFormatting.cs b/projects/client/RabbitMQ.Client/src/client/impl/WireFormatting.cs index c32ca2107a..d1325ad56c 100644 --- a/projects/client/RabbitMQ.Client/src/client/impl/WireFormatting.cs +++ b/projects/client/RabbitMQ.Client/src/client/impl/WireFormatting.cs @@ -38,6 +38,7 @@ // Copyright (c) 2007-2020 VMware, Inc. All rights reserved. //--------------------------------------------------------------------------- +using System.Buffers; using System.Collections; using System.Collections.Generic; using System.IO; @@ -116,7 +117,7 @@ public static decimal ReadDecimal(NetworkBinaryReader reader) public static object ReadFieldValue(NetworkBinaryReader reader) { - switch((char)reader.ReadByte()) + switch ((char)reader.ReadByte()) { case 'S': return ReadLongstr(reader); @@ -268,7 +269,17 @@ public static void WriteFieldValue(NetworkBinaryWriter writer, object value) break; case string val: WriteOctet(writer, (byte)'S'); - WriteLongstr(writer, Encoding.UTF8.GetBytes(val)); + int maxLength = Encoding.UTF8.GetMaxByteCount(val.Length); + byte[] bytes = ArrayPool.Shared.Rent(maxLength); + try + { + int bytesUsed = Encoding.UTF8.GetBytes(val, 0, val.Length, bytes, 0); + WriteLongstr(writer, bytes, 0, bytesUsed); + } + finally + { + ArrayPool.Shared.Return(bytes); + } break; case byte[] val: WriteOctet(writer, (byte)'S'); @@ -353,6 +364,12 @@ public static void WriteLongstr(NetworkBinaryWriter writer, byte[] val) writer.Write(val); } + public static void WriteLongstr(NetworkBinaryWriter writer, byte[] val, int index, int count) + { + WriteLong(writer, (uint)count); + writer.Write(val, index, count); + } + public static void WriteOctet(NetworkBinaryWriter writer, byte val) { writer.Write(val); @@ -365,17 +382,23 @@ public static void WriteShort(NetworkBinaryWriter writer, ushort val) public static void WriteShortstr(NetworkBinaryWriter writer, string val) { - byte[] bytes = Encoding.UTF8.GetBytes(val); - int length = bytes.Length; + int maxLength = Encoding.UTF8.GetMaxByteCount(val.Length); + byte[] bytes = ArrayPool.Shared.Rent(maxLength); + try + { + int bytesUsed = Encoding.UTF8.GetBytes(val, 0, val.Length, bytes, 0); + if (bytesUsed > 255) + { + throw new WireFormattingException($"Short string too long; UTF-8 encoded length={bytesUsed}, max=255"); + } - if (length > 255) + writer.Write((byte)bytesUsed); + writer.Write(bytes, 0, bytesUsed); + } + finally { - throw new WireFormattingException("Short string too long; " + - "UTF-8 encoded length=" + length + ", max=255"); + ArrayPool.Shared.Return(bytes); } - - writer.Write((byte)length); - writer.Write(bytes); } ///Writes an AMQP "table" to the writer. diff --git a/projects/client/RabbitMQ.Client/src/util/NetworkBinaryReader.cs b/projects/client/RabbitMQ.Client/src/util/NetworkBinaryReader.cs index 96c92edd9a..77bcaa8bfd 100644 --- a/projects/client/RabbitMQ.Client/src/util/NetworkBinaryReader.cs +++ b/projects/client/RabbitMQ.Client/src/util/NetworkBinaryReader.cs @@ -38,6 +38,8 @@ // Copyright (c) 2007-2020 VMware, Inc. All rights reserved. //--------------------------------------------------------------------------- +using System; +using System.Buffers.Binary; using System.IO; using System.Text; @@ -54,8 +56,6 @@ namespace RabbitMQ.Util /// public class NetworkBinaryReader : BinaryReader { - private static readonly Encoding s_encoding = new UTF8Encoding(); - // Not particularly efficient. To be more efficient, we could // reuse BinaryReader's implementation details: m_buffer and // FillBuffer, if they weren't private @@ -66,44 +66,17 @@ public class NetworkBinaryReader : BinaryReader /// /// Construct a NetworkBinaryReader over the given input stream. /// - public NetworkBinaryReader(Stream input) : base(input, s_encoding) - { - } - - /// - /// Construct a NetworkBinaryReader over the given input - /// stream, reading strings using the given encoding. - /// - public NetworkBinaryReader(Stream input, Encoding encoding) : base(input, encoding) + public NetworkBinaryReader(Stream input) : base(input, Encoding.UTF8) { } - ///Helper method for constructing a temporary - ///BinaryReader over a byte[]. - public static BinaryReader TemporaryBinaryReader(byte[] bytes) - { - return new BinaryReader(new MemoryStream(bytes)); - } - /// /// Override BinaryReader's method for network-order. /// public override double ReadDouble() { - byte[] bytes = ReadBytes(8); - byte temp = bytes[0]; - bytes[0] = bytes[7]; - bytes[7] = temp; - temp = bytes[1]; - bytes[1] = bytes[6]; - bytes[6] = temp; - temp = bytes[2]; - bytes[2] = bytes[5]; - bytes[5] = temp; - temp = bytes[3]; - bytes[3] = bytes[4]; - bytes[4] = temp; - return TemporaryBinaryReader(bytes).ReadDouble(); + long val = BinaryPrimitives.ReadInt64BigEndian(ReadBytes(8)); + return BitConverter.Int64BitsToDouble(val); } /// @@ -111,9 +84,7 @@ public override double ReadDouble() /// public override short ReadInt16() { - uint i = base.ReadUInt16(); - return (short)(((i & 0xFF00) >> 8) | - ((i & 0x00FF) << 8)); + return BinaryPrimitives.ReadInt16BigEndian(ReadBytes(2)); } /// @@ -121,11 +92,7 @@ public override short ReadInt16() /// public override int ReadInt32() { - uint i = base.ReadUInt32(); - return (int)(((i & 0xFF000000) >> 24) | - ((i & 0x00FF0000) >> 8) | - ((i & 0x0000FF00) << 8) | - ((i & 0x000000FF) << 24)); + return BinaryPrimitives.ReadInt32BigEndian(ReadBytes(4)); } /// @@ -133,15 +100,7 @@ public override int ReadInt32() /// public override long ReadInt64() { - ulong i = base.ReadUInt64(); - return (long)(((i & 0xFF00000000000000) >> 56) | - ((i & 0x00FF000000000000) >> 40) | - ((i & 0x0000FF0000000000) >> 24) | - ((i & 0x000000FF00000000) >> 8) | - ((i & 0x00000000FF000000) << 8) | - ((i & 0x0000000000FF0000) << 24) | - ((i & 0x000000000000FF00) << 40) | - ((i & 0x00000000000000FF) << 56)); + return BinaryPrimitives.ReadInt64BigEndian(ReadBytes(8)); } /// @@ -150,13 +109,12 @@ public override long ReadInt64() public override float ReadSingle() { byte[] bytes = ReadBytes(4); - byte temp = bytes[0]; - bytes[0] = bytes[3]; - bytes[3] = temp; - temp = bytes[1]; - bytes[1] = bytes[2]; - bytes[2] = temp; - return TemporaryBinaryReader(bytes).ReadSingle(); + if (BitConverter.IsLittleEndian) + { + bytes.AsSpan().Reverse(); + } + + return BitConverter.ToSingle(bytes, 0); } /// @@ -164,9 +122,7 @@ public override float ReadSingle() /// public override ushort ReadUInt16() { - uint i = base.ReadUInt16(); - return (ushort)(((i & 0xFF00) >> 8) | - ((i & 0x00FF) << 8)); + return BinaryPrimitives.ReadUInt16BigEndian(ReadBytes(2)); } /// @@ -174,11 +130,7 @@ public override ushort ReadUInt16() /// public override uint ReadUInt32() { - uint i = base.ReadUInt32(); - return ((i & 0xFF000000) >> 24) | - ((i & 0x00FF0000) >> 8) | - ((i & 0x0000FF00) << 8) | - ((i & 0x000000FF) << 24); + return BinaryPrimitives.ReadUInt32BigEndian(ReadBytes(4)); } /// @@ -186,15 +138,7 @@ public override uint ReadUInt32() /// public override ulong ReadUInt64() { - ulong i = base.ReadUInt64(); - return ((i & 0xFF00000000000000) >> 56) | - ((i & 0x00FF000000000000) >> 40) | - ((i & 0x0000FF0000000000) >> 24) | - ((i & 0x000000FF00000000) >> 8) | - ((i & 0x00000000FF000000) << 8) | - ((i & 0x0000000000FF0000) << 24) | - ((i & 0x000000000000FF00) << 40) | - ((i & 0x00000000000000FF) << 56); + return BinaryPrimitives.ReadUInt64BigEndian(ReadBytes(8)); } } } diff --git a/projects/client/RabbitMQ.Client/src/util/NetworkBinaryWriter.cs b/projects/client/RabbitMQ.Client/src/util/NetworkBinaryWriter.cs index 21dad6cea5..4e10b0b737 100644 --- a/projects/client/RabbitMQ.Client/src/util/NetworkBinaryWriter.cs +++ b/projects/client/RabbitMQ.Client/src/util/NetworkBinaryWriter.cs @@ -38,6 +38,9 @@ // Copyright (c) 2007-2020 VMware, Inc. All rights reserved. //--------------------------------------------------------------------------- +using System; +using System.Buffers; +using System.Buffers.Binary; using System.IO; using System.Text; @@ -94,8 +97,16 @@ public static byte[] TemporaryContents(BinaryWriter w) /// public override void Write(short i) { - Write((byte)((i & 0xFF00) >> 8)); - Write((byte)(i & 0x00FF)); + byte[] bytes = ArrayPool.Shared.Rent(2); + try + { + BinaryPrimitives.WriteInt16BigEndian(bytes, i); + Write(bytes, 0, 2); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } /// @@ -103,8 +114,16 @@ public override void Write(short i) /// public override void Write(ushort i) { - Write((byte)((i & 0xFF00) >> 8)); - Write((byte)(i & 0x00FF)); + byte[] bytes = ArrayPool.Shared.Rent(2); + try + { + BinaryPrimitives.WriteUInt16BigEndian(bytes, i); + Write(bytes, 0, 2); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } /// @@ -112,10 +131,16 @@ public override void Write(ushort i) /// public override void Write(int i) { - Write((byte)((i & 0xFF000000) >> 24)); - Write((byte)((i & 0x00FF0000) >> 16)); - Write((byte)((i & 0x0000FF00) >> 8)); - Write((byte)(i & 0x000000FF)); + byte[] bytes = ArrayPool.Shared.Rent(4); + try + { + BinaryPrimitives.WriteInt32BigEndian(bytes, i); + Write(bytes, 0, 4); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } /// @@ -123,10 +148,16 @@ public override void Write(int i) /// public override void Write(uint i) { - Write((byte)((i & 0xFF000000) >> 24)); - Write((byte)((i & 0x00FF0000) >> 16)); - Write((byte)((i & 0x0000FF00) >> 8)); - Write((byte)(i & 0x000000FF)); + byte[] bytes = ArrayPool.Shared.Rent(4); + try + { + BinaryPrimitives.WriteUInt32BigEndian(bytes, i); + Write(bytes, 0, 4); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } /// @@ -134,10 +165,16 @@ public override void Write(uint i) /// public override void Write(long i) { - uint i1 = (uint)(i >> 32); - uint i2 = (uint)i; - Write(i1); - Write(i2); + byte[] bytes = ArrayPool.Shared.Rent(8); + try + { + BinaryPrimitives.WriteInt64BigEndian(bytes, i); + Write(bytes, 0, 8); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } /// @@ -145,10 +182,16 @@ public override void Write(long i) /// public override void Write(ulong i) { - uint i1 = (uint)(i >> 32); - uint i2 = (uint)i; - Write(i1); - Write(i2); + byte[] bytes = ArrayPool.Shared.Rent(8); + try + { + BinaryPrimitives.WriteUInt64BigEndian(bytes, i); + Write(bytes, 0, 8); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } /// @@ -156,13 +199,13 @@ public override void Write(ulong i) /// public override void Write(float f) { - BinaryWriter w = TemporaryBinaryWriter(4); - w.Write(f); - byte[] wrongBytes = TemporaryContents(w); - Write(wrongBytes[3]); - Write(wrongBytes[2]); - Write(wrongBytes[1]); - Write(wrongBytes[0]); + byte[] bytes = BitConverter.GetBytes(f); + if (BitConverter.IsLittleEndian) + { + bytes.AsSpan().Reverse(); + } + + Write(bytes); } /// @@ -170,17 +213,16 @@ public override void Write(float f) /// public override void Write(double d) { - BinaryWriter w = TemporaryBinaryWriter(8); - w.Write(d); - byte[] wrongBytes = TemporaryContents(w); - Write(wrongBytes[7]); - Write(wrongBytes[6]); - Write(wrongBytes[5]); - Write(wrongBytes[4]); - Write(wrongBytes[3]); - Write(wrongBytes[2]); - Write(wrongBytes[1]); - Write(wrongBytes[0]); + byte[] bytes = ArrayPool.Shared.Rent(8); + try + { + BinaryPrimitives.WriteInt64BigEndian(bytes, BitConverter.DoubleToInt64Bits(d)); + Write(bytes, 0, 8); + } + finally + { + ArrayPool.Shared.Return(bytes); + } } } } diff --git a/projects/client/Unit/src/unit/APIApproval.Approve.approved.txt b/projects/client/Unit/src/unit/APIApproval.Approve.approved.txt index 57b1462c8e..944b864d6d 100644 --- a/projects/client/Unit/src/unit/APIApproval.Approve.approved.txt +++ b/projects/client/Unit/src/unit/APIApproval.Approve.approved.txt @@ -2330,6 +2330,7 @@ namespace RabbitMQ.Client.Impl public static void WriteLong(RabbitMQ.Util.NetworkBinaryWriter writer, uint val) { } public static void WriteLonglong(RabbitMQ.Util.NetworkBinaryWriter writer, ulong val) { } public static void WriteLongstr(RabbitMQ.Util.NetworkBinaryWriter writer, byte[] val) { } + public static void WriteLongstr(RabbitMQ.Util.NetworkBinaryWriter writer, byte[] val, int index, int count) { } public static void WriteOctet(RabbitMQ.Util.NetworkBinaryWriter writer, byte val) { } public static void WriteShort(RabbitMQ.Util.NetworkBinaryWriter writer, ushort val) { } public static void WriteShortstr(RabbitMQ.Util.NetworkBinaryWriter writer, string val) { } @@ -2426,7 +2427,6 @@ namespace RabbitMQ.Util public class NetworkBinaryReader : System.IO.BinaryReader { public NetworkBinaryReader(System.IO.Stream input) { } - public NetworkBinaryReader(System.IO.Stream input, System.Text.Encoding encoding) { } public override double ReadDouble() { } public override short ReadInt16() { } public override int ReadInt32() { } @@ -2435,7 +2435,6 @@ namespace RabbitMQ.Util public override ushort ReadUInt16() { } public override uint ReadUInt32() { } public override ulong ReadUInt64() { } - public static System.IO.BinaryReader TemporaryBinaryReader(byte[] bytes) { } } public class NetworkBinaryWriter : System.IO.BinaryWriter {