PageRenderTime 27ms CodeModel.GetById 15ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/Library/lidgren-network/Lidgren.Network/NetBuffer.cs

https://bitbucket.org/kenzoix/tanka
C# | 213 lines | 135 code | 20 blank | 58 comment | 11 complexity | 8840d95343971eaa14fda12963d8266d MD5 | raw file
  1/* Copyright (c) 2008 Michael Lidgren
  2
  3Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  4and associated documentation files (the "Software"), to deal in the Software without
  5restriction, including without limitation the rights to use, copy, modify, merge, publish,
  6distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom
  7the Software is furnished to do so, subject to the following conditions:
  8
  9The above copyright notice and this permission notice shall be included in all copies or
 10substantial portions of the Software.
 11
 12THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 13INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 15LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 16TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 17USE OR OTHER DEALINGS IN THE SOFTWARE.
 18*/
 19using System;
 20using System.Collections.Generic;
 21using System.Diagnostics.CodeAnalysis;
 22using System.Text;
 23
 24namespace Lidgren.Network
 25{
 26	/// <summary>
 27	/// Wrapper around a byte array with methods for reading/writing at bit level
 28	/// </summary>
 29	public sealed partial class NetBuffer
 30	{
 31		// how many NetMessages are using this buffer?
 32		internal int m_refCount;
 33
 34		internal int m_bitLength;
 35		internal int m_readPosition;
 36
 37		[SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
 38		public byte[] Data;
 39
 40		/// <summary>
 41		/// User application data
 42		/// </summary>
 43		public object Tag;
 44
 45		/// <summary>
 46		/// Creates a new NetBuffer
 47		/// </summary>
 48		public NetBuffer()
 49		{
 50			Data = new byte[8];
 51		}
 52
 53		/// <summary>
 54		/// Creates a new NetBuffer initially capable of holding 'capacity' bytes
 55		/// </summary>
 56		public NetBuffer(int capacityBytes)
 57		{
 58			if (capacityBytes < 0)
 59				capacityBytes = 4;
 60			Data = new byte[capacityBytes];
 61		}
 62
 63		/// <summary>
 64		/// Creates a new NetBuffer and copies the data supplied
 65		/// </summary>
 66		public NetBuffer(byte[] copyData)
 67		{
 68			if (copyData != null)
 69			{
 70				Data = new byte[copyData.Length];
 71				Buffer.BlockCopy(copyData, 0, Data, 0, copyData.Length);
 72				m_bitLength = copyData.Length * 8;
 73			}
 74			else
 75			{
 76				Data = new byte[4];
 77			}
 78		}
 79
 80		public NetBuffer(string str)
 81		{
 82			if (string.IsNullOrEmpty(str))
 83			{
 84				Data = new byte[1];
 85				WriteVariableUInt32(0);
 86				return;
 87			}
 88
 89			byte[] strData = Encoding.UTF8.GetBytes(str);
 90			Data = new byte[1 + strData.Length];
 91			WriteVariableUInt32((uint)strData.Length);
 92			Write(strData);
 93		}
 94
 95		/// <summary>
 96		/// Data is NOT copied; but now owned by the NetBuffer
 97		/// </summary>
 98		public static NetBuffer FromData(byte[] data)
 99		{
100			NetBuffer retval = new NetBuffer(false);
101			retval.Data = data;
102			retval.LengthBytes = data.Length;
103			return retval;
104		}
105
106		internal NetBuffer(bool createDataStorage)
107		{
108			if (createDataStorage)
109				Data = new byte[8];
110		}
111
112		/// <summary>
113		/// Gets or sets the length of the buffer in bytes
114		/// </summary>
115		public int LengthBytes {
116			get { return (m_bitLength >> 3) + ((m_bitLength & 7) > 0 ? 1 : 0); }
117			set
118			{
119				m_bitLength = value * 8;
120				InternalEnsureBufferSize(m_bitLength);
121			}
122		}
123
124		/// <summary>
125		/// Gets or sets the length of the buffer in bits
126		/// </summary>
127		public int LengthBits
128		{
129			get { return m_bitLength; }
130			set
131			{
132				m_bitLength = value;
133				InternalEnsureBufferSize(m_bitLength);
134			}
135		}
136
137		/// <summary>
138		/// Gets or sets the read position in the buffer, in bits (not bytes)
139		/// </summary>
140		public int Position
141		{
142			get { return m_readPosition; }
143			set { m_readPosition = value; }
144		}
145
146		/// <summary>
147		/// Resets read and write pointers
148		/// </summary>
149		public void Reset()
150		{
151			m_readPosition = 0;
152			m_bitLength = 0;
153			m_refCount = 0;
154			Tag = null;
155		}
156
157		/// <summary>
158		/// Resets read and write pointers
159		/// </summary>
160		internal void Reset(int readPos, int writePos)
161		{
162			m_readPosition = readPos;
163			m_bitLength = writePos;
164			m_refCount = 0;
165			Tag = null;
166		}
167		
168		/// <summary>
169		/// Ensures this buffer can hold the specified number of bits prior to a write operation
170		/// </summary>
171		public void EnsureBufferSize(int numberOfBits)
172		{
173			int byteLen = (numberOfBits >> 3) + ((numberOfBits & 7) > 0 ? 1 : 0);
174			if (Data == null)
175			{
176				Data = new byte[byteLen + 4]; // overallocate 4 bytes
177				return;
178			}
179			if (Data.Length < byteLen)
180				Array.Resize<byte>(ref Data, byteLen + 4); // overallocate 4 bytes
181			return;
182		}
183
184		internal void InternalEnsureBufferSize(int numberOfBits)
185		{
186			int byteLen = (numberOfBits >> 3) + ((numberOfBits & 7) > 0 ? 1 : 0);
187			if (Data == null)
188			{
189				Data = new byte[byteLen];
190				return;
191			}
192			if (Data.Length < byteLen)
193				Array.Resize<byte>(ref Data, byteLen);
194			return;
195		}
196
197		/// <summary>
198		/// Copies the content of the buffer to a new byte array
199		/// </summary>
200		public byte[] ToArray()
201		{
202			int len = LengthBytes;
203			byte[] copy = new byte[len];
204			Array.Copy(Data, copy, copy.Length);
205			return copy;
206		}
207
208		public override string ToString()
209		{
210			return "[NetBuffer " + m_bitLength + " bits, " + m_readPosition + " read]";
211		}
212	}
213}