Implemented character decomposition mapping propertu parsing.

This commit is contained in:
GoldenCrystal
2014-11-07 01:05:40 +01:00
parent 3fe63595e7
commit 6af111f799
12 changed files with 191 additions and 18 deletions
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System.Unicode.Builder
{
public struct CharacterDecompositionMapping
{
public readonly CompatibilityFormattingTag DecompositionType;
public readonly string DecompositionMapping;
public CharacterDecompositionMapping(CompatibilityFormattingTag decompositionType, string decompositionMapping)
{
this.DecompositionType = decompositionType;
this.DecompositionMapping = decompositionMapping;
}
public unsafe static CharacterDecompositionMapping Parse(string s)
{
if (string.IsNullOrEmpty(s)) return default(CharacterDecompositionMapping);
CompatibilityFormattingTag tag = CompatibilityFormattingTag.Canonical;
int index;
if (s[0] == '<')
{
if (!EnumHelper<CompatibilityFormattingTag>.TryGetNamedValue(s.Substring(1, (index = s.IndexOf('>')) - 1), out tag))
throw new FormatException();
++index;
}
else
{
index = 0;
}
var buffer = stackalloc char[36]; // From the Unicode docs, a decomposition cannot have more than 18 code points.
int charIndex = 0;
while (index < s.Length && charIndex < 35)
{
char c = s[index];
if (c == ' ') ++index;
else
{
int codePoint = ParseCodePoint(s, ref index);
if (codePoint < 0x10000)
buffer[charIndex++] = (char)codePoint;
else if (codePoint < 0x10FFFF)
{
codePoint -= 0x10000;
buffer[charIndex++] = (char)((codePoint >> 10) + 0xD800);
buffer[charIndex++] = (char)((codePoint & 0x3FF) + 0xDC00);
}
else
{
throw new FormatException("The code point was outside of the allowed range.");
}
}
}
return new CharacterDecompositionMapping(tag, new string(buffer, 0, charIndex));
}
private static int ParseCodePoint(string s, ref int index)
{
int i = index;
int accum = 0;
while (i < s.Length)
{
char c = s[i];
if (c == ' ') break;
accum <<= 4;
if (c >= '0' && c <= '9') accum |= c - '0';
else if (c >= 'A' && c <= 'F') accum |= c - 'A' + 0xA;
else if (c >= 'a' && c <= 'f') accum |= c - 'a' + 0xA;
else throw new FormatException();
++i;
}
index = i;
return accum;
}
}
}
@@ -15,7 +15,7 @@ namespace System.Unicode.Builder
private UnicodeCategory category = UnicodeCategory.OtherNotAssigned;
private CanonicalCombiningClass canonicalCombiningClass;
private BidirectionalClass bidirectionalClass;
private string decompositionType;
private CharacterDecompositionMapping characterDecompositionMapping;
private UnicodeNumericType numericType;
private UnicodeRationalNumber numericValue;
private bool bidirectionalMirrored;
@@ -60,10 +60,10 @@ namespace System.Unicode.Builder
set { bidirectionalClass = value; }
}
public string DecompositionType
public CharacterDecompositionMapping CharacterDecompositionMapping
{
get { return decompositionType; }
set { decompositionType = value; }
get { return characterDecompositionMapping; }
set { characterDecompositionMapping = value; }
}
public UnicodeNumericType NumericType
@@ -136,7 +136,8 @@ namespace System.Unicode.Builder
category,
canonicalCombiningClass,
bidirectionalClass,
decompositionType,
characterDecompositionMapping.DecompositionType,
characterDecompositionMapping.DecompositionMapping,
numericType,
numericValue,
bidirectionalMirrored,
@@ -159,7 +160,7 @@ namespace System.Unicode.Builder
if (category != UnicodeCategory.OtherNotAssigned) fields |= UcdFields.Category;
if (canonicalCombiningClass != CanonicalCombiningClass.NotReordered) fields |= UcdFields.CanonicalCombiningClass;
/*if (bidirectionalClass != 0)*/fields |= UcdFields.BidirectionalClass;
if (decompositionType != null) fields |= UcdFields.DecompositionType;
if (characterDecompositionMapping.DecompositionMapping != null) fields |= UcdFields.DecompositionMapping;
fields |= (UcdFields)((int)numericType << 6);
if (bidirectionalMirrored) fields |= UcdFields.BidirectionalMirrored;
if (oldName != null) fields |= UcdFields.OldName;
@@ -177,7 +178,11 @@ namespace System.Unicode.Builder
if ((fields & UcdFields.Category) != 0) writer.Write((byte)category);
if ((fields & UcdFields.CanonicalCombiningClass) != 0) writer.Write((byte)canonicalCombiningClass);
if ((fields & UcdFields.BidirectionalClass) != 0) writer.Write((byte)bidirectionalClass);
if ((fields & UcdFields.DecompositionType) != 0) writer.Write(decompositionType);
if ((fields & UcdFields.DecompositionMapping) != 0)
{
writer.Write((byte)characterDecompositionMapping.DecompositionType);
writer.Write(characterDecompositionMapping.DecompositionMapping);
}
if ((fields & UcdFields.NumericNumeric) != 0)
{
writer.Write(numericValue.Numerator);
@@ -89,7 +89,7 @@ namespace System.Unicode.Builder
throw new InvalidDataException(string.Format("Missing Bidi_Class property for code point(s) {0}.", codePoint));
}
characterData.DecompositionType = NullIfEmpty(reader.ReadField());
characterData.CharacterDecompositionMapping = CharacterDecompositionMapping.Parse(NullIfEmpty(reader.ReadField()));
string numericDecimalField = NullIfEmpty(reader.ReadField());
string numericDigitField = NullIfEmpty(reader.ReadField());
@@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -30,6 +31,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
@@ -51,6 +53,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="BinaryWriterExtensions.cs" />
<Compile Include="CharacterDecompositionMapping.cs" />
<Compile Include="FileUcdSource.cs" />
<Compile Include="HttpUcdSource.cs" />
<Compile Include="IUcdSource.cs" />