1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/********************************************************************
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * COPYRIGHT:
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copyright (c) 2001-2010, International Business Machines Corporation and
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * others. All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************/
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/************************************************************************
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   This test program is intended for testing Replaceable class.
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Date        Name        Description
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   11/28/2001  hshih       Ported back from Java.
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)************************************************************************/
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_TRANSLITERATION
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ittrans.h"
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <string.h>
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdlib.h>
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/rep.h"
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "reptest.h"
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//---------------------------------------------
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// runIndexedTest
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//---------------------------------------------
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * This is a test class that simulates styled text.
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * It associates a style number (0..65535) with each character,
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * and maintains that style in the normal fashion:
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * When setting text from raw string or characters,<br>
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Set the styles to the style of the first character replaced.<br>
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * If no characters are replaced, use the style of the previous character.<br>
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * If at start, use the following character<br>
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Otherwise use NO_STYLE.
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class TestReplaceable : public Replaceable {
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString chars;
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString styles;
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const UChar NO_STYLE;
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const UChar NO_STYLE_MARK;
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * The address of this static class variable serves as this class's ID
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * for ICU "poor man's RTTI".
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const char fgClassID;
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestReplaceable (const UnicodeString& text,
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     const UnicodeString& newStyles) {
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        chars = text;
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString s;
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (int i = 0; i < text.length(); ++i) {
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (i < newStyles.length()) {
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                s.append(newStyles.charAt(i));
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (text.charAt(i) == NO_STYLE_MARK) {
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    s.append(NO_STYLE);
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else {
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    s.append((UChar)(i + 0x0031));
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        this->styles = s;
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual Replaceable *clone() const {
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return new TestReplaceable(chars, styles);
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ~TestReplaceable(void) {}
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString getStyles() {
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return styles;
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString toString() {
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString s = chars;
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s.append("{");
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s.append(styles);
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s.append("}");
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return s;
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void extractBetween(int32_t start, int32_t limit, UnicodeString& result) const {
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        chars.extractBetween(start, limit, result);
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * ICU "poor man's RTTI", returns a UClassID for this class.
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     *
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @draft ICU 2.2
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * ICU "poor man's RTTI", returns a UClassID for the actual class.
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     *
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @draft ICU 2.2
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)protected:
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual int32_t getLength() const {
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return chars.length();
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual UChar getCharAt(int32_t offset) const{
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return chars.charAt(offset);
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual UChar32 getChar32At(int32_t offset) const{
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return chars.char32At(offset);
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void fixStyles(int32_t start, int32_t limit, int32_t newLen) {
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar newStyle = NO_STYLE;
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (start != limit && styles.charAt(start) != NO_STYLE) {
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            newStyle = styles.charAt(start);
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (start > 0 && getCharAt(start-1) != NO_STYLE_MARK) {
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            newStyle = styles.charAt(start-1);
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (limit < styles.length()) {
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            newStyle = styles.charAt(limit);
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // dumb implementation for now.
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString s;
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (int i = 0; i < newLen; ++i) {
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // this doesn't really handle an embedded NO_STYLE_MARK
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // in the middle of a long run of characters right -- but
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // that case shouldn't happen anyway
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (getCharAt(start+i) == NO_STYLE_MARK) {
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                s.append(NO_STYLE);
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                s.append(newStyle);
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        styles.replaceBetween(start, limit, s);
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void handleReplaceBetween(int32_t start, int32_t limit, const UnicodeString& text) {
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString s;
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        this->extractBetween(start, limit, s);
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (s == text) return; // NO ACTION!
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        this->chars.replaceBetween(start, limit, text);
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fixStyles(start, limit, text.length());
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void copy(int32_t start, int32_t limit, int32_t dest) {
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        chars.copy(start, limit, dest);
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        styles.copy(start, limit, dest);
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const char TestReplaceable::fgClassID=0;
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UChar TestReplaceable::NO_STYLE  = 0x005F;
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UChar TestReplaceable::NO_STYLE_MARK = 0xFFFF;
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ReplaceableTest::runIndexedTest(int32_t index, UBool exec,
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                      const char* &name, char* /*par*/) {
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (index) {
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        TESTCASE(0,TestReplaceableClass);
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        default: name = ""; break;
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Dummy Replaceable implementation for better API/code coverage.
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class NoopReplaceable : public Replaceable {
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual int32_t getLength() const {
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual UChar getCharAt(int32_t /*offset*/) const{
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0xffff;
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual UChar32 getChar32At(int32_t /*offset*/) const{
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0xffff;
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void extractBetween(int32_t /*start*/, int32_t /*limit*/, UnicodeString& result) const {
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        result.remove();
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void handleReplaceBetween(int32_t /*start*/, int32_t /*limit*/, const UnicodeString &/*text*/) {
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* do nothing */
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void copy(int32_t /*start*/, int32_t /*limit*/, int32_t /*dest*/) {
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* do nothing */
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private:
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const char fgClassID;
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const char NoopReplaceable::fgClassID=0;
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void ReplaceableTest::TestReplaceableClass(void) {
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar rawTestArray[][6] = {
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0041, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // ABCD
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0061, 0x0062, 0x0063, 0x0064, 0x00DF, 0x0000}, // abcd\u00DF
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0061, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // aBCD
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0041, 0x0300, 0x0045, 0x0300, 0x0000, 0x0000}, // A\u0300E\u0300
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x00C0, 0x00C8, 0x0000, 0x0000, 0x0000, 0x0000}, // \u00C0\u00C8
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000}, /* "wxyz" */
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0077, 0x0078, 0x0079, 0x007A, 0x0075, 0x0000}, /* "wxyzu" */
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000}, /* "xyz" */
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("Lower", rawTestArray[0], "1234");
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("Upper", rawTestArray[1], "123455"); // must map 00DF to SS
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("Title", rawTestArray[2], "1234");
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("NFC",   rawTestArray[3], "13");
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("NFD",   rawTestArray[4], "1122");
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("*(x) > A $1 B", rawTestArray[5], "11223");
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("*(x)(y) > A $2 B $1 C $2 D", rawTestArray[6], "113322334");
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    check("*(x)(y)(z) > A $3 B $2 C $1 D", rawTestArray[7], "114433225");
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Disabled for 2.4.  TODO Revisit in 2.6 or later.
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //check("*x > a", rawTestArray[8], "223"); // expect "123"?
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //check("*x > a", rawTestArray[9], "113"); // expect "123"?
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //check("*x > a", rawTestArray[10], "_33"); // expect "_23"?
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //check("*(x) > A $1 B", rawTestArray[11], "__223");
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // improve API/code coverage
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    NoopReplaceable noop;
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Replaceable *p;
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if((p=noop.clone())!=NULL) {
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("Replaceable::clone() does not return NULL");
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete p;
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(!noop.hasMetaData()) {
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("Replaceable::hasMetaData() does not return TRUE");
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // try to call the compiler-provided
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // UMemory/UObject/Replaceable assignment operators
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    NoopReplaceable noop2;
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    noop2=noop;
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if((p=noop2.clone())!=NULL) {
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("noop2.Replaceable::clone() does not return NULL");
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete p;
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // try to call the compiler-provided
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // UMemory/UObject/Replaceable copy constructors
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    NoopReplaceable noop3(noop);
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if((p=noop3.clone())!=NULL) {
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("noop3.Replaceable::clone() does not return NULL");
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete p;
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void ReplaceableTest::check(const UnicodeString& transliteratorName,
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            const UnicodeString& test,
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            const UnicodeString& shouldProduceStyles)
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestReplaceable *tr = new TestReplaceable(test, "");
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString expectedStyles = shouldProduceStyles;
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString original = tr->toString();
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Transliterator* t;
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (transliteratorName.charAt(0) == 0x2A /*'*'*/) {
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString rules(transliteratorName);
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        rules.remove(0,1);
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UParseError pe;
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        t = Transliterator::createFromRules("test", rules, UTRANS_FORWARD,
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                            pe, status);
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // test clone()
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        TestReplaceable *tr2 = (TestReplaceable *)tr->clone();
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(tr2 != NULL) {
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            delete tr;
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            tr = tr2;
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        t = Transliterator::createInstance(transliteratorName, UTRANS_FORWARD, status);
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        dataerrln("FAIL: failed to create the " + transliteratorName + " transliterator");
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete tr;
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    t->transliterate(*tr);
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString newStyles = tr->getStyles();
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (newStyles != expectedStyles) {
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("FAIL Styles: " + transliteratorName + "{" + original + "} => "
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            + tr->toString() + "; should be {" + expectedStyles + "}!");
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log("OK: ");
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log(transliteratorName);
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log("(");
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log(original);
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log(") => ");
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        logln(tr->toString());
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete tr;
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete t;
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_TRANSLITERATION */
321