Add ProgramIndexMapInfoManager

This commit is contained in:
Alex Barney 2020-08-21 18:47:58 -07:00
parent 004e46cacc
commit 0b050d2189
3 changed files with 131 additions and 0 deletions

View file

@ -0,0 +1,13 @@
using System.Runtime.InteropServices;
using LibHac.Ncm;
namespace LibHac.Fs
{
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
public struct ProgramIndexMapInfo
{
[FieldOffset(0x00)] public ProgramId ProgramId;
[FieldOffset(0x08)] public ProgramId MainProgramId;
[FieldOffset(0x10)] public byte ProgramIndex;
}
}

View file

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using LibHac.Fs;
using LibHac.Ncm;
namespace LibHac.FsSrv
{
public class ProgramIndexMapInfoManager
{
private LinkedList<ProgramIndexMapInfo> MapEntries { get; } = new LinkedList<ProgramIndexMapInfo>();
/// <summary>
/// Clears any existing
/// </summary>
/// <param name="entries">The entries </param>
/// <returns><see cref="Result.Success"/>: The operation was successful.</returns>
public Result Reset(ReadOnlySpan<ProgramIndexMapInfo> entries)
{
lock (MapEntries)
{
ClearImpl();
for (int i = 0; i < entries.Length; i++)
{
MapEntries.AddLast(entries[i]);
}
return Result.Success;
}
}
public void Clear()
{
lock (MapEntries)
{
ClearImpl();
}
}
public ProgramIndexMapInfo? Get(ProgramId programId)
{
lock (MapEntries)
{
return GetImpl((in ProgramIndexMapInfo x) => x.ProgramId == programId);
}
}
/// <summary>
/// Gets the <see cref="ProgramId"/> of the program with index <paramref name="programIndex"/> in the
/// multi-program app <paramref name="programId"/> is part of.
/// </summary>
/// <param name="programId">A program ID in the multi-program app to query.</param>
/// <param name="programIndex">The index of the program to get.</param>
/// <returns>If the program exists, the ID of the program with the specified index,
/// otherwise <see cref="ProgramId.InvalidId"/></returns>
public ProgramId GetProgramId(ProgramId programId, byte programIndex)
{
lock (MapEntries)
{
ProgramIndexMapInfo? mainProgramMapInfo = GetImpl((in ProgramIndexMapInfo x) => x.ProgramId == programId);
if(!mainProgramMapInfo.HasValue)
return ProgramId.InvalidId;
ProgramIndexMapInfo? requestedMapInfo = GetImpl((in ProgramIndexMapInfo x) =>
x.MainProgramId == mainProgramMapInfo.Value.MainProgramId && x.ProgramIndex == programIndex);
if (!requestedMapInfo.HasValue)
return ProgramId.InvalidId;
return requestedMapInfo.Value.ProgramId;
}
}
public int GetProgramCount()
{
lock (MapEntries)
{
return MapEntries.Count;
}
}
private delegate bool EntrySelector(in ProgramIndexMapInfo candidate);
private ProgramIndexMapInfo? GetImpl(EntrySelector selector)
{
foreach (ProgramIndexMapInfo entry in MapEntries)
{
if (selector(in entry))
{
return entry;
}
}
return null;
}
private void ClearImpl()
{
MapEntries.Clear();
}
}
}

View file

@ -8,10 +8,12 @@ namespace LibHac.FsSrv
public class ProgramRegistryServiceImpl public class ProgramRegistryServiceImpl
{ {
private ProgramRegistryManager RegistryManager { get; } private ProgramRegistryManager RegistryManager { get; }
private ProgramIndexMapInfoManager ProgramIndexManager { get; }
public ProgramRegistryServiceImpl(FileSystemServer fsServer) public ProgramRegistryServiceImpl(FileSystemServer fsServer)
{ {
RegistryManager = new ProgramRegistryManager(fsServer); RegistryManager = new ProgramRegistryManager(fsServer);
ProgramIndexManager = new ProgramIndexMapInfoManager();
} }
/// <summary> /// <summary>
@ -67,5 +69,18 @@ namespace LibHac.FsSrv
{ {
return RegistryManager.GetProgramInfoByProgramId(out programInfo, programId); return RegistryManager.GetProgramInfoByProgramId(out programInfo, programId);
} }
/// <summary>
/// Gets the <see cref="ProgramId"/> of the program with index <paramref name="programIndex"/> in the
/// multi-program app <paramref name="programId"/> is part of.
/// </summary>
/// <param name="programId">A program ID in the multi-program app to query.</param>
/// <param name="programIndex">The index of the program to get.</param>
/// <returns>If the program exists, the ID of the program with the specified index,
/// otherwise <see cref="ProgramId.InvalidId"/></returns>
public ProgramId GetProgramId(ProgramId programId, byte programIndex)
{
return ProgramIndexManager.GetProgramId(programId, programIndex);
}
} }
} }