Compare commits

..

11 Commits
1.2.1 ... 1.3.2

Author SHA1 Message Date
Matt Nadareski
3f9b09b943 Bump version 2023-12-05 11:04:02 -05:00
Matt Nadareski
2b1ee393d4 Fix some formatting issues 2023-12-04 14:33:56 -05:00
Matt Nadareski
887c443a17 Correct log statement for universal hash 2023-12-04 14:15:36 -05:00
Matt Nadareski
5ad9bebf88 Bump version 2023-11-22 23:13:09 -05:00
Matt Nadareski
8c8e624ac2 Update compatiblity libraries 2023-11-22 23:12:44 -05:00
Matt Nadareski
d7b2d13d8b Bump version 2023-11-22 10:12:09 -05:00
Matt Nadareski
8c8ae49a3b Support .NET Framework 2.0 2023-11-22 10:11:56 -05:00
Matt Nadareski
b77eec5063 Use different set of libraries 2023-11-22 09:44:04 -05:00
Matt Nadareski
5d992566b5 Update SabreTools.Models 2023-11-22 09:42:15 -05:00
Matt Nadareski
46bde960f3 Perform some prep for .NET Framework 3.5 2023-11-20 21:45:27 -05:00
Matt Nadareski
ba2c3a592f Support async in .NET Framework 4.0 2023-11-20 21:18:36 -05:00
8 changed files with 547 additions and 92 deletions

View File

@@ -23,7 +23,7 @@ namespace SabreTools.RedumpLib.Attributes
// If the value returns a null on ToString, just return null
string? valueStr = value?.ToString();
if (string.IsNullOrWhiteSpace(valueStr))
if (string.IsNullOrEmpty(valueStr))
return null;
// Get the member info array

View File

