1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
6 * Copyright (C) 2003-2014, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 *******************************************************************************
10 * file name: nfsprep.c
12 * tab size: 8 (not used)
15 * created on: 2003jul11
16 * created by: Ram Viswanadha
19 #include "unicode/utypes.h"
28 #define NFS4_MAX_BUFFER_SIZE 1000
29 #define PREFIX_SUFFIX_SEPARATOR 0x0040 /* '@' */
32 const char* NFS4DataFileNames[5] ={
42 nfs4_prepare( const char* src, int32_t srcLength,
43 char* dest, int32_t destCapacity,
44 NFS4ProfileState state,
45 UParseError* parseError,
48 UChar b1Stack[NFS4_MAX_BUFFER_SIZE],
49 b2Stack[NFS4_MAX_BUFFER_SIZE];
50 char b3Stack[NFS4_MAX_BUFFER_SIZE];
52 /* initialize pointers to stack buffers */
53 UChar *b1 = b1Stack, *b2 = b2Stack;
55 int32_t b1Len=0, b2Len=0, b3Len=0,
56 b1Capacity = NFS4_MAX_BUFFER_SIZE,
57 b2Capacity = NFS4_MAX_BUFFER_SIZE,
58 b3Capacity = NFS4_MAX_BUFFER_SIZE,
61 UStringPrepProfile* profile = NULL;
62 /* get the test data path */
63 const char *testdatapath = NULL;
65 if(status==NULL || U_FAILURE(*status)){
68 if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
69 *status = U_ILLEGAL_ARGUMENT_ERROR;
72 testdatapath = loadTestData(status);
74 /* convert the string from UTF-8 to UTF-16 */
75 u_strFromUTF8(b1,b1Capacity,&b1Len,src,srcLength,status);
76 if(*status == U_BUFFER_OVERFLOW_ERROR){
78 /* reset the status */
79 *status = U_ZERO_ERROR;
81 b1 = (UChar*) malloc(b1Len * U_SIZEOF_UCHAR);
83 *status = U_MEMORY_ALLOCATION_ERROR;
88 u_strFromUTF8(b1, b1Capacity, &b1Len, src, srcLength, status);
91 /* open the profile */
92 profile = usprep_open(testdatapath, NFS4DataFileNames[state], status);
93 /* prepare the string */
94 b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Capacity, USPREP_DEFAULT, parseError, status);
95 if(*status == U_BUFFER_OVERFLOW_ERROR){
96 *status = U_ZERO_ERROR;
97 b2 = (UChar*) malloc(b2Len * U_SIZEOF_UCHAR);
99 *status = U_MEMORY_ALLOCATION_ERROR;
102 b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Len, USPREP_DEFAULT, parseError, status);
105 /* convert the string back to UTF-8 */
106 u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status);
107 if(*status == U_BUFFER_OVERFLOW_ERROR){
108 *status = U_ZERO_ERROR;
109 b3 = (char*) malloc(b3Len);
111 *status = U_MEMORY_ALLOCATION_ERROR;
115 u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status);
119 if(dest!=NULL && reqLength <= destCapacity){
120 memmove(dest, b3, reqLength);
134 return u_terminateChars(dest, destCapacity, reqLength, status);
137 /* sorted array for binary search*/
138 static const char* special_prefixes[]={
139 "\x0041\x004e\x004f\x004e\x0059\x004d\x004f\x0055\x0053",
140 "\x0041\x0055\x0054\x0048\x0045\x004e\x0054\x0049\x0043\x0041\x0054\x0045\x0044",
141 "\x0042\x0041\x0054\x0043\x0048",
142 "\x0044\x0049\x0041\x004c\x0055\x0050",
143 "\x0045\x0056\x0045\x0052\x0059\x004f\x004e\x0045",
144 "\x0047\x0052\x004f\x0055\x0050",
145 "\x0049\x004e\x0054\x0045\x0052\x0041\x0043\x0054\x0049\x0056\x0045",
146 "\x004e\x0045\x0054\x0057\x004f\x0052\x004b",
147 "\x004f\x0057\x004e\x0045\x0052",
151 /* binary search the sorted array */
153 findStringIndex(const char* const *sortedArr, int32_t sortedArrLen, const char* target, int32_t targetLen){
155 int left, middle, right,rc;
158 right= sortedArrLen-1;
160 while(left <= right){
161 middle = (left+right)/2;
162 rc=strncmp(sortedArr[middle],target, targetLen);
176 getPrefixSuffix(const char *src, int32_t srcLength,
177 const char **prefix, int32_t *prefixLen,
178 const char **suffix, int32_t *suffixLen,
184 if(src[i] == PREFIX_SUFFIX_SEPARATOR){
185 if((i+1) == srcLength){
186 /* we reached the end of the string */
191 i++;/* the prefix contains the separator */
198 *suffixLen = srcLength - i;
199 /* special prefixes must not be followed by suffixes! */
200 if((findStringIndex(special_prefixes,UPRV_LENGTHOF(special_prefixes), *prefix, *prefixLen-1) != -1) && (*suffix != NULL)){
201 *status = U_PARSE_ERROR;
208 nfs4_mixed_prepare( const char* src, int32_t srcLength,
209 char* dest, int32_t destCapacity,
210 UParseError* parseError,
213 const char *prefix = NULL, *suffix = NULL;
214 int32_t prefixLen=0, suffixLen=0;
215 char pStack[NFS4_MAX_BUFFER_SIZE],
216 sStack[NFS4_MAX_BUFFER_SIZE];
217 char *p=pStack, *s=sStack;
218 int32_t pLen=0, sLen=0, reqLen=0,
219 pCapacity = NFS4_MAX_BUFFER_SIZE,
220 sCapacity = NFS4_MAX_BUFFER_SIZE;
223 if(status==NULL || U_FAILURE(*status)){
226 if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
227 *status = U_ILLEGAL_ARGUMENT_ERROR;
231 srcLength = (int32_t)strlen(src);
233 getPrefixSuffix(src, srcLength, &prefix, &prefixLen, &suffix, &suffixLen, status);
235 /* prepare the prefix */
236 pLen = nfs4_prepare(prefix, prefixLen, p, pCapacity, NFS4_MIXED_PREP_PREFIX, parseError, status);
237 if(*status == U_BUFFER_OVERFLOW_ERROR){
238 *status = U_ZERO_ERROR;
239 p = (char*) malloc(pLen);
241 *status = U_MEMORY_ALLOCATION_ERROR;
244 pLen = nfs4_prepare(prefix, prefixLen, p, pLen, NFS4_MIXED_PREP_PREFIX, parseError, status);
247 /* prepare the suffix */
249 sLen = nfs4_prepare(suffix, suffixLen, s, sCapacity, NFS4_MIXED_PREP_SUFFIX, parseError, status);
250 if(*status == U_BUFFER_OVERFLOW_ERROR){
251 *status = U_ZERO_ERROR;
252 s = (char*) malloc(pLen);
254 *status = U_MEMORY_ALLOCATION_ERROR;
257 sLen = nfs4_prepare(suffix, suffixLen, s, sLen, NFS4_MIXED_PREP_SUFFIX, parseError, status);
260 reqLen = pLen+sLen+1 /* for the delimiter */;
261 if(dest != NULL && reqLen <= destCapacity){
262 memmove(dest, p, pLen);
265 dest[pLen++] = PREFIX_SUFFIX_SEPARATOR;
266 memmove(dest+pLen, s, sLen);
278 return u_terminateChars(dest, destCapacity, reqLen, status);
282 nfs4_cis_prepare( const char* src, int32_t srcLength,
283 char* dest, int32_t destCapacity,
284 UParseError* parseError,
286 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CIS_PREP, parseError, status);
291 nfs4_cs_prepare( const char* src, int32_t srcLength,
292 char* dest, int32_t destCapacity,
293 UBool isCaseSensitive,
294 UParseError* parseError,
297 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CS, parseError, status);
299 return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CI, parseError, status);
305 * Hey, Emacs, please set the following:
308 * indent-tabs-mode: nil