THRIFT-5010 BinaryPrimitives.Read/WriteInt32BigEndian should be used to convert to/from network byte order
Client: netstd
Patch: Edward Zhuravlov
This closes #1944
diff --git a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
index 3f30d4a..f0772aa 100644
--- a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
@@ -16,6 +16,7 @@
// under the License.
using System;
+using System.Buffers.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -215,9 +216,7 @@
{
return;
}
-
- PreAllocatedBuffer[0] = (byte)(0xff & (i16 >> 8));
- PreAllocatedBuffer[1] = (byte)(0xff & i16);
+ BinaryPrimitives.WriteInt16BigEndian(PreAllocatedBuffer, i16);
await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
}
@@ -229,10 +228,7 @@
return;
}
- PreAllocatedBuffer[0] = (byte)(0xff & (i32 >> 24));
- PreAllocatedBuffer[1] = (byte)(0xff & (i32 >> 16));
- PreAllocatedBuffer[2] = (byte)(0xff & (i32 >> 8));
- PreAllocatedBuffer[3] = (byte)(0xff & i32);
+ BinaryPrimitives.WriteInt32BigEndian(PreAllocatedBuffer, i32);
await Trans.WriteAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
}
@@ -245,14 +241,7 @@
return;
}
- PreAllocatedBuffer[0] = (byte)(0xff & (i64 >> 56));
- PreAllocatedBuffer[1] = (byte)(0xff & (i64 >> 48));
- PreAllocatedBuffer[2] = (byte)(0xff & (i64 >> 40));
- PreAllocatedBuffer[3] = (byte)(0xff & (i64 >> 32));
- PreAllocatedBuffer[4] = (byte)(0xff & (i64 >> 24));
- PreAllocatedBuffer[5] = (byte)(0xff & (i64 >> 16));
- PreAllocatedBuffer[6] = (byte)(0xff & (i64 >> 8));
- PreAllocatedBuffer[7] = (byte)(0xff & i64);
+ BinaryPrimitives.WriteInt64BigEndian(PreAllocatedBuffer, i64);
await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
}
@@ -470,7 +459,7 @@
}
await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 2, cancellationToken);
- var result = (short) (((PreAllocatedBuffer[0] & 0xff) << 8) | PreAllocatedBuffer[1] & 0xff);
+ var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer);
return result;
}
@@ -483,34 +472,11 @@
await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 4, cancellationToken);
- var result =
- ((PreAllocatedBuffer[0] & 0xff) << 24) |
- ((PreAllocatedBuffer[1] & 0xff) << 16) |
- ((PreAllocatedBuffer[2] & 0xff) << 8) |
- PreAllocatedBuffer[3] & 0xff;
+ var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer);
return result;
}
-#pragma warning disable 675
-
- protected internal long ReadI64FromPreAllocatedBuffer()
- {
- var result =
- ((long) (PreAllocatedBuffer[0] & 0xff) << 56) |
- ((long) (PreAllocatedBuffer[1] & 0xff) << 48) |
- ((long) (PreAllocatedBuffer[2] & 0xff) << 40) |
- ((long) (PreAllocatedBuffer[3] & 0xff) << 32) |
- ((long) (PreAllocatedBuffer[4] & 0xff) << 24) |
- ((long) (PreAllocatedBuffer[5] & 0xff) << 16) |
- ((long) (PreAllocatedBuffer[6] & 0xff) << 8) |
- PreAllocatedBuffer[7] & 0xff;
-
- return result;
- }
-
-#pragma warning restore 675
-
public override async ValueTask<long> ReadI64Async(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
@@ -519,7 +485,7 @@
}
await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
- return ReadI64FromPreAllocatedBuffer();
+ return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer);
}
public override async ValueTask<double> ReadDoubleAsync(CancellationToken cancellationToken)
diff --git a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
index c26633a..921507c 100644
--- a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
@@ -16,6 +16,7 @@
// under the License.
using System;
+using System.Buffers.Binary;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
@@ -399,8 +400,7 @@
{
return;
}
-
- FixedLongToBytes(BitConverter.DoubleToInt64Bits(d), PreAllocatedBuffer, 0);
+ BinaryPrimitives.WriteInt64LittleEndian(PreAllocatedBuffer, BitConverter.DoubleToInt64Bits(d));
await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
}
@@ -683,8 +683,8 @@
}
await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken);
-
- return BitConverter.Int64BitsToDouble(BytesToLong(PreAllocatedBuffer));
+
+ return BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(PreAllocatedBuffer));
}
public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
@@ -838,25 +838,6 @@
return (long) (n >> 1) ^ -(long) (n & 1);
}
- private static long BytesToLong(byte[] bytes)
- {
- /*
- Note that it's important that the mask bytes are long literals,
- otherwise they'll default to ints, and when you shift an int left 56 bits,
- you just get a messed up int.
- */
-
- return
- ((bytes[7] & 0xffL) << 56) |
- ((bytes[6] & 0xffL) << 48) |
- ((bytes[5] & 0xffL) << 40) |
- ((bytes[4] & 0xffL) << 32) |
- ((bytes[3] & 0xffL) << 24) |
- ((bytes[2] & 0xffL) << 16) |
- ((bytes[1] & 0xffL) << 8) |
- (bytes[0] & 0xffL);
- }
-
private static TType GetTType(byte type)
{
// Given a TCompactProtocol.Types constant, convert it to its corresponding TType value.
@@ -875,19 +856,6 @@
return (uint) (n << 1) ^ (uint) (n >> 31);
}
- private static void FixedLongToBytes(long n, byte[] buf, int off)
- {
- // Convert a long into little-endian bytes in buf starting at off and going until off+7.
- buf[off + 0] = (byte) (n & 0xff);
- buf[off + 1] = (byte) ((n >> 8) & 0xff);
- buf[off + 2] = (byte) ((n >> 16) & 0xff);
- buf[off + 3] = (byte) ((n >> 24) & 0xff);
- buf[off + 4] = (byte) ((n >> 32) & 0xff);
- buf[off + 5] = (byte) ((n >> 40) & 0xff);
- buf[off + 6] = (byte) ((n >> 48) & 0xff);
- buf[off + 7] = (byte) ((n >> 56) & 0xff);
- }
-
public class Factory : TProtocolFactory
{
public override TProtocol GetProtocol(TTransport trans)
diff --git a/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs b/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs
index c842a16..58b45f7 100644
--- a/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs
+++ b/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs
@@ -16,6 +16,7 @@
// under the License.
using System;
+using System.Buffers.Binary;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -86,7 +87,7 @@
private async ValueTask ReadFrameAsync(CancellationToken cancellationToken)
{
await InnerTransport.ReadAllAsync(HeaderBuf, 0, HeaderSize, cancellationToken);
- int size = DecodeFrameSize(HeaderBuf);
+ int size = BinaryPrimitives.ReadInt32BigEndian(HeaderBuf);
if ((0 > size) || (size > Configuration.MaxFrameSize)) // size must be in the range 0 to allowed max
throw new TTransportException(TTransportException.ExceptionType.Unknown, $"Maximum frame size exceeded ({size} bytes)");
@@ -137,7 +138,7 @@
}
// Inject message header into the reserved buffer space
- EncodeFrameSize(dataLen, bufSegment.Array);
+ BinaryPrimitives.WriteInt32BigEndian(bufSegment.Array, dataLen);
// Send the entire message at once
await InnerTransport.WriteAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken);
@@ -154,24 +155,6 @@
WriteBuffer.Seek(0, SeekOrigin.End);
}
- private static void EncodeFrameSize(int frameSize, byte[] buf)
- {
- buf[0] = (byte) (0xff & (frameSize >> 24));
- buf[1] = (byte) (0xff & (frameSize >> 16));
- buf[2] = (byte) (0xff & (frameSize >> 8));
- buf[3] = (byte) (0xff & (frameSize));
- }
-
- private static int DecodeFrameSize(byte[] buf)
- {
- return
- ((buf[0] & 0xff) << 24) |
- ((buf[1] & 0xff) << 16) |
- ((buf[2] & 0xff) << 8) |
- (buf[3] & 0xff);
- }
-
-
private void CheckNotDisposed()
{
if (IsDisposed)