diff --git a/Lidgren.Network/NetBitWriter.cs b/Lidgren.Network/NetBitWriter.cs index ac9d0de..e07bfc7 100644 --- a/Lidgren.Network/NetBitWriter.cs +++ b/Lidgren.Network/NetBitWriter.cs @@ -1,4 +1,6 @@ -/* Copyright (c) 2010 Michael Lidgren +//#define UNSAFE +//#define BIGENDIAN +/* Copyright (c) 2010 Michael Lidgren Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without @@ -169,6 +171,49 @@ namespace Lidgren.Network return; } + [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; +#else + return returnValue; +#endif + } + /// /// Reads the specified number of bits into an UInt32 /// @@ -226,18 +271,47 @@ namespace Lidgren.Network #if BIGENDIAN // reorder bytes return - ((a & 0xff000000) >> 24) | - ((a & 0x00ff0000) >> 8) | - ((a & 0x0000ff00) << 8) | - ((a & 0x000000ff) << 24); -#endif - + ((returnValue & 0xff000000) >> 24) | + ((returnValue & 0x00ff0000) >> 8) | + ((returnValue & 0x0000ff00) << 8) | + ((returnValue & 0x000000ff) << 24); +#else return returnValue; +#endif } //[CLSCompliant(false)] //public static ulong ReadUInt64(byte[] fromBuffer, int numberOfBits, int readBitOffset) + [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; + } + /// /// Writes the specified number of bits into a byte array /// diff --git a/Lidgren.Network/NetBuffer.Peek.cs b/Lidgren.Network/NetBuffer.Peek.cs index 7e18529..7c27e26 100644 --- a/Lidgren.Network/NetBuffer.Peek.cs +++ b/Lidgren.Network/NetBuffer.Peek.cs @@ -109,7 +109,7 @@ namespace Lidgren.Network public Int16 PeekInt16() { NetException.Assert(m_bitLength - m_readPosition >= 16, c_readOverflowError); - uint retval = NetBitWriter.ReadUInt32(m_data, 16, m_readPosition); + uint retval = NetBitWriter.ReadUInt16(m_data, 16, m_readPosition); return (short)retval; } @@ -120,7 +120,7 @@ namespace Lidgren.Network public UInt16 PeekUInt16() { NetException.Assert(m_bitLength - m_readPosition >= 16, c_readOverflowError); - uint retval = NetBitWriter.ReadUInt32(m_data, 16, m_readPosition); + uint retval = NetBitWriter.ReadUInt16(m_data, 16, m_readPosition); return (ushort)retval; } diff --git a/Lidgren.Network/NetBuffer.Read.cs b/Lidgren.Network/NetBuffer.Read.cs index 019141c..aa51722 100644 --- a/Lidgren.Network/NetBuffer.Read.cs +++ b/Lidgren.Network/NetBuffer.Read.cs @@ -146,7 +146,7 @@ namespace Lidgren.Network public Int16 ReadInt16() { NetException.Assert(m_bitLength - m_readPosition >= 16, c_readOverflowError); - uint retval = NetBitWriter.ReadUInt32(m_data, 16, m_readPosition); + uint retval = NetBitWriter.ReadUInt16(m_data, 16, m_readPosition); m_readPosition += 16; return (short)retval; } @@ -158,7 +158,7 @@ namespace Lidgren.Network public UInt16 ReadUInt16() { NetException.Assert(m_bitLength - m_readPosition >= 16, c_readOverflowError); - uint retval = NetBitWriter.ReadUInt32(m_data, 16, m_readPosition); + uint retval = NetBitWriter.ReadUInt16(m_data, 16, m_readPosition); m_readPosition += 16; return (ushort)retval; } diff --git a/Lidgren.Network/NetBuffer.Write.cs b/Lidgren.Network/NetBuffer.Write.cs index f591b20..eccbf4f 100644 --- a/Lidgren.Network/NetBuffer.Write.cs +++ b/Lidgren.Network/NetBuffer.Write.cs @@ -1,4 +1,6 @@ -/* Copyright (c) 2010 Michael Lidgren +//#define UNSAFE +//#define BIGENDIAN +/* Copyright (c) 2010 Michael Lidgren Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without @@ -146,7 +148,7 @@ namespace Lidgren.Network public void Write(UInt16 source) { EnsureBufferSize(m_bitLength + 16); - NetBitWriter.WriteUInt32((uint)source, 16, m_data, m_bitLength); + NetBitWriter.WriteUInt16(source, 16, m_data, m_bitLength); m_bitLength += 16; } @@ -158,7 +160,7 @@ namespace Lidgren.Network { NetException.Assert((numberOfBits > 0 && numberOfBits <= 16), "Write(ushort, numberOfBits) can only write between 1 and 16 bits"); EnsureBufferSize(m_bitLength + numberOfBits); - NetBitWriter.WriteUInt32((uint)source, numberOfBits, m_data, m_bitLength); + NetBitWriter.WriteUInt16(source, numberOfBits, m_data, m_bitLength); m_bitLength += numberOfBits; } @@ -168,7 +170,7 @@ namespace Lidgren.Network public void Write(Int16 source) { EnsureBufferSize(m_bitLength + 16); - NetBitWriter.WriteUInt32((uint)source, 16, m_data, m_bitLength); + NetBitWriter.WriteUInt16((ushort)source, 16, m_data, m_bitLength); m_bitLength += 16; }