// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tools.DotNETCommon
{
public static class BinaryReaderExtensions
{
///
/// Read an objects from a binary reader
///
/// The element type for the array
/// Reader to read data from
/// Object instance.
public static T ReadObject(this BinaryReader Reader) where T : class, IBinarySerializable
{
return (T)Activator.CreateInstance(typeof(T), Reader);
}
///
/// Read an array of strings from a binary reader
///
/// Reader to read data from
/// Array of strings, as serialized. May be null.
public static string[] ReadStringArray(this BinaryReader Reader)
{
return Reader.ReadArray(() => Reader.ReadString());
}
///
/// Read an array of objects from a binary reader
///
/// The element type for the array
/// Reader to read data from
/// Array of objects, as serialized. May be null.
public static T[] ReadArray(this BinaryReader Reader) where T : class, IBinarySerializable
{
return ReadArray(Reader, () => Reader.ReadObject());
}
///
/// Read an array of objects from a binary reader
///
/// The element type for the array
/// Reader to read data from
/// Delegate to call to serialize each element
/// Array of objects, as serialized. May be null.
public static T[] ReadArray(this BinaryReader Reader, Func ReadElement)
{
int NumItems = Reader.ReadInt32();
if(NumItems < 0)
{
return null;
}
T[] Items = new T[NumItems];
for(int Idx = 0; Idx < NumItems; Idx++)
{
Items[Idx] = ReadElement();
}
return Items;
}
///
/// Read a list of strings from a binary reader
///
/// Reader to read data from
/// Array of strings, as serialized. May be null.
public static List ReadStringList(this BinaryReader Reader)
{
return Reader.ReadList(() => Reader.ReadString());
}
///
/// Read a list of objects from a binary reader
///
/// The element type for the list
/// Reader to read data from
/// Delegate to call to serialize each element
/// List of objects, as serialized. May be null.
public static List ReadList(this BinaryReader Reader) where T : class, IBinarySerializable
{
return ReadList(Reader, () => Reader.ReadObject());
}
///
/// Read a list of objects from a binary reader
///
/// The element type for the list
/// Reader to read data from
/// Delegate to call to serialize each element
/// List of objects, as serialized. May be null.
public static List ReadList(this BinaryReader Reader, Func ReadElement)
{
int NumItems = Reader.ReadInt32();
if(NumItems < 0)
{
return null;
}
List Items = new List(NumItems);
for(int Idx = 0; Idx < NumItems; Idx++)
{
Items.Add(ReadElement());
}
return Items;
}
///
/// Read a list of objects from a binary reader
///
/// The element type for the list
/// Reader to read data from
/// Delegate to call to serialize each key
/// Delegate to call to serialize each value
/// List of objects, as serialized. May be null.
public static Dictionary ReadDictionary(this BinaryReader Reader, Func ReadKey, Func ReadValue)
{
int NumItems = Reader.ReadInt32();
if(NumItems < 0)
{
return null;
}
Dictionary Items = new Dictionary(NumItems);
for(int Idx = 0; Idx < NumItems; Idx++)
{
K Key = ReadKey();
V Value = ReadValue();
Items.Add(Key, Value);
}
return Items;
}
///
/// Read a nullable object from a binary reader
///
/// Type of the object
/// Reader to read data from
/// Function to read the payload, if non-null
/// Object instance or null
public static T ReadNullable(this BinaryReader Reader, Func ReadItem) where T : class
{
if(Reader.ReadBoolean())
{
return ReadItem();
}
else
{
return null;
}
}
///
/// Reads a value of a specific type from a binary reader
///
/// Reader for input data
/// Type of value to read
/// The value read from the stream
public static object ReadObject(this BinaryReader Reader, Type ObjectType)
{
if(ObjectType == typeof(string))
{
return Reader.ReadString();
}
else if(ObjectType == typeof(bool))
{
return Reader.ReadBoolean();
}
else if(ObjectType == typeof(int))
{
return Reader.ReadInt32();
}
else if(ObjectType == typeof(float))
{
return Reader.ReadSingle();
}
else if(ObjectType == typeof(double))
{
return Reader.ReadDouble();
}
else if(ObjectType == typeof(string[]))
{
return Reader.ReadStringArray();
}
else if(ObjectType == typeof(bool?))
{
int Value = Reader.ReadInt32();
return (Value == -1)? (bool?)null : (Value == 0)? (bool?)false : (bool?)true;
}
else if(ObjectType.IsEnum)
{
return Enum.ToObject(ObjectType, Reader.ReadInt32());
}
else
{
throw new Exception(String.Format("Reading binary objects of type '{0}' is not currently supported.", ObjectType.Name));
}
}
}
}