/// <summary> /// Reads an array of booleans from the reader. /// </summary> /// <param name="destination">The array to read booleans into.</param> /// <param name="offset">The offset at which to write bytes into the array.</param> public void ReadBooleansInto(bool[] destination, int offset) { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); int total = (int)Math.Ceiling(length / 8.0); //Number of bytes the booleans are stored in if (Position + 4 + total > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected {total} bytes but reader only has {Length - Position - 4} bytes remaining."); } int ptr = offset; //The index of the array we're writing to. //Repeat for each byte we will need for (int i = 0; i < total; i++) { byte b = buffer.Buffer[buffer.Offset + Position + 4 + i]; //Repeat for each bit in that byte for (int k = 7; k >= 0 && ptr < length; k--) { destination[ptr++] = (b & (1 << k)) != 0; } } Position += 4 + total; }
/// <summary> /// Writes an array of booleans to the writer. /// </summary> /// <param name="value">The array of booleans to write.</param> public void Write(bool[] value) { int total = (int)Math.Ceiling(value.Length / 8.0); //Total number of bytes that will be needed buffer.EnsureLength(Position + 4 + total); BigEndianHelper.WriteBytes(buffer.Buffer, Position, value.Length); int ptr = 0; //Pointer to current boolean in value array //Repeat for each byte we will need for (int i = 0; i < total; i++) { byte b = 0; //Temp holder of booleans being packed //Repeat for each bit in that byte for (int k = 7; k >= 0 && ptr < value.Length; k--) { if (value[ptr]) { b |= (byte)(1 << k); } ptr++; } buffer.Buffer[Position + 4 + i] = b; } Position += 4 + total; buffer.Count = Math.Max(Length, Position); }
/// <summary> /// Writes a single unsigned 64bit integer to the writer. /// </summary> /// <param name="value">The unsigned 64bit integer to write.</param> public void Write(ulong value) { buffer.EnsureLength(Position + 8); BigEndianHelper.WriteBytes(buffer.Buffer, Position, value); Position += 8; buffer.Count = Math.Max(Length, Position); }
/// <summary> /// Writes an array of signed bytes to the writer. /// </summary> /// <param name="value">The array of signed bytes to write.</param> public void Write(sbyte[] value) { buffer.EnsureLength(Position + 4 + value.Length); BigEndianHelper.WriteBytes(buffer.Buffer, Position, value.Length); System.Buffer.BlockCopy(value, 0, buffer.Buffer, Position + 4, value.Length); Position += 4 + value.Length; buffer.Count = Math.Max(Length, Position); }
/// <summary> /// Writes an array of characters to the writer using the given encoding. /// </summary> /// <param name="encoding">The encoding to use during the deserialization.</param> /// <param name="value">The array of characters to write.</param> public void Write(char[] value, Encoding encoding) { //Legacy implementation means we need to send number of bytes not chars int length = encoding.GetByteCount(value); buffer.EnsureLength(Position + 4 + length); BigEndianHelper.WriteBytes(buffer.Buffer, Position, length); encoding.GetBytes(value, 0, value.Length, buffer.Buffer, Position + 4); Position += 4 + length; buffer.Count = Math.Max(Length, Position); }
/// <summary> /// Writes an array of strings to the writer using the writer's encoding. /// </summary> /// <param name="value">The array of strings to write.</param> public void Write(string[] value) { buffer.EnsureLength(Position + 4); //Encodings suck, just do this manually BigEndianHelper.WriteBytes(buffer.Buffer, Position, value.Length); Position += 4; buffer.Count = Math.Max(Length, Position); foreach (string b in value) { Write(b); } }
/// <summary> /// Reads a single unsigned 64bit integer from the reader. /// </summary> /// <returns>The unsigned 64bit integer read.</returns> public ulong ReadUInt64() { if (Position + 8 > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected 8 bytes but reader only has {Length - Position} bytes remaining."); } ulong v = BigEndianHelper.ReadUInt64(buffer.Buffer, buffer.Offset + Position); Position += 8; return(v); }
/// <summary> /// Writes an array IDarkRiftSerializables to the writer. /// </summary> /// <param name="value">The array of serializable objects to write.</param> public void Write <T>(T[] value) where T : IDarkRiftSerializable { buffer.EnsureLength(Position + 4); BigEndianHelper.WriteBytes(buffer.Buffer, Position, value.Length); Position += 4; buffer.Count = Math.Max(Length, Position); for (int i = 0; i < value.Length; i++) { Write(value[i]); } }
/// <summary> /// Reads a single 16bit integer from the reader. /// </summary> /// <returns>The 16bit integer read.</returns> public short ReadInt16() { if (Position + 2 > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected 2 bytes but reader only has {Length - Position} bytes remaining."); } short v = BigEndianHelper.ReadInt16(buffer.Buffer, buffer.Offset + Position); Position += 2; return(v); }
/// <summary> /// Writes an array unsigned 64bit integers to the writer. /// </summary> /// <param name="value">The array of unsigned 64bit integers to write.</param> public void Write(ulong[] value) { buffer.EnsureLength(Position + 4 + value.Length * 8); BigEndianHelper.WriteBytes(buffer.Buffer, Position, value.Length); for (int i = 0, j = Position + 4; i < value.Length; i++, j += 8) { BigEndianHelper.WriteBytes(buffer.Buffer, j, value[i]); } Position += 4 + value.Length * 8; buffer.Count = Math.Max(Length, Position); }
/// <summary> /// Reads a single single from the reader. /// </summary> /// <returns>The single read.</returns> public float ReadSingle() { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected 4 bytes but reader only has {Length - Position} bytes remaining."); } float v = BigEndianHelper.ReadSingle(buffer.Buffer, buffer.Offset + Position); Position += 4; return(v); }
/// <summary> /// Reads an array of strings from the reader using the reader's encoding. /// </summary> /// <param name="destination">The array to read strings into.</param> /// <param name="offset">The offset at which to write bytes into the array.</param> public void ReadStringsInto(string[] destination, int offset) { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); Position += 4; for (int i = 0; i < length; i++) { destination[i + offset] = ReadString(); } }
/// <summary> /// Reads an array of signed bytes from the reader. /// </summary> /// <param name="destination">The array to read sbytes into.</param> /// <param name="offset">The offset at which to write bytes into the array.</param> public void ReadSBytesInto(sbyte[] destination, int offset) { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); if (Position + 4 + length > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected {length} bytes but reader only has {Length - Position - 4} bytes remaining."); } Buffer.BlockCopy(buffer.Buffer, buffer.Offset + Position + 4, destination, offset, length); Position += 4 + length; }
/// <summary> /// Writes an array of singles to the writer. /// </summary> /// <param name="value">The array of singles to write.</param> public void Write(float[] value) { buffer.EnsureLength(Position + 4 + value.Length * 4); BigEndianHelper.WriteBytes(buffer.Buffer, Position, value.Length); for (int i = 0, j = Position + 4; i < value.Length; i++, j += 4) { byte[] b = BitConverter.GetBytes(value[i]); if (BitConverter.IsLittleEndian) { Array.Reverse(b); } System.Buffer.BlockCopy(b, 0, buffer.Buffer, j, 4); } Position += 4 + value.Length * 4; buffer.Count = Math.Max(Length, Position); }
/// <summary> /// Reads an array of characters from the reader using the given encoding. /// </summary> /// <param name="destination">The array to read characters into.</param> /// <param name="offset">The offset at which to write bytes into the array.</param> /// <param name="encoding">The encoding to use during the deserialization.</param> public void ReadCharsInto(char[] destination, int offset, Encoding encoding) { //Read number of bytes not chars if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); if (Position + 4 + length > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected {length} bytes but reader only has {Length - Position - 4} bytes remaining."); } encoding.GetChars(buffer.Buffer, buffer.Offset + Position + 4, length, destination, offset); Position += 4 + length; }
/// <summary> /// Reads an array of strings from the reader using the reader's encoding. /// </summary> /// <returns>The array of strings read.</returns> public string[] ReadStrings() { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); Position += 4; string[] array = new string[length]; for (int i = 0; i < length; i++) { array[i] = ReadString(); } return(array); }
/// <summary> /// Reads an array unsigned 16bit integers from the reader. /// </summary> /// <param name="destination">The array to read strings into.</param> /// <param name="offset">The offset at which to write bytes into the array.</param> public void ReadUInt16sInto(ushort[] destination, int offset) { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); if (Position + 4 + length * 2 > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected {length * 2} bytes but reader only has {Length - Position - 4} bytes remaining."); } for (int i = 0, j = buffer.Offset + Position + 4; i < length; i++, j += 2) { destination[i + offset] = BigEndianHelper.ReadUInt16(buffer.Buffer, j); } Position += 4 + length * 2; }
/// <summary> /// Reads a single string from the reader using the given encoding. /// </summary> /// <param name="encoding">The encoding to deserialize the string using.</param> /// <returns>The string read.</returns> public string ReadString(Encoding encoding) { //Read number of bytes not chars if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); if (Position + 4 + length > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected {length} bytes but reader only has {Length - Position - 4} bytes remaining."); } string v = encoding.GetString(buffer.Buffer, buffer.Offset + Position + 4, length); Position += 4 + length; return(v); }
/// <summary> /// Reads an array of signed bytes from the reader. /// </summary> /// <returns>The array of signed bytes read.</returns> public sbyte[] ReadSBytes() { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); if (Position + 4 + length > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected {length} bytes but reader only has {Length - Position - 4} bytes remaining."); } sbyte[] array = new sbyte[length]; Buffer.BlockCopy(buffer.Buffer, buffer.Offset + Position + 4, array, 0, length); Position += 4 + length; return(array); }
/// <summary> /// Reads an array unsigned 32bit integers from the reader. /// </summary> /// <returns>The array of unsigned 32bit integers read.</returns> public uint[] ReadUInt32s() { if (Position + 4 > Length) { throw new EndOfStreamException($"Failed to read as the reader does not have enough data remaining. Expected 4 byte array length header but reader only has {Length - Position} bytes remaining."); } int length = BigEndianHelper.ReadInt32(buffer.Buffer, buffer.Offset + Position); if (Position + 4 + length * 4 > Length) { throw new EndOfStreamException($"Failed to read data from reader as the reader does not have enough data remaining. Expected {length * 4} bytes but reader only has {Length - Position - 4} bytes remaining."); } uint[] array = new uint[length]; for (int i = 0, j = buffer.Offset + Position + 4; i < length; i++, j += 4) { array[i] = BigEndianHelper.ReadUInt32(buffer.Buffer, j); } Position += 4 + length * 4; return(array); }