// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.IO;
namespace EpicGames.Core
{
///
/// Interface that can be implemented by objects to support BinaryWriter container functionality. Also implies that
/// derived objects will have a constructor taking a single BinaryReader argument (similar to how the system ISerializable
/// interface assumes a specific constructor)
///
public interface IBinarySerializable
{
///
/// Write an item
///
///
void Write(BinaryWriter writer);
}
///
/// Extension methods for BinaryWriter class
///
public static class BinaryWriterExtensions
{
///
/// Writes an item implementing the IBinarySerializable interface to a binary writer. Included for symmetry with standard Writer.Write(X) calls.
///
/// Writer to serialize to
/// The item to write
public static void Write(this BinaryWriter writer, IBinarySerializable item)
{
item.Write(writer);
}
///
/// Writes an array of strings to a binary writer.
///
/// Writer to serialize to
/// Array of items
public static void Write(this BinaryWriter writer, string[] items)
{
Write(writer, items, item => writer.Write(item));
}
///
/// Writes an array to a binary writer.
///
/// The array element type
/// Writer to serialize to
/// Array of items
public static void Write(this BinaryWriter writer, T[] items) where T : class, IBinarySerializable
{
Write(writer, items, item => writer.Write(item));
}
///
/// Writes an array to a binary writer.
///
/// The array element type
/// Writer to serialize to
/// Array of items
/// Delegate to call to serialize each element
public static void Write(this BinaryWriter writer, T[] items, Action writeElement)
{
if (items == null)
{
writer.Write(-1);
}
else
{
writer.Write(items.Length);
for (int idx = 0; idx < items.Length; idx++)
{
writeElement(items[idx]);
}
}
}
///
/// Writes a list of strings to a binary writer.
///
/// Writer to serialize to
/// Array of items
public static void Write(this BinaryWriter writer, List items)
{
Write(writer, items, item => writer.Write(item));
}
///
/// Writes a list to a binary writer.
///
/// The array element type
/// Writer to serialize to
/// Array of items
public static void Write(this BinaryWriter writer, List items) where T : class, IBinarySerializable
{
Write(writer, items, item => writer.Write(item));
}
///
/// Writes a list to a binary writer.
///
/// The list element type
/// Writer to serialize to
/// List of items
/// Delegate to call to serialize each element
public static void Write(this BinaryWriter writer, List items, Action writeElement)
{
if (items == null)
{
writer.Write(-1);
}
else
{
writer.Write(items.Count);
for (int idx = 0; idx < items.Count; idx++)
{
writeElement(items[idx]);
}
}
}
///
/// Write a dictionary to a binary writer
///
/// The key type for the dictionary
/// The value type for the dictionary
/// Writer to write data to
/// List of items to be written
/// Delegate to call to serialize each key
/// Delegate to call to serialize each value
/// Dictionary of objects, as serialized. May be null.
public static void Write(this BinaryWriter writer, Dictionary items, Action writeKey, Action writeValue) where TKey : notnull
{
if (items == null)
{
writer.Write(-1);
}
else
{
writer.Write(items.Count);
foreach (KeyValuePair item in items)
{
writeKey(item.Key);
writeValue(item.Value);
}
}
}
///
/// Read a nullable object from a binary reader
///
/// Type of the object
/// Reader to read data from
/// Item to write
/// Function to read the payload, if non-null
/// Object instance or null
public static void WriteNullable(this BinaryWriter writer, T item, Action writeItem) where T : class
{
if (item == null)
{
writer.Write(false);
}
else
{
writer.Write(true);
writeItem();
}
}
///
/// Writes a value of a specific type to a binary writer
///
/// Writer for output data
/// Type of value to write
/// The value to output
public static void Write(this BinaryWriter writer, Type fieldType, object value)
{
if (fieldType == typeof(string))
{
writer.Write((string)value);
}
else if (fieldType == typeof(bool))
{
writer.Write((bool)value);
}
else if (fieldType == typeof(int))
{
writer.Write((int)value);
}
else if (fieldType == typeof(float))
{
writer.Write((float)value);
}
else if (fieldType == typeof(double))
{
writer.Write((double)value);
}
else if (fieldType.IsEnum)
{
writer.Write((int)value);
}
else if (fieldType == typeof(string[]))
{
writer.Write((string[])value);
}
else if (fieldType == typeof(bool?))
{
bool? nullableValue = (bool?)value;
writer.Write(nullableValue.HasValue ? nullableValue.Value ? 1 : 0 : -1);
}
else if (fieldType == typeof(FileReference))
{
writer.Write((FileReference)value);
}
else
{
throw new Exception(String.Format("Unsupported type '{0}' for binary serialization", fieldType.Name));
}
}
}
}