diff --git a/UniversalFiles.sln.DotSettings b/UniversalFiles.sln.DotSettings
index 6f96f68..92a3c6e 100644
--- a/UniversalFiles.sln.DotSettings
+++ b/UniversalFiles.sln.DotSettings
@@ -13,4 +13,5 @@ See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
If not, see <https://www.gnu.org/licenses/>.
True
- True
\ No newline at end of file
+ True
+ True
\ No newline at end of file
diff --git a/src/UniversalFiles.Swarm/Extensions/UniversalUriProviderExtensions.cs b/src/UniversalFiles.Swarm/Extensions/UFileProviderExtension.cs
similarity index 51%
rename from src/UniversalFiles.Swarm/Extensions/UniversalUriProviderExtensions.cs
rename to src/UniversalFiles.Swarm/Extensions/UFileProviderExtension.cs
index 3a6df97..62c95a4 100644
--- a/src/UniversalFiles.Swarm/Extensions/UniversalUriProviderExtensions.cs
+++ b/src/UniversalFiles.Swarm/Extensions/UFileProviderExtension.cs
@@ -13,31 +13,28 @@
// If not, see .
using Etherna.BeeNet;
-using Etherna.BeeNet.Models;
-using Etherna.UniversalFiles.Handlers;
using System;
namespace Etherna.UniversalFiles.Extensions
{
- public static class UniversalUriProviderExtensions
+ public static class UFileProviderExtension
{
- public static UniversalUri GetNewUri(
- this IUniversalUriProvider uriProvider,
- SwarmUri swarmUri,
- IBeeClient beeClient,
- UniversalUriKind allowedUriKinds = UniversalUriKind.Online,
- SwarmAddress? defaultBaseAddress = null)
+ public static SwarmUFile BuildNewUFile(
+ this IUFileProvider fileProvider,
+ SwarmUUri uuri)
{
- ArgumentNullException.ThrowIfNull(uriProvider, nameof(uriProvider));
-
- if ((allowedUriKinds & UniversalUriKind.Local) != 0)
- throw new ArgumentException("Swarm uri can't be local");
+ ArgumentNullException.ThrowIfNull(fileProvider, nameof(fileProvider));
+ return (SwarmUFile)fileProvider.BuildNewUFile(uuri);
+ }
- return new(
- swarmUri.ToString(),
- new SwarmHandler(beeClient),
- allowedUriKinds,
- defaultBaseAddress.ToString());
+ public static UFileProvider UseSwarmUFiles(
+ this UFileProvider fileProvider,
+ IBeeClient beeClient)
+ {
+ ArgumentNullException.ThrowIfNull(fileProvider, nameof(fileProvider));
+
+ fileProvider.RegisterUUriType(uuri => new SwarmUFile(beeClient, uuri));
+ return fileProvider;
}
}
}
\ No newline at end of file
diff --git a/src/UniversalFiles.Swarm/Handlers/SwarmHandler.cs b/src/UniversalFiles.Swarm/Handlers/SwarmHandler.cs
deleted file mode 100644
index 238c99b..0000000
--- a/src/UniversalFiles.Swarm/Handlers/SwarmHandler.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2023-present Etherna SA
-// This file is part of UniversalFiles.
-//
-// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Lesser General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// UniversalFiles is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
-// If not, see .
-
-using Etherna.BeeNet;
-using Etherna.BeeNet.Models;
-using System;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Etherna.UniversalFiles.Handlers
-{
- ///
- /// Supports swarm files
- ///
- public class SwarmHandler(
- IBeeClient beeClient)
- : IHandler
- {
- public async Task<(bool Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> ExistsAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind)
- {
- if (absoluteUriKind != UniversalUriKind.OnlineAbsolute)
- throw new InvalidOperationException(
- "Invalid online absolute uri kind. It can't be casted to SwarmAddress");
-
- // Try to get file head.
- try
- {
- var headers = await beeClient.TryGetFileHeadersAsync(absoluteUri).ConfigureAwait(false);
- if (headers is null)
- return (false, null);
- }
- catch { return (false, null); }
-
- return (true, null);
- }
-
- public async Task<(long Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> GetByteSizeAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind)
- {
- var size = await beeClient.TryGetFileSizeAsync(absoluteUri).ConfigureAwait(false);
- if (size is null)
- throw new InvalidOperationException();
- return (size.Value, null);
- }
-
- public UniversalUriKind GetUriKind(string uri)
- {
- ArgumentNullException.ThrowIfNull(uri, nameof(uri));
- return SwarmHash.IsValidHash(uri.Split(SwarmAddress.Separator)[0])
- ? UniversalUriKind.OnlineAbsolute
- : UniversalUriKind.OnlineRelative;
- }
-
- public async Task<(byte[] ByteArray, Encoding? Encoding)> ReadToByteArrayAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind)
- {
- var (contentStream, encoding) = await ReadToStreamAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
-
- // Copy stream to memory stream.
- using var memoryStream = new MemoryStream();
- await contentStream.CopyToAsync(memoryStream).ConfigureAwait(false);
- memoryStream.Position = 0;
-
- var byteArrayContent = memoryStream.ToArray();
- await contentStream.DisposeAsync().ConfigureAwait(false);
-
- return (byteArrayContent, encoding);
- }
-
- public async Task<(Stream Stream, Encoding? Encoding)> ReadToStreamAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind)
- {
- var result = await beeClient.GetFileAsync(absoluteUri).ConfigureAwait(false);
-
- // Try to extract the encoding from the Content-Type header.
- Encoding? contentEncoding = null;
- if (result.ContentHeaders?.ContentType?.CharSet != null)
- {
- try { contentEncoding = Encoding.GetEncoding(result.ContentHeaders.ContentType.CharSet); }
- catch (ArgumentException) { }
- }
-
- return (result.Stream, contentEncoding);
- }
-
- public Task TryGetFileNameAsync(string originalUri) =>
- beeClient.TryGetFileNameAsync(originalUri);
-
- public (string AbsoluteUri, UniversalUriKind UriKind)? TryGetParentDirectoryAsAbsoluteUri(
- string absoluteUri,
- UniversalUriKind absoluteUriKind) =>
- throw new InvalidOperationException("Swarm doesn't implement concept of directories");
-
- public (string AbsoluteUri, UniversalUriKind UriKind) UriToAbsoluteUri(
- string originalUri,
- string? baseDirectory,
- UniversalUriKind uriKind)
- {
- ArgumentNullException.ThrowIfNull(originalUri, nameof(originalUri));
-
- // Resolve absolute url.
- switch (uriKind)
- {
- case UniversalUriKind.OnlineAbsolute:
- return (new SwarmAddress(originalUri).ToString(), UniversalUriKind.OnlineAbsolute);
-
- case UniversalUriKind.OnlineRelative:
- if (baseDirectory is null)
- throw new ArgumentNullException(nameof(baseDirectory),
- "Base directory can't be null with relative original uri");
-
- if ((GetUriKind(baseDirectory) & UniversalUriKind.Absolute) == 0)
- throw new InvalidOperationException(
- "If uri kind is relative, base directory must be absolute");
-
- var swarmUri = new SwarmUri(originalUri, UriKind.Relative);
- var swarmAddress = swarmUri.ToSwarmAddress(baseDirectory);
-
- return (swarmAddress.ToString(), UniversalUriKind.OnlineAbsolute);
-
- default: throw new InvalidOperationException("Can't find a valid uri kind");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/UniversalFiles.Swarm/SwarmUFile.cs b/src/UniversalFiles.Swarm/SwarmUFile.cs
new file mode 100644
index 0000000..37c1b5c
--- /dev/null
+++ b/src/UniversalFiles.Swarm/SwarmUFile.cs
@@ -0,0 +1,95 @@
+// Copyright 2023-present Etherna SA
+// This file is part of UniversalFiles.
+//
+// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
+// GNU Lesser General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// UniversalFiles is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
+// If not, see .
+
+using Etherna.BeeNet;
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Etherna.UniversalFiles
+{
+ public class SwarmUFile(
+ IBeeClient beeClient,
+ UUri fileUri)
+ : UFile(fileUri)
+ {
+ protected override async Task<(bool Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> ExistsAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind)
+ {
+ if (absoluteUriKind != UUriKind.OnlineAbsolute)
+ throw new InvalidOperationException(
+ "Invalid online absolute uri kind. It can't be casted to SwarmAddress");
+
+ // Try to get file head.
+ try
+ {
+ var headers = await beeClient.TryGetFileHeadersAsync(absoluteUri).ConfigureAwait(false);
+ if (headers is null)
+ return (false, null);
+ }
+ catch { return (false, null); }
+
+ return (true, null);
+ }
+
+ protected override async Task<(long Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> GetByteSizeAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind)
+ {
+ var size = await beeClient.TryGetFileSizeAsync(absoluteUri).ConfigureAwait(false);
+ if (size is null)
+ throw new InvalidOperationException();
+ return (size.Value, null);
+ }
+
+ protected override async Task<(byte[] ByteArray, Encoding? Encoding)> ReadToByteArrayAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind)
+ {
+ var (contentStream, encoding) = await ReadToStreamAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
+
+ // Copy stream to memory stream.
+ using var memoryStream = new MemoryStream();
+ await contentStream.CopyToAsync(memoryStream).ConfigureAwait(false);
+ memoryStream.Position = 0;
+
+ var byteArrayContent = memoryStream.ToArray();
+ await contentStream.DisposeAsync().ConfigureAwait(false);
+
+ return (byteArrayContent, encoding);
+ }
+
+ protected override async Task<(Stream Stream, Encoding? Encoding)> ReadToStreamAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind)
+ {
+ var result = await beeClient.GetFileAsync(absoluteUri).ConfigureAwait(false);
+
+ // Try to extract the encoding from the Content-Type header.
+ Encoding? contentEncoding = null;
+ if (result.ContentHeaders?.ContentType?.CharSet != null)
+ {
+ try { contentEncoding = Encoding.GetEncoding(result.ContentHeaders.ContentType.CharSet); }
+ catch (ArgumentException) { }
+ }
+
+ return (result.Stream, contentEncoding);
+ }
+
+ protected override Task TryGetFileNameAsync(string originalUri) =>
+ beeClient.TryGetFileNameAsync(originalUri);
+ }
+}
\ No newline at end of file
diff --git a/src/UniversalFiles.Swarm/SwarmUUri.cs b/src/UniversalFiles.Swarm/SwarmUUri.cs
new file mode 100644
index 0000000..6867e1a
--- /dev/null
+++ b/src/UniversalFiles.Swarm/SwarmUUri.cs
@@ -0,0 +1,74 @@
+// Copyright 2023-present Etherna SA
+// This file is part of UniversalFiles.
+//
+// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
+// GNU Lesser General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// UniversalFiles is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
+// If not, see .
+
+using Etherna.BeeNet.Models;
+using System;
+
+namespace Etherna.UniversalFiles
+{
+ public class SwarmUUri(
+ SwarmUri uri,
+ UUriKind allowedUriKinds = UUriKind.All,
+ string? defaultBaseDirectory = null)
+ : UUri(uri.ToString(), GetUriKind(uri.ToString()) & allowedUriKinds, defaultBaseDirectory)
+ {
+ // Public static methods.
+ public static UUriKind GetUriKind(string uri)
+ {
+ ArgumentNullException.ThrowIfNull(uri, nameof(uri));
+ return SwarmHash.IsValidHash(uri.Split(SwarmAddress.Separator)[0])
+ ? UUriKind.OnlineAbsolute
+ : UUriKind.OnlineRelative;
+ }
+
+ // Protected methods.
+ protected internal override UUriKind GetUriKindHelper(string uri) => GetUriKind(uri);
+
+ protected internal override (string AbsoluteUri, UUriKind UriKind)? TryGetParentDirectoryAsAbsoluteUri(
+ string absoluteUri,
+ UUriKind absoluteUriKind) =>
+ throw new InvalidOperationException("Swarm doesn't implement concept of directories");
+
+ protected internal override (string AbsoluteUri, UUriKind UriKind) UriToAbsoluteUri(
+ string originalUri,
+ string? baseDirectory,
+ UUriKind uriKind)
+ {
+ ArgumentNullException.ThrowIfNull(originalUri, nameof(originalUri));
+
+ // Resolve absolute url.
+ switch (uriKind)
+ {
+ case UUriKind.OnlineAbsolute:
+ return (new SwarmAddress(originalUri).ToString(), UUriKind.OnlineAbsolute);
+
+ case UUriKind.OnlineRelative:
+ if (baseDirectory is null)
+ throw new ArgumentNullException(nameof(baseDirectory),
+ "Base directory can't be null with relative original uri");
+
+ if ((GetUriKind(baseDirectory) & UUriKind.Absolute) == 0)
+ throw new InvalidOperationException(
+ "If uri kind is relative, base directory must be absolute");
+
+ var swarmUri = new SwarmUri(originalUri, System.UriKind.Relative);
+ var swarmAddress = swarmUri.ToSwarmAddress(baseDirectory);
+
+ return (swarmAddress.ToString(), UUriKind.OnlineAbsolute);
+
+ default: throw new InvalidOperationException("Can't find a valid uri kind");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/UniversalFiles/Handlers/BasicHandler.cs b/src/UniversalFiles/BasicUFile.cs
similarity index 54%
rename from src/UniversalFiles/Handlers/BasicHandler.cs
rename to src/UniversalFiles/BasicUFile.cs
index 5c7a0ef..8a9eb34 100644
--- a/src/UniversalFiles/Handlers/BasicHandler.cs
+++ b/src/UniversalFiles/BasicUFile.cs
@@ -16,30 +16,27 @@
using System.IO;
using System.Linq;
using System.Net.Http;
-using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
-namespace Etherna.UniversalFiles.Handlers
+namespace Etherna.UniversalFiles
{
- ///
- /// Supports local and online files with http protocol
- ///
- public class BasicHandler(
+ public class BasicUFile(
+ BasicUUri fileUri,
IHttpClientFactory httpClientFactory)
- : IHandler
+ : UFile(fileUri)
{
- // Methods.
- public async Task<(bool Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> ExistsAsync(
+ // Protected methods.
+ protected override async Task<(bool Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> ExistsAsync(
string absoluteUri,
- UniversalUriKind absoluteUriKind)
+ UUriKind absoluteUriKind)
{
switch (absoluteUriKind)
{
- case UniversalUriKind.LocalAbsolute:
+ case UUriKind.LocalAbsolute:
return (File.Exists(absoluteUri) || Directory.Exists(absoluteUri), null);
- case UniversalUriKind.OnlineAbsolute:
+ case UUriKind.OnlineAbsolute:
// Try to get resource byte size with an HEAD request.
var byteSyze = await TryGetOnlineByteSizeWithHeadRequestAsync(absoluteUri).ConfigureAwait(false);
if (byteSyze.HasValue)
@@ -54,16 +51,16 @@ public class BasicHandler(
}
}
- public async Task<(long Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> GetByteSizeAsync(
+ protected override async Task<(long Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> GetByteSizeAsync(
string absoluteUri,
- UniversalUriKind absoluteUriKind)
+ UUriKind absoluteUriKind)
{
switch (absoluteUriKind)
{
- case UniversalUriKind.LocalAbsolute:
+ case UUriKind.LocalAbsolute:
return (new FileInfo(absoluteUri).Length, null);
- case UniversalUriKind.OnlineAbsolute:
+ case UUriKind.OnlineAbsolute:
// Try to get resource byte size with an HEAD request.
var byteSyze = await TryGetOnlineByteSizeWithHeadRequestAsync(absoluteUri).ConfigureAwait(false);
if (byteSyze.HasValue)
@@ -79,45 +76,16 @@ public class BasicHandler(
}
}
- public UniversalUriKind GetUriKind(string uri)
- {
- ArgumentNullException.ThrowIfNull(uri, nameof(uri));
-
- var uriKind = UniversalUriKind.None;
-
- if (uri.Length > 0)
- {
- //test online absolute
- if (Uri.TryCreate(uri, UriKind.Absolute, out var onlineAbsUriResult) &&
- (onlineAbsUriResult.Scheme == Uri.UriSchemeHttp || onlineAbsUriResult.Scheme == Uri.UriSchemeHttps))
- uriKind |= UniversalUriKind.OnlineAbsolute;
-
- //test online relative
- if (Uri.TryCreate(uri, UriKind.Relative, out var _))
- uriKind |= UniversalUriKind.OnlineRelative;
-
- //test local absolute and relative
- if ((uriKind & UniversalUriKind.OnlineAbsolute) == 0)
- {
- uriKind |= Path.IsPathRooted(uri) ?
- UniversalUriKind.LocalAbsolute :
- UniversalUriKind.LocalRelative;
- }
- }
-
- return uriKind;
- }
-
- public async Task<(byte[] ByteArray, Encoding? Encoding)> ReadToByteArrayAsync(
+ protected override async Task<(byte[] ByteArray, Encoding? Encoding)> ReadToByteArrayAsync(
string absoluteUri,
- UniversalUriKind absoluteUriKind)
+ UUriKind absoluteUriKind)
{
switch (absoluteUriKind)
{
- case UniversalUriKind.LocalAbsolute:
+ case UUriKind.LocalAbsolute:
return (await File.ReadAllBytesAsync(absoluteUri).ConfigureAwait(false), null);
- case UniversalUriKind.OnlineAbsolute:
+ case UUriKind.OnlineAbsolute:
return await TryGetOnlineAsByteArrayAsync(absoluteUri).ConfigureAwait(false) ??
throw new IOException($"Can't retrieve online resource at {absoluteUri}");
@@ -126,16 +94,16 @@ public UniversalUriKind GetUriKind(string uri)
}
}
- public async Task<(Stream Stream, Encoding? Encoding)> ReadToStreamAsync(
+ protected override async Task<(Stream Stream, Encoding? Encoding)> ReadToStreamAsync(
string absoluteUri,
- UniversalUriKind absoluteUriKind)
+ UUriKind absoluteUriKind)
{
switch (absoluteUriKind)
{
- case UniversalUriKind.LocalAbsolute:
+ case UUriKind.LocalAbsolute:
return (File.OpenRead(absoluteUri), null);
- case UniversalUriKind.OnlineAbsolute:
+ case UUriKind.OnlineAbsolute:
return await TryGetOnlineAsStreamAsync(absoluteUri).ConfigureAwait(false) ??
throw new IOException($"Can't retrieve online resource at {absoluteUri}");
@@ -144,7 +112,7 @@ public UniversalUriKind GetUriKind(string uri)
}
}
- public Task TryGetFileNameAsync(string originalUri)
+ protected override Task TryGetFileNameAsync(string originalUri)
{
ArgumentNullException.ThrowIfNull(originalUri, nameof(originalUri));
@@ -154,67 +122,6 @@ public UniversalUriKind GetUriKind(string uri)
return Task.FromResult(originalUri.Split('/', '\\').Last());
}
- public (string AbsoluteUri, UniversalUriKind UriKind)? TryGetParentDirectoryAsAbsoluteUri(
- string absoluteUri,
- UniversalUriKind absoluteUriKind)
- {
- switch (absoluteUriKind)
- {
- case UniversalUriKind.LocalAbsolute:
- var dirName = Path.GetDirectoryName(absoluteUri);
- return dirName is null ? null :
- (dirName, UniversalUriKind.LocalAbsolute);
-
- case UniversalUriKind.OnlineAbsolute:
- var segments = new Uri(absoluteUri, UriKind.Absolute).Segments;
- return segments.Length == 1 ? null : //if it's already root, return null
- (absoluteUri[..^segments.Last().Length], UniversalUriKind.OnlineAbsolute);
-
- default: throw new InvalidOperationException("Invalid absolute uri kind. It should be well defined and absolute");
- }
- }
-
- public (string AbsoluteUri, UniversalUriKind UriKind) UriToAbsoluteUri(
- string originalUri,
- string? baseDirectory,
- UniversalUriKind uriKind)
- {
- ArgumentNullException.ThrowIfNull(originalUri, nameof(originalUri));
-
- // Verify base directory is absolute.
- if ((uriKind & UniversalUriKind.Relative) != 0 &&
- baseDirectory != null &&
- (GetUriKind(baseDirectory) & UniversalUriKind.Absolute) == 0)
- throw new InvalidOperationException("If uri kind can be relative and base directory is present, it must be absolute");
-
- // Resolve absolute url.
- return uriKind switch
- {
- UniversalUriKind.LocalAbsolute =>
- RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
- !Path.IsPathFullyQualified(originalUri) && //Ex: "/test"
- baseDirectory is not null && Path.IsPathFullyQualified(baseDirectory) ?
- (Path.GetFullPath(originalUri, baseDirectory), UniversalUriKind.LocalAbsolute) : //take unit from base directory
- (Path.GetFullPath(originalUri), UniversalUriKind.LocalAbsolute),
-
- UniversalUriKind.LocalRelative =>
- (Path.GetFullPath(
- originalUri,
- baseDirectory is not null ?
- Path.GetFullPath(baseDirectory) : //GetFullPath is required when on windows baseDirectory is a root path without unit name. Ex: "/test"
- Directory.GetCurrentDirectory()),
- UniversalUriKind.LocalAbsolute),
-
- UniversalUriKind.OnlineAbsolute => (new Uri(originalUri, System.UriKind.Absolute).ToString(), UniversalUriKind.OnlineAbsolute),
-
- UniversalUriKind.OnlineRelative => (new Uri(
- new Uri(baseDirectory!, UriKind.Absolute),
- string.Join('/', originalUri.Split('/', '\\').Select(Uri.EscapeDataString))).ToString(), UniversalUriKind.OnlineAbsolute),
-
- _ => throw new InvalidOperationException("Can't find a valid uri kind")
- };
- }
-
// Helpers.
private async Task<(byte[] ByteArray, Encoding? Encoding)?> TryGetOnlineAsByteArrayAsync(
string onlineAbsoluteUri)
@@ -275,8 +182,8 @@ baseDirectory is not null ?
if (response.Headers.TryGetValues("Content-Length", out var values))
{
- string contentLength = values.GetEnumerator().Current;
- if (long.TryParse(contentLength, out var byteSize))
+ using var enumerator = values.GetEnumerator();
+ if (long.TryParse(enumerator.Current, out var byteSize))
return byteSize;
}
}
diff --git a/src/UniversalFiles/BasicUUri.cs b/src/UniversalFiles/BasicUUri.cs
new file mode 100644
index 0000000..71d628e
--- /dev/null
+++ b/src/UniversalFiles/BasicUUri.cs
@@ -0,0 +1,122 @@
+// Copyright 2023-present Etherna SA
+// This file is part of UniversalFiles.
+//
+// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
+// GNU Lesser General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// UniversalFiles is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
+// If not, see .
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace Etherna.UniversalFiles
+{
+ public class BasicUUri(
+ string uri,
+ UUriKind allowedUriKinds = UUriKind.All,
+ string? defaultBaseDirectory = null)
+ : UUri(uri, GetUriKind(uri) & allowedUriKinds, defaultBaseDirectory)
+ {
+ // Public static methods.
+ public static UUriKind GetUriKind(string uri)
+ {
+ ArgumentNullException.ThrowIfNull(uri, nameof(uri));
+
+ var uriKind = UUriKind.None;
+
+ if (uri.Length > 0)
+ {
+ //test online absolute
+ if (Uri.TryCreate(uri, System.UriKind.Absolute, out var onlineAbsUriResult) &&
+ (onlineAbsUriResult.Scheme == Uri.UriSchemeHttp || onlineAbsUriResult.Scheme == Uri.UriSchemeHttps))
+ uriKind |= UUriKind.OnlineAbsolute;
+
+ //test online relative
+ if (Uri.TryCreate(uri, System.UriKind.Relative, out _))
+ uriKind |= UUriKind.OnlineRelative;
+
+ //test local absolute and relative
+ if ((uriKind & UUriKind.OnlineAbsolute) == 0)
+ {
+ uriKind |= Path.IsPathRooted(uri) ?
+ UUriKind.LocalAbsolute :
+ UUriKind.LocalRelative;
+ }
+ }
+
+ return uriKind;
+ }
+
+ // Protected methods.
+ protected internal override UUriKind GetUriKindHelper(string uri) => GetUriKind(uri);
+
+ protected internal override (string AbsoluteUri, UUriKind UriKind)? TryGetParentDirectoryAsAbsoluteUri(
+ string absoluteUri,
+ UUriKind absoluteUriKind)
+ {
+ switch (absoluteUriKind)
+ {
+ case UUriKind.LocalAbsolute:
+ var dirName = Path.GetDirectoryName(absoluteUri);
+ return dirName is null ? null :
+ (dirName, UUriKind.LocalAbsolute);
+
+ case UUriKind.OnlineAbsolute:
+ var segments = new Uri(absoluteUri, System.UriKind.Absolute).Segments;
+ return segments.Length == 1 ? null : //if it's already root, return null
+ (absoluteUri[..^segments.Last().Length], UUriKind.OnlineAbsolute);
+
+ default: throw new InvalidOperationException("Invalid absolute uri kind. It should be well defined and absolute");
+ }
+ }
+
+ protected internal override (string AbsoluteUri, UUriKind UriKind) UriToAbsoluteUri(
+ string originalUri,
+ string? baseDirectory,
+ UUriKind uriKind)
+ {
+ ArgumentNullException.ThrowIfNull(originalUri, nameof(originalUri));
+
+ // Verify base directory is absolute.
+ if ((uriKind & UUriKind.Relative) != 0 &&
+ baseDirectory != null &&
+ (GetUriKind(baseDirectory) & UUriKind.Absolute) == 0)
+ throw new InvalidOperationException("If uri kind can be relative and base directory is present, it must be absolute");
+
+ // Resolve absolute url.
+ return uriKind switch
+ {
+ UUriKind.LocalAbsolute =>
+ RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
+ !Path.IsPathFullyQualified(originalUri) && //Ex: "/test"
+ baseDirectory is not null && Path.IsPathFullyQualified(baseDirectory) ?
+ (Path.GetFullPath(originalUri, baseDirectory), UUriKind.LocalAbsolute) : //take unit from base directory
+ (Path.GetFullPath(originalUri), UUriKind.LocalAbsolute),
+
+ UUriKind.LocalRelative =>
+ (Path.GetFullPath(
+ originalUri,
+ baseDirectory is not null ?
+ Path.GetFullPath(baseDirectory) : //GetFullPath is required when on windows baseDirectory is a root path without unit name. Ex: "/test"
+ Directory.GetCurrentDirectory()),
+ UUriKind.LocalAbsolute),
+
+ UUriKind.OnlineAbsolute => (new Uri(originalUri, System.UriKind.Absolute).ToString(), UUriKind.OnlineAbsolute),
+
+ UUriKind.OnlineRelative => (new Uri(
+ new Uri(baseDirectory!, System.UriKind.Absolute),
+ string.Join('/', originalUri.Split('/', '\\').Select(Uri.EscapeDataString))).ToString(), UUriKind.OnlineAbsolute),
+
+ _ => throw new InvalidOperationException("Can't find a valid uri kind")
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/UniversalFiles/Handlers/IHandler.cs b/src/UniversalFiles/Handlers/IHandler.cs
deleted file mode 100644
index 2819119..0000000
--- a/src/UniversalFiles/Handlers/IHandler.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2023-present Etherna SA
-// This file is part of UniversalFiles.
-//
-// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Lesser General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// UniversalFiles is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
-// If not, see .
-
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Etherna.UniversalFiles.Handlers
-{
- public interface IHandler
- {
- Task<(bool Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> ExistsAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind);
-
- Task<(long Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> GetByteSizeAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind);
-
- ///
- /// Try to identify the uri kind, doesn't validate paths
- ///
- /// The input uri
- /// Identified uri kind
- UniversalUriKind GetUriKind(string uri);
-
- Task<(byte[] ByteArray, Encoding? Encoding)> ReadToByteArrayAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind);
-
- Task<(Stream Stream, Encoding? Encoding)> ReadToStreamAsync(
- string absoluteUri,
- UniversalUriKind absoluteUriKind);
-
- Task TryGetFileNameAsync(
- string originalUri);
-
- (string AbsoluteUri, UniversalUriKind UriKind)? TryGetParentDirectoryAsAbsoluteUri(
- string absoluteUri,
- UniversalUriKind absoluteUriKind);
-
- (string AbsoluteUri, UniversalUriKind UriKind) UriToAbsoluteUri(
- string originalUri,
- string? baseDirectory,
- UniversalUriKind uriKind);
- }
-}
\ No newline at end of file
diff --git a/src/UniversalFiles/IUniversalUriProvider.cs b/src/UniversalFiles/IUFileProvider.cs
similarity index 68%
rename from src/UniversalFiles/IUniversalUriProvider.cs
rename to src/UniversalFiles/IUFileProvider.cs
index d2f5fea..b0b00fe 100644
--- a/src/UniversalFiles/IUniversalUriProvider.cs
+++ b/src/UniversalFiles/IUFileProvider.cs
@@ -12,13 +12,20 @@
// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
// If not, see .
+using System.Threading.Tasks;
+
namespace Etherna.UniversalFiles
{
- public interface IUniversalUriProvider
+ public interface IUFileProvider
{
- UniversalUri GetNewUri(
- string uri,
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
- string? defaultBaseDirectory = null);
+ BasicUFile BuildNewUFile(BasicUUri uuri);
+
+ UFile BuildNewUFile(UUri uuri);
+
+ Task ToLocalUFileAsync(
+ UFile inputUFile,
+ UUriKind allowedUriKinds = UUriKind.All,
+ string? baseDirectory = null,
+ BasicUUri? outputUUri = null);
}
}
\ No newline at end of file
diff --git a/src/UniversalFiles/Properties/AssemblyInfo.cs b/src/UniversalFiles/Properties/AssemblyInfo.cs
index 1568faa..71c880b 100644
--- a/src/UniversalFiles/Properties/AssemblyInfo.cs
+++ b/src/UniversalFiles/Properties/AssemblyInfo.cs
@@ -14,4 +14,5 @@
using System.Runtime.CompilerServices;
-[assembly: InternalsVisibleTo("UniversalFiles.Swarm")]
\ No newline at end of file
+[assembly: InternalsVisibleTo("UniversalFiles.Swarm")]
+[assembly: InternalsVisibleTo("UniversalFiles.Tests")]
\ No newline at end of file
diff --git a/src/UniversalFiles/UniversalFile.cs b/src/UniversalFiles/UFile.cs
similarity index 67%
rename from src/UniversalFiles/UniversalFile.cs
rename to src/UniversalFiles/UFile.cs
index fdf1033..327d9ed 100644
--- a/src/UniversalFiles/UniversalFile.cs
+++ b/src/UniversalFiles/UFile.cs
@@ -19,14 +19,14 @@
namespace Etherna.UniversalFiles
{
- public class UniversalFile
+ public abstract class UFile
{
// Fields.
private (byte[], Encoding?)? onlineResourceCache;
// Constructor.
- public UniversalFile(
- UniversalUri fileUri)
+ protected UFile(
+ UUri fileUri)
{
ArgumentNullException.ThrowIfNull(fileUri, nameof(fileUri));
@@ -34,14 +34,14 @@ public UniversalFile(
}
// Properties.
- public UniversalUri FileUri { get; }
+ public UUri FileUri { get; }
// Methods.
public void ClearOnlineCache() => onlineResourceCache = null;
public async Task ExistsAsync(
bool useCacheIfOnline = false,
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ UUriKind allowedUriKinds = UUriKind.All,
string? baseDirectory = null)
{
// Use cache if enabled and available.
@@ -50,10 +50,10 @@ public async Task ExistsAsync(
// Get result from handler.
var (absoluteUri, absoluteUriKind) = FileUri.ToAbsoluteUri(allowedUriKinds, baseDirectory);
- var (result, resultCache) = await FileUri.Handler.ExistsAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
+ var (result, resultCache) = await ExistsAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
// Update cache if required.
- if (absoluteUriKind == UniversalUriKind.OnlineAbsolute &&
+ if (absoluteUriKind == UUriKind.OnlineAbsolute &&
resultCache != null &&
useCacheIfOnline)
onlineResourceCache = resultCache;
@@ -63,7 +63,7 @@ public async Task ExistsAsync(
public async Task GetByteSizeAsync(
bool useCacheIfOnline = false,
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ UUriKind allowedUriKinds = UUriKind.All,
string? baseDirectory = null)
{
// Use cache if enabled and available.
@@ -72,10 +72,10 @@ public async Task GetByteSizeAsync(
// Get result from handler.
var (absoluteUri, absoluteUriKind) = FileUri.ToAbsoluteUri(allowedUriKinds, baseDirectory);
- var (result, resultCache) = await FileUri.Handler.GetByteSizeAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
+ var (result, resultCache) = await GetByteSizeAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
// Update cache if required.
- if (absoluteUriKind == UniversalUriKind.OnlineAbsolute &&
+ if (absoluteUriKind == UUriKind.OnlineAbsolute &&
resultCache != null &&
useCacheIfOnline)
onlineResourceCache = resultCache;
@@ -85,7 +85,7 @@ public async Task GetByteSizeAsync(
public async Task<(byte[] ByteArray, Encoding? Encoding)> ReadToByteArrayAsync(
bool useCacheIfOnline = false,
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ UUriKind allowedUriKinds = UUriKind.All,
string? baseDirectory = null)
{
// Use cache if enabled and available.
@@ -94,10 +94,10 @@ public async Task GetByteSizeAsync(
// Get resource.
var (absoluteUri, absoluteUriKind) = FileUri.ToAbsoluteUri(allowedUriKinds, baseDirectory);
- var result = await FileUri.Handler.ReadToByteArrayAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
+ var result = await ReadToByteArrayAsync(absoluteUri, absoluteUriKind).ConfigureAwait(false);
// Update cache if required.
- if (absoluteUriKind == UniversalUriKind.OnlineAbsolute &&
+ if (absoluteUriKind == UUriKind.OnlineAbsolute &&
useCacheIfOnline)
onlineResourceCache = result;
@@ -105,17 +105,17 @@ public async Task GetByteSizeAsync(
}
public Task<(Stream Stream, Encoding? Encoding)> ReadToStreamAsync(
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ UUriKind allowedUriKinds = UUriKind.All,
string? baseDirectory = null)
{
// Get resource.
var (absoluteUri, absoluteUriKind) = FileUri.ToAbsoluteUri(allowedUriKinds, baseDirectory);
- return FileUri.Handler.ReadToStreamAsync(absoluteUri, absoluteUriKind);
+ return ReadToStreamAsync(absoluteUri, absoluteUriKind);
}
public async Task ReadToStringAsync(
bool useCacheIfOnline = false,
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ UUriKind allowedUriKinds = UUriKind.All,
string? baseDirectory = null)
{
var (content, encoding) = await ReadToByteArrayAsync(
@@ -125,8 +125,26 @@ public async Task ReadToStringAsync(
encoding ??= Encoding.UTF8;
return encoding.GetString(content);
}
-
- public Task TryGetFileNameAsync() =>
- FileUri.TryGetFileNameAsync();
+
+ public Task TryGetFileNameAsync() => TryGetFileNameAsync(FileUri.OriginalUri);
+
+ // Protected methods.
+ protected abstract Task<(bool Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> ExistsAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind);
+
+ protected abstract Task<(long Result, (byte[] ByteArray, Encoding? Encoding)? ContentCache)> GetByteSizeAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind);
+
+ protected abstract Task<(byte[] ByteArray, Encoding? Encoding)> ReadToByteArrayAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind);
+
+ protected abstract Task<(Stream Stream, Encoding? Encoding)> ReadToStreamAsync(
+ string absoluteUri,
+ UUriKind absoluteUriKind);
+
+ protected abstract Task TryGetFileNameAsync(string originalUri);
}
}
diff --git a/src/UniversalFiles/UFileProvider.cs b/src/UniversalFiles/UFileProvider.cs
new file mode 100644
index 0000000..6f78222
--- /dev/null
+++ b/src/UniversalFiles/UFileProvider.cs
@@ -0,0 +1,79 @@
+// Copyright 2023-present Etherna SA
+// This file is part of UniversalFiles.
+//
+// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
+// GNU Lesser General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// UniversalFiles is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
+// If not, see .
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace Etherna.UniversalFiles
+{
+ public class UFileProvider : IUFileProvider
+ {
+ // Fields.
+ private readonly Dictionary> uFileBuilders = new(); //
+
+ public UFileProvider(IHttpClientFactory httpClientFactory)
+ {
+ uFileBuilders[typeof(BasicUUri)] = uuri => new BasicUFile((BasicUUri)uuri, httpClientFactory);
+ }
+
+ // Methods.
+ public BasicUFile BuildNewUFile(BasicUUri uuri) =>
+ (BasicUFile)BuildNewUFile((UUri)uuri);
+
+ public UFile BuildNewUFile(UUri uuri)
+ {
+ ArgumentNullException.ThrowIfNull(uuri, nameof(uuri));
+
+ var builder = uFileBuilders[uuri.GetType()];
+ return builder(uuri);
+ }
+
+ public void RegisterUUriType(Func builder) where TUUri : UUri =>
+ uFileBuilders[typeof(TUUri)] = uuri => builder((TUUri)uuri);
+
+ public async Task ToLocalUFileAsync(
+ UFile inputUFile,
+ UUriKind allowedUriKinds = UUriKind.All,
+ string? baseDirectory = null,
+ BasicUUri? outputUUri = null)
+ {
+ ArgumentNullException.ThrowIfNull(inputUFile, nameof(inputUFile));
+
+ // If it's already a local file, skip file retrieve.
+ if (inputUFile is BasicUFile basicUFile &&
+ (basicUFile.FileUri.UriKind & allowedUriKinds & UUriKind.Local) != 0)
+ return basicUFile;
+
+ if (outputUUri != null && outputUUri.UriKind != UUriKind.LocalAbsolute)
+ throw new InvalidOperationException("If provided, output uuri must be local and absolute");
+
+ if (outputUUri is null)
+ {
+ var fileName = await inputUFile.TryGetFileNameAsync().ConfigureAwait(false);
+ outputUUri = fileName is null ?
+ new BasicUUri(Path.GetTempFileName()) :
+ new BasicUUri(Path.Join(Path.GetTempPath(), fileName));
+ }
+
+ using var inputFileStream = (await inputUFile.ReadToStreamAsync(allowedUriKinds, baseDirectory).ConfigureAwait(false)).Stream;
+ using var outputFileStream = new FileStream(outputUUri.ToAbsoluteUri().Item1, FileMode.Create);
+ await inputFileStream.CopyToAsync(outputFileStream).ConfigureAwait(false);
+
+ return (BasicUFile)BuildNewUFile(outputUUri);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/UniversalFiles/UniversalUri.cs b/src/UniversalFiles/UUri.cs
similarity index 68%
rename from src/UniversalFiles/UniversalUri.cs
rename to src/UniversalFiles/UUri.cs
index 1167b47..349c5cb 100644
--- a/src/UniversalFiles/UniversalUri.cs
+++ b/src/UniversalFiles/UUri.cs
@@ -12,42 +12,34 @@
// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
// If not, see .
-using Etherna.UniversalFiles.Handlers;
using System;
-using System.Threading.Tasks;
namespace Etherna.UniversalFiles
{
- public class UniversalUri
+ public abstract class UUri
{
- // Fields.
- private readonly string? defaultBaseDirectory;
-
// Constructor.
- public UniversalUri(
+ protected UUri(
string uri,
- IHandler handler,
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ UUriKind uriKind,
string? defaultBaseDirectory = null)
{
- ArgumentNullException.ThrowIfNull(handler, nameof(handler));
if (string.IsNullOrWhiteSpace(uri))
throw new ArgumentException("Uri cannot be null or white spaces", nameof(uri));
- this.defaultBaseDirectory = defaultBaseDirectory;
- Handler = handler;
+ DefaultBaseDirectory = defaultBaseDirectory;
OriginalUri = uri;
- UriKind = handler.GetUriKind(uri) & allowedUriKinds;
+ UriKind = uriKind;
// Final check.
- if (UriKind == UniversalUriKind.None)
+ if (UriKind == UUriKind.None)
throw new ArgumentException("Invalid uri with allowed uri types", nameof(uri));
}
// Properties.
- public IHandler Handler { get; }
+ public string? DefaultBaseDirectory { get; }
public string OriginalUri { get; }
- public UniversalUriKind UriKind { get; }
+ public UUriKind UriKind { get; }
// Methods.
///
@@ -56,40 +48,40 @@ public UniversalUri(
/// Optional restrictions for original uri kind
/// Optional base directory, required for online relative uri
/// Absolute uri and uri kind
- public (string, UniversalUriKind) ToAbsoluteUri(
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ public (string, UUriKind) ToAbsoluteUri(
+ UUriKind allowedUriKinds = UUriKind.All,
string? baseDirectory = null)
{
// Define actual allowed uri kinds.
var actualAllowedUriKinds = UriKind & allowedUriKinds;
// Check with base directory.
- baseDirectory ??= defaultBaseDirectory;
- if ((actualAllowedUriKinds & UniversalUriKind.Relative) != 0 &&
+ baseDirectory ??= DefaultBaseDirectory;
+ if ((actualAllowedUriKinds & UUriKind.Relative) != 0 &&
baseDirectory is not null)
{
- var baseDirectoryUriKind = Handler.GetUriKind(baseDirectory) & UniversalUriKind.Absolute;
+ var baseDirectoryUriKind = GetUriKindHelper(baseDirectory) & UUriKind.Absolute;
actualAllowedUriKinds &= baseDirectoryUriKind switch
{
- UniversalUriKind.LocalAbsolute => UniversalUriKind.Local,
- UniversalUriKind.OnlineAbsolute => UniversalUriKind.Online,
+ UUriKind.LocalAbsolute => UUriKind.Local,
+ UUriKind.OnlineAbsolute => UUriKind.Online,
_ => throw new InvalidOperationException("Base directory can only be absolute"),
};
}
// Checks.
//none allowed uri kinds.
- if (actualAllowedUriKinds == UniversalUriKind.None)
+ if (actualAllowedUriKinds == UUriKind.None)
throw new InvalidOperationException("Can't identify a valid uri kind");
//local and online ambiguity
- if ((actualAllowedUriKinds & UniversalUriKind.Local) != 0 &&
- (actualAllowedUriKinds & UniversalUriKind.Online) != 0)
+ if ((actualAllowedUriKinds & UUriKind.Local) != 0 &&
+ (actualAllowedUriKinds & UUriKind.Online) != 0)
throw new InvalidOperationException("Unable to distinguish between local and online uri. Try to restrict allowed uri kinds");
//check if it could be an online relative uri, and base directory is null
- if ((actualAllowedUriKinds & UniversalUriKind.OnlineRelative) != 0 &&
+ if ((actualAllowedUriKinds & UUriKind.OnlineRelative) != 0 &&
baseDirectory is null)
throw new InvalidOperationException("Can't resolve online relative uri. Specify a base directory");
@@ -104,24 +96,33 @@ public UniversalUri(
* - if uri can be online relative, then it can't be an absoulute or a local relative.
* It implies that a base directory must be present, and this implies same previous considerations.
*/
- return Handler.UriToAbsoluteUri(OriginalUri, baseDirectory, actualAllowedUriKinds);
+ return UriToAbsoluteUri(OriginalUri, baseDirectory, actualAllowedUriKinds);
}
- public Task TryGetFileNameAsync() =>
- Handler.TryGetFileNameAsync(OriginalUri);
-
///
/// Get parent directory as an absolute uri
///
/// Optional restrictions for original uri kind
/// Optional base directory, required for online relative uri
/// Parent directory absolute uri and its kind
- public (string, UniversalUriKind)? TryGetParentDirectoryAsAbsoluteUri(
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
+ public (string, UUriKind)? TryGetParentDirectoryAsAbsoluteUri(
+ UUriKind allowedUriKinds = UUriKind.All,
string? baseDirectory = null)
{
var (absoluteUri, absoluteUriKind) = ToAbsoluteUri(allowedUriKinds, baseDirectory);
- return Handler.TryGetParentDirectoryAsAbsoluteUri(absoluteUri, absoluteUriKind);
+ return TryGetParentDirectoryAsAbsoluteUri(absoluteUri, absoluteUriKind);
}
+
+ // Protected methods.
+ protected internal abstract UUriKind GetUriKindHelper(string uri);
+
+ protected internal abstract (string AbsoluteUri, UUriKind UriKind)? TryGetParentDirectoryAsAbsoluteUri(
+ string absoluteUri,
+ UUriKind absoluteUriKind);
+
+ protected internal abstract (string AbsoluteUri, UUriKind UriKind) UriToAbsoluteUri(
+ string originalUri,
+ string? baseDirectory,
+ UUriKind uriKind);
}
}
diff --git a/src/UniversalFiles/UniversalUriKind.cs b/src/UniversalFiles/UUriKind.cs
similarity index 97%
rename from src/UniversalFiles/UniversalUriKind.cs
rename to src/UniversalFiles/UUriKind.cs
index 127b704..db8ff98 100644
--- a/src/UniversalFiles/UniversalUriKind.cs
+++ b/src/UniversalFiles/UUriKind.cs
@@ -17,7 +17,7 @@
namespace Etherna.UniversalFiles
{
[Flags]
- public enum UniversalUriKind
+ public enum UUriKind
{
None = 0,
LocalAbsolute = 1,
diff --git a/src/UniversalFiles/UniversalUriProvider.cs b/src/UniversalFiles/UniversalUriProvider.cs
deleted file mode 100644
index b940846..0000000
--- a/src/UniversalFiles/UniversalUriProvider.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2023-present Etherna SA
-// This file is part of UniversalFiles.
-//
-// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
-// GNU Lesser General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// UniversalFiles is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
-// If not, see .
-
-using Etherna.UniversalFiles.Handlers;
-using System.Net.Http;
-
-namespace Etherna.UniversalFiles
-{
- public class UniversalUriProvider(
- IHttpClientFactory httpClientFactory)
- : IUniversalUriProvider
- {
- // Fields.
- private readonly BasicHandler basicHandler = new(httpClientFactory);
-
- // Methods.
- public UniversalUri GetNewUri(
- string uri,
- UniversalUriKind allowedUriKinds = UniversalUriKind.All,
- string? defaultBaseDirectory = null) =>
- new(uri, basicHandler, allowedUriKinds, defaultBaseDirectory);
- }
-}
\ No newline at end of file
diff --git a/test/UniversalFiles.Tests/Handlers/BasicHandlerTest.cs b/test/UniversalFiles.Tests/BasicUUriTest.cs
similarity index 50%
rename from test/UniversalFiles.Tests/Handlers/BasicHandlerTest.cs
rename to test/UniversalFiles.Tests/BasicUUriTest.cs
index e33c384..9845036 100644
--- a/test/UniversalFiles.Tests/Handlers/BasicHandlerTest.cs
+++ b/test/UniversalFiles.Tests/BasicUUriTest.cs
@@ -1,4 +1,4 @@
-// Copyright 2023-present Etherna SA
+// Copyright 2023-present Etherna SA
// This file is part of UniversalFiles.
//
// UniversalFiles is free software: you can redistribute it and/or modify it under the terms of the
@@ -12,55 +12,50 @@
// You should have received a copy of the GNU Lesser General Public License along with UniversalFiles.
// If not, see .
-using Moq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Net.Http;
using System.Runtime.InteropServices;
using Xunit;
-namespace Etherna.UniversalFiles.Handlers
+namespace Etherna.UniversalFiles
{
- public class BasicHandlerTest
+ public class BasicUUriTest
{
- // Fields.
- private static BasicHandler handler = new(new Mock().Object);
-
// Classes.
public class GetUriKindTestElement(
string uri,
- UniversalUriKind expectedUriKind)
+ UUriKind expectedUriKind)
{
public string Uri { get; } = uri;
- public UniversalUriKind ExpectedUriKind { get; } = expectedUriKind;
+ public UUriKind ExpectedUriKind { get; } = expectedUriKind;
}
public class TryGetParentDirectoryAsAbsoluteUriTestElement(
string absoluteUri,
- UniversalUriKind absoluteUriKind,
- (string, UniversalUriKind)? expectedResult)
+ UUriKind absoluteUriKind,
+ (string, UUriKind)? expectedResult)
{
public string AbsoluteUri { get; } = absoluteUri;
- public UniversalUriKind AbsoluteUriKind { get; } = absoluteUriKind;
- public (string, UniversalUriKind)? ExpectedResult { get; } = expectedResult;
+ public UUriKind AbsoluteUriKind { get; } = absoluteUriKind;
+ public (string, UUriKind)? ExpectedResult { get; } = expectedResult;
}
-
+
public class UriToAbsoluteUriTestElement(
string originalUri,
string? baseDirectory,
- UniversalUriKind uriKind,
- (string, UniversalUriKind)? expectedResult = null,
+ UUriKind uriKind,
+ (string, UUriKind)? expectedResult = null,
Type? expectedExceptionType = null)
{
public string OriginalUri { get; } = originalUri;
public string? BaseDirectory { get; } = baseDirectory;
- public UniversalUriKind UriKind { get; } = uriKind;
- public (string, UniversalUriKind)? ExpectedResult { get; } = expectedResult;
+ public UUriKind UriKind { get; } = uriKind;
+ public (string, UUriKind)? ExpectedResult { get; } = expectedResult;
public Type? ExpectedExceptionType { get; } = expectedExceptionType;
}
-
+
// Data.
public static IEnumerable