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