Documentation pass.

This commit is contained in:
H. Utku Maden 2024-08-25 20:29:47 +03:00
parent e6f2a74819
commit 2f964dfe99
7 changed files with 88 additions and 1 deletions

@ -3,6 +3,10 @@ using System.Text;
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 MagicValue(int value) : this(BitConverter.GetBytes(value)) { }
@ -11,6 +15,11 @@ namespace ReMime.ContentResolvers
: this((encoding ?? Encoding.ASCII).GetBytes(value)) { }
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)
{
for (int i = 0; i < haystack.Length && i < Value.Length; i++)

@ -4,6 +4,9 @@ using System.IO;
namespace ReMime
{
/// <summary>
/// Interface for all media type resolvers that inspect content.
/// </summary>
public interface IMediaContentResolver : IMediaTypeResolver
{
/// <summary>

@ -3,6 +3,9 @@ using System.Collections.Generic;
namespace ReMime
{
/// <summary>
/// Interface for all media type resolvers.
/// </summary>
public interface IMediaTypeResolver
{
/// <summary>

@ -8,13 +8,22 @@ using ReMime.Platform;
namespace ReMime
{
/// <summary>
/// Resolve media types from file names and file contents.
/// </summary>
public static class MediaTypeResolver
{
private static readonly SortedList<int, IMediaTypeResolver> s_resolvers = new SortedList<int, IMediaTypeResolver>();
private static IReadOnlyList<MediaType>? s_mediaTypes = null;
/// <summary>
/// Enumeration of currently available media type resolvers.
/// </summary>
public static IEnumerable<IMediaTypeResolver> Resolvers => s_resolvers.Values;
/// <summary>
/// Enumeration of detectable media types.
/// </summary>
public static IEnumerable<MediaType> KnownTypes
{
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)
{
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)
{
path = Path.GetFileName(path);
@ -98,11 +119,18 @@ namespace ReMime
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)
{
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)
@ -123,6 +151,12 @@ namespace ReMime
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)
{
foreach (IMediaTypeResolver resolver in Resolvers)
@ -142,6 +176,17 @@ namespace ReMime
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)
{
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)
{
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)
{
if (open)

@ -2,6 +2,9 @@ using System;
namespace ReMime
{
/// <summary>
/// The result of a combined media type query.
/// </summary>
[Flags]
public enum MediaTypeResult
{

@ -5,6 +5,9 @@ using System.IO;
namespace ReMime.Platform
{
/// <summary>
/// Media type resolver for *nix systems that have a "/etc/mime.types" file.
/// </summary>
public class UnixMediaTypeResolver : IMediaTypeResolver
{
private readonly Dictionary<string, MediaType> _extensionsMap = new Dictionary<string, MediaType>();

@ -5,6 +5,9 @@ using Microsoft.Win32;
namespace ReMime.Platform
{
/// <summary>
/// Media type resolver for Windows systems.
/// </summary>
public class Win32MediaTypeResolver : IMediaTypeResolver
{
private readonly Dictionary<string, MediaType> _extensionsMap = new Dictionary<string, MediaType>();