// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using UltimateXR.Core.Math;
using UltimateXR.Core.Serialization;
using UltimateXR.Core.Unique;
using UltimateXR.Exceptions;
using UnityEngine;
namespace UltimateXR.Extensions.System.IO
{
///
/// extensions.
///
public static class BinaryReaderExt
{
#region Public Methods
///
/// Reads a 32-bit integer in compressed format, using only the amount of bytes that are necessary.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// A 32-bit integer
/// The compressed data is corrupt
public static int ReadCompressedInt32(this BinaryReader reader, int serializationVersion)
{
return (int)ReadCompressedUInt32(reader, serializationVersion);
}
///
/// Reads a 32-bit unsigned integer in compressed format, using only the amount of bytes that are necessary.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// A 32-bit unsigned integer
/// The compressed data is corrupt
public static uint ReadCompressedUInt32(this BinaryReader reader, int serializationVersion)
{
uint num1 = 0;
int num2 = 0;
while (num2 != 35)
{
byte num3 = reader.ReadByte();
num1 |= (uint)(num3 & sbyte.MaxValue) << num2;
num2 += 7;
if ((num3 & 128) == 0)
{
return num1;
}
}
throw new FormatException("ReadCompressedInt32()/ReadCompressedUInt32() found bad format");
}
///
/// Reads a 64-bit integer in compressed format, using only the amount of bytes that are necessary.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// A 64-bit integer
/// The compressed data is corrupt
public static long ReadCompressedInt64(this BinaryReader reader, int serializationVersion)
{
return (long)ReadCompressedUInt64(reader, serializationVersion);
}
///
/// Reads a 64-bit unsigned integer in compressed format, using only the amount of bytes that are necessary.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// A 64-bit unsigned integer
/// The compressed data is corrupt
public static ulong ReadCompressedUInt64(this BinaryReader reader, int serializationVersion)
{
ulong num1 = 0;
int num2 = 0;
while (num2 != 63)
{
byte num3 = reader.ReadByte();
num1 |= (ulong)(num3 & sbyte.MaxValue) << num2;
num2 += 7;
if ((num3 & 128) == 0)
{
return num1;
}
}
throw new FormatException("ReadCompressedInt64()/ReadCompressedUInt64() found bad format");
}
///
/// Reads an enum value.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// Enum object
public static T ReadEnum(this BinaryReader reader, int serializationVersion)
{
return (T)Enum.ToObject(typeof(T), reader.ReadCompressedInt32(serializationVersion));
}
///
/// Reads a string written using .
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// String or null
public static string ReadStringWithNullCheck(this BinaryReader reader)
{
// Serialized as: null-check (bool), string
bool nullCheck = reader.ReadBoolean();
if (!nullCheck)
{
return null;
}
return reader.ReadString();
}
///
/// Reads a type, which has been serialized as two strings: the full type name plus the assembly. If the type is from
/// the same assembly as UltimateXR, the assembly will be an empty string.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// The type
public static Type ReadType(this BinaryReader reader, int serializationVersion)
{
return reader.ReadType(serializationVersion, out string _, out string _);
}
///
/// Reads a type, which has been serialized as two strings: the full type name plus the assembly. If the type is from
/// the same assembly as UltimateXR, the assembly will be an empty string.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// Returns the type name
/// Returns the type assembly or null/empty if the type is in the same assembly as UltimateXR
/// The type
public static Type ReadType(this BinaryReader reader, int serializationVersion, out string typeName, out string assembly)
{
typeName = reader.ReadString();
if (typeName != string.Empty)
{
assembly = reader.ReadString();
return TypeExt.GetType(typeName, assembly);
}
assembly = string.Empty;
return null;
}
///
/// Reads a Guid, which has been serialized as a 16 byte array.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// The Guid
public static Guid ReadGuid(this BinaryReader reader, int serializationVersion)
{
return new Guid(reader.ReadBytes(16));
}
///
/// Reads a tuple.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// The tuple
public static (T1, T2) ReadTuple(this BinaryReader reader, int serializationVersion)
{
return ((T1, T2))(reader.Read(serializationVersion), reader.Read(serializationVersion));
}
///
/// Reads an array.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// The type of elements in the array
/// The array
/// A type is not supported
/// The compressed data is corrupt
/// An was not found when deserializing
///
/// A class that implements the
/// interface was not found when deserializing
///
public static T[] ReadArray(this BinaryReader reader, int serializationVersion)
{
// Serialized as: null-check (bool), count (int32), elements
bool nullCheck = reader.ReadBoolean();
if (!nullCheck)
{
return null;
}
T[] array = new T[reader.ReadCompressedInt32(serializationVersion)];
for (int i = 0; i < array.Length; ++i)
{
array[i] = (T)reader.Read(serializationVersion);
}
return array;
}
///
/// Reads an array of objects where each element can be of a different type.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// The object array
/// A type is not supported
/// The compressed data is corrupt
/// An was not found when deserializing
///
/// A class that implements the
/// interface was not found when deserializing
///
public static object[] ReadObjectArray(this BinaryReader reader, int serializationVersion)
{
// Serialized as: null-check (bool), count (int32), elements
bool nullCheck = reader.ReadBoolean();
if (!nullCheck)
{
return null;
}
object[] array = new object[reader.ReadCompressedInt32(serializationVersion)];
Exception firstException = null;
for (int i = 0; i < array.Length; ++i)
{
try
{
array[i] = reader.ReadAnyVar(serializationVersion);
}
catch (Exception e)
{
if (firstException == null)
{
firstException = e;
}
}
}
if (firstException != null)
{
// This helps debugging UxrMethodInvokedSyncEventArgs. We keep deserializing event parameters even if there are errors.
throw firstException;
}
return array;
}
///
/// Reads a list.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// The type of elements in the list
/// The list
/// A type is not supported
/// The compressed data is corrupt
/// An was not found when deserializing
///
/// A class that implements the
/// interface was not found when deserializing
///
public static List ReadList(this BinaryReader reader, int serializationVersion)
{
// Serialized as: null-check (bool), count (int32), elements
bool nullCheck = reader.ReadBoolean();
if (!nullCheck)
{
return null;
}
List list = new List();
int count = reader.ReadCompressedInt32(serializationVersion);
for (int i = 0; i < count; ++i)
{
list.Add((T)reader.Read(serializationVersion));
}
return list;
}
///
/// Reads a list of objects where each element can be of a different type.
///
/// Reader
/// The serialization version, to provide backwards compatibility
/// The list
/// A type is not supported
/// The compressed data is corrupt
/// An was not found when deserializing
///
/// A class that implements the
/// interface was not found when deserializing
///
public static List