Added support for kRSUnicode/Unicode_Radical_Stroke.

This commit is contained in:
GoldenCrystal
2014-11-24 02:36:09 +01:00
parent 76e5b5f0ba
commit 475e9c5e44
12 changed files with 208 additions and 10 deletions
+2
View File
@@ -123,6 +123,7 @@ This library includes a subset of the official [Unicode Character Database](http
* ID_Continue * ID_Continue
* XID_Start * XID_Start
* XID_Continue * XID_Continue
* Unicode_Radical_Stroke (This is actually kRSUnicode from the Unihan database)
* Code point cross references extracted from NamesList.txt * Code point cross references extracted from NamesList.txt
NB: The UCD property ISO_Comment will never be included since this one is empty in all new Unicode versions. NB: The UCD property ISO_Comment will never be included since this one is empty in all new Unicode versions.
@@ -131,6 +132,7 @@ NB: The UCD property ISO_Comment will never be included since this one is empty
* kAccountingNumeric * kAccountingNumeric
* kOtherNumeric * kOtherNumeric
* kPrimaryNumeric * kPrimaryNumeric
* kRSUnicode
* kDefinition * kDefinition
* kMandarin * kMandarin
* kCantonese * kCantonese
+1
View File
@@ -32,6 +32,7 @@ namespace System.Unicode.Builder
"Unihan_NumericValues.txt", "Unihan_NumericValues.txt",
"Unihan_Readings.txt", "Unihan_Readings.txt",
"Unihan_Variants.txt", "Unihan_Variants.txt",
"Unihan_IRGSources.txt",
}; };
private static HttpMessageHandler httpMessageHandler; private static HttpMessageHandler httpMessageHandler;
@@ -19,6 +19,7 @@ namespace System.Unicode.Builder
public const string UnihanReadingsFileName = "Unihan_Readings.txt"; public const string UnihanReadingsFileName = "Unihan_Readings.txt";
public const string UnihanVariantsFileName = "Unihan_Variants.txt"; public const string UnihanVariantsFileName = "Unihan_Variants.txt";
public const string UnihanNumericValuesFileName = "Unihan_NumericValues.txt"; public const string UnihanNumericValuesFileName = "Unihan_NumericValues.txt";
public const string UnihanIrgSourcesFileName = "Unihan_IRGSources.txt";
private static string ParseSimpleCaseMapping(string mapping) private static string ParseSimpleCaseMapping(string mapping)
{ {
@@ -45,6 +46,7 @@ namespace System.Unicode.Builder
await ProcessUnihanReadings(unihanSource, builder).ConfigureAwait(false); await ProcessUnihanReadings(unihanSource, builder).ConfigureAwait(false);
await ProcessUnihanVariants(unihanSource, builder).ConfigureAwait(false); await ProcessUnihanVariants(unihanSource, builder).ConfigureAwait(false);
await ProcessUnihanNumericValues(unihanSource, builder).ConfigureAwait(false); await ProcessUnihanNumericValues(unihanSource, builder).ConfigureAwait(false);
await ProcessUnihanIrgSources(unihanSource, builder).ConfigureAwait(false);
return builder; return builder;
} }
@@ -438,5 +440,48 @@ namespace System.Unicode.Builder
} }
} }
} }
private static async Task ProcessUnihanIrgSources(IDataSource unihanDataSource, UnicodeInfoBuilder builder)
{
using (var reader = new UnihanDataFileReader(await unihanDataSource.OpenDataFileAsync(UnihanIrgSourcesFileName).ConfigureAwait(false)))
{
while (reader.Read())
{
switch (reader.PropertyName)
{
case UnihanProperty.kRSUnicode:
var entry = builder.GetUnihan(reader.CodePoint);
var values = reader.PropertyValue.Split(' ');
foreach (var value in values)
{
bool isSimplified = false;
int index;
for (int i = 0; i < value.Length; ++i)
{
switch (value[i])
{
case '\'':
isSimplified = true;
goto case '.';
case '.':
index = i;
goto SeparatorFound;
}
}
throw new InvalidDataException("Failed to decode value for kRSUnicode / Unicode_Radical_Stroke.");
SeparatorFound: ;
entry.UnicodeRadicalStrokeCounts.Add(new UnicodeRadicalStrokeCount(byte.Parse(value.Substring(0, index), NumberStyles.None), byte.Parse(value.Substring(index + (isSimplified ? 2 : 1)), NumberStyles.None), isSimplified));
}
break;
default:
// Ignore unhandled properties for now.
break;
}
}
}
}
} }
} }
@@ -23,6 +23,8 @@ namespace System.Unicode.Builder
private string simplifiedVariant; private string simplifiedVariant;
private string traditionalVariant; private string traditionalVariant;
private readonly List<UnicodeRadicalStrokeCount> unicodeRadicalStrokeCounts = new List<UnicodeRadicalStrokeCount>();
public int CodePoint { get { return codePoint; } } public int CodePoint { get { return codePoint; } }
public UnihanNumericType NumericType { get { return numericType; } set { numericType = value; } } public UnihanNumericType NumericType { get { return numericType; } set { numericType = value; } }
public long NumericValue { get { return numericValue; } set { numericValue = value; } } public long NumericValue { get { return numericValue; } set { numericValue = value; } }
@@ -36,6 +38,7 @@ namespace System.Unicode.Builder
public string VietnameseReading { get { return vietnameseReading; } set { vietnameseReading = value; } } public string VietnameseReading { get { return vietnameseReading; } set { vietnameseReading = value; } }
public string SimplifiedVariant { get { return simplifiedVariant; } set { simplifiedVariant = value; } } public string SimplifiedVariant { get { return simplifiedVariant; } set { simplifiedVariant = value; } }
public string TraditionalVariant { get { return traditionalVariant; } set { traditionalVariant = value; } } public string TraditionalVariant { get { return traditionalVariant; } set { traditionalVariant = value; } }
public ICollection<UnicodeRadicalStrokeCount> UnicodeRadicalStrokeCounts { get { return unicodeRadicalStrokeCounts; } }
internal UnihanCharacterDataBuilder(int codePoint) internal UnihanCharacterDataBuilder(int codePoint)
{ {
@@ -49,6 +52,7 @@ namespace System.Unicode.Builder
codePoint, codePoint,
numericType, numericType,
numericValue, numericValue,
unicodeRadicalStrokeCounts.ToArray(),
definition, definition,
mandarinReading, mandarinReading,
cantoneseReading, cantoneseReading,
@@ -67,6 +71,14 @@ namespace System.Unicode.Builder
UnihanFields fields = default(UnihanFields); UnihanFields fields = default(UnihanFields);
fields |= (UnihanFields)NumericType; fields |= (UnihanFields)NumericType;
// For now, we have enough bits to encode the length of the array in the field specifier, so we'll do that.
// (NB: A quick analysis of the files revealed thare there are almost always exactly one Radical/Stroke count, and occasionally two, yet never more.)
if (unicodeRadicalStrokeCounts.Count > 0)
{
if (unicodeRadicalStrokeCounts.Count == 1) fields |= UnihanFields.UnicodeRadicalStrokeCount;
else if (unicodeRadicalStrokeCounts.Count == 2) fields |= UnihanFields.UnicodeRadicalStrokeCountTwice;
else fields |= UnihanFields.UnicodeRadicalStrokeCount | UnihanFields.UnicodeRadicalStrokeCountTwice;
}
if (Definition != null) fields |= UnihanFields.Definition; if (Definition != null) fields |= UnihanFields.Definition;
if (MandarinReading != null) fields |= UnihanFields.MandarinReading; if (MandarinReading != null) fields |= UnihanFields.MandarinReading;
if (CantoneseReading != null) fields |= UnihanFields.CantoneseReading; if (CantoneseReading != null) fields |= UnihanFields.CantoneseReading;
@@ -81,6 +93,17 @@ namespace System.Unicode.Builder
writer.Write((ushort)fields); writer.Write((ushort)fields);
writer.WriteCodePoint(UnihanCharacterData.PackCodePoint(codePoint)); writer.WriteCodePoint(UnihanCharacterData.PackCodePoint(codePoint));
if ((fields & UnihanFields.UnicodeRadicalStrokeCountMore) != 0)
{
if ((fields & (UnihanFields.UnicodeRadicalStrokeCountMore)) == UnihanFields.UnicodeRadicalStrokeCountMore)
writer.Write(checked((byte)(unicodeRadicalStrokeCounts.Count - 3)));
foreach (var radicalStrokeCount in unicodeRadicalStrokeCounts)
{
writer.Write(radicalStrokeCount.Radical);
writer.Write((byte)(radicalStrokeCount.StrokeCount | (radicalStrokeCount.IsSimplified ? 0x80 : 0)));
}
}
if ((fields & UnihanFields.OtherNumeric) != 0) writer.Write(numericValue); if ((fields & UnihanFields.OtherNumeric) != 0) writer.Write(numericValue);
if ((fields & UnihanFields.Definition) != 0) writer.Write(Definition); if ((fields & UnihanFields.Definition) != 0) writer.Write(Definition);
if ((fields & UnihanFields.MandarinReading) != 0) writer.Write(MandarinReading); if ((fields & UnihanFields.MandarinReading) != 0) writer.Write(MandarinReading);
+2
View File
@@ -52,6 +52,8 @@ namespace System.Unicode
public ContributoryProperties ContributoryProperties { get { return unicodeCharacterData?.ContributoryProperties ?? 0; } } public ContributoryProperties ContributoryProperties { get { return unicodeCharacterData?.ContributoryProperties ?? 0; } }
public CoreProperties CoreProperties { get { return unicodeCharacterData?.CoreProperties ?? 0; } } public CoreProperties CoreProperties { get { return unicodeCharacterData?.CoreProperties ?? 0; } }
public UnicodeCrossReferenceCollection CrossRerefences { get { return new UnicodeCrossReferenceCollection(unicodeCharacterData?.CrossRerefences); } } public UnicodeCrossReferenceCollection CrossRerefences { get { return new UnicodeCrossReferenceCollection(unicodeCharacterData?.CrossRerefences); } }
[ValueName("kRSUnicode"), ValueName("cjkRSUnicode"), ValueName("Unicode_Radical_Stroke"), ValueName("URS")]
public UnicodeRadicalStrokeCountCollection UnicodeRadicalStrokeCounts { get { return new UnicodeRadicalStrokeCountCollection(unihanCharacterData?.UnicodeRadicalStrokeCounts); } }
[ValueName("kDefinition")] [ValueName("kDefinition")]
public string Definition { get { return unihanCharacterData?.Definition; } } public string Definition { get { return unihanCharacterData?.Definition; } }
+13
View File
@@ -185,6 +185,18 @@ namespace System.Unicode
reader.ReadInt64() : reader.ReadInt64() :
0; 0;
UnicodeRadicalStrokeCount[] unicodeRadicalStrokeCounts = (fields & UnihanFields.UnicodeRadicalStrokeCountMore) != 0 ?
new UnicodeRadicalStrokeCount
[
(fields & UnihanFields.UnicodeRadicalStrokeCountMore) == UnihanFields.UnicodeRadicalStrokeCountMore ?
reader.ReadByte() + 3 :
((byte)(fields & UnihanFields.UnicodeRadicalStrokeCountMore) >> 2)
] :
UnicodeRadicalStrokeCount.EmptyArray;
for (int i = 0; i < unicodeRadicalStrokeCounts.Length; ++i)
unicodeRadicalStrokeCounts[i] = new UnicodeRadicalStrokeCount(reader.ReadByte(), reader.ReadByte());
string definition = (fields & UnihanFields.Definition) != 0 ? reader.ReadString() : null; string definition = (fields & UnihanFields.Definition) != 0 ? reader.ReadString() : null;
string mandarinReading = (fields & UnihanFields.MandarinReading) != 0 ? reader.ReadString() : null; string mandarinReading = (fields & UnihanFields.MandarinReading) != 0 ? reader.ReadString() : null;
string cantoneseReading = (fields & UnihanFields.CantoneseReading) != 0 ? reader.ReadString() : null; string cantoneseReading = (fields & UnihanFields.CantoneseReading) != 0 ? reader.ReadString() : null;
@@ -201,6 +213,7 @@ namespace System.Unicode
codePoint, codePoint,
numericType, numericType,
numericValue, numericValue,
unicodeRadicalStrokeCounts,
definition, definition,
mandarinReading, mandarinReading,
cantoneseReading, cantoneseReading,
@@ -67,6 +67,7 @@
<Compile Include="CoreProperties.cs" /> <Compile Include="CoreProperties.cs" />
<Compile Include="HangulInfo.cs" /> <Compile Include="HangulInfo.cs" />
<Compile Include="UnicodeCrossReferenceCollection.cs" /> <Compile Include="UnicodeCrossReferenceCollection.cs" />
<Compile Include="UnicodeRadicalStrokeCountCollection.cs" />
<Compile Include="UnicodeNameAliasCollection.cs" /> <Compile Include="UnicodeNameAliasCollection.cs" />
<Compile Include="UcdFields.cs" /> <Compile Include="UcdFields.cs" />
<Compile Include="EnumHelper.cs" /> <Compile Include="EnumHelper.cs" />
@@ -81,6 +82,7 @@
<Compile Include="UnicodeInfo.cs" /> <Compile Include="UnicodeInfo.cs" />
<Compile Include="UnicodeNameAlias.cs" /> <Compile Include="UnicodeNameAlias.cs" />
<Compile Include="UnicodeNameAliasKind.cs" /> <Compile Include="UnicodeNameAliasKind.cs" />
<Compile Include="UnicodeRadicalStrokeCount.cs" />
<Compile Include="UnihanNumericType.cs" /> <Compile Include="UnihanNumericType.cs" />
<Compile Include="UnicodeNumericType.cs" /> <Compile Include="UnicodeNumericType.cs" />
<Compile Include="UnihanCharacterData.cs" /> <Compile Include="UnihanCharacterData.cs" />
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System.Unicode
{
public struct UnicodeRadicalStrokeCount
{
internal static readonly UnicodeRadicalStrokeCount[] EmptyArray = new UnicodeRadicalStrokeCount[0];
private readonly byte radical;
private readonly byte strokeCount;
internal UnicodeRadicalStrokeCount(byte rawRadical, byte rawStrokeCount)
{
radical = rawRadical;
strokeCount = rawStrokeCount;
}
internal UnicodeRadicalStrokeCount(byte radical, byte strokeCount, bool isSimplified)
{
this.radical = radical;
this.strokeCount = strokeCount;
if (isSimplified) this.strokeCount |= 0x80;
}
public byte Radical { get { return radical; } }
public byte StrokeCount { get { return strokeCount; } }
public bool IsSimplified { get { return (strokeCount & 0x80) != 0; } }
}
}
@@ -0,0 +1,68 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System.Unicode
{
public struct UnicodeRadicalStrokeCountCollection : IList<UnicodeRadicalStrokeCount>
{
public struct Enumerator : IEnumerator<UnicodeRadicalStrokeCount>
{
private readonly UnicodeRadicalStrokeCount[] items;
private int index;
internal Enumerator(UnicodeRadicalStrokeCount[] items)
{
this.items = items;
this.index = -1;
}
public void Dispose() { }
public UnicodeRadicalStrokeCount Current { get { return items[index]; } }
object IEnumerator.Current { get { return Current; } }
public bool MoveNext() { return index < items.Length && ++index < items.Length; }
void IEnumerator.Reset() { this.index = -1; }
}
private readonly UnicodeRadicalStrokeCount[] items;
public UnicodeRadicalStrokeCountCollection() { items = UnicodeRadicalStrokeCount.EmptyArray; }
internal UnicodeRadicalStrokeCountCollection(UnicodeRadicalStrokeCount[] items) { this.items = items ?? UnicodeRadicalStrokeCount.EmptyArray; }
public UnicodeRadicalStrokeCount this[int index] { get { return items[index]; } }
UnicodeRadicalStrokeCount IList<UnicodeRadicalStrokeCount>.this[int index]
{
get { return items[index]; }
set { throw new NotSupportedException(); }
}
public int Count { get { return items.Length; } }
bool ICollection<UnicodeRadicalStrokeCount>.IsReadOnly { get { return true; } }
public void Add(UnicodeRadicalStrokeCount item) { throw new NotSupportedException(); }
public void Insert(int index, UnicodeRadicalStrokeCount item) { throw new NotSupportedException(); }
public bool Remove(UnicodeRadicalStrokeCount item) { throw new NotSupportedException(); }
public void RemoveAt(int index) { throw new NotSupportedException(); }
public void Clear() { throw new NotSupportedException(); }
public int IndexOf(UnicodeRadicalStrokeCount item) { return Array.IndexOf(items, item); }
public bool Contains(UnicodeRadicalStrokeCount item) { return IndexOf(item) >= 0; }
public void CopyTo(UnicodeRadicalStrokeCount[] array, int arrayIndex) { items.CopyTo(array, arrayIndex); }
public Enumerator GetEnumerator() { return new Enumerator(items); }
IEnumerator<UnicodeRadicalStrokeCount> IEnumerable<UnicodeRadicalStrokeCount>.GetEnumerator() { return GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
}
@@ -11,6 +11,7 @@ namespace System.Unicode
public readonly int CodePoint; public readonly int CodePoint;
public readonly UnihanNumericType NumericType; public readonly UnihanNumericType NumericType;
public readonly long NumericValue; public readonly long NumericValue;
public readonly UnicodeRadicalStrokeCount[] UnicodeRadicalStrokeCounts;
public readonly string Definition; public readonly string Definition;
public readonly string MandarinReading; public readonly string MandarinReading;
public readonly string CantoneseReading; public readonly string CantoneseReading;
@@ -27,6 +28,7 @@ namespace System.Unicode
int codePoint, int codePoint,
UnihanNumericType numericType, UnihanNumericType numericType,
long numericValue, long numericValue,
UnicodeRadicalStrokeCount[] unicodeRadicalStrokeCounts,
string definition, string definition,
string mandarinReading, string mandarinReading,
string cantoneseReading, string cantoneseReading,
@@ -42,6 +44,7 @@ namespace System.Unicode
CodePoint = codePoint; CodePoint = codePoint;
NumericType = numericType; NumericType = numericType;
NumericValue = numericValue; NumericValue = numericValue;
UnicodeRadicalStrokeCounts = unicodeRadicalStrokeCounts;
Definition = definition; Definition = definition;
MandarinReading = mandarinReading; MandarinReading = mandarinReading;
CantoneseReading = cantoneseReading; CantoneseReading = cantoneseReading;
+15 -10
View File
@@ -14,16 +14,21 @@ namespace System.Unicode
AccountingNumeric = 2, AccountingNumeric = 2,
OtherNumeric = 3, OtherNumeric = 3,
Definition = 4, // UnicodeRadicalStroke : Not exactly a bit mask…
MandarinReading = 8, UnicodeRadicalStrokeCount = 4, // Will indicate exactly one value for Unicode_Radical_Stroke.
CantoneseReading = 16, UnicodeRadicalStrokeCountTwice = 8, // Will indicate exactly two values for Unicode_Radical_Stroke.
JapaneseKunReading = 32, UnicodeRadicalStrokeCountMore = 12, // Will indicate three or more values for Unicode_Radical_Stroke. This combination should never happen in the current files.
JapaneseOnReading = 64,
KoreanReading = 128,
HangulReading = 256,
VietnameseReading = 512,
SimplifiedVariant = 1024, Definition = 16,
TraditionalVariant = 2048, MandarinReading = 32,
CantoneseReading = 64,
JapaneseKunReading = 128,
JapaneseOnReading = 256,
KoreanReading = 512,
HangulReading = 1024,
VietnameseReading = 2048,
SimplifiedVariant = 4096,
TraditionalVariant = 8192,
} }
} }
Binary file not shown.