| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 ******************************************************************************* | |
| 3 * | |
| 4 * Copyright (C) 2003-2014, 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 #include "cmemory.h" | |
| 25 | |
| 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 && destCapa
city > 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, p
arseError, 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, pa
rseError, 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 /* sorted array for binary search*/ | |
| 136 static const char* special_prefixes[]={ | |
| 137 "\x0041\x004e\x004f\x004e\x0059\x004d\x004f\x0055\x0053", | |
| 138 "\x0041\x0055\x0054\x0048\x0045\x004e\x0054\x0049\x0043\x0041\x0054\x0045\x0
044", | |
| 139 "\x0042\x0041\x0054\x0043\x0048", | |
| 140 "\x0044\x0049\x0041\x004c\x0055\x0050", | |
| 141 "\x0045\x0056\x0045\x0052\x0059\x004f\x004e\x0045", | |
| 142 "\x0047\x0052\x004f\x0055\x0050", | |
| 143 "\x0049\x004e\x0054\x0045\x0052\x0041\x0043\x0054\x0049\x0056\x0045", | |
| 144 "\x004e\x0045\x0054\x0057\x004f\x0052\x004b", | |
| 145 "\x004f\x0057\x004e\x0045\x0052", | |
| 146 }; | |
| 147 | |
| 148 | |
| 149 /* binary search the sorted array */ | |
| 150 static int | |
| 151 findStringIndex(const char* const *sortedArr, int32_t sortedArrLen, const char*
target, int32_t targetLen){ | |
| 152 | |
| 153 int left, middle, right,rc; | |
| 154 | |
| 155 left =0; | |
| 156 right= sortedArrLen-1; | |
| 157 | |
| 158 while(left <= right){ | |
| 159 middle = (left+right)/2; | |
| 160 rc=strncmp(sortedArr[middle],target, targetLen); | |
| 161 | |
| 162 if(rc<0){ | |
| 163 left = middle+1; | |
| 164 }else if(rc >0){ | |
| 165 right = middle -1; | |
| 166 }else{ | |
| 167 return middle; | |
| 168 } | |
| 169 } | |
| 170 return -1; | |
| 171 } | |
| 172 | |
| 173 static void | |
| 174 getPrefixSuffix(const char *src, int32_t srcLength, | |
| 175 const char **prefix, int32_t *prefixLen, | |
| 176 const char **suffix, int32_t *suffixLen, | |
| 177 UErrorCode *status){ | |
| 178 | |
| 179 int32_t i=0; | |
| 180 *prefix = src; | |
| 181 while(i<srcLength){ | |
| 182 if(src[i] == PREFIX_SUFFIX_SEPARATOR){ | |
| 183 if((i+1) == srcLength){ | |
| 184 /* we reached the end of the string */ | |
| 185 *suffix = NULL; | |
| 186 i++; | |
| 187 break; | |
| 188 } | |
| 189 i++;/* the prefix contains the separator */ | |
| 190 *suffix = src + i; | |
| 191 break; | |
| 192 } | |
| 193 i++; | |
| 194 } | |
| 195 *prefixLen = i; | |
| 196 *suffixLen = srcLength - i; | |
| 197 /* special prefixes must not be followed by suffixes! */ | |
| 198 if((findStringIndex(special_prefixes,UPRV_LENGTHOF(special_prefixes), *prefi
x, *prefixLen-1) != -1) && (*suffix != NULL)){ | |
| 199 *status = U_PARSE_ERROR; | |
| 200 return; | |
| 201 } | |
| 202 | |
| 203 } | |
| 204 | |
| 205 int32_t | |
| 206 nfs4_mixed_prepare( const char* src, int32_t srcLength, | |
| 207 char* dest, int32_t destCapacity, | |
| 208 UParseError* parseError, | |
| 209 UErrorCode* status){ | |
| 210 | |
| 211 const char *prefix = NULL, *suffix = NULL; | |
| 212 int32_t prefixLen=0, suffixLen=0; | |
| 213 char pStack[NFS4_MAX_BUFFER_SIZE], | |
| 214 sStack[NFS4_MAX_BUFFER_SIZE]; | |
| 215 char *p=pStack, *s=sStack; | |
| 216 int32_t pLen=0, sLen=0, reqLen=0, | |
| 217 pCapacity = NFS4_MAX_BUFFER_SIZE, | |
| 218 sCapacity = NFS4_MAX_BUFFER_SIZE; | |
| 219 | |
| 220 | |
| 221 if(status==NULL || U_FAILURE(*status)){ | |
| 222 return 0; | |
| 223 } | |
| 224 if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapa
city > 0)){ | |
| 225 *status = U_ILLEGAL_ARGUMENT_ERROR; | |
| 226 return 0; | |
| 227 } | |
| 228 if(srcLength == -1){ | |
| 229 srcLength = (int32_t)strlen(src); | |
| 230 } | |
| 231 getPrefixSuffix(src, srcLength, &prefix, &prefixLen, &suffix, &suffixLen, st
atus); | |
| 232 | |
| 233 /* prepare the prefix */ | |
| 234 pLen = nfs4_prepare(prefix, prefixLen, p, pCapacity, NFS4_MIXED_PREP_PREFIX,
parseError, status); | |
| 235 if(*status == U_BUFFER_OVERFLOW_ERROR){ | |
| 236 *status = U_ZERO_ERROR; | |
| 237 p = (char*) malloc(pLen); | |
| 238 if(p == NULL){ | |
| 239 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 240 goto CLEANUP; | |
| 241 } | |
| 242 pLen = nfs4_prepare(prefix, prefixLen, p, pLen, NFS4_MIXED_PREP_PREFIX,
parseError, status); | |
| 243 } | |
| 244 | |
| 245 /* prepare the suffix */ | |
| 246 if(suffix != NULL){ | |
| 247 sLen = nfs4_prepare(suffix, suffixLen, s, sCapacity, NFS4_MIXED_PREP_SUF
FIX, parseError, status); | |
| 248 if(*status == U_BUFFER_OVERFLOW_ERROR){ | |
| 249 *status = U_ZERO_ERROR; | |
| 250 s = (char*) malloc(pLen); | |
| 251 if(s == NULL){ | |
| 252 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 253 goto CLEANUP; | |
| 254 } | |
| 255 sLen = nfs4_prepare(suffix, suffixLen, s, sLen, NFS4_MIXED_PREP_SUFF
IX, parseError, status); | |
| 256 } | |
| 257 } | |
| 258 reqLen = pLen+sLen+1 /* for the delimiter */; | |
| 259 if(dest != NULL && reqLen <= destCapacity){ | |
| 260 memmove(dest, p, pLen); | |
| 261 /* add the suffix */ | |
| 262 if(suffix!=NULL){ | |
| 263 dest[pLen++] = PREFIX_SUFFIX_SEPARATOR; | |
| 264 memmove(dest+pLen, s, sLen); | |
| 265 } | |
| 266 } | |
| 267 | |
| 268 CLEANUP: | |
| 269 if(p != pStack){ | |
| 270 free(p); | |
| 271 } | |
| 272 if(s != sStack){ | |
| 273 free(s); | |
| 274 } | |
| 275 | |
| 276 return u_terminateChars(dest, destCapacity, reqLen, status); | |
| 277 } | |
| 278 | |
| 279 int32_t | |
| 280 nfs4_cis_prepare( const char* src, int32_t srcLength, | |
| 281 char* dest, int32_t destCapacity, | |
| 282 UParseError* parseError, | |
| 283 UErrorCode* status){ | |
| 284 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CIS_PREP, parse
Error, status); | |
| 285 } | |
| 286 | |
| 287 | |
| 288 int32_t | |
| 289 nfs4_cs_prepare( const char* src, int32_t srcLength, | |
| 290 char* dest, int32_t destCapacity, | |
| 291 UBool isCaseSensitive, | |
| 292 UParseError* parseError, | |
| 293 UErrorCode* status){ | |
| 294 if(isCaseSensitive){ | |
| 295 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CS,
parseError, status); | |
| 296 }else{ | |
| 297 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CI,
parseError, status); | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 #endif | |
| 302 /* | |
| 303 * Hey, Emacs, please set the following: | |
| 304 * | |
| 305 * Local Variables: | |
| 306 * indent-tabs-mode: nil | |
| 307 * End: | |
| 308 * | |
| 309 */ | |
| 310 | |
| OLD | NEW |