@@ -25,7 +25,7 @@ namespace SabreTools.RedumpLib
public static SubmissionInfo? CreateFromFile(string? path)
{
// If the path is invalid
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return null;
// If the file doesn't exist
@@ -61,7 +61,7 @@ namespace SabreTools.RedumpLib
};
// No disc data means we can't parse it
if (string.IsNullOrWhiteSpace(discData))
if (string.IsNullOrEmpty(discData))
return null;
try
@@ -250,9 +250,7 @@ namespace SabreTools.RedumpLib
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="id">Redump disc ID to retrieve</param>
/// <param name="includeAllData">True to include all pullable information, false to do bare minimum</param>
#if NET40
public static bool FillFromId(RedumpWebClient wc, SubmissionInfo info, int id, bool includeAllData)
#elif NETFRAMEWORK
#if NETFRAMEWORK
public async static Task<bool> FillFromId(RedumpWebClient wc, SubmissionInfo info, int id, bool includeAllData)
#else
public async static Task<bool> FillFromId(RedumpHttpClient wc, SubmissionInfo info, int id, bool includeAllData)
@@ -261,7 +259,7 @@ namespace SabreTools.RedumpLib
// Ensure that required sections exist
info = EnsureAllSections(info);
#if NET40
var discData = wc.DownloadSingleSiteID(id);
var discData = await Task.Factory.StartNew(() => wc.DownloadSingleSiteID(id));
#elif NETFRAMEWORK
var discData = await Task.Run(() => wc.DownloadSingleSiteID(id));
#else
@@ -274,11 +272,11 @@ namespace SabreTools.RedumpLib
var match = Constants.TitleRegex.Match(discData);
if (match.Success)
{
string title = WebUtility.HtmlDecode(match.Groups[1].Value);
string? title = WebUtility.HtmlDecode(match.Groups[1].Value);
// If we have parenthesis, title is everything before the first one
int firstParenLocation = title.IndexOf(" (");
if (firstParenLocation >= 0)
int firstParenLocation = title?.IndexOf(" (") ?? -1;
if (title != null && firstParenLocation >= 0)
{
info.CommonDiscInfo!.Title = title.Substring(0, firstParenLocation);
var subMatches = Constants.DiscNumberLetterRegex.Matches(title);
@@ -380,7 +378,9 @@ namespace SabreTools.RedumpLib
foreach (Match submatch in matches.Cast<Match>())
{
tempDumpers.Add(WebUtility.HtmlDecode(submatch.Groups[1].Value));
string? dumper = WebUtility.HtmlDecode(submatch.Groups[1].Value);
if (dumper != null)
tempDumpers.Add(dumper);
}
info.DumpersAndStatus.Dumpers = [.. tempDumpers];
@@ -397,7 +397,7 @@ namespace SabreTools.RedumpLib
// Process the old comments block
string oldComments = info.CommonDiscInfo.Comments
+ (string.IsNullOrEmpty(info.CommonDiscInfo.Comments) ? string.Empty : "\n")
+ WebUtility.HtmlDecode(match.Groups[1].Value)
+ (WebUtility.HtmlDecode(match.Groups[1].Value) ?? string.Empty)
.Replace("\r\n", "\n")
.Replace("<br />\n", "\n")
.Replace("<br />", string.Empty)
@@ -418,7 +418,7 @@ namespace SabreTools.RedumpLib
string commentLine = commentsSeparated[i].Trim();
// If we have an empty line, we want to treat this as intentional
if (string.IsNullOrWhiteSpace(commentLine))
if (string.IsNullOrEmpty(commentLine))
{
addToLast = false;
lastSiteCode = null;
@@ -496,7 +496,7 @@ namespace SabreTools.RedumpLib
{
if (addToLast && lastSiteCode != null)
{
if (!string.IsNullOrWhiteSpace(info.CommonDiscInfo.CommentsSpecialFields![lastSiteCode.Value]))
if (!string.IsNullOrEmpty(info.CommonDiscInfo.CommentsSpecialFields![lastSiteCode.Value]))
info.CommonDiscInfo.CommentsSpecialFields[lastSiteCode.Value] += "\n";
info.CommonDiscInfo.CommentsSpecialFields[lastSiteCode.Value] += commentLine;
@@ -522,7 +522,7 @@ namespace SabreTools.RedumpLib
// Process the old contents block
string oldContents = info.CommonDiscInfo.Contents
+ (string.IsNullOrEmpty(info.CommonDiscInfo.Contents) ? string.Empty : "\n")
+ WebUtility.HtmlDecode(match.Groups[1].Value)
+ (WebUtility.HtmlDecode(match.Groups[1].Value) ?? string.Empty)
.Replace("\r\n", "\n")
.Replace("<br />\n", "\n")
.Replace("<br />", string.Empty)
@@ -543,7 +543,7 @@ namespace SabreTools.RedumpLib
string contentLine = contentsSeparated[i].Trim();
// If we have an empty line, we want to treat this as intentional
if (string.IsNullOrWhiteSpace(contentLine))
if (string.IsNullOrEmpty(contentLine))
{
addToLast = false;
lastSiteCode = null;
@@ -584,7 +584,7 @@ namespace SabreTools.RedumpLib
{
if (addToLast && lastSiteCode != null)
{
if (!string.IsNullOrWhiteSpace(info.CommonDiscInfo.ContentsSpecialFields![lastSiteCode.Value]))
if (!string.IsNullOrEmpty(info.CommonDiscInfo.ContentsSpecialFields![lastSiteCode.Value]))
info.CommonDiscInfo.ContentsSpecialFields[lastSiteCode.Value] += "\n";
info.CommonDiscInfo.ContentsSpecialFields[lastSiteCode.Value] += contentLine;
@@ -670,19 +670,19 @@ namespace SabreTools.RedumpLib
if (info.CommonDiscInfo != null && seed.CommonDiscInfo != null)
{
// Info that only overwrites if supplied
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.Title)) info.CommonDiscInfo.Title = seed.CommonDiscInfo.Title;
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.ForeignTitleNonLatin)) info.CommonDiscInfo.ForeignTitleNonLatin = seed.CommonDiscInfo.ForeignTitleNonLatin;
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.DiscNumberLetter)) info.CommonDiscInfo.DiscNumberLetter = seed.CommonDiscInfo.DiscNumberLetter;
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.DiscTitle)) info.CommonDiscInfo.DiscTitle = seed.CommonDiscInfo.DiscTitle;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Title)) info.CommonDiscInfo.Title = seed.CommonDiscInfo.Title;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.ForeignTitleNonLatin)) info.CommonDiscInfo.ForeignTitleNonLatin = seed.CommonDiscInfo.ForeignTitleNonLatin;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.DiscNumberLetter)) info.CommonDiscInfo.DiscNumberLetter = seed.CommonDiscInfo.DiscNumberLetter;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.DiscTitle)) info.CommonDiscInfo.DiscTitle = seed.CommonDiscInfo.DiscTitle;
if (seed.CommonDiscInfo.Category != null) info.CommonDiscInfo.Category = seed.CommonDiscInfo.Category;
if (seed.CommonDiscInfo.Region != null) info.CommonDiscInfo.Region = seed.CommonDiscInfo.Region;
if (seed.CommonDiscInfo.Languages != null) info.CommonDiscInfo.Languages = seed.CommonDiscInfo.Languages;
if (seed.CommonDiscInfo.LanguageSelection != null) info.CommonDiscInfo.LanguageSelection = seed.CommonDiscInfo.LanguageSelection;
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.Serial)) info.CommonDiscInfo.Serial = seed.CommonDiscInfo.Serial;
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.Barcode)) info.CommonDiscInfo.Barcode = seed.CommonDiscInfo.Barcode;
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.Comments)) info.CommonDiscInfo.Comments = seed.CommonDiscInfo.Comments;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Serial)) info.CommonDiscInfo.Serial = seed.CommonDiscInfo.Serial;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Barcode)) info.CommonDiscInfo.Barcode = seed.CommonDiscInfo.Barcode;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Comments)) info.CommonDiscInfo.Comments = seed.CommonDiscInfo.Comments;
if (seed.CommonDiscInfo.CommentsSpecialFields != null) info.CommonDiscInfo.CommentsSpecialFields = seed.CommonDiscInfo.CommentsSpecialFields;
if (!string.IsNullOrWhiteSpace(seed.CommonDiscInfo.Contents)) info.CommonDiscInfo.Contents = seed.CommonDiscInfo.Contents;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Contents)) info.CommonDiscInfo.Contents = seed.CommonDiscInfo.Contents;
if (seed.CommonDiscInfo.ContentsSpecialFields != null) info.CommonDiscInfo.ContentsSpecialFields = seed.CommonDiscInfo.ContentsSpecialFields;
// Info that always overwrites
@@ -710,14 +710,14 @@ namespace SabreTools.RedumpLib
if (info.VersionAndEditions != null && seed.VersionAndEditions != null)
{
// Info that only overwrites if supplied
if (!string.IsNullOrWhiteSpace(seed.VersionAndEditions.Version)) info.VersionAndEditions.Version = seed.VersionAndEditions.Version;
if (!string.IsNullOrWhiteSpace(seed.VersionAndEditions.OtherEditions)) info.VersionAndEditions.OtherEditions = seed.VersionAndEditions.OtherEditions;
if (!string.IsNullOrEmpty(seed.VersionAndEditions.Version)) info.VersionAndEditions.Version = seed.VersionAndEditions.Version;
if (!string.IsNullOrEmpty(seed.VersionAndEditions.OtherEditions)) info.VersionAndEditions.OtherEditions = seed.VersionAndEditions.OtherEditions;
}
if (info.CopyProtection != null && seed.CopyProtection != null)
{
// Info that only overwrites if supplied
if (!string.IsNullOrWhiteSpace(seed.CopyProtection.Protection)) info.CopyProtection.Protection = seed.CopyProtection.Protection;
if (!string.IsNullOrEmpty(seed.CopyProtection.Protection)) info.CopyProtection.Protection = seed.CopyProtection.Protection;
}
}
@@ -732,7 +732,7 @@ namespace SabreTools.RedumpLib
/// <returns>Processed text block, if possible</returns>
private static string ReplaceHtmlWithSiteCodes(this string text)
{
if (string.IsNullOrWhiteSpace(text))
if (string.IsNullOrEmpty(text))
return text;
foreach (SiteCode? siteCode in Enum.GetValues(typeof(SiteCode)))

View File

@@ -173,11 +173,11 @@ namespace SabreTools.RedumpLib
}
// Copy Protection section
if (!string.IsNullOrWhiteSpace(info.CopyProtection?.Protection)
if (!string.IsNullOrEmpty(info.CopyProtection?.Protection)
|| (info.CopyProtection?.AntiModchip != null && info.CopyProtection.AntiModchip != YesNo.NULL)
|| (info.CopyProtection?.LibCrypt != null && info.CopyProtection.LibCrypt != YesNo.NULL)
|| !string.IsNullOrWhiteSpace(info.CopyProtection?.LibCryptData)
|| !string.IsNullOrWhiteSpace(info.CopyProtection?.SecuROMData))
|| !string.IsNullOrEmpty(info.CopyProtection?.LibCryptData)
|| !string.IsNullOrEmpty(info.CopyProtection?.SecuROMData))
{
output.Add(""); output.Add("Copy Protection:");
if (info.CommonDiscInfo?.System == RedumpSystem.SonyPlayStation)
@@ -197,7 +197,7 @@ namespace SabreTools.RedumpLib
// AddIfExists(output, Template.OtherDumpersField, info.OtherDumpers);
// Tracks and Write Offsets section
if (!string.IsNullOrWhiteSpace(info.TracksAndWriteOffsets?.ClrMameProData))
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets?.ClrMameProData))
{
output.Add(""); output.Add("Tracks and Write Offsets:");
AddIfExists(output, Template.DATField, info.TracksAndWriteOffsets!.ClrMameProData + "\n", 1);
@@ -240,7 +240,7 @@ namespace SabreTools.RedumpLib
string? last = null;
for (int i = 0; i < output.Count;)
{
if (output[i] == last && string.IsNullOrWhiteSpace(last))
if (output[i] == last && string.IsNullOrEmpty(last))
{
output.RemoveAt(i);
}
@@ -279,9 +279,10 @@ namespace SabreTools.RedumpLib
// Add all special fields before any comments
info.CommonDiscInfo.Comments = string.Join(
"\n", OrderCommentTags(info.CommonDiscInfo.CommentsSpecialFields)
.Where(kvp => !string.IsNullOrWhiteSpace(kvp.Value))
.Where(kvp => !string.IsNullOrEmpty(kvp.Value))
.Select(FormatSiteTag)
.Where(s => !string.IsNullOrEmpty(s))
.ToArray()
) + "\n" + info.CommonDiscInfo.Comments;
// Normalize newlines
@@ -304,9 +305,10 @@ namespace SabreTools.RedumpLib
// Add all special fields before any contents
info.CommonDiscInfo.Contents = string.Join(
"\n", OrderContentTags(info.CommonDiscInfo.ContentsSpecialFields)
.Where(kvp => !string.IsNullOrWhiteSpace(kvp.Value))
.Where(kvp => !string.IsNullOrEmpty(kvp.Value))
.Select(FormatSiteTag)
.Where(s => !string.IsNullOrEmpty(s))
.ToArray()
) + "\n" + info.CommonDiscInfo.Contents;
// Normalize newlines
@@ -421,7 +423,7 @@ namespace SabreTools.RedumpLib
if (value == null || value.Count == 0)
return;
AddIfExists(output, key, string.Join(", ", value.Select(o => o.ToString())), indent);
AddIfExists(output, key, string.Join(", ", value.Select(o => o.ToString()).ToArray()), indent);
}
/// <summary>

461
OldDotNet.cs Normal file
View File

@@ -0,0 +1,461 @@
#if NET20 || NET35
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace SabreTools.RedumpLib
{
/// <see href="https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs"/>
internal static class WebUtility
{
// some consts copied from Char / CharUnicodeInfo since we don't have friend access to those types
private const char HIGH_SURROGATE_START = '\uD800';
private const char LOW_SURROGATE_START = '\uDC00';
private const char LOW_SURROGATE_END = '\uDFFF';
private const int UNICODE_PLANE00_END = 0x00FFFF;
private const int UNICODE_PLANE01_START = 0x10000;
private const int UNICODE_PLANE16_END = 0x10FFFF;
public static string? HtmlDecode(string? value)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
char[] valueSpan = value!.ToCharArray();
int index = Array.IndexOf(valueSpan, '&');
if (index < 0)
{
return value;
}
// In the worst case the decoded string has the same length.
// For small inputs we use stack allocation.
StringBuilder sb = value.Length <= 256 ?
new StringBuilder(256) :
new StringBuilder(value.Length);
sb.Append(valueSpan.Take(index).ToArray());
HtmlDecode(valueSpan.Skip(index).ToArray(), ref sb);
return sb.ToString();
}
private static void HtmlDecode(char[] input, ref StringBuilder output)
{
for (int i = 0; i < input.Length; i++)
{
char ch = input[i];
if (ch == '&')
{
// We found a '&'. Now look for the next ';' or '&'. The idea is that
// if we find another '&' before finding a ';', then this is not an entity,
// and the next '&' might start a real entity (VSWhidbey 275184)
char[] inputSlice = input.Skip(i + 1).ToArray();
int semicolonPos = Array.IndexOf(inputSlice, ';');
int ampersandPos = Array.IndexOf(inputSlice, '&');
int entityLength;
if (semicolonPos > -1 && ampersandPos > -1)
entityLength = Math.Min(semicolonPos, ampersandPos);
else if (semicolonPos <= -1 && ampersandPos > -1)
entityLength = ampersandPos;
else if (semicolonPos > -1 && ampersandPos <= -1)
entityLength = semicolonPos;
else
entityLength = -1;
if (entityLength >= 0 && inputSlice[entityLength] == ';')
{
int entityEndPosition = (i + 1) + entityLength;
if (entityLength > 1 && inputSlice[0] == '#')
{
// The # syntax can be in decimal or hex, e.g.
// &#229; --> decimal
// &#xE5; --> same char in hex
// See http://www.w3.org/TR/REC-html40/charset.html#entities
bool parsedSuccessfully = inputSlice[1] == 'x' || inputSlice[1] == 'X'
? uint.TryParse(new string(inputSlice.Skip(2).Take(entityLength - 2).ToArray()), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out uint parsedValue)
: uint.TryParse(new string(inputSlice.Skip(1).Take(entityLength - 1).ToArray()), NumberStyles.Integer, CultureInfo.InvariantCulture, out parsedValue);
if (parsedSuccessfully)
{
// decoded character must be U+0000 .. U+10FFFF, excluding surrogates
parsedSuccessfully = ((parsedValue < HIGH_SURROGATE_START) || (LOW_SURROGATE_END < parsedValue && parsedValue <= UNICODE_PLANE16_END));
}
if (parsedSuccessfully)
{
if (parsedValue <= UNICODE_PLANE00_END)
{
// single character
output.Append((char)parsedValue);
}
else
{
// multi-character
ConvertSmpToUtf16(parsedValue, out char leadingSurrogate, out char trailingSurrogate);
output.Append(leadingSurrogate);
output.Append(trailingSurrogate);
}
i = entityEndPosition; // already looked at everything until semicolon
continue;
}
}
else
{
char[] entity = inputSlice.Take(entityLength).ToArray();
i = entityEndPosition; // already looked at everything until semicolon
char entityChar = HtmlEntities.Lookup(entity);
if (entityChar != (char)0)
{
ch = entityChar;
}
else
{
output.Append('&');
output.Append(entity);
output.Append(';');
continue;
}
}
}
}
output.Append(ch);
}
}
// similar to Char.ConvertFromUtf32, but doesn't check arguments or generate strings
// input is assumed to be an SMP character
private static void ConvertSmpToUtf16(uint smpChar, out char leadingSurrogate, out char trailingSurrogate)
{
int utf32 = (int)(smpChar - UNICODE_PLANE01_START);
leadingSurrogate = (char)((utf32 / 0x400) + HIGH_SURROGATE_START);
trailingSurrogate = (char)((utf32 % 0x400) + LOW_SURROGATE_START);
}
// helper class for lookup of HTML encoding entities
private static class HtmlEntities
{
// The list is from http://www.w3.org/TR/REC-html40/sgml/entities.html, except for &apos;, which
// is defined in http://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent.
private static Dictionary<ulong, char> InitializeLookupTable()
{
byte[] tableData =
[
0x74, 0x6F, 0x75, 0x71, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("quot")*/ 0x22, 0x00, /*'\x0022'*/
0x70, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("amp")*/ 0x26, 0x00, /*'\x0026'*/
0x73, 0x6F, 0x70, 0x61, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("apos")*/ 0x27, 0x00, /*'\x0027'*/
0x74, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("lt")*/ 0x3C, 0x00, /*'\x003c'*/
0x74, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("gt")*/ 0x3E, 0x00, /*'\x003e'*/
0x70, 0x73, 0x62, 0x6E, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("nbsp")*/ 0xA0, 0x00, /*'\x00a0'*/
0x6C, 0x63, 0x78, 0x65, 0x69, 0x00, 0x00, 0x00, /*ToUInt64Key("iexcl")*/ 0xA1, 0x00, /*'\x00a1'*/
0x74, 0x6E, 0x65, 0x63, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("cent")*/ 0xA2, 0x00, /*'\x00a2'*/
0x64, 0x6E, 0x75, 0x6F, 0x70, 0x00, 0x00, 0x00, /*ToUInt64Key("pound")*/ 0xA3, 0x00, /*'\x00a3'*/
0x6E, 0x65, 0x72, 0x72, 0x75, 0x63, 0x00, 0x00, /*ToUInt64Key("curren")*/ 0xA4, 0x00, /*'\x00a4'*/
0x6E, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("yen")*/ 0xA5, 0x00, /*'\x00a5'*/
0x72, 0x61, 0x62, 0x76, 0x72, 0x62, 0x00, 0x00, /*ToUInt64Key("brvbar")*/ 0xA6, 0x00, /*'\x00a6'*/
0x74, 0x63, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sect")*/ 0xA7, 0x00, /*'\x00a7'*/
0x6C, 0x6D, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("uml")*/ 0xA8, 0x00, /*'\x00a8'*/
0x79, 0x70, 0x6F, 0x63, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("copy")*/ 0xA9, 0x00, /*'\x00a9'*/
0x66, 0x64, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ordf")*/ 0xAA, 0x00, /*'\x00aa'*/
0x6F, 0x75, 0x71, 0x61, 0x6C, 0x00, 0x00, 0x00, /*ToUInt64Key("laquo")*/ 0xAB, 0x00, /*'\x00ab'*/
0x74, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("not")*/ 0xAC, 0x00, /*'\x00ac'*/
0x79, 0x68, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("shy")*/ 0xAD, 0x00, /*'\x00ad'*/
0x67, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("reg")*/ 0xAE, 0x00, /*'\x00ae'*/
0x72, 0x63, 0x61, 0x6D, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("macr")*/ 0xAF, 0x00, /*'\x00af'*/
0x67, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("deg")*/ 0xB0, 0x00, /*'\x00b0'*/
0x6E, 0x6D, 0x73, 0x75, 0x6C, 0x70, 0x00, 0x00, /*ToUInt64Key("plusmn")*/ 0xB1, 0x00, /*'\x00b1'*/
0x32, 0x70, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sup2")*/ 0xB2, 0x00, /*'\x00b2'*/
0x33, 0x70, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sup3")*/ 0xB3, 0x00, /*'\x00b3'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x00, 0x00, 0x00, /*ToUInt64Key("acute")*/ 0xB4, 0x00, /*'\x00b4'*/
0x6F, 0x72, 0x63, 0x69, 0x6D, 0x00, 0x00, 0x00, /*ToUInt64Key("micro")*/ 0xB5, 0x00, /*'\x00b5'*/
0x61, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("para")*/ 0xB6, 0x00, /*'\x00b6'*/
0x74, 0x6F, 0x64, 0x64, 0x69, 0x6D, 0x00, 0x00, /*ToUInt64Key("middot")*/ 0xB7, 0x00, /*'\x00b7'*/
0x6C, 0x69, 0x64, 0x65, 0x63, 0x00, 0x00, 0x00, /*ToUInt64Key("cedil")*/ 0xB8, 0x00, /*'\x00b8'*/
0x31, 0x70, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sup1")*/ 0xB9, 0x00, /*'\x00b9'*/
0x6D, 0x64, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ordm")*/ 0xBA, 0x00, /*'\x00ba'*/
0x6F, 0x75, 0x71, 0x61, 0x72, 0x00, 0x00, 0x00, /*ToUInt64Key("raquo")*/ 0xBB, 0x00, /*'\x00bb'*/
0x34, 0x31, 0x63, 0x61, 0x72, 0x66, 0x00, 0x00, /*ToUInt64Key("frac14")*/ 0xBC, 0x00, /*'\x00bc'*/
0x32, 0x31, 0x63, 0x61, 0x72, 0x66, 0x00, 0x00, /*ToUInt64Key("frac12")*/ 0xBD, 0x00, /*'\x00bd'*/
0x34, 0x33, 0x63, 0x61, 0x72, 0x66, 0x00, 0x00, /*ToUInt64Key("frac34")*/ 0xBE, 0x00, /*'\x00be'*/
0x74, 0x73, 0x65, 0x75, 0x71, 0x69, 0x00, 0x00, /*ToUInt64Key("iquest")*/ 0xBF, 0x00, /*'\x00bf'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x41, 0x00, 0x00, /*ToUInt64Key("Agrave")*/ 0xC0, 0x00, /*'\x00c0'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x41, 0x00, 0x00, /*ToUInt64Key("Aacute")*/ 0xC1, 0x00, /*'\x00c1'*/
0x63, 0x72, 0x69, 0x63, 0x41, 0x00, 0x00, 0x00, /*ToUInt64Key("Acirc")*/ 0xC2, 0x00, /*'\x00c2'*/
0x65, 0x64, 0x6C, 0x69, 0x74, 0x41, 0x00, 0x00, /*ToUInt64Key("Atilde")*/ 0xC3, 0x00, /*'\x00c3'*/
0x6C, 0x6D, 0x75, 0x41, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Auml")*/ 0xC4, 0x00, /*'\x00c4'*/
0x67, 0x6E, 0x69, 0x72, 0x41, 0x00, 0x00, 0x00, /*ToUInt64Key("Aring")*/ 0xC5, 0x00, /*'\x00c5'*/
0x67, 0x69, 0x6C, 0x45, 0x41, 0x00, 0x00, 0x00, /*ToUInt64Key("AElig")*/ 0xC6, 0x00, /*'\x00c6'*/
0x6C, 0x69, 0x64, 0x65, 0x63, 0x43, 0x00, 0x00, /*ToUInt64Key("Ccedil")*/ 0xC7, 0x00, /*'\x00c7'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x45, 0x00, 0x00, /*ToUInt64Key("Egrave")*/ 0xC8, 0x00, /*'\x00c8'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x45, 0x00, 0x00, /*ToUInt64Key("Eacute")*/ 0xC9, 0x00, /*'\x00c9'*/
0x63, 0x72, 0x69, 0x63, 0x45, 0x00, 0x00, 0x00, /*ToUInt64Key("Ecirc")*/ 0xCA, 0x00, /*'\x00ca'*/
0x6C, 0x6D, 0x75, 0x45, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Euml")*/ 0xCB, 0x00, /*'\x00cb'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x49, 0x00, 0x00, /*ToUInt64Key("Igrave")*/ 0xCC, 0x00, /*'\x00cc'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x49, 0x00, 0x00, /*ToUInt64Key("Iacute")*/ 0xCD, 0x00, /*'\x00cd'*/
0x63, 0x72, 0x69, 0x63, 0x49, 0x00, 0x00, 0x00, /*ToUInt64Key("Icirc")*/ 0xCE, 0x00, /*'\x00ce'*/
0x6C, 0x6D, 0x75, 0x49, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Iuml")*/ 0xCF, 0x00, /*'\x00cf'*/
0x48, 0x54, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ETH")*/ 0xD0, 0x00, /*'\x00d0'*/
0x65, 0x64, 0x6C, 0x69, 0x74, 0x4E, 0x00, 0x00, /*ToUInt64Key("Ntilde")*/ 0xD1, 0x00, /*'\x00d1'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x4F, 0x00, 0x00, /*ToUInt64Key("Ograve")*/ 0xD2, 0x00, /*'\x00d2'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x4F, 0x00, 0x00, /*ToUInt64Key("Oacute")*/ 0xD3, 0x00, /*'\x00d3'*/
0x63, 0x72, 0x69, 0x63, 0x4F, 0x00, 0x00, 0x00, /*ToUInt64Key("Ocirc")*/ 0xD4, 0x00, /*'\x00d4'*/
0x65, 0x64, 0x6C, 0x69, 0x74, 0x4F, 0x00, 0x00, /*ToUInt64Key("Otilde")*/ 0xD5, 0x00, /*'\x00d5'*/
0x6C, 0x6D, 0x75, 0x4F, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Ouml")*/ 0xD6, 0x00, /*'\x00d6'*/
0x73, 0x65, 0x6D, 0x69, 0x74, 0x00, 0x00, 0x00, /*ToUInt64Key("times")*/ 0xD7, 0x00, /*'\x00d7'*/
0x68, 0x73, 0x61, 0x6C, 0x73, 0x4F, 0x00, 0x00, /*ToUInt64Key("Oslash")*/ 0xD8, 0x00, /*'\x00d8'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x55, 0x00, 0x00, /*ToUInt64Key("Ugrave")*/ 0xD9, 0x00, /*'\x00d9'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x55, 0x00, 0x00, /*ToUInt64Key("Uacute")*/ 0xDA, 0x00, /*'\x00da'*/
0x63, 0x72, 0x69, 0x63, 0x55, 0x00, 0x00, 0x00, /*ToUInt64Key("Ucirc")*/ 0xDB, 0x00, /*'\x00db'*/
0x6C, 0x6D, 0x75, 0x55, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Uuml")*/ 0xDC, 0x00, /*'\x00dc'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x59, 0x00, 0x00, /*ToUInt64Key("Yacute")*/ 0xDD, 0x00, /*'\x00dd'*/
0x4E, 0x52, 0x4F, 0x48, 0x54, 0x00, 0x00, 0x00, /*ToUInt64Key("THORN")*/ 0xDE, 0x00, /*'\x00de'*/
0x67, 0x69, 0x6C, 0x7A, 0x73, 0x00, 0x00, 0x00, /*ToUInt64Key("szlig")*/ 0xDF, 0x00, /*'\x00df'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x61, 0x00, 0x00, /*ToUInt64Key("agrave")*/ 0xE0, 0x00, /*'\x00e0'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x61, 0x00, 0x00, /*ToUInt64Key("aacute")*/ 0xE1, 0x00, /*'\x00e1'*/
0x63, 0x72, 0x69, 0x63, 0x61, 0x00, 0x00, 0x00, /*ToUInt64Key("acirc")*/ 0xE2, 0x00, /*'\x00e2'*/
0x65, 0x64, 0x6C, 0x69, 0x74, 0x61, 0x00, 0x00, /*ToUInt64Key("atilde")*/ 0xE3, 0x00, /*'\x00e3'*/
0x6C, 0x6D, 0x75, 0x61, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("auml")*/ 0xE4, 0x00, /*'\x00e4'*/
0x67, 0x6E, 0x69, 0x72, 0x61, 0x00, 0x00, 0x00, /*ToUInt64Key("aring")*/ 0xE5, 0x00, /*'\x00e5'*/
0x67, 0x69, 0x6C, 0x65, 0x61, 0x00, 0x00, 0x00, /*ToUInt64Key("aelig")*/ 0xE6, 0x00, /*'\x00e6'*/
0x6C, 0x69, 0x64, 0x65, 0x63, 0x63, 0x00, 0x00, /*ToUInt64Key("ccedil")*/ 0xE7, 0x00, /*'\x00e7'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x65, 0x00, 0x00, /*ToUInt64Key("egrave")*/ 0xE8, 0x00, /*'\x00e8'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x65, 0x00, 0x00, /*ToUInt64Key("eacute")*/ 0xE9, 0x00, /*'\x00e9'*/
0x63, 0x72, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, /*ToUInt64Key("ecirc")*/ 0xEA, 0x00, /*'\x00ea'*/
0x6C, 0x6D, 0x75, 0x65, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("euml")*/ 0xEB, 0x00, /*'\x00eb'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x69, 0x00, 0x00, /*ToUInt64Key("igrave")*/ 0xEC, 0x00, /*'\x00ec'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x69, 0x00, 0x00, /*ToUInt64Key("iacute")*/ 0xED, 0x00, /*'\x00ed'*/
0x63, 0x72, 0x69, 0x63, 0x69, 0x00, 0x00, 0x00, /*ToUInt64Key("icirc")*/ 0xEE, 0x00, /*'\x00ee'*/
0x6C, 0x6D, 0x75, 0x69, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("iuml")*/ 0xEF, 0x00, /*'\x00ef'*/
0x68, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("eth")*/ 0xF0, 0x00, /*'\x00f0'*/
0x65, 0x64, 0x6C, 0x69, 0x74, 0x6E, 0x00, 0x00, /*ToUInt64Key("ntilde")*/ 0xF1, 0x00, /*'\x00f1'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x6F, 0x00, 0x00, /*ToUInt64Key("ograve")*/ 0xF2, 0x00, /*'\x00f2'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x6F, 0x00, 0x00, /*ToUInt64Key("oacute")*/ 0xF3, 0x00, /*'\x00f3'*/
0x63, 0x72, 0x69, 0x63, 0x6F, 0x00, 0x00, 0x00, /*ToUInt64Key("ocirc")*/ 0xF4, 0x00, /*'\x00f4'*/
0x65, 0x64, 0x6C, 0x69, 0x74, 0x6F, 0x00, 0x00, /*ToUInt64Key("otilde")*/ 0xF5, 0x00, /*'\x00f5'*/
0x6C, 0x6D, 0x75, 0x6F, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ouml")*/ 0xF6, 0x00, /*'\x00f6'*/
0x65, 0x64, 0x69, 0x76, 0x69, 0x64, 0x00, 0x00, /*ToUInt64Key("divide")*/ 0xF7, 0x00, /*'\x00f7'*/
0x68, 0x73, 0x61, 0x6C, 0x73, 0x6F, 0x00, 0x00, /*ToUInt64Key("oslash")*/ 0xF8, 0x00, /*'\x00f8'*/
0x65, 0x76, 0x61, 0x72, 0x67, 0x75, 0x00, 0x00, /*ToUInt64Key("ugrave")*/ 0xF9, 0x00, /*'\x00f9'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x75, 0x00, 0x00, /*ToUInt64Key("uacute")*/ 0xFA, 0x00, /*'\x00fa'*/
0x63, 0x72, 0x69, 0x63, 0x75, 0x00, 0x00, 0x00, /*ToUInt64Key("ucirc")*/ 0xFB, 0x00, /*'\x00fb'*/
0x6C, 0x6D, 0x75, 0x75, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("uuml")*/ 0xFC, 0x00, /*'\x00fc'*/
0x65, 0x74, 0x75, 0x63, 0x61, 0x79, 0x00, 0x00, /*ToUInt64Key("yacute")*/ 0xFD, 0x00, /*'\x00fd'*/
0x6E, 0x72, 0x6F, 0x68, 0x74, 0x00, 0x00, 0x00, /*ToUInt64Key("thorn")*/ 0xFE, 0x00, /*'\x00fe'*/
0x6C, 0x6D, 0x75, 0x79, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("yuml")*/ 0xFF, 0x00, /*'\x00ff'*/
0x67, 0x69, 0x6C, 0x45, 0x4F, 0x00, 0x00, 0x00, /*ToUInt64Key("OElig")*/ 0x52, 0x01, /*'\x0152'*/
0x67, 0x69, 0x6C, 0x65, 0x6F, 0x00, 0x00, 0x00, /*ToUInt64Key("oelig")*/ 0x53, 0x01, /*'\x0153'*/
0x6E, 0x6F, 0x72, 0x61, 0x63, 0x53, 0x00, 0x00, /*ToUInt64Key("Scaron")*/ 0x60, 0x01, /*'\x0160'*/
0x6E, 0x6F, 0x72, 0x61, 0x63, 0x73, 0x00, 0x00, /*ToUInt64Key("scaron")*/ 0x61, 0x01, /*'\x0161'*/
0x6C, 0x6D, 0x75, 0x59, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Yuml")*/ 0x78, 0x01, /*'\x0178'*/
0x66, 0x6F, 0x6E, 0x66, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("fnof")*/ 0x92, 0x01, /*'\x0192'*/
0x63, 0x72, 0x69, 0x63, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("circ")*/ 0xC6, 0x02, /*'\x02c6'*/
0x65, 0x64, 0x6C, 0x69, 0x74, 0x00, 0x00, 0x00, /*ToUInt64Key("tilde")*/ 0xDC, 0x02, /*'\x02dc'*/
0x61, 0x68, 0x70, 0x6C, 0x41, 0x00, 0x00, 0x00, /*ToUInt64Key("Alpha")*/ 0x91, 0x03, /*'\x0391'*/
0x61, 0x74, 0x65, 0x42, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Beta")*/ 0x92, 0x03, /*'\x0392'*/
0x61, 0x6D, 0x6D, 0x61, 0x47, 0x00, 0x00, 0x00, /*ToUInt64Key("Gamma")*/ 0x93, 0x03, /*'\x0393'*/
0x61, 0x74, 0x6C, 0x65, 0x44, 0x00, 0x00, 0x00, /*ToUInt64Key("Delta")*/ 0x94, 0x03, /*'\x0394'*/
0x6E, 0x6F, 0x6C, 0x69, 0x73, 0x70, 0x45, 0x00, /*ToUInt64Key("Epsilon")*/ 0x95, 0x03, /*'\x0395'*/
0x61, 0x74, 0x65, 0x5A, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Zeta")*/ 0x96, 0x03, /*'\x0396'*/
0x61, 0x74, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Eta")*/ 0x97, 0x03, /*'\x0397'*/
0x61, 0x74, 0x65, 0x68, 0x54, 0x00, 0x00, 0x00, /*ToUInt64Key("Theta")*/ 0x98, 0x03, /*'\x0398'*/
0x61, 0x74, 0x6F, 0x49, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Iota")*/ 0x99, 0x03, /*'\x0399'*/
0x61, 0x70, 0x70, 0x61, 0x4B, 0x00, 0x00, 0x00, /*ToUInt64Key("Kappa")*/ 0x9A, 0x03, /*'\x039a'*/
0x61, 0x64, 0x62, 0x6D, 0x61, 0x4C, 0x00, 0x00, /*ToUInt64Key("Lambda")*/ 0x9B, 0x03, /*'\x039b'*/
0x75, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Mu")*/ 0x9C, 0x03, /*'\x039c'*/
0x75, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Nu")*/ 0x9D, 0x03, /*'\x039d'*/
0x69, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Xi")*/ 0x9E, 0x03, /*'\x039e'*/
0x6E, 0x6F, 0x72, 0x63, 0x69, 0x6D, 0x4F, 0x00, /*ToUInt64Key("Omicron")*/ 0x9F, 0x03, /*'\x039f'*/
0x69, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Pi")*/ 0xA0, 0x03, /*'\x03a0'*/
0x6F, 0x68, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Rho")*/ 0xA1, 0x03, /*'\x03a1'*/
0x61, 0x6D, 0x67, 0x69, 0x53, 0x00, 0x00, 0x00, /*ToUInt64Key("Sigma")*/ 0xA3, 0x03, /*'\x03a3'*/
0x75, 0x61, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Tau")*/ 0xA4, 0x03, /*'\x03a4'*/
0x6E, 0x6F, 0x6C, 0x69, 0x73, 0x70, 0x55, 0x00, /*ToUInt64Key("Upsilon")*/ 0xA5, 0x03, /*'\x03a5'*/
0x69, 0x68, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Phi")*/ 0xA6, 0x03, /*'\x03a6'*/
0x69, 0x68, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Chi")*/ 0xA7, 0x03, /*'\x03a7'*/
0x69, 0x73, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("Psi")*/ 0xA8, 0x03, /*'\x03a8'*/
0x61, 0x67, 0x65, 0x6D, 0x4F, 0x00, 0x00, 0x00, /*ToUInt64Key("Omega")*/ 0xA9, 0x03, /*'\x03a9'*/
0x61, 0x68, 0x70, 0x6C, 0x61, 0x00, 0x00, 0x00, /*ToUInt64Key("alpha")*/ 0xB1, 0x03, /*'\x03b1'*/
0x61, 0x74, 0x65, 0x62, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("beta")*/ 0xB2, 0x03, /*'\x03b2'*/
0x61, 0x6D, 0x6D, 0x61, 0x67, 0x00, 0x00, 0x00, /*ToUInt64Key("gamma")*/ 0xB3, 0x03, /*'\x03b3'*/
0x61, 0x74, 0x6C, 0x65, 0x64, 0x00, 0x00, 0x00, /*ToUInt64Key("delta")*/ 0xB4, 0x03, /*'\x03b4'*/
0x6E, 0x6F, 0x6C, 0x69, 0x73, 0x70, 0x65, 0x00, /*ToUInt64Key("epsilon")*/ 0xB5, 0x03, /*'\x03b5'*/
0x61, 0x74, 0x65, 0x7A, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("zeta")*/ 0xB6, 0x03, /*'\x03b6'*/
0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("eta")*/ 0xB7, 0x03, /*'\x03b7'*/
0x61, 0x74, 0x65, 0x68, 0x74, 0x00, 0x00, 0x00, /*ToUInt64Key("theta")*/ 0xB8, 0x03, /*'\x03b8'*/
0x61, 0x74, 0x6F, 0x69, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("iota")*/ 0xB9, 0x03, /*'\x03b9'*/
0x61, 0x70, 0x70, 0x61, 0x6B, 0x00, 0x00, 0x00, /*ToUInt64Key("kappa")*/ 0xBA, 0x03, /*'\x03ba'*/
0x61, 0x64, 0x62, 0x6D, 0x61, 0x6C, 0x00, 0x00, /*ToUInt64Key("lambda")*/ 0xBB, 0x03, /*'\x03bb'*/
0x75, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("mu")*/ 0xBC, 0x03, /*'\x03bc'*/
0x75, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("nu")*/ 0xBD, 0x03, /*'\x03bd'*/
0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("xi")*/ 0xBE, 0x03, /*'\x03be'*/
0x6E, 0x6F, 0x72, 0x63, 0x69, 0x6D, 0x6F, 0x00, /*ToUInt64Key("omicron")*/ 0xBF, 0x03, /*'\x03bf'*/
0x69, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("pi")*/ 0xC0, 0x03, /*'\x03c0'*/
0x6F, 0x68, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("rho")*/ 0xC1, 0x03, /*'\x03c1'*/
0x66, 0x61, 0x6D, 0x67, 0x69, 0x73, 0x00, 0x00, /*ToUInt64Key("sigmaf")*/ 0xC2, 0x03, /*'\x03c2'*/
0x61, 0x6D, 0x67, 0x69, 0x73, 0x00, 0x00, 0x00, /*ToUInt64Key("sigma")*/ 0xC3, 0x03, /*'\x03c3'*/
0x75, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("tau")*/ 0xC4, 0x03, /*'\x03c4'*/
0x6E, 0x6F, 0x6C, 0x69, 0x73, 0x70, 0x75, 0x00, /*ToUInt64Key("upsilon")*/ 0xC5, 0x03, /*'\x03c5'*/
0x69, 0x68, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("phi")*/ 0xC6, 0x03, /*'\x03c6'*/
0x69, 0x68, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("chi")*/ 0xC7, 0x03, /*'\x03c7'*/
0x69, 0x73, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("psi")*/ 0xC8, 0x03, /*'\x03c8'*/
0x61, 0x67, 0x65, 0x6D, 0x6F, 0x00, 0x00, 0x00, /*ToUInt64Key("omega")*/ 0xC9, 0x03, /*'\x03c9'*/
0x6D, 0x79, 0x73, 0x61, 0x74, 0x65, 0x68, 0x74, /*ToUInt64Key("thetasym")*/0xD1, 0x03, /*'\x03d1'*/
0x68, 0x69, 0x73, 0x70, 0x75, 0x00, 0x00, 0x00, /*ToUInt64Key("upsih")*/ 0xD2, 0x03, /*'\x03d2'*/
0x76, 0x69, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("piv")*/ 0xD6, 0x03, /*'\x03d6'*/
0x70, 0x73, 0x6E, 0x65, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ensp")*/ 0x02, 0x20, /*'\x2002'*/
0x70, 0x73, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("emsp")*/ 0x03, 0x20, /*'\x2003'*/
0x70, 0x73, 0x6E, 0x69, 0x68, 0x74, 0x00, 0x00, /*ToUInt64Key("thinsp")*/ 0x09, 0x20, /*'\x2009'*/
0x6A, 0x6E, 0x77, 0x7A, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("zwnj")*/ 0x0C, 0x20, /*'\x200c'*/
0x6A, 0x77, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("zwj")*/ 0x0D, 0x20, /*'\x200d'*/
0x6D, 0x72, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("lrm")*/ 0x0E, 0x20, /*'\x200e'*/
0x6D, 0x6C, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("rlm")*/ 0x0F, 0x20, /*'\x200f'*/
0x68, 0x73, 0x61, 0x64, 0x6E, 0x00, 0x00, 0x00, /*ToUInt64Key("ndash")*/ 0x13, 0x20, /*'\x2013'*/
0x68, 0x73, 0x61, 0x64, 0x6D, 0x00, 0x00, 0x00, /*ToUInt64Key("mdash")*/ 0x14, 0x20, /*'\x2014'*/
0x6F, 0x75, 0x71, 0x73, 0x6C, 0x00, 0x00, 0x00, /*ToUInt64Key("lsquo")*/ 0x18, 0x20, /*'\x2018'*/
0x6F, 0x75, 0x71, 0x73, 0x72, 0x00, 0x00, 0x00, /*ToUInt64Key("rsquo")*/ 0x19, 0x20, /*'\x2019'*/
0x6F, 0x75, 0x71, 0x62, 0x73, 0x00, 0x00, 0x00, /*ToUInt64Key("sbquo")*/ 0x1A, 0x20, /*'\x201a'*/
0x6F, 0x75, 0x71, 0x64, 0x6C, 0x00, 0x00, 0x00, /*ToUInt64Key("ldquo")*/ 0x1C, 0x20, /*'\x201c'*/
0x6F, 0x75, 0x71, 0x64, 0x72, 0x00, 0x00, 0x00, /*ToUInt64Key("rdquo")*/ 0x1D, 0x20, /*'\x201d'*/
0x6F, 0x75, 0x71, 0x64, 0x62, 0x00, 0x00, 0x00, /*ToUInt64Key("bdquo")*/ 0x1E, 0x20, /*'\x201e'*/
0x72, 0x65, 0x67, 0x67, 0x61, 0x64, 0x00, 0x00, /*ToUInt64Key("dagger")*/ 0x20, 0x20, /*'\x2020'*/
0x72, 0x65, 0x67, 0x67, 0x61, 0x44, 0x00, 0x00, /*ToUInt64Key("Dagger")*/ 0x21, 0x20, /*'\x2021'*/
0x6C, 0x6C, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("bull")*/ 0x22, 0x20, /*'\x2022'*/
0x70, 0x69, 0x6C, 0x6C, 0x65, 0x68, 0x00, 0x00, /*ToUInt64Key("hellip")*/ 0x26, 0x20, /*'\x2026'*/
0x6C, 0x69, 0x6D, 0x72, 0x65, 0x70, 0x00, 0x00, /*ToUInt64Key("permil")*/ 0x30, 0x20, /*'\x2030'*/
0x65, 0x6D, 0x69, 0x72, 0x70, 0x00, 0x00, 0x00, /*ToUInt64Key("prime")*/ 0x32, 0x20, /*'\x2032'*/
0x65, 0x6D, 0x69, 0x72, 0x50, 0x00, 0x00, 0x00, /*ToUInt64Key("Prime")*/ 0x33, 0x20, /*'\x2033'*/
0x6F, 0x75, 0x71, 0x61, 0x73, 0x6C, 0x00, 0x00, /*ToUInt64Key("lsaquo")*/ 0x39, 0x20, /*'\x2039'*/
0x6F, 0x75, 0x71, 0x61, 0x73, 0x72, 0x00, 0x00, /*ToUInt64Key("rsaquo")*/ 0x3A, 0x20, /*'\x203a'*/
0x65, 0x6E, 0x69, 0x6C, 0x6F, 0x00, 0x00, 0x00, /*ToUInt64Key("oline")*/ 0x3E, 0x20, /*'\x203e'*/
0x6C, 0x73, 0x61, 0x72, 0x66, 0x00, 0x00, 0x00, /*ToUInt64Key("frasl")*/ 0x44, 0x20, /*'\x2044'*/
0x6F, 0x72, 0x75, 0x65, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("euro")*/ 0xAC, 0x20, /*'\x20ac'*/
0x65, 0x67, 0x61, 0x6D, 0x69, 0x00, 0x00, 0x00, /*ToUInt64Key("image")*/ 0x11, 0x21, /*'\x2111'*/
0x70, 0x72, 0x65, 0x69, 0x65, 0x77, 0x00, 0x00, /*ToUInt64Key("weierp")*/ 0x18, 0x21, /*'\x2118'*/
0x6C, 0x61, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("real")*/ 0x1C, 0x21, /*'\x211c'*/
0x65, 0x64, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, /*ToUInt64Key("trade")*/ 0x22, 0x21, /*'\x2122'*/
0x6D, 0x79, 0x73, 0x66, 0x65, 0x6C, 0x61, 0x00, /*ToUInt64Key("alefsym")*/ 0x35, 0x21, /*'\x2135'*/
0x72, 0x72, 0x61, 0x6C, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("larr")*/ 0x90, 0x21, /*'\x2190'*/
0x72, 0x72, 0x61, 0x75, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("uarr")*/ 0x91, 0x21, /*'\x2191'*/
0x72, 0x72, 0x61, 0x72, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("rarr")*/ 0x92, 0x21, /*'\x2192'*/
0x72, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("darr")*/ 0x93, 0x21, /*'\x2193'*/
0x72, 0x72, 0x61, 0x68, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("harr")*/ 0x94, 0x21, /*'\x2194'*/
0x72, 0x72, 0x61, 0x72, 0x63, 0x00, 0x00, 0x00, /*ToUInt64Key("crarr")*/ 0xB5, 0x21, /*'\x21b5'*/
0x72, 0x72, 0x41, 0x6C, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("lArr")*/ 0xD0, 0x21, /*'\x21d0'*/
0x72, 0x72, 0x41, 0x75, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("uArr")*/ 0xD1, 0x21, /*'\x21d1'*/
0x72, 0x72, 0x41, 0x72, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("rArr")*/ 0xD2, 0x21, /*'\x21d2'*/
0x72, 0x72, 0x41, 0x64, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("dArr")*/ 0xD3, 0x21, /*'\x21d3'*/
0x72, 0x72, 0x41, 0x68, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("hArr")*/ 0xD4, 0x21, /*'\x21d4'*/
0x6C, 0x6C, 0x61, 0x72, 0x6F, 0x66, 0x00, 0x00, /*ToUInt64Key("forall")*/ 0x00, 0x22, /*'\x2200'*/
0x74, 0x72, 0x61, 0x70, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("part")*/ 0x02, 0x22, /*'\x2202'*/
0x74, 0x73, 0x69, 0x78, 0x65, 0x00, 0x00, 0x00, /*ToUInt64Key("exist")*/ 0x03, 0x22, /*'\x2203'*/
0x79, 0x74, 0x70, 0x6D, 0x65, 0x00, 0x00, 0x00, /*ToUInt64Key("empty")*/ 0x05, 0x22, /*'\x2205'*/
0x61, 0x6C, 0x62, 0x61, 0x6E, 0x00, 0x00, 0x00, /*ToUInt64Key("nabla")*/ 0x07, 0x22, /*'\x2207'*/
0x6E, 0x69, 0x73, 0x69, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("isin")*/ 0x08, 0x22, /*'\x2208'*/
0x6E, 0x69, 0x74, 0x6F, 0x6E, 0x00, 0x00, 0x00, /*ToUInt64Key("notin")*/ 0x09, 0x22, /*'\x2209'*/
0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ni")*/ 0x0B, 0x22, /*'\x220b'*/
0x64, 0x6F, 0x72, 0x70, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("prod")*/ 0x0F, 0x22, /*'\x220f'*/
0x6D, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sum")*/ 0x11, 0x22, /*'\x2211'*/
0x73, 0x75, 0x6E, 0x69, 0x6D, 0x00, 0x00, 0x00, /*ToUInt64Key("minus")*/ 0x12, 0x22, /*'\x2212'*/
0x74, 0x73, 0x61, 0x77, 0x6F, 0x6C, 0x00, 0x00, /*ToUInt64Key("lowast")*/ 0x17, 0x22, /*'\x2217'*/
0x63, 0x69, 0x64, 0x61, 0x72, 0x00, 0x00, 0x00, /*ToUInt64Key("radic")*/ 0x1A, 0x22, /*'\x221a'*/
0x70, 0x6F, 0x72, 0x70, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("prop")*/ 0x1D, 0x22, /*'\x221d'*/
0x6E, 0x69, 0x66, 0x6E, 0x69, 0x00, 0x00, 0x00, /*ToUInt64Key("infin")*/ 0x1E, 0x22, /*'\x221e'*/
0x67, 0x6E, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ang")*/ 0x20, 0x22, /*'\x2220'*/
0x64, 0x6E, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("and")*/ 0x27, 0x22, /*'\x2227'*/
0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("or")*/ 0x28, 0x22, /*'\x2228'*/
0x70, 0x61, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("cap")*/ 0x29, 0x22, /*'\x2229'*/
0x70, 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("cup")*/ 0x2A, 0x22, /*'\x222a'*/
0x74, 0x6E, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("int")*/ 0x2B, 0x22, /*'\x222b'*/
0x34, 0x65, 0x72, 0x65, 0x68, 0x74, 0x00, 0x00, /*ToUInt64Key("there4")*/ 0x34, 0x22, /*'\x2234'*/
0x6D, 0x69, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sim")*/ 0x3C, 0x22, /*'\x223c'*/
0x67, 0x6E, 0x6F, 0x63, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("cong")*/ 0x45, 0x22, /*'\x2245'*/
0x70, 0x6D, 0x79, 0x73, 0x61, 0x00, 0x00, 0x00, /*ToUInt64Key("asymp")*/ 0x48, 0x22, /*'\x2248'*/
0x65, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ne")*/ 0x60, 0x22, /*'\x2260'*/
0x76, 0x69, 0x75, 0x71, 0x65, 0x00, 0x00, 0x00, /*ToUInt64Key("equiv")*/ 0x61, 0x22, /*'\x2261'*/
0x65, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("le")*/ 0x64, 0x22, /*'\x2264'*/
0x65, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("ge")*/ 0x65, 0x22, /*'\x2265'*/
0x62, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sub")*/ 0x82, 0x22, /*'\x2282'*/
0x70, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sup")*/ 0x83, 0x22, /*'\x2283'*/
0x62, 0x75, 0x73, 0x6E, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("nsub")*/ 0x84, 0x22, /*'\x2284'*/
0x65, 0x62, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sube")*/ 0x86, 0x22, /*'\x2286'*/
0x65, 0x70, 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("supe")*/ 0x87, 0x22, /*'\x2287'*/
0x73, 0x75, 0x6C, 0x70, 0x6F, 0x00, 0x00, 0x00, /*ToUInt64Key("oplus")*/ 0x95, 0x22, /*'\x2295'*/
0x73, 0x65, 0x6D, 0x69, 0x74, 0x6F, 0x00, 0x00, /*ToUInt64Key("otimes")*/ 0x97, 0x22, /*'\x2297'*/
0x70, 0x72, 0x65, 0x70, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("perp")*/ 0xA5, 0x22, /*'\x22a5'*/
0x74, 0x6F, 0x64, 0x73, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("sdot")*/ 0xC5, 0x22, /*'\x22c5'*/
0x6C, 0x69, 0x65, 0x63, 0x6C, 0x00, 0x00, 0x00, /*ToUInt64Key("lceil")*/ 0x08, 0x23, /*'\x2308'*/
0x6C, 0x69, 0x65, 0x63, 0x72, 0x00, 0x00, 0x00, /*ToUInt64Key("rceil")*/ 0x09, 0x23, /*'\x2309'*/
0x72, 0x6F, 0x6F, 0x6C, 0x66, 0x6C, 0x00, 0x00, /*ToUInt64Key("lfloor")*/ 0x0A, 0x23, /*'\x230a'*/
0x72, 0x6F, 0x6F, 0x6C, 0x66, 0x72, 0x00, 0x00, /*ToUInt64Key("rfloor")*/ 0x0B, 0x23, /*'\x230b'*/
0x67, 0x6E, 0x61, 0x6C, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("lang")*/ 0x29, 0x23, /*'\x2329'*/
0x67, 0x6E, 0x61, 0x72, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("rang")*/ 0x2A, 0x23, /*'\x232a'*/
0x7A, 0x6F, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /*ToUInt64Key("loz")*/ 0xCA, 0x25, /*'\x25ca'*/
0x73, 0x65, 0x64, 0x61, 0x70, 0x73, 0x00, 0x00, /*ToUInt64Key("spades")*/ 0x60, 0x26, /*'\x2660'*/
0x73, 0x62, 0x75, 0x6C, 0x63, 0x00, 0x00, 0x00, /*ToUInt64Key("clubs")*/ 0x63, 0x26, /*'\x2663'*/
0x73, 0x74, 0x72, 0x61, 0x65, 0x68, 0x00, 0x00, /*ToUInt64Key("hearts")*/ 0x65, 0x26, /*'\x2665'*/
0x73, 0x6D, 0x61, 0x69, 0x64, 0x00, 0x00, 0x00, /*ToUInt64Key("diams")*/ 0x66, 0x26, /*'\x2666'*/
];
var dictionary = new Dictionary<ulong, char>(tableData.Length / (sizeof(ulong) + sizeof(char)));
while (tableData.Length > 0)
{
ulong key = BitConverter.ToUInt64(tableData, 0);
char value = (char)BitConverter.ToUInt16(tableData, sizeof(ulong));
dictionary[key] = value;
tableData = tableData.Skip((sizeof(ulong) + sizeof(char))).ToArray();
}
return dictionary;
}
// maps entity strings => unicode chars
private static readonly Dictionary<ulong, char> s_lookupTable = InitializeLookupTable();
public static char Lookup(char[] entity)
{
// To avoid an allocation, keys of type "ulong" are used in the lookup table.
// Since all entity strings comprise 8 characters or less and are ASCII-only, they "fit" into an ulong (8 bytes).
if (entity.Length <= 8)
{
s_lookupTable.TryGetValue(ToUInt64Key(entity), out char result);
return result;
}
else
{
// Currently, there are no entities that are longer than 8 characters.
return (char)0;
}
}
private static ulong ToUInt64Key(char[] entity)
{
// The ulong key is the reversed single-byte character representation of the actual entity string.
ulong key = 0;
for (int i = 0; i < entity.Length; i++)
{
if (entity[i] > 0xFF)
{
return 0;
}
key = (key << 8) | entity[i];
}
return key;
}
}
}
}
#endif

