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