// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) VRMADA, All rights reserved. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Threading; using System.Threading.Tasks; using UltimateXR.Exceptions; using UnityEngine; using UnityEngine.Networking; namespace UltimateXR.Extensions.Unity.IO { /// /// extensions to read data synchronously and asynchronously. /// public static class UnityWebRequestExt { #region Public Methods /// /// Checks whether a given URI can be read using a . /// /// URI to check /// Whether the URI is compatible with public static bool IsUwrUri(string uri) { return uri.Contains(Application.streamingAssetsPath) || uri.StartsWith(FilePrefix) || uri.StartsWith(HttpPrefix) || uri.StartsWith(HttpsPrefix); } /// /// Sends a . /// /// Request to send /// HttpError flag is on /// NetworkError flag is on public static void Fetch(this UnityWebRequest self) { UnityWebRequestAsyncOperation request = self.SendWebRequest(); while (!request.isDone) { // Active wait Thread.Sleep(0); } if (self.result == UnityWebRequest.Result.ConnectionError) { throw new NetUwrException(self.error); } if (self.result == UnityWebRequest.Result.ProtocolError) { throw new HttpUwrException(self.error, self.responseCode); } } /// /// Sends a asynchronously. /// /// Request to send /// Cancellation token, to cancel the operation /// Awaitable task that will finish when the request was sent /// The task was canceled using /// HttpError flag is on /// NetworkError flag is on public static async Task FetchAsync(this UnityWebRequest self, CancellationToken ct = default) { if (ct.IsCancellationRequested) { return; } await self.SendWebRequest().Wait(ct); if (ct.IsCancellationRequested) { self.Abort(); } if (self.result == UnityWebRequest.Result.ConnectionError) { throw new NetUwrException(self.error); } if (self.result == UnityWebRequest.Result.ProtocolError) { throw new HttpUwrException(self.error, self.responseCode); } } /// /// Loads an asynchronously from an URI. /// /// Location of the audio clip /// HttpError flag is on /// NetworkError flag is on public static AudioClip LoadAudioClip(string uri) { using UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(FixUri(uri), AudioType.UNKNOWN); req.Fetch(); AudioClip result = DownloadHandlerAudioClip.GetContent(req); result.name = Path.GetFileNameWithoutExtension(uri); return result; } /// /// Loads an asynchronously from an URI. /// /// Location of the audio clip /// Optional cancellation token, to cancel the operation /// Awaitable that returns the loaded audio clip /// HttpError flag is on /// NetworkError flag is on /// The task was canceled using public static async Task LoadAudioClipAsync(string uri, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); using UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(FixUri(uri), AudioType.UNKNOWN); await req.FetchAsync(ct); ct.ThrowIfCancellationRequested(); AudioClip result = DownloadHandlerAudioClip.GetContent(req); result.name = Path.GetFileNameWithoutExtension(uri); return result; } /// /// Reads bytes from an URI. /// /// Location of the data /// /// HttpError flag is on /// /// /// NetworkError flag is on /// public static byte[] ReadBytes(string uri) { using UnityWebRequest req = UnityWebRequest.Get(FixUri(uri)); req.Fetch(); return req.downloadHandler.data; } /// /// Reads bytes asynchronously from an URI. /// /// Location of the data /// Optional cancellation token, to cancel the operation /// Awaitable task that returns the bytes read /// The task was canceled using /// /// HttpError flag is on /// /// /// NetworkError flag is on /// public static async Task ReadBytesAsync(string uri, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); using UnityWebRequest req = UnityWebRequest.Get(FixUri(uri)); await req.FetchAsync(ct); ct.ThrowIfCancellationRequested(); return req.downloadHandler.data; } /// /// Reads a string from an URI. /// /// Text location /// /// HttpError flag is on /// /// /// NetworkError flag is on /// public static string ReadText(string uri) { using UnityWebRequest req = UnityWebRequest.Get(FixUri(uri)); req.Fetch(); return req.downloadHandler.text; } /// /// Reads a string asynchronously from an URI. /// /// Text location /// Optional cancellation, to cancel the operation /// Awaitable task that returns the string read /// The task was canceled using /// /// HttpError flag is on /// /// /// NetworkError flag is on /// public static async Task ReadTextAsync(string uri, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); using UnityWebRequest req = UnityWebRequest.Get(FixUri(uri)); await req.FetchAsync(ct); ct.ThrowIfCancellationRequested(); return req.downloadHandler.text; } #endregion #region Private Methods /// /// Fixes an URI string. /// /// String to fix /// Fixed URI string private static string FixUri(string uri) { string result = uri.Trim('\\', '/', ' '); if (!IsUwrUri(uri)) { result = FilePrefix + uri; } return result; } #endregion #region Private Types & Data private const string FilePrefix = "file://"; private const string HttpPrefix = "http://"; private const string HttpsPrefix = "https://"; #endregion } }