1/*
2 * Copyright (C) 1996-2010, International Business Machines Corporation and
3 * others. All Rights Reserved.
4 */
5package com.ibm.icu.text;
6import com.ibm.icu.lang.UCharacter;
7
8/**
9 * A transliterator that performs character to name mapping.
10 * It generates the Perl syntax \N{name}.
11 * @author Alan Liu
12 */
13class UnicodeNameTransliterator extends Transliterator {
14
15    static final String _ID = "Any-Name";
16
17    static final String OPEN_DELIM = "\\N{";
18    static final char CLOSE_DELIM = '}';
19    static final int OPEN_DELIM_LEN = 3;
20
21    /**
22     * System registration hook.
23     */
24    static void register() {
25        Transliterator.registerFactory(_ID, new Transliterator.Factory() {
26            public Transliterator getInstance(String ID) {
27                return new UnicodeNameTransliterator(null);
28            }
29        });
30    }
31
32    /**
33     * Constructs a transliterator.
34     */
35    public UnicodeNameTransliterator(UnicodeFilter filter) {
36        super(_ID, filter);
37    }
38
39    /**
40     * Implements {@link Transliterator#handleTransliterate}.
41     */
42    protected void handleTransliterate(Replaceable text,
43                                       Position offsets, boolean isIncremental) {
44        int cursor = offsets.start;
45        int limit = offsets.limit;
46
47        StringBuilder str = new StringBuilder();
48        str.append(OPEN_DELIM);
49        int len;
50        String name;
51
52        while (cursor < limit) {
53            int c = text.char32At(cursor);
54            if ((name=UCharacter.getExtendedName(c)) != null) {
55
56                str.setLength(OPEN_DELIM_LEN);
57                str.append(name).append(CLOSE_DELIM);
58
59                int clen = UTF16.getCharCount(c);
60                text.replace(cursor, cursor+clen, str.toString());
61                len = str.length();
62                cursor += len; // advance cursor by 1 and adjust for new text
63                limit += len-clen; // change in length
64            } else {
65                ++cursor;
66            }
67        }
68
69        offsets.contextLimit += limit - offsets.limit;
70        offsets.limit = limit;
71        offsets.start = cursor;
72    }
73
74    /* (non-Javadoc)
75     * @see com.ibm.icu.text.Transliterator#addSourceTargetSet(com.ibm.icu.text.UnicodeSet, com.ibm.icu.text.UnicodeSet, com.ibm.icu.text.UnicodeSet)
76     */
77    @Override
78    public void addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet) {
79        UnicodeSet myFilter = getFilterAsUnicodeSet(inputFilter);
80        if (myFilter.size() > 0) {
81            sourceSet.addAll(myFilter);
82            targetSet.addAll('0', '9')
83            .addAll('A', 'Z')
84            .add('-')
85            .add(' ')
86            .addAll(OPEN_DELIM)
87            .add(CLOSE_DELIM)
88            .addAll('a', 'z') // for controls
89            .add('<').add('>') // for controls
90            .add('(').add(')') // for controls
91            ;
92        }
93    }
94}
95