1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-04-28 18:15:47 +02:00
TweetDuck/lib/TweetLib.Core/Resources/CachingResourceProvider.cs

84 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using TweetLib.Browser.Interfaces;
using IOFile = System.IO.File;
namespace TweetLib.Core.Resources {
public sealed class CachingResourceProvider<T> : IResourceProvider<T> {
private readonly IResourceProvider<T> resourceProvider;
private readonly Dictionary<string, ICachedResource> cache = new ();
public CachingResourceProvider(IResourceProvider<T> resourceProvider) {
this.resourceProvider = resourceProvider;
}
public void ClearCache() {
cache.Clear();
}
public T Status(HttpStatusCode code, string message) {
return resourceProvider.Status(code, message);
}
public T File(byte[] contents, string extension) {
return resourceProvider.File(contents, extension);
}
internal T CachedFile(string path) {
string key = new Uri(path).LocalPath;
if (cache.TryGetValue(key, out var cachedResource)) {
return cachedResource.GetResource(resourceProvider);
}
ICachedResource resource;
try {
resource = new CachedFileResource(IOFile.ReadAllBytes(path), Path.GetExtension(path));
} catch (FileNotFoundException) {
resource = new CachedStatusResource(HttpStatusCode.NotFound, "File not found.");
} catch (DirectoryNotFoundException) {
resource = new CachedStatusResource(HttpStatusCode.NotFound, "Directory not found.");
} catch (Exception e) {
resource = new CachedStatusResource(HttpStatusCode.InternalServerError, e.Message);
}
cache[key] = resource;
return resource.GetResource(resourceProvider);
}
private interface ICachedResource {
T GetResource(IResourceProvider<T> resourceProvider);
}
private sealed class CachedFileResource : ICachedResource {
private readonly byte[] contents;
private readonly string extension;
public CachedFileResource(byte[] contents, string extension) {
this.contents = contents;
this.extension = extension;
}
T ICachedResource.GetResource(IResourceProvider<T> resourceProvider) {
return resourceProvider.File(contents, extension);
}
}
private sealed class CachedStatusResource : ICachedResource {
private readonly HttpStatusCode code;
private readonly string message;
public CachedStatusResource(HttpStatusCode code, string message) {
this.code = code;
this.message = message;
}
public T GetResource(IResourceProvider<T> resourceProvider) {
return resourceProvider.Status(code, message);
}
}
}
}