diff options
Diffstat (limited to 'Build/source/libs/icu/icu-4.6/test/cintltst/nfsprep.c')
-rw-r--r-- | Build/source/libs/icu/icu-4.6/test/cintltst/nfsprep.c | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-4.6/test/cintltst/nfsprep.c b/Build/source/libs/icu/icu-4.6/test/cintltst/nfsprep.c new file mode 100644 index 00000000000..61b11214beb --- /dev/null +++ b/Build/source/libs/icu/icu-4.6/test/cintltst/nfsprep.c @@ -0,0 +1,310 @@ +/* + ******************************************************************************* + * + * Copyright (C) 2003-2007, International Business Machines + * Corporation and others. All Rights Reserved. + * + ******************************************************************************* + * file name: nfsprep.c + * encoding: US-ASCII + * tab size: 8 (not used) + * indentation:4 + * + * created on: 2003jul11 + * created by: Ram Viswanadha + */ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_IDNA + +#include "nfsprep.h" +#include "ustr_imp.h" +#include "cintltst.h" + +#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) +#define NFS4_MAX_BUFFER_SIZE 1000 +#define PREFIX_SUFFIX_SEPARATOR 0x0040 /* '@' */ + + +const char* NFS4DataFileNames[5] ={ + "nfscss", + "nfscsi", + "nfscis", + "nfsmxp", + "nfsmxs" +}; + + +int32_t +nfs4_prepare( const char* src, int32_t srcLength, + char* dest, int32_t destCapacity, + NFS4ProfileState state, + UParseError* parseError, + UErrorCode* status){ + + UChar b1Stack[NFS4_MAX_BUFFER_SIZE], + b2Stack[NFS4_MAX_BUFFER_SIZE]; + char b3Stack[NFS4_MAX_BUFFER_SIZE]; + + /* initialize pointers to stack buffers */ + UChar *b1 = b1Stack, *b2 = b2Stack; + char *b3=b3Stack; + int32_t b1Len=0, b2Len=0, b3Len=0, + b1Capacity = NFS4_MAX_BUFFER_SIZE, + b2Capacity = NFS4_MAX_BUFFER_SIZE, + b3Capacity = NFS4_MAX_BUFFER_SIZE, + reqLength=0; + + UStringPrepProfile* profile = NULL; + /* get the test data path */ + const char *testdatapath = NULL; + + if(status==NULL || U_FAILURE(*status)){ + return 0; + } + if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + testdatapath = loadTestData(status); + + /* convert the string from UTF-8 to UTF-16 */ + u_strFromUTF8(b1,b1Capacity,&b1Len,src,srcLength,status); + if(*status == U_BUFFER_OVERFLOW_ERROR){ + + /* reset the status */ + *status = U_ZERO_ERROR; + + b1 = (UChar*) malloc(b1Len * U_SIZEOF_UCHAR); + if(b1==NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + goto CLEANUP; + } + + b1Capacity = b1Len; + u_strFromUTF8(b1, b1Capacity, &b1Len, src, srcLength, status); + } + + /* open the profile */ + profile = usprep_open(testdatapath, NFS4DataFileNames[state], status); + /* prepare the string */ + b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Capacity, USPREP_DEFAULT, parseError, status); + if(*status == U_BUFFER_OVERFLOW_ERROR){ + *status = U_ZERO_ERROR; + b2 = (UChar*) malloc(b2Len * U_SIZEOF_UCHAR); + if(b2== NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + goto CLEANUP; + } + b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Len, USPREP_DEFAULT, parseError, status); + } + + /* convert the string back to UTF-8 */ + u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status); + if(*status == U_BUFFER_OVERFLOW_ERROR){ + *status = U_ZERO_ERROR; + b3 = (char*) malloc(b3Len); + if(b3== NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + goto CLEANUP; + } + b3Capacity = b3Len; + u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status); + } + + reqLength = b3Len; + if(dest!=NULL && reqLength <= destCapacity){ + memmove(dest, b3, reqLength); + } + +CLEANUP: + if(b1!=b1Stack){ + free(b1); + } + if(b2!=b2Stack){ + free(b2); + } + if(b3!=b3Stack){ + free(b3); + } + + return u_terminateChars(dest, destCapacity, reqLength, status); +} + +/* sorted array for binary search*/ +static const char* special_prefixes[]={ + "\x0041\x004e\x004f\x004e\x0059\x004d\x004f\x0055\x0053", + "\x0041\x0055\x0054\x0048\x0045\x004e\x0054\x0049\x0043\x0041\x0054\x0045\x0044", + "\x0042\x0041\x0054\x0043\x0048", + "\x0044\x0049\x0041\x004c\x0055\x0050", + "\x0045\x0056\x0045\x0052\x0059\x004f\x004e\x0045", + "\x0047\x0052\x004f\x0055\x0050", + "\x0049\x004e\x0054\x0045\x0052\x0041\x0043\x0054\x0049\x0056\x0045", + "\x004e\x0045\x0054\x0057\x004f\x0052\x004b", + "\x004f\x0057\x004e\x0045\x0052", +}; + + +/* binary search the sorted array */ +static int +findStringIndex(const char* const *sortedArr, int32_t sortedArrLen, const char* target, int32_t targetLen){ + + int left, middle, right,rc; + + left =0; + right= sortedArrLen-1; + + while(left <= right){ + middle = (left+right)/2; + rc=strncmp(sortedArr[middle],target, targetLen); + + if(rc<0){ + left = middle+1; + }else if(rc >0){ + right = middle -1; + }else{ + return middle; + } + } + return -1; +} + +static void +getPrefixSuffix(const char *src, int32_t srcLength, + const char **prefix, int32_t *prefixLen, + const char **suffix, int32_t *suffixLen, + UErrorCode *status){ + + int32_t i=0; + *prefix = src; + while(i<srcLength){ + if(src[i] == PREFIX_SUFFIX_SEPARATOR){ + if((i+1) == srcLength){ + /* we reached the end of the string */ + *suffix = NULL; + i++; + break; + } + i++;/* the prefix contains the separator */ + *suffix = src + i; + break; + } + i++; + } + *prefixLen = i; + *suffixLen = srcLength - i; + /* special prefixes must not be followed by suffixes! */ + if((findStringIndex(special_prefixes,LENGTHOF(special_prefixes), *prefix, *prefixLen-1) != -1) && (*suffix != NULL)){ + *status = U_PARSE_ERROR; + return; + } + +} + +int32_t +nfs4_mixed_prepare( const char* src, int32_t srcLength, + char* dest, int32_t destCapacity, + UParseError* parseError, + UErrorCode* status){ + + const char *prefix = NULL, *suffix = NULL; + int32_t prefixLen=0, suffixLen=0; + char pStack[NFS4_MAX_BUFFER_SIZE], + sStack[NFS4_MAX_BUFFER_SIZE]; + char *p=pStack, *s=sStack; + int32_t pLen=0, sLen=0, reqLen=0, + pCapacity = NFS4_MAX_BUFFER_SIZE, + sCapacity = NFS4_MAX_BUFFER_SIZE; + + + if(status==NULL || U_FAILURE(*status)){ + return 0; + } + if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + if(srcLength == -1){ + srcLength = (int32_t)strlen(src); + } + getPrefixSuffix(src, srcLength, &prefix, &prefixLen, &suffix, &suffixLen, status); + + /* prepare the prefix */ + pLen = nfs4_prepare(prefix, prefixLen, p, pCapacity, NFS4_MIXED_PREP_PREFIX, parseError, status); + if(*status == U_BUFFER_OVERFLOW_ERROR){ + *status = U_ZERO_ERROR; + p = (char*) malloc(pLen); + if(p == NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + goto CLEANUP; + } + pLen = nfs4_prepare(prefix, prefixLen, p, pLen, NFS4_MIXED_PREP_PREFIX, parseError, status); + } + + /* prepare the suffix */ + if(suffix != NULL){ + sLen = nfs4_prepare(suffix, suffixLen, s, sCapacity, NFS4_MIXED_PREP_SUFFIX, parseError, status); + if(*status == U_BUFFER_OVERFLOW_ERROR){ + *status = U_ZERO_ERROR; + s = (char*) malloc(pLen); + if(s == NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + goto CLEANUP; + } + sLen = nfs4_prepare(suffix, suffixLen, s, sLen, NFS4_MIXED_PREP_SUFFIX, parseError, status); + } + } + reqLen = pLen+sLen+1 /* for the delimiter */; + if(dest != NULL && reqLen <= destCapacity){ + memmove(dest, p, pLen); + /* add the suffix */ + if(suffix!=NULL){ + dest[pLen++] = PREFIX_SUFFIX_SEPARATOR; + memmove(dest+pLen, s, sLen); + } + } + +CLEANUP: + if(p != pStack){ + free(p); + } + if(s != sStack){ + free(s); + } + + return u_terminateChars(dest, destCapacity, reqLen, status); +} + +int32_t +nfs4_cis_prepare( const char* src, int32_t srcLength, + char* dest, int32_t destCapacity, + UParseError* parseError, + UErrorCode* status){ + return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CIS_PREP, parseError, status); +} + + +int32_t +nfs4_cs_prepare( const char* src, int32_t srcLength, + char* dest, int32_t destCapacity, + UBool isCaseSensitive, + UParseError* parseError, + UErrorCode* status){ + if(isCaseSensitive){ + return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CS, parseError, status); + }else{ + return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CI, parseError, status); + } +} + +#endif +/* + * Hey, Emacs, please set the following: + * + * Local Variables: + * indent-tabs-mode: nil + * End: + * + */ + |