]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/cintltst/nfsprep.c
ICU-6.2.7.tar.gz
[apple/icu.git] / icuSources / test / cintltst / nfsprep.c
1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 2003, International Business Machines
5 * Corporation and others. All Rights Reserved.
6 *
7 *******************************************************************************
8 * file name: nfsprep.c
9 * encoding: US-ASCII
10 * tab size: 8 (not used)
11 * indentation:4
12 *
13 * created on: 2003jul11
14 * created by: Ram Viswanadha
15 */
16
17 #include "unicode/utypes.h"
18
19 #if !UCONFIG_NO_IDNA
20
21 #include "nfsprep.h"
22 #include "ustr_imp.h"
23 #include "cintltst.h"
24
25 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
26 #define NFS4_MAX_BUFFER_SIZE 1000
27 #define PREFIX_SUFFIX_SEPARATOR 0x0040 /* '@' */
28
29
30 const char* NFS4DataFileNames[5] ={
31 "nfscss",
32 "nfscsi",
33 "nfscis",
34 "nfsmxp",
35 "nfsmxs"
36 };
37
38
39 int32_t
40 nfs4_prepare( const char* src, int32_t srcLength,
41 char* dest, int32_t destCapacity,
42 NFS4ProfileState state,
43 UParseError* parseError,
44 UErrorCode* status){
45
46 UChar b1Stack[NFS4_MAX_BUFFER_SIZE],
47 b2Stack[NFS4_MAX_BUFFER_SIZE];
48 char b3Stack[NFS4_MAX_BUFFER_SIZE];
49
50 /* initialize pointers to stack buffers */
51 UChar *b1 = b1Stack, *b2 = b2Stack;
52 char *b3=b3Stack;
53 int32_t b1Len=0, b2Len=0, b3Len=0,
54 b1Capacity = NFS4_MAX_BUFFER_SIZE,
55 b2Capacity = NFS4_MAX_BUFFER_SIZE,
56 b3Capacity = NFS4_MAX_BUFFER_SIZE,
57 reqLength=0;
58
59 UStringPrepProfile* profile = NULL;
60 /* get the test data path */
61 const char *testdatapath = NULL;
62
63 if(status==NULL || U_FAILURE(*status)){
64 return 0;
65 }
66 if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
67 *status = U_ILLEGAL_ARGUMENT_ERROR;
68 return 0;
69 }
70 testdatapath = loadTestData(status);
71
72 /* convert the string from UTF-8 to UTF-16 */
73 u_strFromUTF8(b1,b1Capacity,&b1Len,src,srcLength,status);
74 if(*status == U_BUFFER_OVERFLOW_ERROR){
75
76 /* reset the status */
77 *status = U_ZERO_ERROR;
78
79 b1 = (UChar*) malloc(b1Len * U_SIZEOF_UCHAR);
80 if(b1==NULL){
81 *status = U_MEMORY_ALLOCATION_ERROR;
82 goto CLEANUP;
83 }
84
85 b1Capacity = b1Len;
86 u_strFromUTF8(b1, b1Capacity, &b1Len, src, srcLength, status);
87 }
88
89 /* open the profile */
90 profile = usprep_open(testdatapath, NFS4DataFileNames[state], status);
91 /* prepare the string */
92 b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Capacity, USPREP_DEFAULT, parseError, status);
93 if(*status == U_BUFFER_OVERFLOW_ERROR){
94 *status = U_ZERO_ERROR;
95 b2 = (UChar*) malloc(b2Len * U_SIZEOF_UCHAR);
96 if(b2== NULL){
97 *status = U_MEMORY_ALLOCATION_ERROR;
98 goto CLEANUP;
99 }
100 b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Len, USPREP_DEFAULT, parseError, status);
101 }
102
103 /* convert the string back to UTF-8 */
104 u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status);
105 if(*status == U_BUFFER_OVERFLOW_ERROR){
106 *status = U_ZERO_ERROR;
107 b3 = (char*) malloc(b3Len);
108 if(b3== NULL){
109 *status = U_MEMORY_ALLOCATION_ERROR;
110 goto CLEANUP;
111 }
112 b3Capacity = b3Len;
113 u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status);
114 }
115
116 reqLength = b3Len;
117 if(dest!=NULL && reqLength <= destCapacity){
118 memmove(dest, b3, reqLength);
119 }
120
121 CLEANUP:
122 if(b1!=b1Stack){
123 free(b1);
124 }
125 if(b2!=b2Stack){
126 free(b2);
127 }
128 if(b3!=b3Stack){
129 free(b3);
130 }
131
132 return u_terminateChars(dest, destCapacity, reqLength, status);
133 }
134
135 static void
136 syntaxError( const UChar* rules,
137 int32_t pos,
138 int32_t rulesLen,
139 UParseError* parseError){
140 int32_t start, stop;
141 if(parseError == NULL){
142 return;
143 }
144 if(pos == rulesLen && rulesLen >0){
145 pos--;
146 }
147 parseError->offset = pos;
148 parseError->line = 0 ; /* we are not using line numbers */
149
150 /* for pre-context */
151 start = (pos <=U_PARSE_CONTEXT_LEN)? 0 : (pos - (U_PARSE_CONTEXT_LEN-1));
152 stop = pos;
153
154 u_memcpy(parseError->preContext,rules+start,stop-start);
155 /* null terminate the buffer */
156 parseError->preContext[stop-start] = 0;
157
158 /* for post-context */
159 start = pos;
160 if(start<rulesLen) {
161 U16_FWD_1(rules, start, rulesLen);
162 }
163
164 stop = ((pos+U_PARSE_CONTEXT_LEN)<= rulesLen )? (pos+(U_PARSE_CONTEXT_LEN)) :
165 rulesLen;
166 if(start < stop){
167 u_memcpy(parseError->postContext,rules+start,stop-start);
168 /* null terminate the buffer */
169 parseError->postContext[stop-start]= 0;
170 }
171
172 }
173
174
175 /* sorted array for binary search*/
176 static const char* special_prefixes[]={
177 "\x0041\x004e\x004f\x004e\x0059\x004d\x004f\x0055\x0053",
178 "\x0041\x0055\x0054\x0048\x0045\x004e\x0054\x0049\x0043\x0041\x0054\x0045\x0044",
179 "\x0042\x0041\x0054\x0043\x0048",
180 "\x0044\x0049\x0041\x004c\x0055\x0050",
181 "\x0045\x0056\x0045\x0052\x0059\x004f\x004e\x0045",
182 "\x0047\x0052\x004f\x0055\x0050",
183 "\x0049\x004e\x0054\x0045\x0052\x0041\x0043\x0054\x0049\x0056\x0045",
184 "\x004e\x0045\x0054\x0057\x004f\x0052\x004b",
185 "\x004f\x0057\x004e\x0045\x0052",
186 };
187
188
189 /* binary search the sorted array */
190 static int
191 findStringIndex(const char* const *sortedArr, int32_t sortedArrLen, const char* target, int32_t targetLen){
192
193 int left, middle, right,rc;
194
195 left =0;
196 right= sortedArrLen-1;
197
198 while(left <= right){
199 middle = (left+right)/2;
200 rc=strncmp(sortedArr[middle],target, targetLen);
201
202 if(rc<0){
203 left = middle+1;
204 }else if(rc >0){
205 right = middle -1;
206 }else{
207 return middle;
208 }
209 }
210 return -1;
211 }
212
213 static void
214 getPrefixSuffix(const char *src, int32_t srcLength,
215 const char **prefix, int32_t *prefixLen,
216 const char **suffix, int32_t *suffixLen,
217 UErrorCode *status){
218
219 int32_t i=0;
220 *prefix = src;
221 while(i<srcLength){
222 if(src[i] == PREFIX_SUFFIX_SEPARATOR){
223 if((i+1) == srcLength){
224 /* we reached the end of the string */
225 *suffix = NULL;
226 i++;
227 break;
228 }
229 i++;/* the prefix contains the separator */
230 *suffix = src + i;
231 break;
232 }
233 i++;
234 }
235 *prefixLen = i;
236 *suffixLen = srcLength - i;
237 /* special prefixes must not be followed by suffixes! */
238 if((findStringIndex(special_prefixes,LENGTHOF(special_prefixes), *prefix, *prefixLen-1) != -1) && (*suffix != NULL)){
239 *status = U_PARSE_ERROR;
240 return;
241 }
242
243 }
244
245 int32_t
246 nfs4_mixed_prepare( const char* src, int32_t srcLength,
247 char* dest, int32_t destCapacity,
248 UParseError* parseError,
249 UErrorCode* status){
250
251 const char *prefix = NULL, *suffix = NULL;
252 int32_t prefixLen=0, suffixLen=0;
253 char pStack[NFS4_MAX_BUFFER_SIZE],
254 sStack[NFS4_MAX_BUFFER_SIZE];
255 char *p=pStack, *s=sStack;
256 int32_t pLen=0, sLen=0, reqLen=0,
257 pCapacity = NFS4_MAX_BUFFER_SIZE,
258 sCapacity = NFS4_MAX_BUFFER_SIZE;
259
260
261 if(status==NULL || U_FAILURE(*status)){
262 return 0;
263 }
264 if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
265 *status = U_ILLEGAL_ARGUMENT_ERROR;
266 return 0;
267 }
268 if(srcLength == -1){
269 srcLength = (int32_t)strlen(src);
270 }
271 getPrefixSuffix(src, srcLength, &prefix, &prefixLen, &suffix, &suffixLen, status);
272
273 /* prepare the prefix */
274 pLen = nfs4_prepare(prefix, prefixLen, p, pCapacity, NFS4_MIXED_PREP_PREFIX, parseError, status);
275 if(*status == U_BUFFER_OVERFLOW_ERROR){
276 *status = U_ZERO_ERROR;
277 p = (char*) malloc(pLen);
278 if(p == NULL){
279 *status = U_MEMORY_ALLOCATION_ERROR;
280 goto CLEANUP;
281 }
282 pLen = nfs4_prepare(prefix, prefixLen, p, pLen, NFS4_MIXED_PREP_PREFIX, parseError, status);
283 }
284
285 /* prepare the suffix */
286 if(suffix != NULL){
287 sLen = nfs4_prepare(suffix, suffixLen, s, sCapacity, NFS4_MIXED_PREP_SUFFIX, parseError, status);
288 if(*status == U_BUFFER_OVERFLOW_ERROR){
289 *status = U_ZERO_ERROR;
290 s = (char*) malloc(pLen);
291 if(s == NULL){
292 *status = U_MEMORY_ALLOCATION_ERROR;
293 goto CLEANUP;
294 }
295 sLen = nfs4_prepare(suffix, suffixLen, s, sLen, NFS4_MIXED_PREP_SUFFIX, parseError, status);
296 }
297 }
298 reqLen = pLen+sLen+1 /* for the delimiter */;
299 if(dest != NULL && reqLen <= destCapacity){
300 memmove(dest, p, pLen);
301 /* add the suffix */
302 if(suffix!=NULL){
303 dest[pLen++] = PREFIX_SUFFIX_SEPARATOR;
304 memmove(dest+pLen, s, sLen);
305 }
306 }
307
308 CLEANUP:
309 if(p != pStack){
310 free(p);
311 }
312 if(s != sStack){
313 free(s);
314 }
315
316 return u_terminateChars(dest, destCapacity, reqLen, status);
317 }
318
319 int32_t
320 nfs4_cis_prepare( const char* src, int32_t srcLength,
321 char* dest, int32_t destCapacity,
322 UParseError* parseError,
323 UErrorCode* status){
324 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CIS_PREP, parseError, status);
325 }
326
327
328 int32_t
329 nfs4_cs_prepare( const char* src, int32_t srcLength,
330 char* dest, int32_t destCapacity,
331 UBool isCaseSensitive,
332 UParseError* parseError,
333 UErrorCode* status){
334 if(isCaseSensitive){
335 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CS, parseError, status);
336 }else{
337 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CI, parseError, status);
338 }
339 }
340
341 #endif
342 /*
343 * Hey, Emacs, please set the following:
344 *
345 * Local Variables:
346 * indent-tabs-mode: nil
347 * End:
348 *
349 */
350