// %BANNER_BEGIN% // --------------------------------------------------------------------- // %COPYRIGHT_BEGIN% // Copyright (c) 2022-2023 Magic Leap, Inc. All Rights Reserved. // Use of this file is governed by the Magic Leap 2 Software License Agreement, located here: https://www.magicleap.com/software-license-agreement-ml2 // Terms and conditions applicable to third-party materials accompanying this distribution may also be found in the top-level NOTICE file appearing herein. // %COPYRIGHT_END% // --------------------------------------------------------------------- // %BANNER_END% using System; using System.IO; using System.Text; using UnityEngine; namespace MagicLeap.Spectator { public class StreamHelper { #region Read public static byte ReadByte(Stream stream) { return (byte)stream.ReadByte(); } public static int ReadInt32(Stream stream) { byte[] buffer = ReadBytes(stream, sizeof(int)); return BitConverter.ToInt32(buffer, 0); } public static uint ReadUInt32(Stream stream) { byte[] buffer = ReadBytes(stream, sizeof(uint)); return BitConverter.ToUInt32(buffer, 0); } public static long ReadInt64(Stream stream) { byte[] buffer = ReadBytes(stream, sizeof(long)); return BitConverter.ToInt64(buffer, 0); } public static ulong ReadUInt64(Stream stream) { byte[] buffer = ReadBytes(stream, sizeof(ulong)); return BitConverter.ToUInt64(buffer, 0); } public static float ReadFloat(Stream stream) { byte[] buffer = ReadBytes(stream, sizeof(float)); return BitConverter.ToSingle(buffer, 0); } public static string ReadString(Stream stream) { int stringLength = ReadInt32(stream); byte[] buffer = ReadBytes(stream, stringLength); return Encoding.Unicode.GetString(buffer); } public static Guid ReadGuid(Stream stream) { int guidLength = Guid.NewGuid().ToByteArray().Length; byte[] buffer = ReadBytes(stream, guidLength); return new Guid(buffer); } public static Vector2 ReadVector2(Stream stream) { return new Vector2(ReadFloat(stream), ReadFloat(stream)); } public static Vector3 ReadVector3(Stream stream) { return new Vector3(ReadFloat(stream), ReadFloat(stream), ReadFloat(stream)); } public static Quaternion ReadQuaternion(Stream stream) { return new Quaternion(ReadFloat(stream), ReadFloat(stream), ReadFloat(stream), ReadFloat(stream)); } public static Matrix4x4 ReadMatrix4x4(Stream stream) { Matrix4x4 matrix = Matrix4x4.zero; for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { float v = ReadFloat(stream); matrix[j * 4 + k] = v; } } return matrix; } public static Resolution ReadResolution(Stream stream) { return new Resolution() { width = ReadInt32(stream), height = ReadInt32(stream) }; } public static Pose ReadPose(Stream stream) { return new Pose() { position = ReadVector3(stream), rotation = ReadQuaternion(stream) }; } public static byte[] ReadBytes(Stream stream, int length, int padding = 0) { int bytesRead = 0; byte[] buffer = new byte[length + padding]; while (bytesRead < length) { int currentRead = stream.Read(buffer, bytesRead + padding, length - bytesRead); bytesRead += currentRead; if (currentRead == 0 && bytesRead != length) { throw new IOException($"Unexpected end of stream. Could not read the requested amount of bytes. {length} request, {bytesRead} read"); } } return buffer; } public static void ReadBytes(Stream stream, int length, byte[] buffer) { if (buffer.Length < length) throw new IOException($"Trying to read {length} bytes into a buffer of size {buffer.Length}"); int bytesRead = 0; while (bytesRead < length) { int currentRead = stream.Read(buffer, bytesRead, length - bytesRead); bytesRead += currentRead; if (currentRead == 0 && bytesRead != length) { throw new IOException($"Unexpected end of stream. Could not read the requested amount of bytes. {length} request, {bytesRead} read"); } } } #endregion #region Write public static void Write(Stream stream, bool b) { byte[] buffer = BitConverter.GetBytes(b); stream.Write(buffer, 0, buffer.Length); } public static void Write(Stream stream, byte b) { stream.Write(new byte[] { b }, 0, 1); } public static void Write(Stream stream, byte[] bytes, int size) { stream.Write(bytes, 0, size); } public static void Write(Stream stream, int i) { byte[] buffer = BitConverter.GetBytes(i); stream.Write(buffer, 0, buffer.Length); } public static void Write(Stream stream, uint i) { byte[] buffer = BitConverter.GetBytes(i); stream.Write(buffer, 0, buffer.Length); } public static void Write(Stream stream, long l) { byte[] buffer = BitConverter.GetBytes(l); stream.Write(buffer, 0, buffer.Length); } public static void Write(Stream stream, ulong i) { byte[] buffer = BitConverter.GetBytes(i); stream.Write(buffer, 0, buffer.Length); } public static void Write(Stream stream, float x) { byte[] buffer = BitConverter.GetBytes(x); stream.Write(buffer, 0, buffer.Length); } public static void Write(Stream stream, string s) { byte[] buffer = Encoding.Unicode.GetBytes(s); Write(stream, buffer.Length); stream.Write(buffer, 0, buffer.Length); } public static void Write(Stream stream, Guid guid) { stream.Write(guid.ToByteArray(), 0, guid.ToByteArray().Length); } public static void Write(Stream stream, Vector2 v) { Write(stream, v.x); Write(stream, v.y); } public static void Write(Stream stream, Vector3 v) { Write(stream, v.x); Write(stream, v.y); Write(stream, v.z); } public static void Write(Stream stream, Quaternion q) { Write(stream, q.x); Write(stream, q.y); Write(stream, q.z); Write(stream, q.w); } public static void Write(Stream stream, Matrix4x4 m) { for (int j = 0; j < 4; j++) for (int k = 0; k < 4; k++) Write(stream, m[j * 4 + k]); } public static void Write(Stream stream, Resolution r) { Write(stream, r.width); Write(stream, r.height); } public static void Write(Stream stream, Pose p) { Write(stream, p.position); Write(stream, p.rotation); } #endregion #region Skip public static void SkipBytes(Stream stream, int bytesToSkip) { int bytesLeftToSkip = bytesToSkip; byte[] buffer = new byte[1024]; while (bytesLeftToSkip > 0) { bytesLeftToSkip -= stream.Read(buffer, 0, Math.Min(1024, bytesLeftToSkip)); } } #endregion } }