Author: atsushi
Date: 2005-04-25 02:05:08 -0400 (Mon, 25 Apr 2005)
New Revision: 43531

Added:
   
branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/DataStructures.txt
   branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/LdmlReader.cs
   branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/README
Modified:
   branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog
Log:
2005-04-25  Atsushi Enomoto  <[EMAIL PROTECTED]>

        * README, LdmlReader.cs, DataStructures.txt : new files.



Modified: branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog
===================================================================
--- branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog      
2005-04-25 05:37:20 UTC (rev 43530)
+++ branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog      
2005-04-25 06:05:08 UTC (rev 43531)
@@ -1,5 +1,9 @@
 2005-04-25  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
+       * README, LdmlReader.cs, DataStructures.txt : new files.
+
+2005-04-25  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
        * CodePointIndexer.cs,
          Collation-notes.txt,
          CollationElementTable.template,

Added: 
branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/DataStructures.txt
===================================================================
--- 
branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/DataStructures.txt 
    2005-04-25 05:37:20 UTC (rev 43530)
+++ 
branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/DataStructures.txt 
    2005-04-25 06:05:08 UTC (rev 43531)
@@ -0,0 +1,115 @@
+!!!NOTE!!!  The implementation had been improved without updating this
+document, so some part of it is obsolete.
+
+
+* CharUnicodeInfo internal design
+
+** Normalization information structures
+
+       From    DerivedNormalizationProps.txt
+               NormalizationCorrections.txt
+               UnicodeData.txt
+       To Normalization.cs
+
+       1) byte [] NormalizationPropIndexes (length = 65536)
+
+       2) int [] NormalizationPropValues (length = property value count)
+
+       A value consists of those flags:
+
+       bit     semantics
+       0       NFD_QC
+       1       NFKD_QC
+       2       NFC_QC : NO
+       3       NFC_QC : Maybe
+       4       NFKC_QC : NO
+       5       NFKC_QC : Maybe
+       6       Expands_On_NFD
+       7       Expands_On_NFC
+       8       Expands_On_NKFD
+       9       Expands_On_NKFC
+       10      Full_Composition_Exclusion
+       11-12   index to NormalizationCorrections
+       16-31   FC_NFKC : short[]
+               0 : no replacement;
+               plus - index to SingleNormalization
+               minus - 0xF0000000 and index to MultiNormalization
+
+       3) char [] SingleNormalization
+               FIXME: it should consider NormalizationCorrections.txt
+
+       4) char [] MultiNormalization (index for each 4 bytes, zero padded)
+
+       5) int [] canonicalEq
+       6) int [] canonEquiv : index to canonicalEq
+
+
+** Default Collation Element Table
+
+       From allkeys.txt from UCA
+       To CollationElementTable.cs
+
+       struct SortKeyValue {
+               bool Alt;
+               int Primary;
+               int Secondary;
+               int Thirtiary;
+               int Quartenary;
+       }
+
+       SortKeyValue [] keyValues; of length count of defined values
+
+       struct CollationElementEntry {
+               short Index;
+               short Count;
+       }
+
+       int [] collElem; of length char.MaxValue
+       bits:
+        0-15 : index of top entry to keyValues
+       16-31 : count or 0 (count = 1)
+
+       Indexes are computed for compression (eliminating vast zero-arrays).
+       See CollationElementTableUtil.cs for the implementation.
+
+
+** Combining class information
+
+       From DerivedCombiningClass.txt
+       To CombiningClass.cs
+
+       It generates one simple GetCombiningClass () method.
+
+** Width information
+
+       From EastAsianWidth.txt
+
+       1) WidthType : enum ( : short)
+               values are: N/A/H/W/F/Na (FIXME: descriptive names!)
+
+
+** Case folding information
+
+       FromCaseFolding.txt
+
+       (SpecialCasing.txt is not considered. We could use TextInfo.)
+
+       Common case folding is handled in Char.ToLower(InvariantCulture).
+
+       1) CaseFoldingIndexes : short index to CaseFolding
+
+       2) CaseFoldingDetails : array of CaseFolding structure defined below:
+
+       struct CaseFolding {
+               char Simple;
+               char Full1;
+               char Full2;
+               char Full3;
+       }
+
+
+** Properties which do not consist of tables
+
+       - Hex_Digit, ASCII_Hex_Digit : too few to create tables.
+       - Logical_Order_Exception : too few to create table.
+

