// 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)); } } } }