accncc / lidgren-network-gen3

Automatically exported from code.google.com/p/lidgren-network-gen3
0 stars 0 forks source link

BIGENDIAN bug with ushort #110

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Add BIGENDIAN conditional to the Lidgren.Network project
2. Fix minor build error
3. Run unit tests

What is the expected output? What do you see instead?

- ushort values under BIGENDIAN are encoded as zero. This is due to the fact 
that it uses WriteUInt32. When it does the endian swap it loses the relevant 
bits. Dedicated methods for Read/WriteUInt16 and Read/WriteInt16 are required 
to support BIGENDIAN.

What version of the product are you using? On what operating system?

- Latest download (2012-02-15) on Win7 communicating with Xbox 360.

Please provide any additional information below.

- Here is my fix for ushort (note, UNSAFE and !BIGENDIAN compiles not tested 
yet):

        [CLSCompliant(false)]
        public static int WriteUInt16(ushort source, int numberOfBits, byte[] destination, int destinationBitOffset)
        {
#if BIGENDIAN
            // reorder bytes
            uint intSource = source;
            intSource = ((intSource & 0x0000ff00) >> 8) | ((intSource & 0x000000ff) << 8);
            source = (ushort)intSource;
#endif

            int returnValue = destinationBitOffset + numberOfBits;
            if (numberOfBits <= 8)
            {
                NetBitWriter.WriteByte((byte)source, numberOfBits, destination, destinationBitOffset);
                return returnValue;
            }
            NetBitWriter.WriteByte((byte)source, 8, destination, destinationBitOffset);
            destinationBitOffset += 8;
            numberOfBits -= 8;

            if (numberOfBits <= 8)
            {
                NetBitWriter.WriteByte((byte)(source >> 8), numberOfBits, destination, destinationBitOffset);
                return returnValue;
            }

            return returnValue;
        }

        [CLSCompliant(false)]
#if UNSAFE
        public static unsafe ushort ReadUInt16(byte[] fromBuffer, int numberOfBits, int readBitOffset)
        {
            Debug.Assert(((numberOfBits > 0) && (numberOfBits <= 16)), "ReadUInt16() can only read between 1 and 16 bits");

            if (numberOfBits == 16 && ((readBitOffset % 8) == 0))
            {
                fixed (byte* ptr = &(fromBuffer[readBitOffset / 8]))
                {
                    return *(((ushort*)ptr));
                }
            }
#else
        public static ushort ReadUInt16(byte[] fromBuffer, int numberOfBits, int readBitOffset)
        {
            Debug.Assert(((numberOfBits > 0) && (numberOfBits <= 16)), "ReadUInt16() can only read between 1 and 16 bits");
#endif
            ushort returnValue;
            if (numberOfBits <= 8)
            {
                returnValue = ReadByte(fromBuffer, numberOfBits, readBitOffset);
                return returnValue;
            }
            returnValue = ReadByte(fromBuffer, 8, readBitOffset);
            numberOfBits -= 8;
            readBitOffset += 8;

            if (numberOfBits <= 8)
            {
                returnValue |= (ushort)(ReadByte(fromBuffer, numberOfBits, readBitOffset) << 8);
            }

#if BIGENDIAN
            // reorder bytes
            uint retVal = returnValue;
            retVal = ((retVal & 0x0000ff00) >> 8) | ((retVal & 0x000000ff) << 8);
            return (ushort)retVal;
#endif

            return returnValue;
        }

Original issue reported on code.google.com by roond...@gmail.com on 11 Mar 2012 at 6:45

GoogleCodeExporter commented 9 years ago
fixed in 291

Original comment by lidg...@gmail.com on 26 May 2012 at 8:24