1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/*
5*******************************************************************************
6*   Copyright (C) 2001-2009, International Business Machines
7*   Corporation and others.  All Rights Reserved.
8*******************************************************************************
9*/
10
11package android.icu.dev.test.shaping;
12
13import org.junit.Ignore;
14import org.junit.Test;
15
16import android.icu.text.ArabicShaping;
17import android.icu.text.ArabicShapingException;
18
19/**
20 * Interactive test for Arabic shaping.
21 * Invoke from a command line passing args and strings.  Use '-help' to see description of arguments.
22 */
23// TODO(junit): wasn't running before - needs to be fixed
24public class ArabicShapingTest{
25    private static final int COPY = 0;
26    private static final int INPLACE = 1;
27    private static final int STRING = 2;
28
29    // TODO(junit): marked with a test to keep from failing during ant run
30    @Ignore
31    @Test
32    public void dummyTest() {
33    }
34
35    public static final void main(String[] args) {
36        int testtype = COPY;
37        int options = 0;
38        int ss = 0;
39        int sl = -1;
40        int ds = 0;
41        int dl = -1;
42        String text = "$22.4 test 123 \ufef6\u0644\u0622 456 \u0664\u0665\u0666!";
43
44        for (int i = 0; i < args.length; ++i) {
45            String arg = args[i];
46            if (arg.charAt(0) == '-') {
47                String opt = arg.substring(1);
48                String val = opt;
49                int index = arg.indexOf(':');
50                if (index != -1) {
51                    opt = opt.substring(0, Math.min(index, 3));
52                    val = arg.substring(index + 1);
53                }
54
55                if (opt.equalsIgnoreCase("len")) {
56                    options &= ~ArabicShaping.LENGTH_MASK;
57                    if (val.equalsIgnoreCase("gs")) {
58                        options |= ArabicShaping.LENGTH_GROW_SHRINK;
59                    } else if (val.equalsIgnoreCase("sn")) {
60                        options |= ArabicShaping.LENGTH_FIXED_SPACES_NEAR;
61                    } else if (val.equalsIgnoreCase("se")) {
62                        options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_END;
63                    } else if (val.equalsIgnoreCase("sb")) {
64                        options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_BEGINNING;
65                    } else {
66                        throwValError(opt, val);
67                    }
68                } else if (opt.equalsIgnoreCase("dir")) {
69                    options &= ~ArabicShaping.TEXT_DIRECTION_MASK;
70                    if (val.equalsIgnoreCase("log")) {
71                        options |= ArabicShaping.TEXT_DIRECTION_LOGICAL;
72                    } else if (val.equalsIgnoreCase("vis")) {
73                        options |= ArabicShaping.TEXT_DIRECTION_VISUAL_LTR;
74                    } else {
75                        throwValError(opt, val);
76                    }
77                } else if (opt.equalsIgnoreCase("let")) {
78                    options &= ~ArabicShaping.LETTERS_MASK;
79                    if (val.equalsIgnoreCase("no")) {
80                        options |= ArabicShaping.LETTERS_NOOP;
81                    } else if (val.equalsIgnoreCase("sh")) {
82                        options |= ArabicShaping.LETTERS_SHAPE;
83                    } else if (val.equalsIgnoreCase("un")) {
84                        options |= ArabicShaping.LETTERS_UNSHAPE;
85                    } else if (val.equalsIgnoreCase("ta")) {
86                        options |= ArabicShaping.LETTERS_SHAPE_TASHKEEL_ISOLATED;
87                    } else {
88                        throwValError(opt, val);
89                    }
90                } else if (opt.equalsIgnoreCase("dig")) {
91                    options &= ~ArabicShaping.DIGITS_MASK;
92                    if (val.equalsIgnoreCase("no")) {
93                        options |= ArabicShaping.DIGITS_NOOP;
94                    } else if (val.equalsIgnoreCase("ea")) {
95                        options |= ArabicShaping.DIGITS_EN2AN;
96                    } else if (val.equalsIgnoreCase("ae")) {
97                        options |= ArabicShaping.DIGITS_AN2EN;
98                    } else if (val.equalsIgnoreCase("lr")) {
99                        options |= ArabicShaping.DIGITS_EN2AN_INIT_LR;
100                    } else if (val.equalsIgnoreCase("al")) {
101                        options |= ArabicShaping.DIGITS_EN2AN_INIT_AL;
102                    } else {
103                        throwValError(opt, val);
104                    }
105                } else if (opt.equalsIgnoreCase("typ")) {
106                    options &= ~ArabicShaping.DIGIT_TYPE_MASK;
107                    if (val.equalsIgnoreCase("an")) {
108                        options |= ArabicShaping.DIGIT_TYPE_AN;
109                    } else if (val.equalsIgnoreCase("ex")) {
110                        options |= ArabicShaping.DIGIT_TYPE_AN_EXTENDED;
111                    } else {
112                        throwValError(opt, val);
113                    }
114                } else if (opt.equalsIgnoreCase("dst")) {
115                    try {
116                        ds = Integer.parseInt(val);
117                    }
118                    catch (Exception e) {
119                        throwValError(opt, val);
120                    }
121                } else if (opt.equalsIgnoreCase("dln")) {
122                    try {
123                        dl = Integer.parseInt(val);
124                    }
125                    catch (Exception e) {
126                        throwValError(opt, val);
127                    }
128                } else if (opt.equalsIgnoreCase("sst")) {
129                    try {
130                        ss = Integer.parseInt(val);
131                    }
132                    catch (Exception e) {
133                        throwValError(opt, val);
134                    }
135                } else if (opt.equalsIgnoreCase("sln")) {
136                    try {
137                        sl = Integer.parseInt(val);
138                    }
139                    catch (Exception e) {
140                        throwValError(opt, val);
141                    }
142                } else if (opt.equalsIgnoreCase("tes")) {
143                    if (val.equalsIgnoreCase("cp")) {
144                        testtype = COPY;
145                    } else if (val.equalsIgnoreCase("ip")) {
146                        testtype = INPLACE;
147                    } else if (val.equalsIgnoreCase("st")) {
148                        testtype = STRING;
149                    } else {
150                        throwValError(opt, val);
151                    }
152                } else if (opt.equalsIgnoreCase("help")) {
153                    System.out.println(usage);
154                } else {
155                    throwOptError(opt);
156                }
157            } else {
158                // assume text
159                text = parseText(arg);
160            }
161        }
162
163        if (sl < 0) {
164            sl = text.length() - ss;
165            System.out.println("sl defaulting to " + sl);
166        }
167        if (dl < 0) {
168            dl = 2 * sl;
169            System.out.println("dl defaulting to " + dl);
170        }
171
172        ArabicShaping shaper = new ArabicShaping(options);
173        System.out.println("shaper: " + shaper);
174
175        char[] src = text.toCharArray();
176        System.out.println(" input: '" + escapedText(src, ss, sl) + "'");
177        if (testtype != STRING) {
178            System.out.println("start: " + ss + " length: " + sl + " total length: " + src.length);
179        }
180
181        int result = -1;
182        char[] dest = null;
183
184        try {
185            switch (testtype) {
186            case COPY:
187                dest = new char[ds + dl];
188                result = shaper.shape(src, ss, sl, dest, ds, dl);
189                break;
190
191            case INPLACE:
192                shaper.shape(src, ss, sl);
193                ds = ss;
194                result = sl;
195                dest = src;
196                break;
197
198            case STRING:
199                dest = shaper.shape(text).toCharArray();
200                ds = 0;
201                result = dest.length;
202                break;
203            }
204
205            System.out.println("output: '" + escapedText(dest, ds, result) + "'");
206            System.out.println("length: " + result);
207            if (ds != 0 || result != dest.length) {
208                System.out.println("full output: '" + escapedText(dest, 0, dest.length) + "'");
209            }
210        }
211        catch (ArabicShapingException e) {
212            System.out.println("Caught ArabicShapingException");
213            System.out.println(e);
214        }
215        catch (Exception e) {
216            System.out.println("Caught Exception");
217            System.out.println(e);
218        }
219    }
220
221    private static void throwOptError(String opt) {
222        throwUsageError("unknown option: " + opt);
223    }
224
225    private static void throwValError(String opt, String val) {
226        throwUsageError("unknown value: " + val + " for option: " + opt);
227    }
228
229    private static void throwUsageError(String message) {
230        StringBuffer buf = new StringBuffer("*** usage error ***\n");
231        buf.append(message);
232        buf.append("\n");
233        buf.append(usage);
234        throw new Error(buf.toString());
235    }
236
237    private static final String usage =
238        "Usage: [option]* [text]\n" +
239        "  where option is in the format '-opt[:val]'\n" +
240        "  options are:\n" +
241        "    -len:[gs|sn|se|sb]    (length: grow/shrink, spaces near, spaces end, spaces beginning)\n" +
242        "    -dir:[log|vis]        (direction: logical, visual)\n" +
243        "    -let:[no|sh|un|ta]    (letters: noop, shape, unshape, tashkeel)\n" +
244        // "    -let:[no|sh|un]       (letters: noop, shape, unshape)\n" +
245        "    -dig:[no|ea|ae|lr|al] (digits: noop, en2an, an2en, en2an_lr, en2an_al)\n" +
246        "    -typ:[an|ex]          (digit type: arabic, arabic extended)\n" +
247        "    -dst:#                (dest start: [integer])\n" +
248        "    -dln:#                (dest length (max size): [integer])\n" +
249        "    -sst:#                (source start: [integer])\n" +
250        "    -sln:#                (source length: [integer])\n" +
251        "    -tes:[cp|ip|st]       (test type: copy, in place, string)\n" +
252        "    -help                 (print this help message)\n" +
253        "  text can contain unicode escape values in the format '\\uXXXX' only\n";
254
255    private static String escapedText(char[] text, int start, int length) {
256        StringBuffer buf = new StringBuffer();
257        for (int i = start, e = start + length; i < e; ++i) {
258            char ch = text[i];
259            if (ch < 0x20 || ch > 0x7e) {
260                buf.append("\\u");
261                if (ch < 0x1000) {
262                    buf.append('0');
263                }
264                if (ch < 0x100) {
265                    buf.append('0');
266                }
267                if (ch < 0x10) {
268                    buf.append('0');
269                }
270                buf.append(Integer.toHexString(ch));
271            } else {
272                buf.append(ch);
273            }
274        }
275        return buf.toString();
276    }
277
278    private static String parseText(String text) {
279        // process unicode escapes (only)
280        StringBuffer buf = new StringBuffer();
281        char[] chars = text.toCharArray();
282        for (int i = 0; i < chars.length; ++i) {
283            char ch = chars[i];
284            if (ch == '\\') {
285                if ((i < chars.length - 1) &&
286                    (chars[i+1] == 'u')) {
287                    int val = Integer.parseInt(text.substring(i+2, i+6), 16);
288                    buf.append((char)val);
289                    i += 5;
290                } else {
291                    buf.append('\\');
292                }
293            } else {
294                buf.append(ch);
295            }
296        }
297        return buf.toString();
298    }
299}
300