Added: 
branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/LdmlReader.cs
===================================================================
--- branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/LdmlReader.cs  
2005-04-25 05:37:20 UTC (rev 43530)
+++ branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/LdmlReader.cs  
2005-04-25 06:05:08 UTC (rev 43531)
@@ -0,0 +1,508 @@
+//
+// LdmlReader.cs
+//
+// Author:
+//     Atsushi Enomoto <[EMAIL PROTECTED]>
+//
+// Parses LDML basic text files.
+//
+// TODO: store parsed LDML data into some kind of structures.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+namespace Mono.Globalization.Unicode
+{
+       public class LdmlException : ApplicationException
+       {
+               public LdmlException (string msg)
+                       : base (msg)
+               {
+               }
+
+               public LdmlException (string msg, int line, int column)
+                       : base (String.Format ("{0} ({1}, {2})", msg, line, 
column))
+               {
+               }
+       }
+
+       public class LdmlConst
+       {
+               public const int Reset = -1;
+               public const int Secondary = -2;
+               public const int Thirtiary = -3;
+               public const int Quarternary = -4;
+               public const int Identical = -5;
+               public const int Before1 = -6;
+               public const int Before2 = -7;
+               public const int Before3 = -8;
+               public const int LastSecondaryIgnorable = -9;
+               public const int LastRegular = -10;
+               public const int ThreeDots = -11;
+       }
+
+       public class LdmlReader
+       {
+               Ldml ldml = new Ldml ();
+               TextReader reader;
+               int line = 1;
+               int column;
+               char [] nameBuffer = new char [128];
+
+               public static void Main (string [] args)
+               {
+                       string dirname = null;
+
+                       foreach (string arg in args) {
+                               // handle options here
+                               dirname = arg;
+                       }
+                       if (dirname == null) {
+                               Console.WriteLine ("pass directory name for 
collation *.txt files");
+                               return;
+                       }
+
+                       foreach (FileInfo fi in new DirectoryInfo 
(dirname).GetFiles ("*.txt"))
+                               if (fi.Name != "root.txt")
+                                       new LdmlReader 
(fi.FullName).ReadCulture ();
+               }
+
+               public LdmlReader (string filename)
+               {
+                       Console.WriteLine ("Filename: " + filename);
+                       reader = new StreamReader (filename, Encoding.UTF8);
+               }
+
+               Exception Error (string msg)
+               {
+                       throw new LdmlException (msg, line, column);
+               }
+
+               int PeekChar ()
+               {
+                       return reader.Peek ();
+               }
+
+               int ReadChar ()
+               {
+                       int i = reader.Read ();
+                       if (i >= 0) {
+                               if (i == '\n') {
+                                       line++;
+                                       column = 0;
+                               }
+                               column++;
+                       }
+                       return i;
+               }
+
+               string ReadLine ()
+               {
+                       line++;
+                       return reader.ReadLine ();
+               }
+
+               void Expect (char c)
+               {
+                       int ch;
+                       if (c != (ch = ReadChar ()))
+                               throw Error (String.Format ("Expected '{0}' 
(#x{1:x}) but was '{2}' (#x{3:x}).", c, (int) c, (char) ch, ch));
+               }
+
+               void Expect (string s)
+               {
+                       foreach (char c in s)
+                               Expect (c);
+               }
+
+               void SkipIgnorables ()
+               {
+                       SkipComments ();
+                       SkipWhitespace ();
+               }
+
+               void SkipWhitespace ()
+               {
+                       int ch;
+                       while ((ch = PeekChar ()) >= 0 && Char.IsWhiteSpace 
((char) ch))
+                               ReadChar ();
+               }
+
+               string ReadName ()
+               {
+                       SkipIgnorables ();
+                       int ch;
+                       if ((ch = PeekChar ()) < 0 || !IsFirstNameChar ((char) 
ch))
+                               throw Error ("Name was expected");
+                       int i = 0;
+                       for (; (ch = PeekChar ()) > 0 && (ch == '_' || 
IsNameChar ((char) ch)); i++)
+                                       nameBuffer [i] = (char) ReadChar ();
+                       if (i == nameBuffer.Length)
+                               throw Error ("Name too long.");
+                       return new string (nameBuffer, 0, i);
+               }
+
+               void ReadCulture ()
+               {
+                       SkipComments ();
+                       SkipIgnorables ();
+                       ldml.Language = ReadName ();
+Console.WriteLine (" Culture name is " + ldml.Language);
+                       SkipIgnorables ();
+                       Expect ('{');
+                       SkipIgnorables ();
+                       while (PeekChar () != '}')
+                               ReadCultureContent ();
+                       ReadChar ();
+                       // successfully read.
+               }
+
+               void ReadCultureContent ()
+               {
+                       string name = ReadName ();
+                       switch (name) {
+                       case "collations":
+                               ReadCollations ();
+                               break;
+                       case "Version":
+                       case "___":
+                               SkipSection ();
+                               break;
+                       default:
+Console.WriteLine ("** " + name);
+                               SkipSection ();
+Console.WriteLine ("   ... done");
+                               break;
+                       }
+                       SkipIgnorables ();
+               }
+
+               void ReadCollations ()
+               {
+                       if (PeekChar () == ':') {
+                               ReadChar ();
+                               Expect ("alias");
+                               SkipWhitespace ();
+                               Expect ('{');
+                               Expect ('"');
+                               SkipWhitespace ();
+                               ldml.Alias = ReadName ();
+                               while (PeekChar () != '"' && PeekChar () >= 0)
+                                       ReadChar ();
+                               Expect ('"');
+                               Expect ('}');
+                               return;
+                       }
+                       Expect ('{');
+                       SkipIgnorables ();
+                       while (PeekChar () != '}') {
+                               string name = ReadName ();
+                               switch (name) {
+                               case "standard":
+                                       Expect ('{');
+                                       ReadStandardCollation ();
+                                       Expect ('}');
+                                       break;
+                               case "big5han":
+                                       Expect ('{');
+                                       ReadBig5HanCollation ();
+                                       Expect ('}');
+                                       break;
+                               default:
+Console.WriteLine ("****** " + name);
+                                       SkipSection ();
+Console.WriteLine ("    ... done.");
+                                       break;
+                               }
+                               SkipWhitespace ();
+                       }
+                       SkipIgnorables ();
+                       Expect ('}');
+               }
+
+               void ReadStandardCollation ()
+               {
+                       SkipIgnorables ();
+                       int ch;
+                       while ((ch = PeekChar ()) >= 0 && IsNameChar ((char) 
ch)) {
+                               string name = ReadName ();
+                               switch (name) {
+                               case "Sequence":
+                                       ReadSequence ();
+                                       break;
+                               default:
+Console.WriteLine ("**** " + name);
+                                       SkipSection ();
+Console.WriteLine ("    ... done.");
+                                       break;
+                               }
+                               SkipWhitespace ();
+                       }
+               }
+
+               void ReadBig5HanCollation ()
+               {
+                       SkipIgnorables ();
+                       int ch;
+                       while ((ch = PeekChar ()) >= 0 && IsNameChar ((char) 
ch)) {
+                               string name = ReadName ();
+                               switch (name) {
+                               case "Sequence":
+//                                     ReadBig5Sequence ();
+                                       ReadSequence ();
+                                       break;
+                               default:
+Console.WriteLine ("******** " + name);
+                                       SkipSection ();
+Console.WriteLine ("    ... done.");
+                                       break;
+                               }
+                               SkipWhitespace ();
+                       }
+               }
+
+               bool IsFirstNameChar (char c)
+               {
+                       return Char.IsLetter (c) || c == '_' || c == '-';
+               }
+
+               bool IsNameChar (char c)
+               {
+                       return IsFirstNameChar (c) || Char.IsDigit (c);
+               }
+
+               void AddValue (int v)
+               {
+                       ldml.AddValue (v);
+               }
+
+               void ReadSequence ()
+               {
+                       SkipIgnorables ();
+                       Expect ('{');
+                       bool loop = true;
+                       bool quoted = false;
+                       while (loop) {
+                               SkipIgnorables ();
+                               if (PeekChar () < 0)
+                                       throw Error ("Unterminated sequence 
section.");
+                               if (PeekChar () == '}')
+                                       break;
+                               if (!quoted) {
+                                       Expect ('"');
+                                       quoted = true;
+                               }
+                               SkipIgnorables ();
+                               switch ((char) PeekChar ()) {
+                               case '"':
+                                       ReadChar ();
+                                       quoted = !quoted;
+                                       break;
+                               case '&':
+                                       ReadChar ();
+                                       if (PeekChar () != '[') {
+                                               AddValue (LdmlConst.Reset); // 
reset
+                                               break;
+                                       }
+                                       ReadChar ();
+                                       SkipIgnorables ();
+                                       string name = ReadName ();
+                                       switch (name) {
+                                       case "before":
+                                               SkipIgnorables ();
+                                               int x = ReadChar ();
+                                               switch (x) {
+                                               case '1':
+                                                       AddValue 
(LdmlConst.Before1);
+                                                       break;
+                                               case '2':
+                                                       AddValue 
(LdmlConst.Before2);
+                                                       break;
+                                               case '3':
+                                                       AddValue 
(LdmlConst.Before3);
+                                                       break;
+                                               default:
+                                                       throw Error ("Not 
supported before : " + (char) x);
+                                               }
+                                               break;
+                                       case "last":
+                                               SkipWhitespace ();
+                                               name = ReadName ();
+                                               switch (name) {
+                                               case "secondary":
+                                                       SkipWhitespace ();
+                                                       Expect ("ignorable");
+                                                       AddValue 
(LdmlConst.LastSecondaryIgnorable);
+                                                       break;
+                                               case "regular":
+                                                       AddValue 
(LdmlConst.LastRegular);
+                                                       break;
+                                               default:
+                                                       throw Error ("Not 
supported last : " + name);
+                                               }
+                                               SkipWhitespace ();
+                                               break;
+                                       default:
+                                               throw Error ("To be supported: 
" + name);
+                                       }
+                                       Expect (']');
+                                       break;
+                               case '<':
+                                       int i = 0;
+                                       for (; PeekChar () == '<'; i++)
+                                               ReadChar ();
+                                       switch (i) {
+                                       case 2:
+                                               AddValue (LdmlConst.Secondary);
+                                               break;
+                                       case 3:
+                                               AddValue (LdmlConst.Thirtiary);
+                                               break;
+                                       case 4:
+                                               AddValue 
(LdmlConst.Quarternary);
+                                               break;
+                                       }
+                                       break;
+                               case '=':
+                                       AddValue (LdmlConst.Identical);
+                                       ReadChar ();
+                                       break;
+                               case '\'':
+                                       ReadChar ();
+                                       if (PeekChar () == '\'') {
+                                               ReadChar ();
+                                               AddValue ('\'');
+                                               break;
+                                       }
+                                       // '\uXXXX'
+                                       else if (PeekChar () == '\\') {
+                                               ReadChar ();
+                                               if (ReadChar () == 'u') {
+                                                       int v = 0;
+                                                       while (true) {
+                                                               int ch = 
PeekChar ();
+                                                               if ('0' <= ch 
&& ch <= '9')
+                                                                       v = v * 
16 + ch - '0';
+                                                               else if ('A' <= 
ch && ch <= 'F')
+                                                                       v = v * 
16 + ch - 'A';
+                                                               else if ('a' <= 
ch && ch <= 'f')
+                                                                       v = v * 
16 + ch - 'a';
+                                                               else
+                                                                       break;
+                                                               ReadChar ();
+                                                       }
+                                                       AddValue ((char) v);
+                                               }
+                                               else
+                                                       AddValue ('}');
+                                       }
+                                       else if (PeekChar () == '.') {
+                                               ReadChar ();
+                                               if (PeekChar () == '.') {
+                                                       Expect ("..");
+                                                       AddValue 
(LdmlConst.ThreeDots);
+                                               }
+                                               else
+                                                       AddValue ('.');
+                                       }
+                                       else
+                                               AddValue ((char) ReadChar ());
+                                       Expect ('\'');
+                                       break;
+                               default:
+                                       AddValue ((char) ReadChar ());
+                                       break;
+                               }
+                       }
+                       Expect ('}');
+               }
+
+               void SkipSection ()
+               {
+                       SkipIgnorables ();
+                       Expect ('{');
+                       bool quoted = false;
+                       for (int count = 1; count > 0;) {
+                               if (PeekChar () < 0)
+                                       throw Error ("Unterminated brace 
section.");
+                               switch (ReadChar ()) {
+                               case '\'':
+                                       count += quoted ? -1 : 1;
+                                       quoted = !quoted;
+                                       break;
+                               case '{':
+                                       if (!quoted)
+                                               count++;
+                                       break;
+                               case '}':
+                                       if (!quoted)
+                                               count--;
+                                       break;
+                               }
+                       }
+               }
+
+               void SkipComments ()
+               {
+                       for (SkipWhitespace ();
+                               PeekChar () == '/';
+                               SkipWhitespace ()) {
+                               ReadChar ();
+                               if (PeekChar () == '/') {
+                                       ReadLine ();
+                                       continue;
+                               }
+                               if (PeekChar () != '*')
+                                       break; // FIXME: it is unsafe (but 
won't happen)
+                               ReadChar ();
+                               bool loop = true;
+                               while (loop) {
+                                       if (PeekChar () < 0)
+                                               throw Error ("Invalid LDML 
basic document");
+                                       // can't ReadChar() at second step,
+                                       // since * might be sequential.
+                                       if (ReadChar () == '*' && PeekChar () 
== '/')
+                                               break;
+                               }
+                               ReadChar (); // '/'
+                       }
+               }
+       }
+
+       public class Ldml
+       {
+               public string Language;
+               public string [] ValidSubLocales;
+
+               // Store only standard collation (except for Chinese which
+               // has "big5han" for the standard collation).
+
+               // There is only on "rules"
+
+               public string Alias;
+
+               int [] rules = new int [200];
+               int ruleLength;
+
+               // it could be transient (might result in different instance in 
the end).
+               public int [] Rules {
+                       get { return rules; }
+               }
+
+               public int RuleLength {
+                       get { return ruleLength; }
+               }
+
+               public void AddValue (int value)
+               {
+                       if (ruleLength == rules.Length) {
+                               int [] tmp = new int [ruleLength * 2];
+                               Array.Copy (rules, tmp, ruleLength);
+                               rules = tmp;
+                       }
+               }
+       }
+}

Added: branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/README
===================================================================
--- branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/README 
2005-04-25 05:37:20 UTC (rev 43530)
+++ branches/atsushi/mcs/class/corlib/Mono.Globalization.Unicode/README 
2005-04-25 06:05:08 UTC (rev 43531)
@@ -0,0 +1,13 @@
+
+This directory contains support for Unicode normalization and collation.
+
+This branch contains Normalization.cs and CollationElementTable.cs which
+can be built from generator executables and Unicode Character Database found
+at unicode.org (see Makefile for details).
+
+Many of the files in this directory are subject to change (for example,
+being rewritten to generate C header like char-conversions.h and
+culture-info-table.h).
+
+Atsushi Eno <[EMAIL PROTECTED]>
+

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to