1 /*
2 * EasySoap++ - A C++ library for SOAP (Simple Object Access Protocol)
3 * Copyright (C) 2001 David Crowley; SciTegic, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * $Id: SOAPUtil.h,v 1.7 2004/06/02 06:33:04 dcrowley Exp $
20 */
21
22 #ifndef __SOAPUTIL_H__
23 #define __SOAPUTIL_H__
24
25 #include <stdlib.h>
26
27 BEGIN_EASYSOAP_NAMESPACE
28
29 template<typename T>
30 inline T*
sp_alloc(size_t n)31 sp_alloc(size_t n)
32 {
33 return (T*)malloc(n * sizeof(T));
34 }
35
36 template<typename T>
37 inline void
sp_free(T * & ptr)38 sp_free(T*& ptr)
39 {
40 if (ptr)
41 free((void *)ptr);
42 ptr = 0;
43 }
44
45 inline char *
sp_strcpy(char * dest,const char * src)46 sp_strcpy(char *dest, const char *src)
47 {
48 char *work = dest;
49 if (src && dest)
50 {
51 while ((*work++ = *src++))
52 ;
53 }
54 return dest;
55 }
56
57 inline char *
sp_strncpy(char * dest,const char * src,size_t n)58 sp_strncpy(char *dest, const char *src, size_t n)
59 {
60 char *work = dest;
61 if (src && dest)
62 {
63 while (n-- && (*work++ = *src++))
64 ;
65 }
66 return dest;
67 }
68
69 inline size_t
sp_strlen(const char * str)70 sp_strlen(const char *str)
71 {
72 size_t ret = 0;
73 if (str)
74 {
75 while (*str++)
76 ++ret;
77 }
78 return ret;
79 }
80
81 inline int
sp_toupper(int c)82 sp_toupper(int c)
83 {
84 if (c >= 'a' && c <= 'z')
85 c += 'A' - 'a';
86 return c;
87 }
88
89 inline int
sp_strcmp(const char * a,const char * b)90 sp_strcmp(const char *a, const char *b)
91 {
92 int ret = 0;
93 if (a && b)
94 {
95 while (*a && *b && *a == *b)
96 ++a, ++b;
97 ret = *a - *b;
98 }
99 else if (a)
100 ret = 1;
101 else if (b)
102 ret = -1;
103 return ret;
104 }
105
106 inline int
sp_strncmp(const char * a,const char * b,unsigned int n)107 sp_strncmp(const char *a, const char *b, unsigned int n)
108 {
109 int ret = 0;
110 if (a && b)
111 {
112 while (n > 0 && *a && *b && *a == *b)
113 ++a, ++b, --n;
114 if (n == 0)
115 ret = 0;
116 else
117 ret = *a - *b;
118 }
119 else if (a)
120 ret = 1;
121 else if (b)
122 ret = -1;
123 return ret;
124 }
125
126 inline int
sp_strcasecmp(const char * a,const char * b)127 sp_strcasecmp(const char *a, const char *b)
128 {
129 int ret = 0;
130 if (a && b)
131 {
132 int ua;
133 int ub;
134 do
135 {
136 ua = sp_toupper(*a++);
137 ub = sp_toupper(*b++);
138 }
139 while (ua && ub && ua == ub);
140 ret = ua - ub;
141 }
142 else if (a)
143 ret = 1;
144 else if (b)
145 ret = -1;
146 return ret;
147 }
148
149 inline char*
sp_strstr(const char * haystack,const char * needle)150 sp_strstr(const char *haystack, const char *needle)
151 {
152 if (haystack && needle)
153 {
154 if (*needle == 0)
155 return (char *)haystack;
156
157 // step along the main string
158 while (*haystack)
159 {
160 const char *nn = needle;
161 const char *hh = haystack;
162 // see if substring characters match
163 while (*nn++ == *hh++)
164 {
165 if (*nn == 0)
166 // we got all the way to the end of the substring
167 // so we must've won
168 return (char *)haystack;
169 }
170 ++haystack;
171 }
172 }
173 return 0;
174 }
175
176 inline bool
sp_isspace(char c)177 sp_isspace(char c)
178 {
179 switch (c)
180 {
181 case '\r': // carriage return
182 case '\n': // newline
183 case '\t': // tab
184 case '\v': // vertical tab
185 case '\f': // form feed
186 case ' ': // space
187 return true;
188 }
189 return false;
190 }
191
192 inline char*
sp_strchr(const char * s,char c)193 sp_strchr(const char *s, char c)
194 {
195 if (s)
196 {
197 do
198 if (*s == c)
199 return (char*)s;
200 while (*s++);
201 }
202 return 0;
203 }
204
205 inline char*
sp_strrchr(const char * s,char c)206 sp_strrchr(const char *s, char c)
207 {
208 char *w = 0;
209 if (s)
210 {
211 do
212 if (*s == c)
213 w = (char*)s;
214 while (*s++);
215 }
216 return w;
217 }
218
219 inline void *
sp_memset(void * s,int c,size_t n)220 sp_memset(void *s, int c, size_t n)
221 {
222 unsigned char *ptr = (unsigned char *)s;
223 if (ptr)
224 {
225 while (n--)
226 *ptr++ = (unsigned char)c;
227 }
228 return s;
229 }
230
231 inline unsigned int
sp_hashcode(const char * key)232 sp_hashcode(const char *key)
233 {
234 unsigned char* ptr = (unsigned char*)key;
235 unsigned int h = 0;
236 if (ptr)
237 {
238 unsigned int c;
239 while ((c = *ptr++))
240 h = 31 * h + c;
241 }
242 return h;
243 }
244
245 inline unsigned int
sp_hashcodecase(const char * key)246 sp_hashcodecase(const char *key)
247 {
248 unsigned char* ptr = (unsigned char*)key;
249 unsigned int h = 0;
250 if (ptr)
251 {
252 unsigned int c;
253 while ((c = sp_toupper(*ptr++)) != 0)
254 h = 31 * h + c;
255 }
256 return h;
257 }
258
259 template <class T>
260 inline T
sp_minimum(const T & a,const T & b)261 sp_minimum(const T& a, const T& b)
262 {
263 return (a < b) ? a : b;
264 }
265
266 template <class T>
267 inline T
sp_maximum(const T & a,const T & b)268 sp_maximum(const T& a, const T& b)
269 {
270 return (a < b) ? b : a;
271 }
272
273 template <typename L, typename T>
274 inline T*
275 // The incoming buffer should be at least 12 bytes for a long
sp_itoa(L a,T * const buffer)276 sp_itoa(L a, T *const buffer)
277 {
278 T *ptr = buffer;
279
280 //
281 // store begining of string
282 // we have to reverse
283 T *b = ptr;
284
285 // check if we're negative
286 if (a < 0)
287 {
288 // while we have a non-zero value
289 // get the base 10 remainder
290 while (a != 0)
291 {
292 *ptr++ = T('0' - (a % 10));
293 a /= 10;
294 }
295 *ptr++ = '-';
296 }
297 else
298 {
299 // while we have a non-zero value
300 // get the base 10 remainder
301 do
302 {
303 *ptr++ = T((a % 10) + '0');
304 a /= 10;
305 } while (a != 0);
306 }
307
308 // null terminate
309 *ptr = 0;
310
311 // now reverse the string
312 while (b < --ptr)
313 {
314 T keep = *b;
315 *b++ = *ptr;
316 *ptr = keep;
317 }
318
319 return buffer;
320 }
321
322 //
323 // Functions to convert between
324 // UTF16 and UCS character encoding.
325 template <typename T>
326 inline bool
sp_UCS_UTF16(int c,T & utf16)327 sp_UCS_UTF16(int c, T& utf16)
328 {
329 if (c > 0xFFFF && c < 0x00110000)
330 {
331 *utf16++ = (0xD7C0 + (c >> 10));
332 *utf16++ = (0xDC00 | c & 0x3FF);
333 }
334 else if (c >= 0)
335 {
336 *utf16++ = c;
337 }
338 else
339 {
340 return false;
341 }
342 return true;
343 }
344
345 template <typename T>
346 inline bool
sp_UTF16_UCS(T & utf16,int & c)347 sp_UTF16_UCS(T& utf16, int& c)
348 {
349 int x = utf16[0];
350
351 if (x >= 0 && x <= 0xD7FF || x >= 0xE000 && x <= 0xFFFF)
352 {
353 c = x;
354 ++utf16;
355 }
356 else
357 {
358 int y = utf16[1];
359 if (x >= 0xD800 && x <= 0xDBFF && y >= 0xDC00 && y <= 0xDFFF)
360 {
361 c = (x - 0xD800) * 0x400 + y - 0xDC00;
362 ++utf16; ++utf16;
363 }
364 else
365 {
366 return false;
367 }
368 }
369 return true;
370 }
371
372 //
373 // Functions to convert between
374 // UTF8 and UCS character encoding.
375 //
376 // T is an iterator. (or pointer)
377 inline bool
sp_UCS_UTF8(int c,char * & utf8)378 sp_UCS_UTF8(int c, char *& utf8)
379 {
380 if (c < 0)
381 return false;
382
383 if (c <= 0x7F)
384 {
385 /* Leave ASCII encoded */
386 *utf8++ = char(c);
387 }
388 else if (c <= 0x07FF)
389 {
390 /* 110xxxxx 10xxxxxx */
391 *utf8++ = char(0xC0 | (c >> 6));
392 *utf8++ = char(0x80 | (c & 0x3F));
393 }
394 else if (c <= 0xFFFF)
395 {
396 /* 1110xxxx + 2 */
397 *utf8++ = char(0xE0 | (c >> 12));
398 *utf8++ = char(0x80 | ((c >> 6) & 0x3F));
399 *utf8++ = char(0x80 | (c & 0x3F));
400 }
401 else if (c <= 0x1FFFFF)
402 {
403 /* 11110xxx + 3 */
404 *utf8++ = char(0xF0 | (c >> 18));
405 *utf8++ = char(0x80 | ((c >> 12) & 0x3F));
406 *utf8++ = char(0x80 | ((c >> 6) & 0x3F));
407 *utf8++ = char(0x80 | (c & 0x3F));
408 }
409 else if (c <= 0x3FFFFFF)
410 {
411 /* 111110xx + 4 */
412 *utf8++ = char(0xF8 | (c >> 24));
413 *utf8++ = char(0x80 | ((c >> 18) & 0x3F));
414 *utf8++ = char(0x80 | ((c >> 12) & 0x3F));
415 *utf8++ = char(0x80 | ((c >> 6) & 0x3F));
416 *utf8++ = char(0x80 | (c & 0x3F));
417 }
418 else //if (c <= 0x7FFFFFFF)
419 {
420 /* 1111110x + 5 */
421 *utf8++ = char(0xFC | (c >> 30));
422 *utf8++ = char(0x80 | ((c >> 24) & 0x3F));
423 *utf8++ = char(0x80 | ((c >> 18) & 0x3F));
424 *utf8++ = char(0x80 | ((c >> 12) & 0x3F));
425 *utf8++ = char(0x80 | ((c >> 6) & 0x3F));
426 *utf8++ = char(0x80 | (c & 0x3F));
427 }
428
429 return true;
430 }
431
432 inline bool
sp_UTF8_UCS(const char * & utf8,int & c)433 sp_UTF8_UCS(const char *& utf8, int& c)
434 {
435 int b = (unsigned char)*utf8++;
436 if (b <= 0x7F)
437 {
438 c = b;
439 }
440 else if ((b & 0xE0) == 0xC0)
441 { /* 110xxxxx 10xxxxxx */
442 c = (b & 0x1F) << 6;
443 b = *utf8++;
444 c |= b & 0x3F;
445 }
446 else if ((b & 0xF0) == 0xE0)
447 { /* 1110xxxx + 2 */
448 c = (b & 0x0F) << 12;
449 b = *utf8++;
450 c |= (b & 0x3F) << 6;
451 b = *utf8++;
452 c |= b & 0x3F;
453 }
454 else if ((b & 0xF1) == 0xF0)
455 { /* 11110xxx + 3 */
456 c = (b & 0x0F) << 18;
457 b = *utf8++;
458 c |= (b & 0x3F) << 12;
459 b = *utf8++;
460 c |= (b & 0x3F) << 6;
461 b = *utf8++;
462 c |= b & 0x3F;
463 }
464 else if ((b & 0xFD) == 0xF8)
465 {
466 /* 111110xx + 4 */
467 c = (b & 0x0F) << 24;
468 b = *utf8++;
469 c |= (b & 0x0F) << 18;
470 b = *utf8++;
471 c |= (b & 0x3F) << 12;
472 b = *utf8++;
473 c |= (b & 0x3F) << 6;
474 b = *utf8++;
475 c |= b & 0x3F;
476 }
477 else if ((b & 0xFE) == 0xFC)
478 {
479 /* 1111110x + 5 */
480 c = (b & 0x0F) << 30;
481 b = *utf8++;
482 c |= (b & 0x0F) << 24;
483 b = *utf8++;
484 c |= (b & 0x0F) << 18;
485 b = *utf8++;
486 c |= (b & 0x3F) << 12;
487 b = *utf8++;
488 c |= (b & 0x3F) << 6;
489 b = *utf8++;
490 c |= b & 0x3F;
491 }
492 else
493 {
494 /* Error */
495 return false;
496 }
497 return true;
498 }
499
500 END_EASYSOAP_NAMESPACE
501
502 #endif // __SOAPUTIL_H__
503
504