001: /*
002: *******************************************************************************
003: * Copyright (C) 2001, International Business Machines
004: * Corporation and others. All Rights Reserved.
005: *******************************************************************************
006: */
007:
008: package com.ibm.icu.dev.test.shaping;
009:
010: import com.ibm.icu.text.ArabicShaping;
011: import com.ibm.icu.text.ArabicShapingException;
012:
013: /**
014: * Interactive test for Arabic shaping.
015: * Invoke from a command line passing args and strings. Use '-help' to see description of arguments.
016: */
017: public class ArabicShapingTest {
018: private static final int COPY = 0;
019: private static final int INPLACE = 1;
020: private static final int STRING = 2;
021:
022: public static final void main(String[] args) {
023: int testtype = COPY;
024: int options = 0;
025: int ss = 0;
026: int sl = -1;
027: int ds = 0;
028: int dl = -1;
029: String text = "$22.4 test 123 \ufef6\u0644\u0622 456 \u0664\u0665\u0666!";
030:
031: for (int i = 0; i < args.length; ++i) {
032: String arg = args[i];
033: if (arg.charAt(0) == '-') {
034: String opt = arg.substring(1);
035: String val = opt;
036: int index = arg.indexOf(':');
037: if (index != -1) {
038: opt = opt.substring(0, Math.min(index, 3));
039: val = arg.substring(index + 1);
040: }
041:
042: if (opt.equalsIgnoreCase("len")) {
043: options &= ~ArabicShaping.LENGTH_MASK;
044: if (val.equalsIgnoreCase("gs")) {
045: options |= ArabicShaping.LENGTH_GROW_SHRINK;
046: } else if (val.equalsIgnoreCase("sn")) {
047: options |= ArabicShaping.LENGTH_FIXED_SPACES_NEAR;
048: } else if (val.equalsIgnoreCase("se")) {
049: options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_END;
050: } else if (val.equalsIgnoreCase("sb")) {
051: options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_BEGINNING;
052: } else {
053: throwValError(opt, val);
054: }
055: } else if (opt.equalsIgnoreCase("dir")) {
056: options &= ~ArabicShaping.TEXT_DIRECTION_MASK;
057: if (val.equalsIgnoreCase("log")) {
058: options |= ArabicShaping.TEXT_DIRECTION_LOGICAL;
059: } else if (val.equalsIgnoreCase("vis")) {
060: options |= ArabicShaping.TEXT_DIRECTION_VISUAL_LTR;
061: } else {
062: throwValError(opt, val);
063: }
064: } else if (opt.equalsIgnoreCase("let")) {
065: options &= ~ArabicShaping.LETTERS_MASK;
066: if (val.equalsIgnoreCase("no")) {
067: options |= ArabicShaping.LETTERS_NOOP;
068: } else if (val.equalsIgnoreCase("sh")) {
069: options |= ArabicShaping.LETTERS_SHAPE;
070: } else if (val.equalsIgnoreCase("un")) {
071: options |= ArabicShaping.LETTERS_UNSHAPE;
072: } else if (val.equalsIgnoreCase("ta")) {
073: options |= ArabicShaping.LETTERS_SHAPE_TASHKEEL_ISOLATED;
074: } else {
075: throwValError(opt, val);
076: }
077: } else if (opt.equalsIgnoreCase("dig")) {
078: options &= ~ArabicShaping.DIGITS_MASK;
079: if (val.equalsIgnoreCase("no")) {
080: options |= ArabicShaping.DIGITS_NOOP;
081: } else if (val.equalsIgnoreCase("ea")) {
082: options |= ArabicShaping.DIGITS_EN2AN;
083: } else if (val.equalsIgnoreCase("ae")) {
084: options |= ArabicShaping.DIGITS_AN2EN;
085: } else if (val.equalsIgnoreCase("lr")) {
086: options |= ArabicShaping.DIGITS_EN2AN_INIT_LR;
087: } else if (val.equalsIgnoreCase("al")) {
088: options |= ArabicShaping.DIGITS_EN2AN_INIT_AL;
089: } else {
090: throwValError(opt, val);
091: }
092: } else if (opt.equalsIgnoreCase("typ")) {
093: options &= ~ArabicShaping.DIGIT_TYPE_MASK;
094: if (val.equalsIgnoreCase("an")) {
095: options |= ArabicShaping.DIGIT_TYPE_AN;
096: } else if (val.equalsIgnoreCase("ex")) {
097: options |= ArabicShaping.DIGIT_TYPE_AN_EXTENDED;
098: } else {
099: throwValError(opt, val);
100: }
101: } else if (opt.equalsIgnoreCase("dst")) {
102: try {
103: ds = Integer.parseInt(val);
104: } catch (Exception e) {
105: throwValError(opt, val);
106: }
107: } else if (opt.equalsIgnoreCase("dln")) {
108: try {
109: dl = Integer.parseInt(val);
110: } catch (Exception e) {
111: throwValError(opt, val);
112: }
113: } else if (opt.equalsIgnoreCase("sst")) {
114: try {
115: ss = Integer.parseInt(val);
116: } catch (Exception e) {
117: throwValError(opt, val);
118: }
119: } else if (opt.equalsIgnoreCase("sln")) {
120: try {
121: sl = Integer.parseInt(val);
122: } catch (Exception e) {
123: throwValError(opt, val);
124: }
125: } else if (opt.equalsIgnoreCase("tes")) {
126: if (val.equalsIgnoreCase("cp")) {
127: testtype = COPY;
128: } else if (val.equalsIgnoreCase("ip")) {
129: testtype = INPLACE;
130: } else if (val.equalsIgnoreCase("st")) {
131: testtype = STRING;
132: } else {
133: throwValError(opt, val);
134: }
135: } else if (opt.equalsIgnoreCase("help")) {
136: System.out.println(usage);
137: } else {
138: throwOptError(opt);
139: }
140: } else {
141: // assume text
142: text = parseText(arg);
143: }
144: }
145:
146: if (sl < 0) {
147: sl = text.length() - ss;
148: System.out.println("sl defaulting to " + sl);
149: }
150: if (dl < 0) {
151: dl = 2 * sl;
152: System.out.println("dl defaulting to " + dl);
153: }
154:
155: ArabicShaping shaper = new ArabicShaping(options);
156: System.out.println("shaper: " + shaper);
157:
158: char[] src = text.toCharArray();
159: System.out
160: .println(" input: '" + escapedText(src, ss, sl) + "'");
161: if (testtype != STRING) {
162: System.out.println("start: " + ss + " length: " + sl
163: + " total length: " + src.length);
164: }
165:
166: int result = -1;
167: char[] dest = null;
168:
169: try {
170: switch (testtype) {
171: case COPY:
172: dest = new char[ds + dl];
173: result = shaper.shape(src, ss, sl, dest, ds, dl);
174: break;
175:
176: case INPLACE:
177: shaper.shape(src, ss, sl);
178: ds = ss;
179: result = sl;
180: dest = src;
181: break;
182:
183: case STRING:
184: dest = shaper.shape(text).toCharArray();
185: ds = 0;
186: result = dest.length;
187: break;
188: }
189:
190: System.out.println("output: '"
191: + escapedText(dest, ds, result) + "'");
192: System.out.println("length: " + result);
193: if (ds != 0 || result != dest.length) {
194: System.out.println("full output: '"
195: + escapedText(dest, 0, dest.length) + "'");
196: }
197: } catch (ArabicShapingException e) {
198: System.out.println("Caught ArabicShapingException");
199: System.out.println(e);
200: } catch (Exception e) {
201: System.out.println("Caught Exception");
202: System.out.println(e);
203: }
204: }
205:
206: private static void throwOptError(String opt) {
207: throwUsageError("unknown option: " + opt);
208: }
209:
210: private static void throwValError(String opt, String val) {
211: throwUsageError("unknown value: " + val + " for option: " + opt);
212: }
213:
214: private static void throwUsageError(String message) {
215: StringBuffer buf = new StringBuffer("*** usage error ***\n");
216: buf.append(message);
217: buf.append("\n");
218: buf.append(usage);
219: throw new Error(buf.toString());
220: }
221:
222: private static final String usage = "Usage: [option]* [text]\n"
223: + " where option is in the format '-opt[:val]'\n"
224: + " options are:\n"
225: + " -len:[gs|sn|se|sb] (length: grow/shrink, spaces near, spaces end, spaces beginning)\n"
226: + " -dir:[log|vis] (direction: logical, visual)\n"
227: + " -let:[no|sh|un|ta] (letters: noop, shape, unshape, tashkeel)\n"
228: +
229: // " -let:[no|sh|un] (letters: noop, shape, unshape)\n" +
230: " -dig:[no|ea|ae|lr|al] (digits: noop, en2an, an2en, en2an_lr, en2an_al)\n"
231: + " -typ:[an|ex] (digit type: arabic, arabic extended)\n"
232: + " -dst:# (dest start: [integer])\n"
233: + " -dln:# (dest length (max size): [integer])\n"
234: + " -sst:# (source start: [integer])\n"
235: + " -sln:# (source length: [integer])\n"
236: + " -tes:[cp|ip|st] (test type: copy, in place, string)\n"
237: + " -help (print this help message)\n"
238: + " text can contain unicode escape values in the format '\\uXXXX' only\n";
239:
240: private static String escapedText(char[] text, int start, int length) {
241: StringBuffer buf = new StringBuffer();
242: for (int i = start, e = start + length; i < e; ++i) {
243: char ch = text[i];
244: if (ch < 0x20 || ch > 0x7e) {
245: buf.append("\\u");
246: if (ch < 0x1000) {
247: buf.append('0');
248: }
249: if (ch < 0x100) {
250: buf.append('0');
251: }
252: if (ch < 0x10) {
253: buf.append('0');
254: }
255: buf.append(Integer.toHexString(ch));
256: } else {
257: buf.append(ch);
258: }
259: }
260: return buf.toString();
261: }
262:
263: private static String parseText(String text) {
264: // process unicode escapes (only)
265: StringBuffer buf = new StringBuffer();
266: char[] chars = text.toCharArray();
267: for (int i = 0; i < chars.length; ++i) {
268: char ch = chars[i];
269: if (ch == '\\') {
270: if ((i < chars.length - 1) && (chars[i + 1] == 'u')) {
271: int val = Integer.parseInt(text.substring(i + 2,
272: i + 6), 16);
273: buf.append((char) val);
274: i += 5;
275: } else {
276: buf.append('\\');
277: }
278: } else {
279: buf.append(ch);
280: }
281: }
282: return buf.toString();
283: }
284: }
|