mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-07-24 23:47:10 +02:00
Implement NGC service (#5681)
* Implement NGC service * Use raw byte arrays instead of string for _wordSeparators * Silence IDE0230 for _wordSeparators * Try to silence warning about _rangeValuesCount not being read on SparseSet * Make AcType enum private * Add abstract methods and one TODO that I forgot * PR feedback * More PR feedback * More PR feedback
This commit is contained in:
parent
4bd2ca3f0d
commit
01c2b8097c
44 changed files with 4630 additions and 4 deletions
132
src/Ryujinx.Horizon/Sdk/Ngc/Detail/SimilarFormTable.cs
Normal file
132
src/Ryujinx.Horizon/Sdk/Ngc/Detail/SimilarFormTable.cs
Normal file
|
@ -0,0 +1,132 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Ngc.Detail
|
||||
{
|
||||
class SimilarFormTable
|
||||
{
|
||||
private int _similarTableStringLength;
|
||||
private int _canonicalTableStringLength;
|
||||
private int _count;
|
||||
private byte[][] _similarTable;
|
||||
private byte[][] _canonicalTable;
|
||||
|
||||
public bool Import(ref BinaryReader reader)
|
||||
{
|
||||
if (!reader.Read(out _similarTableStringLength) ||
|
||||
!reader.Read(out _canonicalTableStringLength) ||
|
||||
!reader.Read(out _count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_similarTable = new byte[_count][];
|
||||
_canonicalTable = new byte[_count][];
|
||||
|
||||
if (_count < 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int tableIndex = 0; tableIndex < _count; tableIndex++)
|
||||
{
|
||||
if (reader.AllocateAndReadArray(ref _similarTable[tableIndex], _similarTableStringLength) != _similarTableStringLength ||
|
||||
reader.AllocateAndReadArray(ref _canonicalTable[tableIndex], _canonicalTableStringLength) != _canonicalTableStringLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> FindCanonicalString(ReadOnlySpan<byte> similarFormString)
|
||||
{
|
||||
int lowerBound = 0;
|
||||
int upperBound = _count;
|
||||
|
||||
for (int charIndex = 0; charIndex < similarFormString.Length; charIndex++)
|
||||
{
|
||||
byte character = similarFormString[charIndex];
|
||||
|
||||
int newLowerBound = GetLowerBound(character, charIndex, lowerBound - 1, upperBound - 1);
|
||||
if (newLowerBound < 0 || _similarTable[newLowerBound][charIndex] != character)
|
||||
{
|
||||
return ReadOnlySpan<byte>.Empty;
|
||||
}
|
||||
|
||||
int newUpperBound = GetUpperBound(character, charIndex, lowerBound - 1, upperBound - 1);
|
||||
if (newUpperBound < 0)
|
||||
{
|
||||
newUpperBound = upperBound;
|
||||
}
|
||||
|
||||
lowerBound = newLowerBound;
|
||||
upperBound = newUpperBound;
|
||||
}
|
||||
|
||||
return _canonicalTable[lowerBound];
|
||||
}
|
||||
|
||||
private int GetLowerBound(byte character, int charIndex, int left, int right)
|
||||
{
|
||||
while (right - left > 1)
|
||||
{
|
||||
int range = right + left;
|
||||
|
||||
if (range < 0)
|
||||
{
|
||||
range++;
|
||||
}
|
||||
|
||||
int middle = range / 2;
|
||||
|
||||
if (character <= _similarTable[middle][charIndex])
|
||||
{
|
||||
right = middle;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = middle;
|
||||
}
|
||||
}
|
||||
|
||||
if (_similarTable[right][charIndex] < character)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return right;
|
||||
}
|
||||
|
||||
private int GetUpperBound(byte character, int charIndex, int left, int right)
|
||||
{
|
||||
while (right - left > 1)
|
||||
{
|
||||
int range = right + left;
|
||||
|
||||
if (range < 0)
|
||||
{
|
||||
range++;
|
||||
}
|
||||
|
||||
int middle = range / 2;
|
||||
|
||||
if (_similarTable[middle][charIndex] <= character)
|
||||
{
|
||||
left = middle;
|
||||
}
|
||||
else
|
||||
{
|
||||
right = middle;
|
||||
}
|
||||
}
|
||||
|
||||
if (_similarTable[right][charIndex] <= character)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return right;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue