diff --git a/Lidgren.Network/NetIncomingMessage.Read.cs b/Lidgren.Network/NetIncomingMessage.Read.cs
index 1432e53..5eb0b2f 100644
--- a/Lidgren.Network/NetIncomingMessage.Read.cs
+++ b/Lidgren.Network/NetIncomingMessage.Read.cs
@@ -90,7 +90,22 @@ namespace Lidgren.Network
m_readPosition += 8;
return retval;
}
-
+
+ ///
+ /// Reads a byte and returns true or false for success
+ ///
+ public bool ReadByte(out byte result)
+ {
+ if (m_bitLength - m_readPosition < 8)
+ {
+ result = 0;
+ return false;
+ }
+ result = NetBitWriter.ReadByte(m_data, 8, m_readPosition);
+ m_readPosition += 8;
+ return true;
+ }
+
///
/// Reads a signed byte
///
@@ -127,6 +142,23 @@ namespace Lidgren.Network
return retval;
}
+ ///
+ /// Reads the specified number of bytes and returns true for success
+ ///
+ public bool ReadBytes(int numberOfBytes, out byte[] result)
+ {
+ if (m_bitLength - m_readPosition + 7 < (numberOfBytes * 8))
+ {
+ result = null;
+ return false;
+ }
+
+ result = new byte[numberOfBytes];
+ NetBitWriter.ReadBytes(m_data, numberOfBytes, m_readPosition, result, 0);
+ m_readPosition += (8 * numberOfBytes);
+ return true;
+ }
+
///
/// Reads the specified number of bytes into a preallocated array
///
@@ -239,6 +271,22 @@ namespace Lidgren.Network
return retval;
}
+ ///
+ /// Reads an 32 bit unsigned integer written using Write(UInt32) and returns true for success
+ ///
+ [CLSCompliant(false)]
+ public bool ReadUInt32(out UInt32 result)
+ {
+ if (m_bitLength - m_readPosition < 32)
+ {
+ result = 0;
+ return false;
+ }
+ result = NetBitWriter.ReadUInt32(m_data, 32, m_readPosition);
+ m_readPosition += 32;
+ return true;
+ }
+
///
/// Reads an unsigned integer stored in 1 to 32 bits, written using Write(UInt32, Int32)
///
@@ -384,6 +432,32 @@ namespace Lidgren.Network
}
}
+ ///
+ /// Reads a variable sized UInt32 written using WriteVariableUInt32() and returns true for success
+ ///
+ [CLSCompliant(false)]
+ public bool ReadVariableUInt32(out uint result)
+ {
+ int num1 = 0;
+ int num2 = 0;
+ while (true)
+ {
+ byte num3;
+ if (ReadByte(out num3) == false)
+ {
+ result = 0;
+ return false;
+ }
+ num1 |= (num3 & 0x7f) << num2;
+ num2 += 7;
+ if ((num3 & 0x80) == 0)
+ {
+ result = (uint)num1;
+ return true;
+ }
+ }
+ }
+
///
/// Reads a variable sized Int32 written using WriteVariableInt32()
///
@@ -502,6 +576,49 @@ namespace Lidgren.Network
return System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
+ ///
+ /// Reads a string written using Write(string) and returns true for success
+ ///
+ public bool ReadString(out string result)
+ {
+ uint byteLen;
+ if (ReadVariableUInt32(out byteLen) == false)
+ {
+ result = String.Empty;
+ return false;
+ }
+
+ if (byteLen == 0)
+ {
+ result = String.Empty;
+ return true;
+ }
+
+ if (m_bitLength - m_readPosition < (byteLen * 8))
+ {
+ result = String.Empty;
+ return false;
+ }
+
+ if ((m_readPosition & 7) == 0)
+ {
+ // read directly
+ result = System.Text.Encoding.UTF8.GetString(m_data, m_readPosition >> 3, (int)byteLen);
+ m_readPosition += (8 * (int)byteLen);
+ return true;
+ }
+
+ byte[] bytes;
+ if (ReadBytes((int)byteLen, out bytes) == false)
+ {
+ result = String.Empty;
+ return false;
+ }
+
+ result = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+ return true;
+ }
+
///
/// Reads a stored IPv4 endpoint description
///
diff --git a/UnitTests/ReadWriteTests.cs b/UnitTests/ReadWriteTests.cs
index 0327d71..cec9961 100644
--- a/UnitTests/ReadWriteTests.cs
+++ b/UnitTests/ReadWriteTests.cs
@@ -69,7 +69,13 @@ namespace UnitTests
bdr.Append(inc.ReadBoolean());
bdr.Append(inc.ReadInt32(6));
bdr.Append(inc.ReadInt32());
- bdr.Append(inc.ReadString());
+
+ string strResult;
+ bool ok = inc.ReadString(out strResult);
+ if (ok == false)
+ throw new NetException("Read/write failure");
+ bdr.Append(strResult);
+
bdr.Append(inc.ReadByte());
if (inc.PeekUInt16() != (ushort)44)