]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/RBNFChinesePostProcessor.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / RBNFChinesePostProcessor.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2004-2006, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 package com.ibm.icu.text;\r
9 \r
10 import com.ibm.icu.impl.Utility;\r
11 \r
12 /**\r
13  * A post-processor for Chinese text.\r
14  */\r
15 final class RBNFChinesePostProcessor implements RBNFPostProcessor {\r
16     private NFRuleSet lastRuleSet;\r
17     private boolean longForm;\r
18     private int format;\r
19 \r
20     private static final String[] rulesetNames = {\r
21         "%traditional", "%simplified", "%accounting", "%time"\r
22     };\r
23 \r
24     /**\r
25      * Initialization routine for this instance, called once\r
26      * immediately after first construction and never again.  \r
27      */\r
28     public void init(RuleBasedNumberFormat formatter, String rules) {\r
29     }\r
30 \r
31     /**\r
32      * Work routine.  Post process the output, which was generated by the\r
33      * ruleset with the given name.\r
34      */\r
35     public void process(StringBuffer buf, NFRuleSet ruleSet) {\r
36         // markers depend on what rule set we are using\r
37 \r
38         if (ruleSet != lastRuleSet) {\r
39             String name = ruleSet.getName();\r
40             for (int i = 0; i < rulesetNames.length; ++i) {\r
41                 if (rulesetNames[i].equals(name)) {\r
42                     format = i;\r
43                     longForm = i == 1 || i == 3;\r
44                     break;\r
45                 }\r
46             }\r
47         }\r
48 \r
49         if (longForm) {\r
50             for (int i = Utility.indexOf(buf,"*"); i != -1; i = Utility.indexOf(buf, "*", i)) {\r
51                 buf.delete(i, i+1);\r
52             }\r
53             return;\r
54         }\r
55 \r
56         final String DIAN = "\u9ede"; // decimal point\r
57 \r
58         final String[][] markers = {\r
59             { "\u842c", "\u5104", "\u5146", "\u3007" }, // marker chars, last char is the 'zero'\r
60             { "\u4e07", "\u4ebf", "\u5146", "\u3007" },\r
61             { "\u842c", "\u5104", "\u5146", "\u96f6" }\r
62             // need markers for time?\r
63         };\r
64 \r
65         // remove unwanted lings\r
66         // a '0' (ling) with * might be removed\r
67         // mark off 10,000 'chunks', markers are Z, Y, W (zhao, yii, and wan)\r
68         // already, we avoid two lings in the same chunk -- ling without * wins\r
69         // now, just need  to avoid optional lings in adjacent chunks\r
70         // process right to left\r
71 \r
72         // decision matrix:\r
73         // state, situation\r
74         //     state         none       opt.          req.\r
75         //     -----         ----       ----          ----\r
76         // none to right     none       opt.          req.  \r
77         // opt. to right     none   clear, none  clear right, req.\r
78         // req. to right     none   clear, none       req.\r
79 \r
80         // mark chunks with '|' for convenience\r
81         {\r
82             String[] m = markers[format];\r
83             for (int i = 0; i < m.length-1; ++i) {\r
84                 int n = Utility.indexOf(buf, m[i]);\r
85                 if (n != -1) {\r
86                     buf.insert(n+m[i].length(), '|');\r
87                 }\r
88             }\r
89         }\r
90 \r
91         int x = Utility.indexOf(buf, DIAN);\r
92         if (x == -1) {\r
93             x = buf.length();\r
94         }\r
95         int s = 0; // 0 = none to right, 1 = opt. to right, 2 = req. to right\r
96         int n = -1; // previous optional ling\r
97         String ling = markers[format][3];\r
98         while (x >= 0) {\r
99             int m = Utility.lastIndexOf(buf, "|", x);\r
100             int nn = Utility.lastIndexOf(buf, ling, x);\r
101             int ns = 0;\r
102             if (nn > m) {\r
103                 ns = (nn > 0 && buf.charAt(nn-1) != '*') ? 2 : 1;\r
104             }\r
105             x = m - 1;\r
106 \r
107             // actually much simpler, but leave this verbose for now so it's easier to follow\r
108             switch (s*3+ns) {\r
109             case 0: /* none, none */\r
110                 s = ns; // redundant\r
111                 n = -1;\r
112                 break;\r
113             case 1: /* none, opt. */\r
114                 s = ns;\r
115                 n = nn; // remember optional ling to right\r
116                 break;\r
117             case 2: /* none, req. */\r
118                 s = ns;\r
119                 n = -1;\r
120                 break;\r
121             case 3: /* opt., none */\r
122                 s = ns;\r
123                 n = -1;\r
124                 break;\r
125             case 4: /* opt., opt. */\r
126                 buf.delete(nn-1, nn+ling.length()); // delete current optional ling\r
127                 s = 0;\r
128                 n = -1;\r
129                 break;\r
130             case 5: /* opt., req. */\r
131                 buf.delete(n-1, n+ling.length()); // delete previous optional ling\r
132                 s = ns;\r
133                 n = -1;\r
134                 break;\r
135             case 6: /* req., none */\r
136                 s = ns;\r
137                 n = -1;\r
138                 break;\r
139             case 7: /* req., opt. */\r
140                 buf.delete(nn-1, nn+ling.length()); // delete current optional ling\r
141                 s = 0;\r
142                 n = -1;\r
143                 break;\r
144             case 8: /* req., req. */\r
145                 s = ns;\r
146                 n = -1;\r
147                 break;\r
148             default:\r
149                 throw new IllegalStateException();\r
150             }\r
151         }\r
152 \r
153         for (int i = buf.length(); --i >= 0;) {\r
154             char c = buf.charAt(i);\r
155             if (c == '*' || c == '|') {\r
156                 buf.delete(i, i+1);\r
157             }\r
158         }\r
159     }\r
160 }\r