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