|
@@ -32,6 +32,7 @@
|
|
|
|
|
|
using System;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
using System.Security;
|
|
|
using System.Text;
|
|
|
|
|
@@ -61,25 +62,35 @@ namespace Google.Protobuf
|
|
|
/// Writes a float field value, without a tag, to the stream.
|
|
|
/// </summary>
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- public static void WriteFloat(ref Span<byte> buffer, ref WriterInternalState state, float value)
|
|
|
+ public static unsafe void WriteFloat(ref Span<byte> buffer, ref WriterInternalState state, float value)
|
|
|
{
|
|
|
- // TODO: avoid allocating a byte array!!!
|
|
|
- byte[] rawBytes = BitConverter.GetBytes(value);
|
|
|
- if (!BitConverter.IsLittleEndian)
|
|
|
+ const int length = sizeof(float);
|
|
|
+ if (state.limit - state.position >= length)
|
|
|
{
|
|
|
- ByteArray.Reverse(rawBytes);
|
|
|
- }
|
|
|
+ // if there's enough space in the buffer, write the float directly into the buffer
|
|
|
+ var floatSpan = buffer.Slice(state.position, length);
|
|
|
+ Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
|
|
|
|
|
|
- if (state.limit - state.position >= 4)
|
|
|
- {
|
|
|
- buffer[state.position++] = rawBytes[0];
|
|
|
- buffer[state.position++] = rawBytes[1];
|
|
|
- buffer[state.position++] = rawBytes[2];
|
|
|
- buffer[state.position++] = rawBytes[3];
|
|
|
+ if (!BitConverter.IsLittleEndian)
|
|
|
+ {
|
|
|
+ floatSpan.Reverse();
|
|
|
+ }
|
|
|
+ state.position += length;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- WriteRawBytes(ref buffer, ref state, rawBytes, 0, 4);
|
|
|
+ Span<byte> floatSpan = stackalloc byte[length];
|
|
|
+ Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
|
|
|
+
|
|
|
+ if (!BitConverter.IsLittleEndian)
|
|
|
+ {
|
|
|
+ floatSpan.Reverse();
|
|
|
+ }
|
|
|
+
|
|
|
+ WriteRawByte(ref buffer, ref state, floatSpan[0]);
|
|
|
+ WriteRawByte(ref buffer, ref state, floatSpan[1]);
|
|
|
+ WriteRawByte(ref buffer, ref state, floatSpan[2]);
|
|
|
+ WriteRawByte(ref buffer, ref state, floatSpan[3]);
|
|
|
}
|
|
|
}
|
|
|
|