• 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 
lstrtosize_t(const LCHAR * text,size_t * result,int base)105 ESR_ReturnCode lstrtosize_t(const LCHAR* text, size_t* result, int base)
106 {
107   LCHAR* endPtr;
108 
109   if (result == NULL)
110     return ESR_INVALID_ARGUMENT;
111   *result = (size_t) LSTRTOUL(text, &endPtr, base);
112   if (endPtr == text || (!LISSPACE(*endPtr) && *endPtr != L('\0')))
113     return ESR_INVALID_ARGUMENT;
114   return ESR_SUCCESS;
115 }
116 
lstrtof(const LCHAR * text,float * result)117 ESR_ReturnCode lstrtof(const LCHAR* text, float* result)
118 {
119   LCHAR* endPtr;
120 
121   if (result == NULL)
122     return ESR_INVALID_ARGUMENT;
123   *result = (float) LSTRTOD(text, &endPtr);
124   if (endPtr == text || (!LISSPACE(*endPtr) && *endPtr != L('\0')))
125     return ESR_INVALID_ARGUMENT;
126   return ESR_SUCCESS;
127 }
128 
lstrtob(const LCHAR * text,ESR_BOOL * result)129 ESR_ReturnCode lstrtob(const LCHAR* text, ESR_BOOL* result)
130 {
131   ESR_ReturnCode rc = ESR_SUCCESS;
132   int compare;
133   unsigned int temp;
134 
135   if (result == NULL)
136     return ESR_INVALID_ARGUMENT;
137   CHKLOG(rc, lstrcasecmp(text, L("true"), &compare));
138   if (compare == 0)
139   {
140     *result = ESR_TRUE;
141     return ESR_SUCCESS;
142   }
143   CHKLOG(rc, lstrcasecmp(text, L("yes"), &compare));
144   if (compare == 0)
145   {
146     *result = ESR_TRUE;
147     return ESR_SUCCESS;
148   }
149   CHKLOG(rc, lstrcasecmp(text, L("false"), &compare));
150   if (compare == 0)
151   {
152     *result = ESR_FALSE;
153     return ESR_SUCCESS;
154   }
155   CHKLOG(rc, lstrcasecmp(text, L("no"), &compare));
156   if (compare == 0)
157   {
158     *result = ESR_FALSE;
159     return ESR_SUCCESS;
160   }
161 
162   /* Check for boolean expressed as an integer value */
163   CHK(rc, lstrtoui(text, &temp, 10));
164   *result = (temp != 0);
165   return ESR_SUCCESS;
166 CLEANUP:
167   return rc;
168 }
169 
LCHARGetInt(LCHAR * text,int * value,LCHAR ** finalPosition)170 ESR_ReturnCode LCHARGetInt( LCHAR* text, int* value, LCHAR** finalPosition)
171 {
172   LCHAR *beg, *end;
173   LCHAR temp;
174   ESR_ReturnCode rc;
175 
176   /* Skip whitespace */
177   for (beg = text; *beg != L('\0') && LISSPACE(*beg); ++beg);
178   if (beg == NULL)
179     return ESR_INVALID_ARGUMENT; /* invalid command syntax */
180   /* Find next whitespace */
181   for (end = beg; *end != L('\0') && !LISSPACE(*end); ++end);
182   if (end == NULL)
183     return ESR_INVALID_ARGUMENT; /* invalid command syntax */
184 
185   temp = *end;
186   *end = L('\0');
187   rc = lstrtoi(beg, value, 10);
188   if (rc != ESR_SUCCESS)
189   {
190     *end = temp;
191     PLogError(ESR_rc2str(rc));
192     goto CLEANUP;
193   }
194   *end = temp;
195   if (finalPosition != NULL)
196     *finalPosition = end;
197   return ESR_SUCCESS;
198 CLEANUP:
199   return rc;
200 }
201 
lstrlwr(LCHAR * string)202 ESR_ReturnCode lstrlwr(LCHAR* string)
203 {
204   if (string)
205   {
206     while (*string)
207     {
208       if (LISALPHA(*string))
209         *string = (LCHAR) LTOLOWER(*string);
210       ++string;
211     }
212   }
213   else
214     return ESR_INVALID_ARGUMENT;
215 
216   return ESR_SUCCESS;
217 }
218 
lstrupr(LCHAR * string)219 ESR_ReturnCode lstrupr(LCHAR* string)
220 {
221   if (string)
222   {
223     while (*string)
224     {
225       if (LISALPHA(*string))
226         *string = (LCHAR) LTOUPPER(*string);
227       ++string;
228     }
229   }
230   else
231     return ESR_INVALID_ARGUMENT;
232 
233   return ESR_SUCCESS;
234 }
235 
236 /* strcasecmp is not POSIX.4 API */
lstrcasecmp(const LCHAR * string1,const LCHAR * string2,int * result)237 ESR_ReturnCode lstrcasecmp(const LCHAR *string1, const LCHAR *string2, int *result)
238 {
239 
240   if (!string1 || !string2)
241     return ESR_INVALID_ARGUMENT;
242 
243   while (LTOUPPER(*string1) == LTOUPPER(*string2++))
244   {
245     if (!*string1++)
246     {
247       *result = 0;
248       return ESR_SUCCESS;
249     }
250   }
251 
252   *result = LTOUPPER(*string1) - LTOUPPER(*--string2);
253   return ESR_SUCCESS;
254 }
255 
256 /**
257  * This code is from MS SDK: C:\PROGRAM FILES\MICROSOFT SDK\src\crt\xtoa.c
258  * Buffer overflow checking is left up to the caller.
259  *
260  * @param value Number to be converted
261  * @param string String result
262  * @param radix Base of value; must be in the range 2 - 36
263  */
pxtoa(unsigned long val,LCHAR * buf,unsigned radix,int is_neg)264 static void pxtoa(unsigned long val, LCHAR *buf, unsigned radix, int is_neg)
265 {
266   LCHAR *p;                /* pointer to traverse string */
267   LCHAR *firstdig;         /* pointer to first digit */
268   LCHAR temp;              /* temp char */
269   unsigned digval;        /* value of digit */
270 
271   p = buf;
272 
273   if (is_neg)
274   {
275     /* negative, so output '-' and negate */
276     *p++ = '-';
277     val = (unsigned long)(-(long)val);
278   }
279 
280   firstdig = p;           /* save pointer to first digit */
281 
282   do
283   {
284     digval = (unsigned)(val % radix);
285     val /= radix;       /* get next digit */
286 
287     /* convert to ascii and store */
288     if (digval > 9)
289       *p++ = (LCHAR)(digval - 10 + 'a');  /* a letter */
290     else
291       *p++ = (LCHAR)(digval + '0');       /* a digit */
292   }
293   while (val > 0);
294 
295   /* We now have the digit of the number in the buffer, but in reverse
296      order.  Thus we reverse them now. */
297 
298   *p-- = '\0';            /* terminate string; p points to last digit */
299 
300   do
301   {
302     temp = *p;
303     *p = *firstdig;
304     *firstdig = temp;   /* swap *p and *firstdig */
305     --p;
306     ++firstdig;         /* advance to next two digits */
307   }
308   while (firstdig < p); /* repeat until halfway */
309 }
310 
311 /*
312  * Convert an integer to a string.
313  */
litostr(int value,LCHAR * string,size_t * len,int radix)314 ESR_ReturnCode litostr(int value, LCHAR *string, size_t *len, int radix)
315 {
316   size_t size;
317   /* pxtoa() is guaranteed not to overflow past 33 characters */
318   LCHAR buffer[33];
319 
320   if (!string)
321     return ESR_INVALID_ARGUMENT;
322 
323   if (radix == 10 && value < 0)
324     pxtoa((unsigned long) value, buffer, radix, 1);
325   else
326     pxtoa((unsigned long) value, buffer, radix, 0);
327 
328   size = LSTRLEN(buffer);
329 
330   if (size >= *len)   /* + null-terminated character */
331   {
332     *len = size;
333     return ESR_BUFFER_OVERFLOW;
334   }
335   else
336     LSTRCPY(string, buffer);
337 
338   return ESR_SUCCESS;
339 }
340 
341 
342 /* Convert an unsigned long integer to a string. */
lultostr(unsigned long value,LCHAR * string,size_t * len,int radix)343 ESR_ReturnCode lultostr(unsigned long  value, LCHAR *string, size_t *len, int radix)
344 {
345   size_t size;
346   LCHAR buffer[33];
347 
348   if (!string)
349     return ESR_INVALID_ARGUMENT;
350 
351   pxtoa(value, buffer, radix, 0);
352 
353   size = LSTRLEN(buffer);
354 
355   if (size >= *len)   /* + null-terminated character */
356   {
357     *len = size;
358     return ESR_BUFFER_OVERFLOW;
359   }
360   else
361   {
362     *len = size;
363     LSTRCPY(string, buffer);
364   }
365 
366   return ESR_SUCCESS;
367 }
368