Pepernoot
Pepernoot

Reputation: 3609

big-endian BinaryReader gives wrong value when reading long

I am currently working on a socket server. The client sends data in BigEdian format so I Decided to use this package. But for Int64 it gives me a different value

This is the test code. It works fine for int32

long val = ((long)868324021119164);
byte[] longval = BitConverter.GetBytes((long)868324021119164);
Array.Reverse(longval);
using (MemoryStream stream = new MemoryStream(longval))
using (BeBinaryReader BeReader = new BeBinaryReader(stream))
{
   Console.WriteLine(BeReader.ReadInt64());
}

This was my result 8130168015229752764

I looked into the source code And found these Functions. I don't have any experience with unsafe code. So I don't know if they are wrong

public override long ReadInt64()
{
    FillBuffer(8);
    fixed (byte* p = buffer)
         return BigEndian.ReadInt64(p);
}


[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long ReadInt64(byte* p)
{
    int lo = ReadInt32(p);
    int hi = ReadInt32(p + 4);
    return (long)hi << 32 | (uint)lo;
}

I have a windows 10 64 bits Pc

Thanks

Upvotes: 1

Views: 349

Answers (1)

Lucas Trzesniewski
Lucas Trzesniewski

Reputation: 51330

That code here:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long ReadInt64(byte* p)
{
    int lo = ReadInt32(p);
    int hi = ReadInt32(p + 4);
    return (long)hi << 32 | (uint)lo;
}

Doesn't seem right. It should have been:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long ReadInt64(byte* p)
{
    int hi = ReadInt32(p);
    int lo = ReadInt32(p + 4);
    return (long)hi << 32 | (uint)lo;
}

In big endian, the high 32-bit number comes first. The code inverts that. You should submit a bug report, and maybe suggest the author to write some unit tests :)

Upvotes: 1

Related Questions