diff --git a/UnicodeInformation.Builder/BinaryWriterExtensions.cs b/UnicodeInformation.Builder/BinaryWriterExtensions.cs
index 3f97206..cbd13b4 100644
--- a/UnicodeInformation.Builder/BinaryWriterExtensions.cs
+++ b/UnicodeInformation.Builder/BinaryWriterExtensions.cs
@@ -57,20 +57,22 @@ namespace System.Unicode.Builder
/// The name alias value to write.
public static void WriteNameAliasToFile(this BinaryWriter writer, UnicodeNameAlias nameAlias)
{
- WriteNameToFile(writer, (byte)(nameAlias.Kind - 1), nameAlias.Name);
+ // This method will stuff two extra bits together with the byte count, provided that this one doesn't exceed 64.
+ var bytes = Encoding.UTF8.GetBytes(nameAlias.Name);
+ if (bytes.Length > 64) throw new InvalidOperationException("Did not expect UTF-8 encoded name aliases to be longer than 64 bytes.");
+ writer.WritePackedLength((byte)(nameAlias.Kind - 1), nameAlias.Name.Length);
+ writer.Write(bytes);
}
/// Writes a character name, packing two information bits along with the length.
- /// We assume that character names will not exceed 64 bytes in length.
+ /// We assume that character names will not exceed 128 bytes in length.
/// The writer to use.
- /// Extra bits to pack with the 6 bit length.
/// The name to write.
- public static void WriteNameToFile(this BinaryWriter writer, byte extraBits, string name)
+ public static void WriteNamePropertyToFile(this BinaryWriter writer, string name)
{
- // This method will stuff two extra bits together with the byte count, provided that this one doesn't exceed 64.
var bytes = Encoding.UTF8.GetBytes(name);
- if (bytes.Length > 64) throw new InvalidOperationException("Did not expect UTF-8 encoded names to be longer than 64 bytes.");
- writer.WritePackedLength(extraBits, name.Length);
+ if (bytes.Length > 128) throw new InvalidOperationException("Did not expect UTF-8 encoded name to be longer than 128 bytes.");
+ writer.Write((byte)(name.Length - 1)); // The most significant bit will always be cleared, because it will be used for other cases.
writer.Write(bytes);
}
diff --git a/UnicodeInformation.Builder/UnicodeCharacterDataBuilder.cs b/UnicodeInformation.Builder/UnicodeCharacterDataBuilder.cs
index e0c17de..b4dff85 100644
--- a/UnicodeInformation.Builder/UnicodeCharacterDataBuilder.cs
+++ b/UnicodeInformation.Builder/UnicodeCharacterDataBuilder.cs
@@ -193,29 +193,24 @@ namespace System.Unicode.Builder
if ((fields & UcdFields.Name) != 0)
{
// We write the names by optimizing for the common case.
- // i.e. Most characters have one name, and most of those characters have only one name.
- // In the first byte, we will encode a 6bit length, along with two extra bits describing the structure:
- // 00: The common case, this byte is the length of the name, and no other name follows.
- // 01: This byte is the length of the name, and one alias follows.
- // 10: This byte is the length of the name, and the number of aliases follows.
- // 11: This byte is the number of aliases.
-
- if (name == null)
- {
- writer.WritePackedLength(3, nameAliases.Count);
- }
- else
- {
- writer.WriteNameToFile((byte)(nameAliases.Count > 0 ? nameAliases.Count > 1 ? 2 : 1 : 0), name);
- }
+ // i.e. Most characters have only one name.
+ // The first 8 bit sequence will encore either the length of the name property alone,
+ // or the number of aliases and a bit indicating the presence of the name property.
if (nameAliases.Count > 0)
{
- if (name != null) writer.Write((byte)nameAliases.Count);
+ writer.WritePackedLength((byte)(name != null ? 3 : 2), nameAliases.Count);
+
+ if (name != null)
+ writer.WriteNamePropertyToFile(name);
foreach (var nameAlias in nameAliases)
writer.WriteNameAliasToFile(nameAlias);
}
+ else
+ {
+ writer.WriteNamePropertyToFile(name);
+ }
}
if ((fields & UcdFields.Category) != 0) writer.Write((byte)category);
if ((fields & UcdFields.CanonicalCombiningClass) != 0) writer.Write((byte)canonicalCombiningClass);
diff --git a/UnicodeInformation/UnicodeInfo.cs b/UnicodeInformation/UnicodeInfo.cs
index e409f4a..a2bde78 100644
--- a/UnicodeInformation/UnicodeInfo.cs
+++ b/UnicodeInformation/UnicodeInfo.cs
@@ -43,7 +43,7 @@ namespace System.Unicode
var fileUnicodeVersion = new Version(reader.ReadUInt16(), reader.ReadByte());
var unicodeCharacterDataEntries = new UnicodeCharacterData[ReadCodePoint(reader)];
- byte[] nameBuffer = new byte[64];
+ byte[] nameBuffer = new byte[128];
for (int i = 0; i < unicodeCharacterDataEntries.Length; ++i)
{
@@ -85,23 +85,25 @@ namespace System.Unicode
{
int length = reader.ReadByte();
byte @case = (byte)(length & 0xC0);
- length = (length & 0x3F) + 1;
- if (@case < 0xC0) // These cases have an official name.
+ if (@case < 0x80) // Handles the case where only the name is present.
{
- if (@case != 0)
- {
- }
+ length = (length & 0x7F) + 1;
if (reader.Read(nameBuffer, 0, length) != length) throw new EndOfStreamException();
name = Encoding.UTF8.GetString(nameBuffer, 0, length);
- if (@case == 2) length = (reader.ReadByte() & 0x3F) + 1;
- else length = @case;
}
-
- if (length > 0) // These cases have official name aliases.
+ else
{
- nameAliases = new UnicodeNameAlias[length];
+ nameAliases = new UnicodeNameAlias[(length & 0x3F) + 1];
+
+ if ((@case & 0x40) != 0)
+ {
+ length = reader.ReadByte() + 1;
+ if (length > 128) throw new InvalidDataException("Did not expect names longer than 128 bytes.");
+ if (reader.Read(nameBuffer, 0, length) != length) throw new EndOfStreamException();
+ name = Encoding.UTF8.GetString(nameBuffer, 0, length);
+ }
for (int i = 0; i < nameAliases.Length; ++i)
{
@@ -111,7 +113,7 @@ namespace System.Unicode
if (reader.Read(nameBuffer, 0, length) != length) throw new EndOfStreamException();
nameAliases[i] = new UnicodeNameAlias(Encoding.UTF8.GetString(nameBuffer, 0, length), aliasKind);
- }
+ }
}
}
diff --git a/UnicodeInformation/ucd.dat b/UnicodeInformation/ucd.dat
index a0e3743..806a960 100644
Binary files a/UnicodeInformation/ucd.dat and b/UnicodeInformation/ucd.dat differ