View File

@@ -2,12 +2,12 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.2.1</Version>
<Version>1.3.2</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -26,13 +26,21 @@
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))">
<PackageReference Include="MinValueTupleBridge" Version="0.2.1" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
<PackageReference Include="MinAsyncBridge" Version="0.12.4" />
<PackageReference Include="MinThreadingBridge" Version="0.11.4" />
<PackageReference Include="Net30.LinqBridge" Version="1.3.0" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`))">
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.Models" Version="1.2.0" />
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
</ItemGroup>
</Project>

View File

@@ -83,16 +83,14 @@ namespace SabreTools.RedumpLib
/// <param name="query">Query string to attempt to search for</param>
/// <param name="filterForwardSlashes">True to filter forward slashes, false otherwise</param>
/// <returns>All disc IDs for the given query, null on error</returns>
#if NET40
public static List<int>? ListSearchResults(RedumpWebClient wc, string? query, bool filterForwardSlashes = true)
#elif NETFRAMEWORK
#if NETFRAMEWORK
public async static Task<List<int>?> ListSearchResults(RedumpWebClient wc, string? query, bool filterForwardSlashes = true)
#else
public async static Task<List<int>?> ListSearchResults(RedumpHttpClient wc, string? query, bool filterForwardSlashes = true)
#endif
{
// If there is an invalid query
if (string.IsNullOrWhiteSpace(query))
if (string.IsNullOrEmpty(query))
return null;
var ids = new List<int>();
@@ -116,7 +114,7 @@ namespace SabreTools.RedumpLib
while (true)
{
#if NET40
List<int> pageIds = wc.CheckSingleSitePage(string.Format(Constants.QuickSearchUrl, query, pageNumber++));
List<int> pageIds = await Task.Factory.StartNew(() => wc.CheckSingleSitePage(string.Format(Constants.QuickSearchUrl, query, pageNumber++)));
#elif NETFRAMEWORK
List<int> pageIds = await Task.Run(() => wc.CheckSingleSitePage(string.Format(Constants.QuickSearchUrl, query, pageNumber++)));
#else
@@ -143,20 +141,14 @@ namespace SabreTools.RedumpLib
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="sha1">SHA-1 hash to check against</param>
/// <returns>True if the track was found, false otherwise; List of found values, if possible</returns>
#if NET40
public static (bool, List<int>?, string?) ValidateSingleTrack(RedumpWebClient wc, SubmissionInfo info, string sha1)
#elif NETFRAMEWORK
public async static Task<(bool, List<int>?, string?)> ValidateSingleTrack(RedumpWebClient wc, SubmissionInfo info, string sha1)
#if NETFRAMEWORK
public async static Task<(bool, List<int>?, string?)> ValidateSingleTrack(RedumpWebClient wc, SubmissionInfo info, string? sha1)
#else
public async static Task<(bool, List<int>?, string?)> ValidateSingleTrack(RedumpHttpClient wc, SubmissionInfo info, string sha1)
public async static Task<(bool, List<int>?, string?)> ValidateSingleTrack(RedumpHttpClient wc, SubmissionInfo info, string? sha1)
#endif
{
// Get all matching IDs for the track
#if NET40
var newIds = ListSearchResults(wc, sha1);
#else
var newIds = await ListSearchResults(wc, sha1);
#endif
// If we got null back, there was an error
if (newIds == null)
@@ -182,9 +174,7 @@ namespace SabreTools.RedumpLib
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="resultProgress">Optional result progress callback</param>
/// <returns>True if the track was found, false otherwise; List of found values, if possible</returns>
#if NET40
public static (bool, List<int>?, string?) ValidateUniversalHash(RedumpWebClient wc, SubmissionInfo info)
#elif NETFRAMEWORK
#if NETFRAMEWORK
public async static Task<(bool, List<int>?, string?)> ValidateUniversalHash(RedumpWebClient wc, SubmissionInfo info)
#else
public async static Task<(bool, List<int>?, string?)> ValidateUniversalHash(RedumpHttpClient wc, SubmissionInfo info)
@@ -200,14 +190,10 @@ namespace SabreTools.RedumpLib
return (false, null, "Universal hash was missing");
// Format the universal hash for finding within the comments
universalHash = $"{universalHash.Substring(0, universalHash.Length - 1)}/comments/only";
string universalHashQuery = $"{universalHash.Substring(0, universalHash.Length - 1)}/comments/only";
// Get all matching IDs for the hash
#if NET40
var newIds = ListSearchResults(wc, universalHash, filterForwardSlashes: false);
#else
var newIds = await ListSearchResults(wc, universalHash, filterForwardSlashes: false);
#endif
var newIds = await ListSearchResults(wc, universalHashQuery, filterForwardSlashes: false);
// If we got null back, there was an error
if (newIds == null)
@@ -233,9 +219,7 @@ namespace SabreTools.RedumpLib
/// <param name="id">Redump disc ID to retrieve</param>
/// <param name="localCount">Local count of tracks for the current disc</param>
/// <returns>True if the track count matches, false otherwise</returns>
#if NET40
public static bool ValidateTrackCount(RedumpWebClient wc, int id, int localCount)
#elif NETFRAMEWORK
#if NETFRAMEWORK
public async static Task<bool> ValidateTrackCount(RedumpWebClient wc, int id, int localCount)
#else
public async static Task<bool> ValidateTrackCount(RedumpHttpClient wc, int id, int localCount)
@@ -243,7 +227,7 @@ namespace SabreTools.RedumpLib
{
// If we can't pull the remote data, we can't match
#if NET40
string? discData = wc.DownloadSingleSiteID(id);
string? discData = await Task.Factory.StartNew(() => wc.DownloadSingleSiteID(id));
#elif NETFRAMEWORK
string? discData = await Task.Run(() => wc.DownloadSingleSiteID(id));
#else

View File

@@ -46,7 +46,7 @@ namespace SabreTools.RedumpLib.Web
public async static Task<(bool?, string?)> ValidateCredentials(string username, string password)
{
// If options are invalid or we're missing something key, just return
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
return (false, null);
// Try logging in with the supplied credentials otherwise
@@ -70,16 +70,16 @@ namespace SabreTools.RedumpLib.Web
public async Task<bool?> Login(string username, string password)
{
// Credentials verification
if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password))
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
Console.WriteLine("Credentials entered, will attempt Redump login...");
}
else if (!string.IsNullOrWhiteSpace(username) && string.IsNullOrWhiteSpace(password))
else if (!string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password))
{
Console.WriteLine("Only a username was specified, will not attempt Redump login...");
return false;
}
else if (string.IsNullOrWhiteSpace(username))
else if (string.IsNullOrEmpty(username))
{
Console.WriteLine("No credentials entered, will not attempt Redump login...");
return false;
@@ -107,7 +107,7 @@ namespace SabreTools.RedumpLib.Web
if (response?.Content != null)
responseContent = await response.Content.ReadAsStringAsync();
if (string.IsNullOrWhiteSpace(responseContent))
if (string.IsNullOrEmpty(responseContent))
{
Console.WriteLine($"An error occurred while trying to log in on attempt {i}: No response");
continue;
@@ -362,7 +362,7 @@ namespace SabreTools.RedumpLib.Web
try
{
// If no output directory is defined, use the current directory instead
if (string.IsNullOrWhiteSpace(outDir))
if (string.IsNullOrEmpty(outDir))
outDir = Environment.CurrentDirectory;
string tempfile = Path.Combine(outDir, "tmp" + Guid.NewGuid().ToString());
@@ -421,7 +421,7 @@ namespace SabreTools.RedumpLib.Web
public async Task<bool> DownloadSingleSiteID(int id, string? outDir, bool rename)
{
// If no output directory is defined, use the current directory instead
if (string.IsNullOrWhiteSpace(outDir))
if (string.IsNullOrEmpty(outDir))
outDir = Environment.CurrentDirectory;
string paddedId = id.ToString().PadLeft(6, '0');
@@ -583,7 +583,7 @@ namespace SabreTools.RedumpLib.Web
public async Task<bool> DownloadSingleWIPID(int id, string? outDir, bool rename)
{
// If no output directory is defined, use the current directory instead
if (string.IsNullOrWhiteSpace(outDir))
if (string.IsNullOrEmpty(outDir))
outDir = Environment.CurrentDirectory;
string paddedId = id.ToString().PadLeft(6, '0');
@@ -684,7 +684,7 @@ namespace SabreTools.RedumpLib.Web
// If the system is unknown, we can't do anything
string? longName = system.LongName();
if (string.IsNullOrWhiteSpace(longName))
if (string.IsNullOrEmpty(longName))
continue;
Console.Write($"\r{longName}{new string(' ', Console.BufferWidth - longName.Length - 1)}");
@@ -722,7 +722,7 @@ namespace SabreTools.RedumpLib.Web
// If the system is unknown, we can't do anything
string? longName = system.LongName();
if (string.IsNullOrWhiteSpace(longName))
if (string.IsNullOrEmpty(longName))
continue;
Console.Write($"\r{longName}{new string(' ', Console.BufferWidth - longName.Length - 1)}");
@@ -794,14 +794,14 @@ namespace SabreTools.RedumpLib.Web
private static void MoveOrDelete(string tempfile, string? newfile, string outDir, string? subfolder)
{
// If we don't have a file to move to, just delete the temp file
if (string.IsNullOrWhiteSpace(newfile))
if (string.IsNullOrEmpty(newfile))
{
File.Delete(tempfile);
return;
}
// If we have a subfolder, create it and update the newfile name
if (!string.IsNullOrWhiteSpace(subfolder))
if (!string.IsNullOrEmpty(subfolder))
{
if (!Directory.Exists(Path.Combine(outDir, subfolder)))
Directory.CreateDirectory(Path.Combine(outDir, subfolder));

View File

@@ -37,7 +37,7 @@ namespace SabreTools.RedumpLib.Web
// If we don't have the response header we care about
string headerValue = ResponseHeaders.Get("Content-Disposition");
if (string.IsNullOrWhiteSpace(headerValue))
if (string.IsNullOrEmpty(headerValue))
return null;
// Extract the filename from the value
@@ -60,7 +60,7 @@ namespace SabreTools.RedumpLib.Web
public static (bool?, string?) ValidateCredentials(string username, string password)
{
// If options are invalid or we're missing something key, just return
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
return (false, null);
// Try logging in with the supplied credentials otherwise
@@ -83,23 +83,23 @@ namespace SabreTools.RedumpLib.Web
public bool? Login(string username, string password)
{
// Credentials verification
if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password))
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
Console.WriteLine("Credentials entered, will attempt Redump login...");
}
else if (!string.IsNullOrWhiteSpace(username) && string.IsNullOrWhiteSpace(password))
else if (!string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password))
{
Console.WriteLine("Only a username was specified, will not attempt Redump login...");
return false;
}
else if (string.IsNullOrWhiteSpace(username))
else if (string.IsNullOrEmpty(username))
{
Console.WriteLine("No credentials entered, will not attempt Redump login...");
return false;
}
// HTTP encode the password
#if NET40
#if NET20 || NET35 || NET40
password = Uri.EscapeUriString(password);
#else
password = WebUtility.UrlEncode(password);
@@ -392,7 +392,7 @@ namespace SabreTools.RedumpLib.Web
try
{
// If no output directory is defined, use the current directory instead
if (string.IsNullOrWhiteSpace(outDir))
if (string.IsNullOrEmpty(outDir))
outDir = Environment.CurrentDirectory;
string tempfile = Path.Combine(outDir, "tmp" + Guid.NewGuid().ToString());
@@ -455,7 +455,7 @@ namespace SabreTools.RedumpLib.Web
public bool DownloadSingleSiteID(int id, string? outDir, bool rename)
{
// If no output directory is defined, use the current directory instead
if (string.IsNullOrWhiteSpace(outDir))
if (string.IsNullOrEmpty(outDir))
outDir = Environment.CurrentDirectory;
string paddedId = id.ToString().PadLeft(6, '0');
@@ -635,7 +635,7 @@ namespace SabreTools.RedumpLib.Web
public bool DownloadSingleWIPID(int id, string? outDir, bool rename)
{
// If no output directory is defined, use the current directory instead
if (string.IsNullOrWhiteSpace(outDir))
if (string.IsNullOrEmpty(outDir))
outDir = Environment.CurrentDirectory;
string paddedId = id.ToString().PadLeft(6, '0');
@@ -745,7 +745,7 @@ namespace SabreTools.RedumpLib.Web
// If the system is unknown, we can't do anything
string? longName = system.LongName();
if (string.IsNullOrWhiteSpace(longName))
if (string.IsNullOrEmpty(longName))
continue;
Console.Write($"\r{longName}{new string(' ', Console.BufferWidth - longName!.Length - 1)}");
@@ -783,7 +783,7 @@ namespace SabreTools.RedumpLib.Web
// If the system is unknown, we can't do anything
string? longName = system.LongName();
if (string.IsNullOrWhiteSpace(longName))
if (string.IsNullOrEmpty(longName))
continue;
Console.Write($"\r{longName}{new string(' ', Console.BufferWidth - longName!.Length - 1)}");
@@ -803,9 +803,9 @@ namespace SabreTools.RedumpLib.Web
/// <param name="subfolder">Optional subfolder to append to the path</param>
private static void MoveOrDelete(string tempfile, string? newfile, string outDir, string? subfolder)
{
if (!string.IsNullOrWhiteSpace(newfile))
if (!string.IsNullOrEmpty(newfile))
{
if (!string.IsNullOrWhiteSpace(subfolder))
if (!string.IsNullOrEmpty(subfolder))
{
if (!Directory.Exists(Path.Combine(outDir, subfolder)))
Directory.CreateDirectory(Path.Combine(outDir, subfolder));