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