1 /*************************************************************************
2 #
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26 #*************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sal.hxx"
30 
31 //------------------------------------------------------------------------
32 //------------------------------------------------------------------------
33 
34 #include <math.h>
35 #include <stdlib.h>
36 
37 //------------------------------------------------------------------------
38 //------------------------------------------------------------------------
39 
40 #ifndef _SAL_TYPES_H_
41 	#include <sal/types.h>
42 #endif
43 
44 #ifndef _RTL_USTRING_H_
45 	#include <rtl/ustring.h>
46 #endif
47 
48 #ifndef _RTL_STRING_HXX_
49 	#include <rtl/string.hxx>
50 #endif
51 
52 //------------------------------------------------------------------------
53 //------------------------------------------------------------------------
54 
55 #ifndef _RTL_STRING_UTILS_CONST_H_
56 	#include <rtl_String_Utils_Const.h>
57 #endif
58 
59 //------------------------------------------------------------------------
60 //------------------------------------------------------------------------
61 
62 using namespace rtl;
63 
64 sal_uInt32 AStringLen( const sal_Char *pAStr )
65 {
66 	sal_uInt32  nStrLen = 0;
67 
68 	if ( pAStr != NULL )
69 	{
70 		const sal_Char *pTempStr = pAStr;
71 
72 		while( *pTempStr )
73 		{
74 			pTempStr++;
75 		} // while
76 
77 		nStrLen = (sal_uInt32)( pTempStr - pAStr );
78 	} // if
79 
80 	return nStrLen;
81 } // AStringLen
82 /* disable assignment within condition expression */
83 #ifdef WNT
84 #pragma warning( disable : 4706 )
85 #endif
86 sal_Char* cpystr( sal_Char* dst, const sal_Char* src )
87 {
88     const sal_Char* psrc = src;
89     sal_Char* pdst = dst;
90 
91     while( (*pdst++ = *psrc++) );
92     return ( dst );
93 }
94 
95 sal_Char* cpynstr( sal_Char* dst, const sal_Char* src, sal_uInt32 cnt )
96 {
97 
98     const sal_Char* psrc = src;
99     sal_Char* pdst = dst;
100     sal_uInt32 len = cnt;
101     sal_uInt32 i;
102 
103     if ( len >= AStringLen(src) )
104     {
105         return( cpystr( dst, src ) );
106     }
107 
108     // copy string by char
109     for( i = 0; i < len; i++ )
110         *pdst++ = *psrc++;
111     *pdst = '\0';
112 
113     return ( dst );
114 }
115 
116 //------------------------------------------------------------------------
117 sal_Bool cmpstr( const sal_Char* str1, const sal_Char* str2, sal_uInt32 len )
118 {
119     const sal_Char* pBuf1 = str1;
120     const sal_Char* pBuf2 = str2;
121     sal_uInt32 i = 0;
122 
123     while ( (*pBuf1 == *pBuf2) && i < len )
124     {
125         (pBuf1)++;
126         (pBuf2)++;
127         i++;
128     }
129     return( i == len );
130 }
131 //-----------------------------------------------------------------------
132 sal_Bool cmpstr( const sal_Char* str1, const sal_Char* str2 )
133 {
134     const sal_Char* pBuf1 = str1;
135     const sal_Char* pBuf2 = str2;
136     sal_Bool res = sal_True;
137 
138     while ( (*pBuf1 == *pBuf2) && *pBuf1 !='\0' && *pBuf2 != '\0')
139     {
140         (pBuf1)++;
141         (pBuf2)++;
142     }
143     if (*pBuf1 == '\0' && *pBuf2 == '\0')
144         res = sal_True;
145     else
146         res = sal_False;
147     return (res);
148 }
149 //------------------------------------------------------------------------
150 sal_Bool cmpustr( const sal_Unicode* str1, const sal_Unicode* str2, sal_uInt32 len )
151 {
152     const sal_Unicode* pBuf1 = str1;
153     const sal_Unicode* pBuf2 = str2;
154     sal_uInt32 i = 0;
155 
156     while ( (*pBuf1 == *pBuf2) && i < len )
157     {
158         (pBuf1)++;
159         (pBuf2)++;
160         i++;
161     }
162     return( i == len );
163 }
164 
165 //-----------------------------------------------------------------------
166 sal_Bool cmpustr( const sal_Unicode* str1, const sal_Unicode* str2 )
167 {
168     const sal_Unicode* pBuf1 = str1;
169     const sal_Unicode* pBuf2 = str2;
170     sal_Bool res = sal_True;
171 
172     while ( (*pBuf1 == *pBuf2) && *pBuf1 !='\0' && *pBuf2 != '\0')
173     {
174         (pBuf1)++;
175         (pBuf2)++;
176     }
177     if (*pBuf1 == '\0' && *pBuf2 == '\0')
178         res = sal_True;
179     else
180         res = sal_False;
181     return (res);
182 }
183 
184 sal_Char* createName( sal_Char* dst, const sal_Char* meth, sal_uInt32 cnt )
185 {
186     sal_Char* pdst = dst;
187     sal_Char nstr[16];
188     sal_Char* pstr = nstr;
189     rtl_str_valueOfInt32( pstr, cnt, 10 );
190 
191     cpystr( pdst, meth );
192     cpystr( pdst+ AStringLen(meth), "_" );
193 
194     if ( cnt < 100 )
195     {
196         cpystr(pdst + AStringLen(pdst), "0" );
197     }
198     if ( cnt < 10 )
199     {
200         cpystr(pdst + AStringLen(pdst), "0" );
201     }
202 
203     cpystr( pdst + AStringLen(pdst), nstr );
204     return( pdst );
205 }
206 
207 //------------------------------------------------------------------------
208 //  testing the method compareTo( const OString & aStr )
209 //------------------------------------------------------------------------
210 void makeComment( char *com, const char *str1, const char *str2,
211                                                             sal_Int32 sgn )
212 {
213     cpystr(com, str1);
214     int str1Length = AStringLen( str1 );
215     const char *sign = (sgn == 0) ? " == " : (sgn > 0) ? " > " : " < " ;
216     cpystr(com + str1Length, sign);
217     int signLength = AStringLen(sign);
218     cpystr(com + str1Length + signLength, str2);
219     com[str1Length + signLength + AStringLen(str2)] = 0;
220 }
221 
222 
223 //------------------------------------------------------------------------
224 
225 sal_Bool AStringToFloatCompare ( const sal_Char  *pStr,
226                                  const float      nX,
227                                  const float      nEPS
228                                 )
229 {
230 	sal_Bool cmp = sal_False;
231 
232 	if ( pStr != NULL )
233 	{
234 		::rtl::OString aStr(pStr);
235 
236 		float actNum = 0;
237 		float expNum = nX;
238 		float eps    = nEPS;
239 
240 		actNum = aStr.toFloat();
241 
242         if ( abs( (int)(actNum - expNum) ) <= eps )
243 		{
244 			cmp = sal_True;
245 		} // if
246 	} // if
247 
248 	return cmp;
249 } // AStringToFloatCompare
250 
251 //------------------------------------------------------------------------
252 
253 sal_Bool AStringToDoubleCompare ( const sal_Char  *pStr,
254                                   const double     nX,
255                                   const double     nEPS
256                                 )
257 {
258 	sal_Bool cmp = sal_False;
259 
260 	if ( pStr != NULL )
261 	{
262 		::rtl::OString aStr(pStr);
263 
264 		double actNum = 0;
265 		double expNum = nX;
266 		double eps    = nEPS;
267 
268 		actNum = aStr.toDouble();
269 
270         if ( abs( (int)(actNum - expNum) ) <= eps )
271 		{
272 			cmp = sal_True;
273 		} // if
274 	} // if
275 
276 	return cmp;
277 } // AStringToDoubleCompare
278 
279 //------------------------------------------------------------------------
280 
281 
282 //------------------------------------------------------------------------
283 
284 sal_uInt32 UStringLen( const sal_Unicode *pUStr )
285 {
286 	sal_uInt32 nUStrLen = 0;
287 
288 	if ( pUStr != NULL )
289 	{
290 		const sal_Unicode *pTempUStr = pUStr;
291 
292 		while( *pTempUStr )
293 		{
294 			pTempUStr++;
295 		} // while
296 
297 		nUStrLen = (sal_uInt32)( pTempUStr - pUStr );
298 	} // if
299 
300 	return nUStrLen;
301 } // UStringLen
302 
303 //------------------------------------------------------------------------
304 
305 sal_Bool AStringIsValid( const sal_Char  *pAStr )
306 {
307 	if ( pAStr != NULL )
308 	{
309 		sal_uInt32 nLen  = AStringLen( pAStr );
310 		sal_uChar  uChar = 0;
311 
312 		while ( *pAStr )
313 		{
314 			uChar = (unsigned char)*pAStr;
315 
316 			if ( uChar > 127 )
317 			{
318 				return sal_False;
319 			} // if
320 
321 			pAStr++;
322 
323 			// Since we are dealing with unsigned integers
324 			// we want to make sure that the last number is
325 			// indeed zero.
326 
327 			if ( nLen > 0 )
328 			{
329 				nLen--;
330 			} // if
331 			else
332 			{
333 				break;
334 			} // else
335 		} // while
336 	} // if
337 
338 	return sal_True;
339 } // AStringIsValid
340 
341 //------------------------------------------------------------------------
342 
343 sal_Bool AStringNIsValid( const sal_Char   *pAStr,
344                           const sal_uInt32  nStrLen
345                         )
346 {
347 	sal_uInt32 nLen  = nStrLen;
348 	sal_uChar  uChar = 0;
349 
350 	while ( *pAStr )
351 	{
352 		uChar = (unsigned char)*pAStr;
353 
354 		if ( uChar > 127 )
355 		{
356 			return sal_False;
357 		} // if
358 
359 		pAStr++;
360 
361 		// Since we are dealing with unsigned integers
362 		// we want to make sure that the last number is
363 		// indeed zero.
364 
365 		if ( nLen > 0 )
366 		{
367 			nLen--;
368 		} // if
369 		else
370 		{
371 			break;
372 		} // else
373 	} // while
374 
375 	return sal_True;
376 } // AStringNIsValid
377 
378 //------------------------------------------------------------------------
379 
380 static inline sal_Int32 ACharToUCharCompare( const sal_Unicode *pUStr,
381                                              const sal_Char    *pAStr
382                                            )
383 {
384 	sal_Int32  nCmp   = 0;
385 	sal_Int32  nUChar = (sal_Int32)*pUStr;
386 	sal_Int32  nChar  = (sal_Int32)((unsigned char)*pAStr);
387 
388 	nCmp = nUChar - nChar;
389 
390 	return  nCmp;
391 } // ACharToUCharCompare
392 
393 //------------------------------------------------------------------------
394 
395 sal_Int32 AStringToUStringCompare( const sal_Unicode *pUStr,
396                                    const sal_Char    *pAStr
397                                  )
398 {
399  	sal_Int32 nCmp = kErrCompareAStringToUString;
400 
401 	if ( ( pUStr != NULL ) && ( pAStr != NULL ) )
402 	{
403 		nCmp = ACharToUCharCompare( pUStr, pAStr );
404 
405 		while ( ( nCmp == 0 ) && ( *pAStr ) )
406 		{
407 			pUStr++;
408 			pAStr++;
409 
410 			nCmp = ACharToUCharCompare( pUStr, pAStr );
411 		} // while
412 	} // if
413 
414 	return nCmp;
415 } // AStringToUStringCompare
416 
417 //------------------------------------------------------------------------
418 
419 sal_Int32 AStringToUStringNCompare( const sal_Unicode  *pUStr,
420                                     const sal_Char     *pAStr,
421                                     const sal_uInt32    nAStrCount
422                                    )
423 {
424 	sal_Int32 nCmp = kErrCompareNAStringToUString;
425 
426 	if ( ( pUStr != NULL ) && ( pAStr != NULL ) )
427 	{
428 		sal_uInt32 nCount = nAStrCount;
429 
430 		nCmp = ACharToUCharCompare( pUStr, pAStr );
431 
432 		while ( ( nCmp == 0 ) && ( *pAStr ) && ( nCount ) )
433 		{
434 			pUStr++;
435 			pAStr++;
436 
437 			nCmp = ACharToUCharCompare( pUStr, pAStr );
438 
439 			// Since we are dealing with unsigned integers
440 			// we want to make sure that the last number is
441 			// indeed zero.
442 
443 			if ( nCount > 0 )
444 			{
445 				nCount--;
446 			} // if
447 			else
448 			{
449 				break;
450 			} // else
451 		} // while
452 	} // if
453 
454 	return nCmp;
455 } // AStringToUStringNCompare
456 
457 //------------------------------------------------------------------------
458 
459 sal_Int32 AStringToRTLUStringCompare( const rtl_uString  *pRTLUStr,
460                                       const sal_Char     *pAStr
461                                     )
462 {
463 	sal_Int32 nCmp = kErrCompareAStringToRTLUString;
464 
465 	if ( ( pRTLUStr != NULL ) && ( pAStr != NULL ) )
466 	{
467 		rtl_uString *pRTLUStrCopy = NULL;
468 
469 		rtl_uString_newFromString( &pRTLUStrCopy, pRTLUStr );
470 
471 		if ( pRTLUStrCopy != NULL )
472 		{
473 			const sal_Unicode *pUStr = rtl_uString_getStr( pRTLUStrCopy );
474 
475 			if ( pUStr != NULL )
476 			{
477 				nCmp = AStringToUStringCompare( pUStr, pAStr );
478 			} // if
479 
480 			rtl_uString_release( pRTLUStrCopy );
481 
482 			pRTLUStrCopy = NULL;
483 		} // if
484 	} // if
485 
486 	return nCmp;
487 } // AStringToRTLUStringCompare
488 
489 //------------------------------------------------------------------------
490 
491 sal_Int32 AStringToRTLUStringNCompare( const rtl_uString  *pRTLUStr,
492                                        const sal_Char     *pAStr,
493                                        const sal_uInt32    nAStrCount
494                                      )
495 {
496 	sal_Int32 nCmp = kErrCompareNAStringToRTLUString;
497 
498 	if ( ( pRTLUStr != NULL ) && ( pAStr != NULL ) )
499 	{
500 		rtl_uString *pRTLUStrCopy = NULL;
501 
502 		rtl_uString_newFromString( &pRTLUStrCopy, pRTLUStr );
503 
504 		if ( pRTLUStrCopy != NULL )
505 		{
506 			const sal_Unicode  *pUStr = rtl_uString_getStr( pRTLUStrCopy );
507 
508 			if ( pUStr != NULL )
509 			{
510 				nCmp = AStringToUStringNCompare( pUStr, pAStr, nAStrCount );
511 			} // if
512 
513 			rtl_uString_release( pRTLUStrCopy );
514 
515 			pRTLUStrCopy = NULL;
516 		} // if
517 	} // if
518 
519 	return nCmp;
520 } // AStringToRTLUStringNCompare
521 
522 //------------------------------------------------------------------------
523 
524 sal_Bool AStringToUStringCopy( sal_Unicode     *pDest,
525                                const sal_Char  *pSrc
526                              )
527 {
528 	sal_Bool    bCopied = sal_False;
529 	sal_uInt32  nCount  = AStringLen( pSrc );
530 	sal_uInt32  nLen    = nCount;
531 
532 	if (    ( pDest != NULL )
533 	     && ( pSrc  != NULL )
534 	     && ( AStringNIsValid( pSrc, nLen ) )
535 	   )
536 	{
537 		for (;;)
538 		{
539 			*pDest = (unsigned char)*pSrc;
540 
541 			pDest++;
542 			pSrc++;
543 
544 			// Since we are dealing with unsigned integers
545 			// we want to make sure that the last number is
546 			// indeed zero.
547 
548 			if ( nCount > 0 )
549 			{
550 				nCount--;
551 			} // if
552 			else
553 			{
554 				break;
555 			} // else
556 		} // while
557 
558 		if ( nCount == 0 )
559 		{
560 			bCopied = sal_True;
561 		} // if
562 	} // if
563 
564 	return  bCopied;
565 } // AStringToUStringCopy
566 
567 //------------------------------------------------------------------------
568 
569 sal_Bool AStringToUStringNCopy( sal_Unicode       *pDest,
570                                 const sal_Char    *pSrc,
571                                 const sal_uInt32   nSrcLen
572                               )
573 {
574 	sal_Bool    bCopied = sal_False;
575 	sal_uInt32  nCount  = nSrcLen;
576 	sal_uInt32  nLen    = nSrcLen;
577 
578 	if (    ( pDest != NULL )
579 	     && ( pSrc  != NULL )
580 	     && ( AStringNIsValid( pSrc, nLen ) )
581 	   )
582 	{
583         for (;;)
584 		{
585 			*pDest = (unsigned char)*pSrc;
586 
587 			pDest++;
588 			pSrc++;
589 
590 			// Since we are dealing with unsigned integers
591 			// we want to make sure that the last number is
592 			// indeed zero.
593 
594 			if ( nCount > 0 )
595 			{
596 				nCount--;
597 			} // if
598 			else
599 			{
600 				break;
601 			} // else
602 		} // while
603 
604 		if ( nCount == 0 )
605 		{
606 			bCopied = sal_True;
607 		} // if
608 	} // if
609 
610 	return  bCopied;
611 } // AStringToUStringNCopy
612 
613 //------------------------------------------------------------------------
614 //------------------------------------------------------------------------
615 
616