]>
Commit | Line | Data |
---|---|---|
46f4442e A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
4 | * Copyright (C) 1999-2007, International Business Machines | |
5 | * Corporation and others. All Rights Reserved. | |
6 | * | |
7 | ******************************************************************************* | |
8 | */ | |
9 | ||
10 | #include "unicode/utypes.h" | |
11 | #include "unicode/uclean.h" | |
12 | #include "unicode/uchar.h" | |
13 | #include "unicode/unistr.h" | |
14 | #include "unicode/uscript.h" | |
15 | #include "unicode/putil.h" | |
16 | #include "unicode/ctest.h" | |
17 | ||
18 | #include "layout/LETypes.h" | |
19 | #include "layout/LEScripts.h" | |
20 | ||
21 | #include "letsutil.h" | |
22 | #include "letest.h" | |
23 | ||
24 | #include "xmlreader.h" | |
25 | ||
26 | #include "xmlparser.h" | |
27 | ||
28 | #include <stdlib.h> | |
29 | #include <stdio.h> | |
30 | #include <string.h> | |
31 | ||
32 | //U_NAMESPACE_USE | |
33 | ||
34 | #define CH_COMMA 0x002C | |
35 | ||
36 | static le_uint32 *getHexArray(const UnicodeString &numbers, int32_t &arraySize) | |
37 | { | |
38 | int32_t offset = -1; | |
39 | ||
40 | arraySize = 1; | |
41 | while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) { | |
42 | arraySize += 1; | |
43 | } | |
44 | ||
45 | le_uint32 *array = NEW_ARRAY(le_uint32, arraySize); | |
46 | char number[16]; | |
47 | le_int32 count = 0; | |
48 | le_int32 start = 0, end = 0; | |
49 | le_int32 len = 0; | |
50 | ||
51 | // trim leading whitespace | |
52 | while(u_isUWhiteSpace(numbers[start])) { | |
53 | start += 1; | |
54 | } | |
55 | ||
56 | while((end = numbers.indexOf(CH_COMMA, start)) >= 0) { | |
57 | len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); | |
58 | number[len] = '\0'; | |
59 | start = end + 1; | |
60 | ||
61 | sscanf(number, "%x", &array[count++]); | |
62 | ||
63 | // trim whitespace following the comma | |
64 | while(u_isUWhiteSpace(numbers[start])) { | |
65 | start += 1; | |
66 | } | |
67 | } | |
68 | ||
69 | // trim trailing whitespace | |
70 | end = numbers.length(); | |
71 | while(u_isUWhiteSpace(numbers[end - 1])) { | |
72 | end -= 1; | |
73 | } | |
74 | ||
75 | len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); | |
76 | number[len] = '\0'; | |
77 | sscanf(number, "%x", &array[count]); | |
78 | ||
79 | return array; | |
80 | } | |
81 | ||
82 | static float *getFloatArray(const UnicodeString &numbers, int32_t &arraySize) | |
83 | { | |
84 | int32_t offset = -1; | |
85 | ||
86 | arraySize = 1; | |
87 | while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) { | |
88 | arraySize += 1; | |
89 | } | |
90 | ||
91 | float *array = NEW_ARRAY(float, arraySize); | |
92 | char number[32]; | |
93 | le_int32 count = 0; | |
94 | le_int32 start = 0, end = 0; | |
95 | le_int32 len = 0; | |
96 | ||
97 | // trim leading whitespace | |
98 | while(u_isUWhiteSpace(numbers[start])) { | |
99 | start += 1; | |
100 | } | |
101 | ||
102 | while((end = numbers.indexOf(CH_COMMA, start)) >= 0) { | |
103 | len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); | |
104 | number[len] = '\0'; | |
105 | start = end + 1; | |
106 | ||
107 | sscanf(number, "%f", &array[count++]); | |
108 | ||
109 | // trim whiteapce following the comma | |
110 | while(u_isUWhiteSpace(numbers[start])) { | |
111 | start += 1; | |
112 | } | |
113 | } | |
114 | ||
115 | while(u_isUWhiteSpace(numbers[start])) { | |
116 | start += 1; | |
117 | } | |
118 | ||
119 | // trim trailing whitespace | |
120 | end = numbers.length(); | |
121 | while(u_isUWhiteSpace(numbers[end - 1])) { | |
122 | end -= 1; | |
123 | } | |
124 | ||
125 | len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); | |
126 | number[len] = '\0'; | |
127 | sscanf(number, "%f", &array[count]); | |
128 | ||
129 | return array; | |
130 | } | |
131 | ||
132 | U_CDECL_BEGIN | |
133 | void readTestFile(const char *testFilePath, TestCaseCallback callback) | |
134 | { | |
135 | #if !UCONFIG_NO_REGULAR_EXPRESSIONS | |
136 | UErrorCode status = U_ZERO_ERROR; | |
137 | UXMLParser *parser = UXMLParser::createParser(status); | |
138 | UXMLElement *root = parser->parseFile(testFilePath, status); | |
139 | ||
140 | if (root == NULL) { | |
141 | log_err("Could not open the test data file: %s\n", testFilePath); | |
142 | delete parser; | |
143 | return; | |
144 | } | |
145 | ||
146 | UnicodeString test_case = UNICODE_STRING_SIMPLE("test-case"); | |
147 | UnicodeString test_text = UNICODE_STRING_SIMPLE("test-text"); | |
148 | UnicodeString test_font = UNICODE_STRING_SIMPLE("test-font"); | |
149 | UnicodeString result_glyphs = UNICODE_STRING_SIMPLE("result-glyphs"); | |
150 | UnicodeString result_indices = UNICODE_STRING_SIMPLE("result-indices"); | |
151 | UnicodeString result_positions = UNICODE_STRING_SIMPLE("result-positions"); | |
152 | ||
153 | // test-case attributes | |
154 | UnicodeString id_attr = UNICODE_STRING_SIMPLE("id"); | |
155 | UnicodeString script_attr = UNICODE_STRING_SIMPLE("script"); | |
156 | UnicodeString lang_attr = UNICODE_STRING_SIMPLE("lang"); | |
157 | ||
158 | // test-font attributes | |
159 | UnicodeString name_attr = UNICODE_STRING_SIMPLE("name"); | |
160 | UnicodeString ver_attr = UNICODE_STRING_SIMPLE("version"); | |
161 | UnicodeString cksum_attr = UNICODE_STRING_SIMPLE("checksum"); | |
162 | ||
163 | const UXMLElement *testCase; | |
164 | int32_t tc = 0; | |
165 | ||
166 | while((testCase = root->nextChildElement(tc)) != NULL) { | |
167 | if (testCase->getTagName().compare(test_case) == 0) { | |
168 | char *id = getCString(testCase->getAttribute(id_attr)); | |
169 | char *script = getCString(testCase->getAttribute(script_attr)); | |
170 | char *lang = getCString(testCase->getAttribute(lang_attr)); | |
171 | char *fontName = NULL; | |
172 | char *fontVer = NULL; | |
173 | char *fontCksum = NULL; | |
174 | const UXMLElement *element; | |
175 | int32_t ec = 0; | |
176 | int32_t charCount = 0; | |
177 | int32_t typoFlags = 3; // kerning + ligatures... | |
178 | UScriptCode scriptCode; | |
179 | le_int32 languageCode = -1; | |
180 | UnicodeString text, glyphs, indices, positions; | |
181 | int32_t glyphCount = 0, indexCount = 0, positionCount = 0; | |
182 | TestResult expected = {0, NULL, NULL, NULL}; | |
183 | ||
184 | uscript_getCode(script, &scriptCode, 1, &status); | |
185 | if (LE_FAILURE(status)) { | |
186 | log_err("invalid script name: %s.\n", script); | |
187 | goto free_c_strings; | |
188 | } | |
189 | ||
190 | if (lang != NULL) { | |
191 | languageCode = getLanguageCode(lang); | |
192 | ||
193 | if (languageCode < 0) { | |
194 | log_err("invalid language name: %s.\n", lang); | |
195 | goto free_c_strings; | |
196 | } | |
197 | } | |
198 | ||
199 | while((element = testCase->nextChildElement(ec)) != NULL) { | |
200 | UnicodeString tag = element->getTagName(); | |
201 | ||
202 | // TODO: make sure that each element is only used once. | |
203 | if (tag.compare(test_font) == 0) { | |
204 | fontName = getCString(element->getAttribute(name_attr)); | |
205 | fontVer = getCString(element->getAttribute(ver_attr)); | |
206 | fontCksum = getCString(element->getAttribute(cksum_attr)); | |
207 | ||
208 | } else if (tag.compare(test_text) == 0) { | |
209 | text = element->getText(TRUE); | |
210 | charCount = text.length(); | |
211 | } else if (tag.compare(result_glyphs) == 0) { | |
212 | glyphs = element->getText(TRUE); | |
213 | } else if (tag.compare(result_indices) == 0) { | |
214 | indices = element->getText(TRUE); | |
215 | } else if (tag.compare(result_positions) == 0) { | |
216 | positions = element->getText(TRUE); | |
217 | } else { | |
218 | // an unknown tag... | |
219 | char *cTag = getCString(&tag); | |
220 | ||
221 | log_info("Test %s: unknown element with tag \"%s\"\n", id, cTag); | |
222 | freeCString(cTag); | |
223 | } | |
224 | } | |
225 | ||
226 | expected.glyphs = (LEGlyphID *) getHexArray(glyphs, glyphCount); | |
227 | expected.indices = (le_int32 *) getHexArray(indices, indexCount); | |
228 | expected.positions = getFloatArray(positions, positionCount); | |
229 | ||
230 | expected.glyphCount = glyphCount; | |
231 | ||
232 | if (glyphCount < charCount || indexCount != glyphCount || positionCount < glyphCount * 2 + 2) { | |
233 | log_err("Test %s: inconsistent input data: charCount = %d, glyphCount = %d, indexCount = %d, positionCount = %d\n", | |
234 | id, charCount, glyphCount, indexCount, positionCount); | |
235 | goto free_expected; | |
236 | }; | |
237 | ||
238 | (*callback)(id, fontName, fontVer, fontCksum, scriptCode, languageCode, text.getBuffer(), charCount, &expected); | |
239 | ||
240 | free_expected: | |
241 | DELETE_ARRAY(expected.positions); | |
242 | DELETE_ARRAY(expected.indices); | |
243 | DELETE_ARRAY(expected.glyphs); | |
244 | ||
245 | free_c_strings: | |
246 | freeCString(fontCksum); | |
247 | freeCString(fontVer); | |
248 | freeCString(fontName); | |
249 | freeCString(lang); | |
250 | freeCString(script); | |
251 | freeCString(id); | |
252 | } | |
253 | } | |
254 | ||
255 | delete root; | |
256 | delete parser; | |
257 | #endif | |
258 | } | |
259 | U_CDECL_END |