Implement DeliveryCacheDirectoryService

This commit is contained in:
Alex Barney 2020-04-10 11:31:46 -07:00
parent ef36568a8d
commit 6e4372ce58
4 changed files with 94 additions and 10 deletions

View file

@ -8,5 +8,12 @@ namespace LibHac.Bcat
[FieldOffset(0x00)] public FileName Name;
[FieldOffset(0x20)] public long Size;
[FieldOffset(0x28)] public Digest Digest;
public DeliveryCacheDirectoryEntry(ref FileName name, long size, ref Digest digest)
{
Name = name;
Size = size;
Digest = digest;
}
}
}

View file

@ -5,7 +5,7 @@ namespace LibHac.Bcat.Detail.Ipc
public interface IDeliveryCacheDirectoryService
{
Result Open(ref DirectoryName name);
Result Read(ref int entriesRead, Span<DeliveryCacheDirectoryEntry> entryBuffer);
Result GetCount(ref int count);
Result Read(out int entriesRead, Span<DeliveryCacheDirectoryEntry> entryBuffer);
Result GetCount(out int count);
}
}

View file

@ -14,7 +14,7 @@ namespace LibHac.Bcat.Detail.Service.Core
private BcatServer Server { get; }
private object Locker { get; } = new object();
private DeliveryCacheFileMetaEntry[] Entries { get; } = new DeliveryCacheFileMetaEntry[MaxEntryCount];
private int Count { get; set; }
public int Count { get; private set; }
public DeliveryCacheFileMetaAccessor(BcatServer server)
{
@ -30,6 +30,21 @@ namespace LibHac.Bcat.Detail.Service.Core
return Read(new U8Span(metaPath), allowMissingMetaFile);
}
public Result GetEntry(out DeliveryCacheFileMetaEntry entry, int index)
{
lock (Locker)
{
if (index >= Count)
{
entry = default;
return ResultBcat.NotFound.Log();
}
entry = Entries[index];
return Result.Success;
}
}
public Result FindEntry(out DeliveryCacheFileMetaEntry entry, ref FileName fileName)
{
lock (Locker)

View file

@ -1,12 +1,13 @@
using System;
using LibHac.Bcat.Detail.Ipc;
using LibHac.Bcat.Detail.Service.Core;
namespace LibHac.Bcat.Detail.Service
{
internal class DeliveryCacheDirectoryService : IDeliveryCacheDirectoryService
internal class DeliveryCacheDirectoryService : IDeliveryCacheDirectoryService, IDisposable
{
private BcatServer Server { get; }
public object Locker { get; } = new object();
private object Locker { get; } = new object();
private DeliveryCacheStorageService Parent { get; }
private AccessControl Access { get; }
private ulong ApplicationId { get; }
@ -25,17 +26,78 @@ namespace LibHac.Bcat.Detail.Service
public Result Open(ref DirectoryName name)
{
throw new NotImplementedException();
if (!name.IsValid())
return ResultBcat.InvalidArgument.Log();
lock (Locker)
{
if (IsDirectoryOpen)
return ResultBcat.AlreadyOpen.Log();
var metaReader = new DeliveryCacheFileMetaAccessor(Server);
Result rc = metaReader.ReadApplicationFileMeta(ApplicationId, ref name, false);
if (rc.IsFailure()) return rc;
Count = metaReader.Count;
_name = name;
IsDirectoryOpen = true;
return Result.Success;
}
}
public Result Read(ref int entriesRead, Span<DeliveryCacheDirectoryEntry> entryBuffer)
public Result Read(out int entriesRead, Span<DeliveryCacheDirectoryEntry> entryBuffer)
{
throw new NotImplementedException();
lock (Locker)
{
entriesRead = default;
if (!IsDirectoryOpen)
return ResultBcat.NotOpen.Log();
var metaReader = new DeliveryCacheFileMetaAccessor(Server);
Result rc = metaReader.ReadApplicationFileMeta(ApplicationId, ref _name, true);
if (rc.IsFailure()) return rc;
int i;
for (i = 0; i < entryBuffer.Length; i++)
{
rc = metaReader.GetEntry(out DeliveryCacheFileMetaEntry entry, i);
if (rc.IsFailure())
{
if (!ResultBcat.NotFound.Includes(rc))
return rc;
break;
}
entryBuffer[i] = new DeliveryCacheDirectoryEntry(ref entry.Name, entry.Size, ref entry.Digest);
}
entriesRead = i;
return Result.Success;
}
}
public Result GetCount(ref int count)
public Result GetCount(out int count)
{
throw new NotImplementedException();
lock (Locker)
{
if (!IsDirectoryOpen)
{
count = default;
return ResultBcat.NotOpen.Log();
}
count = Count;
return Result.Success;
}
}
public void Dispose()
{
Parent.NotifyCloseDirectory();
}
}
}