// Copyright (c) Wojciech Figat. All rights reserved. using System; using System.Text; namespace FlaxEngine.Networking { unsafe partial class NetworkStream { /// /// Writes raw bytes into the message. /// /// The bytes that will be written. /// The amount of bytes to write from the bytes pointer. public void WriteBytes(byte* bytes, int length) { WriteData(new IntPtr(bytes), length); } /// /// Reads raw bytes from the message into the given byte array. /// /// The buffer pointer that will be used to store the bytes. Should be of the same length as length or longer. /// /// The minimal amount of bytes that the buffer contains. public void ReadBytes(byte* buffer, int length) { ReadData(new IntPtr(buffer), length); } /// /// Writes raw bytes into the message. /// /// The bytes that will be written. /// The amount of bytes to write from the bytes array. public void WriteBytes(byte[] bytes, int length) { fixed (byte* bytesPtr = bytes) WriteData(new IntPtr(bytesPtr), length); } /// /// Reads raw bytes from the message into the given byte array. /// /// The buffer that will be used to store the bytes. Should be of the same length as length or longer. /// The minimal amount of bytes that the buffer contains. public void ReadBytes(byte[] buffer, int length) { fixed (byte* bufferPtr = buffer) ReadData(new IntPtr(bufferPtr), length); } /// /// Writes data of type into the message. /// public void WriteInt64(long value) { WriteBytes((byte*)&value, sizeof(long)); } /// /// Reads and returns data of type from the message. /// public long ReadInt64() { long value = 0; ReadBytes((byte*)&value, sizeof(long)); return value; } /// /// Writes data of type into the message. /// public void WriteInt32(int value) { WriteBytes((byte*)&value, sizeof(int)); } /// /// Reads and returns data of type from the message. /// public int ReadInt32() { int value = 0; ReadBytes((byte*)&value, sizeof(int)); return value; } /// /// Writes data of type into the message. /// public void WriteInt16(short value) { WriteBytes((byte*)&value, sizeof(short)); } /// /// Reads and returns data of type from the message. /// public short ReadInt16() { short value = 0; ReadBytes((byte*)&value, sizeof(short)); return value; } /// /// Writes data of type into the message. /// public void WriteSByte(sbyte value) { WriteBytes((byte*)&value, sizeof(sbyte)); } /// /// Reads and returns data of type from the message. /// public sbyte ReadSByte() { sbyte value = 0; ReadBytes((byte*)&value, sizeof(sbyte)); return value; } /// /// Writes data of type into the message. /// public void WriteUInt64(ulong value) { WriteBytes((byte*)&value, sizeof(ulong)); } /// /// Reads and returns data of type from the message. /// public ulong ReadUInt64() { ulong value = 0; ReadBytes((byte*)&value, sizeof(ulong)); return value; } /// /// Writes data of type into the message. /// public void WriteUInt32(uint value) { WriteBytes((byte*)&value, sizeof(uint)); } /// /// Reads and returns data of type from the message. /// public uint ReadUInt32() { uint value = 0; ReadBytes((byte*)&value, sizeof(uint)); return value; } /// /// Writes data of type into the message. /// public void WriteUInt16(ushort value) { WriteBytes((byte*)&value, sizeof(ushort)); } /// /// Reads and returns data of type from the message. /// public ushort ReadUInt16() { ushort value = 0; ReadBytes((byte*)&value, sizeof(ushort)); return value; } /// /// Writes data of type into the message. /// public void WriteByte(byte value) { WriteBytes(&value, sizeof(byte)); } /// /// Reads and returns data of type from the message. /// public byte ReadByte() { byte value = 0; ReadBytes(&value, sizeof(byte)); return value; } /// /// Writes data of type into the message. /// public void WriteSingle(float value) { WriteBytes((byte*)&value, sizeof(float)); } /// /// Reads and returns data of type from the message. /// public float ReadSingle() { float value = 0.0f; ReadBytes((byte*)&value, sizeof(float)); return value; } /// /// Writes data of type into the message. /// public void WriteDouble(double value) { WriteBytes((byte*)&value, sizeof(double)); } /// /// Reads and returns data of type from the message. /// public double ReadDouble() { double value = 0.0; ReadBytes((byte*)&value, sizeof(double)); return value; } /// /// Writes data of type into the message. UTF-16 encoded. /// public void WriteString(string value) { // Note: Make sure that this is consistent with the C++ message API! if (value == null) { WriteInt32(0); return; } var stringLength = value.Length; WriteInt32(stringLength); fixed (char* ptr = value) WriteData(new IntPtr(ptr), value.Length * 2); } /// /// Reads and returns data of type from the message. UTF-16 encoded. /// public string ReadString() { // Note: Make sure that this is consistent with the C++ message API! var stringLength = ReadInt32(); if (stringLength == 0) return string.Empty; var dataLength = stringLength * sizeof(char); var bytes = stackalloc char[stringLength]; ReadBytes((byte*)bytes, dataLength); return new string(bytes, 0, stringLength); } /// /// Writes data of type into the message. /// public void WriteGuid(Guid value) { WriteBytes((byte*)&value, sizeof(Guid)); } /// /// Reads and returns data of type from the message. /// public Guid ReadGuid() { var guidData = stackalloc Guid[1]; ReadBytes((byte*)guidData, sizeof(Guid)); return guidData[0]; } /// /// Writes data of type into the message. /// public void WriteVector2(Vector2 value) { WriteSingle((float)value.X); WriteSingle((float)value.Y); } /// /// Reads and returns data of type from the message. /// public Vector2 ReadVector2() { return new Vector2(ReadSingle(), ReadSingle()); } /// /// Writes data of type into the message. /// public void WriteVector3(Vector3 value) { WriteSingle((float)value.X); WriteSingle((float)value.Y); WriteSingle((float)value.Z); } /// /// Reads and returns data of type from the message. /// public Vector3 ReadVector3() { return new Vector3(ReadSingle(), ReadSingle(), ReadSingle()); } /// /// Writes data of type into the message. /// public void WriteVector4(Vector4 value) { WriteSingle((float)value.X); WriteSingle((float)value.Y); WriteSingle((float)value.Z); WriteSingle((float)value.W); } /// /// Reads and returns data of type from the message. /// public Vector4 ReadVector4() { return new Vector4(ReadSingle(), ReadSingle(), ReadSingle(), ReadSingle()); } /// /// Writes data of type into the message. /// public void WriteFloat2(Float2 value) { WriteSingle(value.X); WriteSingle(value.Y); } /// /// Reads and returns data of type from the message. /// public Float2 ReadFloat2() { return new Float2(ReadSingle(), ReadSingle()); } /// /// Writes data of type into the message. /// public void WriteFloat3(Float3 value) { WriteSingle(value.X); WriteSingle(value.Y); WriteSingle(value.Z); } /// /// Reads and returns data of type from the message. /// public Float3 ReadFloat3() { return new Float3(ReadSingle(), ReadSingle(), ReadSingle()); } /// /// Writes data of type into the message. /// public void WriteFloat4(Float4 value) { WriteSingle(value.X); WriteSingle(value.Y); WriteSingle(value.Z); WriteSingle(value.W); } /// /// Reads and returns data of type from the message. /// public Float4 ReadFloat4() { return new Float4(ReadSingle(), ReadSingle(), ReadSingle(), ReadSingle()); } /// /// Writes data of type into the message. /// public void WriteQuaternion(Quaternion value) { WriteSingle(value.X); WriteSingle(value.Y); WriteSingle(value.Z); WriteSingle(value.W); } /// /// Reads and returns data of type from the message. /// public Quaternion ReadQuaternion() { return new Quaternion(ReadSingle(), ReadSingle(), ReadSingle(), ReadSingle()); } /// /// Writes data of type into the message. /// public void WriteRay(Ray value) { WriteVector3(value.Position); WriteVector3(value.Direction); } /// /// Reads and returns data of type from the message. /// public Ray ReadRay() { return new Ray(ReadVector3(), ReadVector3()); } /// /// Writes data of type into the message. /// public void WriteBoolean(bool value) { WriteBytes((byte*)&value, sizeof(bool)); } /// /// Reads and returns data of type from the message. /// public bool ReadBoolean() { bool value = default; ReadBytes((byte*)&value, sizeof(bool)); return value; } /// /// Writes the object data to the stream. Object has to be allocated. /// /// The serializable object. public void Write(INetworkSerializable obj) { obj.Serialize(this); } /// /// Reads the object data from the stream. Object has to be allocated. /// /// The serializable object. public void Read(INetworkSerializable obj) { obj.Deserialize(this); } } }