Documentation pass.
This commit is contained in:
parent
e6f2a74819
commit
2f964dfe99
@ -3,6 +3,10 @@ using System.Text;
|
|||||||
|
|
||||||
namespace ReMime.ContentResolvers
|
namespace ReMime.ContentResolvers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A magic value to identify file types.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Value">The byte arary that makes up the magic value.</param>
|
||||||
public record struct MagicValue(byte[] Value)
|
public record struct MagicValue(byte[] Value)
|
||||||
{
|
{
|
||||||
public MagicValue(int value) : this(BitConverter.GetBytes(value)) { }
|
public MagicValue(int value) : this(BitConverter.GetBytes(value)) { }
|
||||||
@ -11,6 +15,11 @@ namespace ReMime.ContentResolvers
|
|||||||
: this((encoding ?? Encoding.ASCII).GetBytes(value)) { }
|
: this((encoding ?? Encoding.ASCII).GetBytes(value)) { }
|
||||||
public MagicValue(ReadOnlySpan<byte> bytes) : this(bytes.ToArray()) { }
|
public MagicValue(ReadOnlySpan<byte> bytes) : this(bytes.ToArray()) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if <paramref name="haystack"/> matches this magic value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="haystack"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public bool Matches(ReadOnlySpan<byte> haystack)
|
public bool Matches(ReadOnlySpan<byte> haystack)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < haystack.Length && i < Value.Length; i++)
|
for (int i = 0; i < haystack.Length && i < Value.Length; i++)
|
||||||
|
@ -4,6 +4,9 @@ using System.IO;
|
|||||||
|
|
||||||
namespace ReMime
|
namespace ReMime
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for all media type resolvers that inspect content.
|
||||||
|
/// </summary>
|
||||||
public interface IMediaContentResolver : IMediaTypeResolver
|
public interface IMediaContentResolver : IMediaTypeResolver
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3,6 +3,9 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace ReMime
|
namespace ReMime
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for all media type resolvers.
|
||||||
|
/// </summary>
|
||||||
public interface IMediaTypeResolver
|
public interface IMediaTypeResolver
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,13 +8,22 @@ using ReMime.Platform;
|
|||||||
|
|
||||||
namespace ReMime
|
namespace ReMime
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Resolve media types from file names and file contents.
|
||||||
|
/// </summary>
|
||||||
public static class MediaTypeResolver
|
public static class MediaTypeResolver
|
||||||
{
|
{
|
||||||
private static readonly SortedList<int, IMediaTypeResolver> s_resolvers = new SortedList<int, IMediaTypeResolver>();
|
private static readonly SortedList<int, IMediaTypeResolver> s_resolvers = new SortedList<int, IMediaTypeResolver>();
|
||||||
private static IReadOnlyList<MediaType>? s_mediaTypes = null;
|
private static IReadOnlyList<MediaType>? s_mediaTypes = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of currently available media type resolvers.
|
||||||
|
/// </summary>
|
||||||
public static IEnumerable<IMediaTypeResolver> Resolvers => s_resolvers.Values;
|
public static IEnumerable<IMediaTypeResolver> Resolvers => s_resolvers.Values;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of detectable media types.
|
||||||
|
/// </summary>
|
||||||
public static IEnumerable<MediaType> KnownTypes
|
public static IEnumerable<MediaType> KnownTypes
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -58,11 +67,23 @@ namespace ReMime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a media type resolver.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="resolver">The resolver instance to add.</param>
|
||||||
|
/// <param name="priority">The resolver priority. Less is more prescedent.</param>
|
||||||
public static void AddResolver(IMediaTypeResolver resolver, int priority = 9999)
|
public static void AddResolver(IMediaTypeResolver resolver, int priority = 9999)
|
||||||
{
|
{
|
||||||
s_resolvers.Add(priority, resolver);
|
s_resolvers.Add(priority, resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve the media type from a path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path string.</param>
|
||||||
|
/// <param name="mediaType">The result media type.</param>
|
||||||
|
/// <returns>True if there was a matching media type.</returns>
|
||||||
|
/// <exception cref="ArgumentException">Issues with <paramref name="path"> string. See <see cref="Path.GetFileName"/>.</exception>
|
||||||
public static bool TryResolve(ReadOnlySpan<char> path, out MediaType mediaType)
|
public static bool TryResolve(ReadOnlySpan<char> path, out MediaType mediaType)
|
||||||
{
|
{
|
||||||
path = Path.GetFileName(path);
|
path = Path.GetFileName(path);
|
||||||
@ -98,11 +119,18 @@ namespace ReMime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve the media type from a stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to inspect.</param>
|
||||||
|
/// <param name="mediaType">The result media type.</param>
|
||||||
|
/// <returns>True if the type was resolved.</returns>
|
||||||
|
/// <exception cref="ArgumentException">The <paramref name="stream"/> is unseekable.</exception>
|
||||||
public static bool TryResolve(Stream stream, out MediaType mediaType)
|
public static bool TryResolve(Stream stream, out MediaType mediaType)
|
||||||
{
|
{
|
||||||
if (!stream.CanSeek)
|
if (!stream.CanSeek)
|
||||||
{
|
{
|
||||||
throw new Exception("This stream is not seekable, cannot resolve unseekable streams.");
|
throw new ArgumentException("This stream is not seekable, cannot resolve unseekable streams.", nameof(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (IMediaTypeResolver resolver in Resolvers)
|
foreach (IMediaTypeResolver resolver in Resolvers)
|
||||||
@ -123,6 +151,12 @@ namespace ReMime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve the media type from a span.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">A span of bytes from the start of the media.</param>
|
||||||
|
/// <param name="mediaType">The result media type.</param>
|
||||||
|
/// <returns>True if the type was resolved.</returns>
|
||||||
public static bool TryResolve(ReadOnlySpan<byte> bytes, out MediaType mediaType)
|
public static bool TryResolve(ReadOnlySpan<byte> bytes, out MediaType mediaType)
|
||||||
{
|
{
|
||||||
foreach (IMediaTypeResolver resolver in Resolvers)
|
foreach (IMediaTypeResolver resolver in Resolvers)
|
||||||
@ -142,6 +176,17 @@ namespace ReMime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve the media type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path string.</param>
|
||||||
|
/// <param name="bytes">A span of bytes from the start of the media.</param>
|
||||||
|
/// <param name="mediaType">The result media type.</param>
|
||||||
|
/// <returns><see cref="MediaTypeResult.None"/> if none matched.</returns>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// The <paramref name="stream"/> is unseekable, or issues with <paramref name="path"> string.
|
||||||
|
/// See <see cref="Path.GetFileName"/>
|
||||||
|
/// </exception>
|
||||||
public static MediaTypeResult TryResolve(ReadOnlySpan<char> path, ReadOnlySpan<byte> bytes, out MediaType mediaType)
|
public static MediaTypeResult TryResolve(ReadOnlySpan<char> path, ReadOnlySpan<byte> bytes, out MediaType mediaType)
|
||||||
{
|
{
|
||||||
if (TryResolve(bytes, out mediaType))
|
if (TryResolve(bytes, out mediaType))
|
||||||
@ -163,6 +208,17 @@ namespace ReMime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve the media type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path string.</param>
|
||||||
|
/// <param name="stream">The stream to inspect.</param>
|
||||||
|
/// <param name="mediaType">The result media type.</param>
|
||||||
|
/// <returns><see cref="MediaTypeResult.None"/> if none matched.</returns>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// The <paramref name="stream"/> is unseekable, or issues with <paramref name="path"> string.
|
||||||
|
/// See <see cref="Path.GetFileName"/>
|
||||||
|
/// </exception>
|
||||||
public static MediaTypeResult TryResolve(ReadOnlySpan<char> path, Stream stream, out MediaType mediaType)
|
public static MediaTypeResult TryResolve(ReadOnlySpan<char> path, Stream stream, out MediaType mediaType)
|
||||||
{
|
{
|
||||||
if (TryResolve(stream, out mediaType))
|
if (TryResolve(stream, out mediaType))
|
||||||
@ -184,6 +240,13 @@ namespace ReMime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve the media type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileInfo">The FileInfo object to the file.</param>
|
||||||
|
/// <param name="mediaType">The result media type.</param>
|
||||||
|
/// <param name="open">True to open the file and inspect the contents as well.</param>
|
||||||
|
/// <returns><see cref="MediaTypeResult.None"/> if none matched.</returns>
|
||||||
public static MediaTypeResult TryResolve(FileInfo fileInfo, out MediaType mediaType, bool open = true)
|
public static MediaTypeResult TryResolve(FileInfo fileInfo, out MediaType mediaType, bool open = true)
|
||||||
{
|
{
|
||||||
if (open)
|
if (open)
|
||||||
|
@ -2,6 +2,9 @@ using System;
|
|||||||
|
|
||||||
namespace ReMime
|
namespace ReMime
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The result of a combined media type query.
|
||||||
|
/// </summary>
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum MediaTypeResult
|
public enum MediaTypeResult
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,9 @@ using System.IO;
|
|||||||
|
|
||||||
namespace ReMime.Platform
|
namespace ReMime.Platform
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Media type resolver for *nix systems that have a "/etc/mime.types" file.
|
||||||
|
/// </summary>
|
||||||
public class UnixMediaTypeResolver : IMediaTypeResolver
|
public class UnixMediaTypeResolver : IMediaTypeResolver
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, MediaType> _extensionsMap = new Dictionary<string, MediaType>();
|
private readonly Dictionary<string, MediaType> _extensionsMap = new Dictionary<string, MediaType>();
|
||||||
|
@ -5,6 +5,9 @@ using Microsoft.Win32;
|
|||||||
|
|
||||||
namespace ReMime.Platform
|
namespace ReMime.Platform
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Media type resolver for Windows systems.
|
||||||
|
/// </summary>
|
||||||
public class Win32MediaTypeResolver : IMediaTypeResolver
|
public class Win32MediaTypeResolver : IMediaTypeResolver
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, MediaType> _extensionsMap = new Dictionary<string, MediaType>();
|
private readonly Dictionary<string, MediaType> _extensionsMap = new Dictionary<string, MediaType>();
|
||||||
|
Loading…
Reference in New Issue
Block a user