using System.Collections.Generic;
using System;
using System.IO;
using System.Text;
namespace MLAgents.SideChannels
{
///
/// Utility class for forming the data that is sent to the SideChannel.
///
public class OutgoingMessage : IDisposable
{
BinaryWriter m_Writer;
MemoryStream m_Stream;
///
/// Create a new empty OutgoingMessage.
///
public OutgoingMessage()
{
m_Stream = new MemoryStream();
m_Writer = new BinaryWriter(m_Stream);
}
///
/// Clean up the internal storage.
///
public void Dispose()
{
m_Writer?.Dispose();
m_Stream?.Dispose();
}
///
/// Write a boolean value to the message.
///
///
public void WriteBoolean(bool b)
{
m_Writer.Write(b);
}
///
/// Write an interger value to the message.
///
///
public void WriteInt32(int i)
{
m_Writer.Write(i);
}
///
/// Write a float values to the message.
///
///
public void WriteFloat32(float f)
{
m_Writer.Write(f);
}
///
/// Write a string value to the message.
///
///
public void WriteString(string s)
{
var stringEncoded = Encoding.ASCII.GetBytes(s);
m_Writer.Write(stringEncoded.Length);
m_Writer.Write(stringEncoded);
}
///
/// Write a list or array of floats to the message.
///
///
public void WriteFloatList(IList floatList)
{
WriteInt32(floatList.Count);
foreach (var f in floatList)
{
WriteFloat32(f);
}
}
///
/// Overwrite the message with a specific byte array.
///
///
public void SetRawBytes(byte[] data)
{
// Reset first. Set the length to zero so that if there's more data than we're going to
// write, we don't have any of the original data.
m_Stream.Seek(0, SeekOrigin.Begin);
m_Stream.SetLength(0);
// Then append the data. Increase the capacity if needed (but don't shrink it).
m_Stream.Capacity = (m_Stream.Capacity < data.Length) ? data.Length : m_Stream.Capacity;
m_Stream.Write(data, 0, data.Length);
}
///
/// Read the byte array of the message.
///
///
internal byte[] ToByteArray()
{
return m_Stream.ToArray();
}
}
}