• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  LCHAR.c  *
3  *                                                                           *
4  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
5  *                                                                           *
6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
7  *  you may not use this file except in compliance with the License.         *
8  *                                                                           *
9  *  You may obtain a copy of the License at                                  *
10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
11  *                                                                           *
12  *  Unless required by applicable law or agreed to in writing, software      *
13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15  *  See the License for the specific language governing permissions and      *
16  *  limitations under the License.                                           *
17  *                                                                           *
18  *---------------------------------------------------------------------------*/
19 
20 #include "LCHAR.h"
21 #include "plog.h"
22 #include "pmemory.h"
23 
24 #define MTAG NULL
25 
lstrtrim(LCHAR * text)26 ESR_ReturnCode lstrtrim(LCHAR* text)
27 {
28   size_t beginning, ending, len;
29 
30   len = LSTRLEN(text);
31 
32   /* locating first non-whitespace character from beginning */
33   for (beginning = 0; beginning < len && LISSPACE(text[beginning]); ++beginning);
34   /* locating first non-whitespace character from end */
35   for (ending = len - 1; ending > beginning && LISSPACE(text[ending]); --ending);
36 
37   if (beginning > 0 && beginning <= ending)
38     LMEMMOVE(text, text + beginning, ending - beginning + 1);
39   text[ending-beginning+1] = '\0';
40   return ESR_SUCCESS;
41 }
42 
lstrinsert(const LCHAR * source,LCHAR * target,size_t offset,size_t * len)43 ESR_ReturnCode lstrinsert(const LCHAR* source, LCHAR* target, size_t offset, size_t* len)
44 {
45   ESR_ReturnCode rc;
46 
47   if (source == NULL || target == NULL || len == NULL)
48   {
49     rc = ESR_INVALID_ARGUMENT;
50     PLogError(ESR_rc2str(rc));
51     goto CLEANUP;
52   }
53   if (LSTRLEN(source) + LSTRLEN(target) + 1 > *len)
54   {
55     *len = LSTRLEN(source) + LSTRLEN(target) + 1;
56     rc = ESR_BUFFER_OVERFLOW;
57     PLOG_DBG_TRACE((ESR_rc2str(rc)));
58     goto CLEANUP;
59   }
60   memmove(target + offset + LSTRLEN(source), target + offset, LSTRLEN(target + offset) + 1);
61   LSTRNCPY(target + offset, source, LSTRLEN(source));
62   return ESR_SUCCESS;
63 CLEANUP:
64   return rc;
65 }
66 
lstrreplace(LCHAR * text,const LCHAR source,const LCHAR target)67 ESR_ReturnCode lstrreplace(LCHAR* text, const LCHAR source, const LCHAR target)
68 {
69   LCHAR* index;
70 
71   while (ESR_TRUE)
72   {
73     index = LSTRCHR(text, source);
74     if (index == NULL)
75       break;
76     *index = target;
77   }
78   return ESR_SUCCESS;
79 }
80 
lstrtoi(const LCHAR * text,int * result,int base)81 ESR_ReturnCode lstrtoi(const LCHAR* text, int* result, int base)
82 {
83   LCHAR* endPtr;
84 
85   if (result == NULL)
86     return ESR_INVALID_ARGUMENT;
87   *result = LSTRTOL(text, &endPtr, base);
88   if (endPtr == text || (!LISSPACE(*endPtr) && *endPtr != L('\0')))
89     return ESR_INVALID_ARGUMENT;
90   return ESR_SUCCESS;
91 }
92 
lstrtoui(const LCHAR * text,unsigned int * result,int base)93 ESR_ReturnCode lstrtoui(const LCHAR* text, unsigned int* result, int base)
94 {
95   LCHAR* endPtr;
96 
97   if (result == NULL)
98     return ESR_INVALID_ARGUMENT;
99   *result = LSTRTOUL(text, &endPtr, base);
100   if (endPtr == text || (!LISSPACE(*endPtr) && *endPtr != L('\0')))
101     return ESR_INVALID_ARGUMENT;
102   return ESR_SUCCESS;
103 }
104 
lstrtof(const LCHAR * text,float * result)105 ESR_ReturnCode lstrtof(const LCHAR* text, float* result)
106 {
107   LCHAR* endPtr;
108 
109   if (result == NULL)
110     return ESR_INVALID_ARGUMENT;
111   *result = (float) LSTRTOD(text, &endPtr);
112   if (endPtr == text || (!LISSPACE(*endPtr) && *endPtr != L('\0')))
113     return ESR_INVALID_ARGUMENT;
114   return ESR_SUCCESS;
115 }
116 
lstrtob(const LCHAR * text,ESR_BOOL * result)117 ESR_ReturnCode lstrtob(const LCHAR* text, ESR_BOOL* result)
118 {
119   ESR_ReturnCode rc = ESR_SUCCESS;
120   int compare;
121   unsigned int temp;
122 
123   if (result == NULL)
124     return ESR_INVALID_ARGUMENT;
125   CHKLOG(rc, lstrcasecmp(text, L("true"), &compare));
126   if (compare == 0)
127   {
128     *result = ESR_TRUE;
129     return ESR_SUCCESS;
130   }
131   CHKLOG(rc, lstrcasecmp(text, L("yes"), &compare));
132   if (compare == 0)
133   {
134     *result = ESR_TRUE;
135     return ESR_SUCCESS;
136   }
137   CHKLOG(rc, lstrcasecmp(text, L("false"), &compare));
138   if (compare == 0)
139   {
140     *result = ESR_FALSE;
141     return ESR_SUCCESS;
142   }
143   CHKLOG(rc, lstrcasecmp(text, L("no"), &compare));
144   if (compare == 0)
145   {
146     *result = ESR_FALSE;
147     return ESR_SUCCESS;
148   }
149 
150   /* Check for boolean expressed as an integer value */
151   CHK(rc, lstrtoui(text, &temp, 10));
152   *result = (temp != 0);
153   return ESR_SUCCESS;
154 CLEANUP:
155   return rc;
156 }
157 
LCHARGetInt(LCHAR * text,int * value,LCHAR ** finalPosition)158 ESR_ReturnCode LCHARGetInt( LCHAR* text, int* value, LCHAR** finalPosition)
159 {
160   LCHAR *beg, *end;
161   LCHAR temp;
162   ESR_ReturnCode rc;
163 
164   /* Skip whitespace */
165   for (beg = text; *beg != L('\0') && LISSPACE(*beg); ++beg);
166   if (beg == NULL)
167     return ESR_INVALID_ARGUMENT; /* invalid command syntax */
168   /* Find next whitespace */
169   for (end = beg; *end != L('\0') && !LISSPACE(*end); ++end);
170   if (end == NULL)
171     return ESR_INVALID_ARGUMENT; /* invalid command syntax */
172 
173   temp = *end;
174   *end = L('\0');
175   rc = lstrtoi(beg, value, 10);
176   if (rc != ESR_SUCCESS)
177   {
178     *end = temp;
179     PLogError(ESR_rc2str(rc));
180     goto CLEANUP;
181   }
182   *end = temp;
183   if (finalPosition != NULL)
184     *finalPosition = end;
185   return ESR_SUCCESS;
186 CLEANUP:
187   return rc;
188 }
189 
lstrlwr(LCHAR * string)190 ESR_ReturnCode lstrlwr(LCHAR* string)
191 {
192   if (string)
193   {
194     while (*string)
195     {
196       if (LISALPHA(*string))
197         *string = (LCHAR) LTOLOWER(*string);
198       ++string;
199     }
200   }
201   else
202     return ESR_INVALID_ARGUMENT;
203 
204   return ESR_SUCCESS;
205 }
206 
lstrupr(LCHAR * string)207 ESR_ReturnCode lstrupr(LCHAR* string)
208 {
209   if (string)
210   {
211     while (*string)
212     {
213       if (LISALPHA(*string))
214         *string = (LCHAR) LTOUPPER(*string);
215       ++string;
216     }
217   }
218   else
219     return ESR_INVALID_ARGUMENT;
220 
221   return ESR_SUCCESS;
222 }
223 
224 /* strcasecmp is not POSIX.4 API */
lstrcasecmp(const LCHAR * string1,const LCHAR * string2,int * result)225 ESR_ReturnCode lstrcasecmp(const LCHAR *string1, const LCHAR *string2, int *result)
226 {
227 
228   if (!string1 || !string2)
229     return ESR_INVALID_ARGUMENT;
230 
231   while (LTOUPPER(*string1) == LTOUPPER(*string2++))
232   {
233     if (!*string1++)
234     {
235       *result = 0;
236       return ESR_SUCCESS;
237     }
238   }
239 
240   *result = LTOUPPER(*string1) - LTOUPPER(*--string2);
241   return ESR_SUCCESS;
242 }
243 
244 /**
245  * This code is from MS SDK: C:\PROGRAM FILES\MICROSOFT SDK\src\crt\xtoa.c
246  * Buffer overflow checking is left up to the caller.
247  *
248  * @param value Number to be converted
249  * @param string String result
250  * @param radix Base of value; must be in the range 2 - 36
251  */
pxtoa(unsigned long val,LCHAR * buf,unsigned radix,int is_neg)252 static void pxtoa(unsigned long val, LCHAR *buf, unsigned radix, int is_neg)
253 {
254   LCHAR *p;                /* pointer to traverse string */
255   LCHAR *firstdig;         /* pointer to first digit */
256   LCHAR temp;              /* temp char */
257   unsigned digval;        /* value of digit */
258 
259   p = buf;
260 
261   if (is_neg)
262   {
263     /* negative, so output '-' and negate */
264     *p++ = '-';
265     val = (unsigned long)(-(long)val);
266   }
267 
268   firstdig = p;           /* save pointer to first digit */
269 
270   do
271   {
272     digval = (unsigned)(val % radix);
273     val /= radix;       /* get next digit */
274 
275     /* convert to ascii and store */
276     if (digval > 9)
277       *p++ = (LCHAR)(digval - 10 + 'a');  /* a letter */
278     else
279       *p++ = (LCHAR)(digval + '0');       /* a digit */
280   }
281   while (val > 0);
282 
283   /* We now have the digit of the number in the buffer, but in reverse
284      order.  Thus we reverse them now. */
285 
286   *p-- = '\0';            /* terminate string; p points to last digit */
287 
288   do
289   {
290     temp = *p;
291     *p = *firstdig;
292     *firstdig = temp;   /* swap *p and *firstdig */
293     --p;
294     ++firstdig;         /* advance to next two digits */
295   }
296   while (firstdig < p); /* repeat until halfway */
297 }
298 
299 /*
300  * Convert an integer to a string.
301  */
litostr(int value,LCHAR * string,size_t * len,int radix)302 ESR_ReturnCode litostr(int value, LCHAR *string, size_t *len, int radix)
303 {
304   size_t size;
305   /* pxtoa() is guaranteed not to overflow past 33 characters */
306   LCHAR buffer[33];
307 
308   if (!string)
309     return ESR_INVALID_ARGUMENT;
310 
311   if (radix == 10 && value < 0)
312     pxtoa((unsigned long) value, buffer, radix, 1);
313   else
314     pxtoa((unsigned long) value, buffer, radix, 0);
315 
316   size = LSTRLEN(buffer);
317 
318   if (size >= *len)   /* + null-terminated character */
319   {
320     *len = size;
321     return ESR_BUFFER_OVERFLOW;
322   }
323   else
324     LSTRCPY(string, buffer);
325 
326   return ESR_SUCCESS;
327 }
328 
329 
330 /* Convert an unsigned long integer to a string. */
lultostr(unsigned long value,LCHAR * string,size_t * len,int radix)331 ESR_ReturnCode lultostr(unsigned long  value, LCHAR *string, size_t *len, int radix)
332 {
333   size_t size;
334   LCHAR buffer[33];
335 
336   if (!string)
337     return ESR_INVALID_ARGUMENT;
338 
339   pxtoa(value, buffer, radix, 0);
340 
341   size = LSTRLEN(buffer);
342 
343   if (size >= *len)   /* + null-terminated character */
344   {
345     *len = size;
346     return ESR_BUFFER_OVERFLOW;
347   }
348   else
349   {
350     *len = size;
351     LSTRCPY(string, buffer);
352   }
353 
354   return ESR_SUCCESS;
355 }
356