xref: /trunk/main/unotools/source/i18n/charclass.cxx (revision cdf0e10c)
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_unotools.hxx"
30 
31 #include <unotools/charclass.hxx>
32 #include <tools/string.hxx>
33 #include <tools/debug.hxx>
34 
35 #ifndef _COMPHELPER_COMPONENTFACTORY_HXX_
36 #include <comphelper/componentfactory.hxx>
37 #endif
38 #include <com/sun/star/uno/XInterface.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 
41 #define CHARCLASS_LIBRARYNAME "i18n"
42 #define CHARCLASS_SERVICENAME "com.sun.star.i18n.CharacterClassification"
43 
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::i18n;
46 using namespace ::com::sun::star::uno;
47 
48 
49 CharClass::CharClass(
50 			const Reference< lang::XMultiServiceFactory > & xSF,
51 			const lang::Locale& rLocale
52 			)
53 		:
54 		xSMgr( xSF )
55 {
56 	setLocale( rLocale );
57 	if ( xSMgr.is() )
58 	{
59 		try
60 		{
61 			xCC = Reference< XCharacterClassification > ( xSMgr->createInstance(
62 				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CHARCLASS_SERVICENAME ) ) ),
63 				uno::UNO_QUERY );
64 		}
65 		catch ( Exception& )
66 		{
67 			DBG_ERRORFILE( "CharClass ctor: Exception caught!" );
68 		}
69 	}
70 	else
71 	{	// try to get an instance somehow
72 		getComponentInstance();
73 	}
74 }
75 
76 
77 CharClass::CharClass(
78 			const ::com::sun::star::lang::Locale& rLocale )
79 {
80 	setLocale( rLocale );
81 	getComponentInstance();
82 }
83 
84 
85 CharClass::~CharClass()
86 {
87 }
88 
89 
90 void CharClass::getComponentInstance()
91 {
92 	try
93 	{
94 		// CharClass may be needed by "small tools" like the Setup
95 		// => maybe no service manager => loadLibComponentFactory
96 		Reference < XInterface > xI = ::comphelper::getComponentInstance(
97 			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( CHARCLASS_LIBRARYNAME ) ) ),
98 			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CHARCLASS_SERVICENAME ) ) );
99 		if ( xI.is() )
100 		{
101 			Any x = xI->queryInterface( ::getCppuType((const Reference< XCharacterClassification >*)0) );
102 			x >>= xCC;
103 		}
104 	}
105 	catch ( Exception& )
106 	{
107 		DBG_ERRORFILE( "getComponentInstance: Exception caught!" );
108 	}
109 }
110 
111 
112 void CharClass::setLocale( const ::com::sun::star::lang::Locale& rLocale )
113 {
114     ::osl::MutexGuard aGuard( aMutex );
115 	aLocale.Language = rLocale.Language;
116 	aLocale.Country = rLocale.Country;
117 	aLocale.Variant = rLocale.Variant;
118 }
119 
120 
121 const ::com::sun::star::lang::Locale& CharClass::getLocale() const
122 {
123     ::osl::MutexGuard aGuard( aMutex );
124     return aLocale;
125 }
126 
127 
128 // static
129 sal_Bool CharClass::isAsciiNumeric( const String& rStr )
130 {
131 	if ( !rStr.Len() )
132 		return sal_False;
133 	register const sal_Unicode* p = rStr.GetBuffer();
134 	register const sal_Unicode* const pStop = p + rStr.Len();
135 	do
136 	{
137 		if ( !isAsciiDigit( *p ) )
138 			return sal_False;
139 	} while ( ++p < pStop );
140 	return sal_True;
141 }
142 
143 
144 // static
145 sal_Bool CharClass::isAsciiAlpha( const String& rStr )
146 {
147 	if ( !rStr.Len() )
148 		return sal_False;
149 	register const sal_Unicode* p = rStr.GetBuffer();
150 	register const sal_Unicode* const pStop = p + rStr.Len();
151 	do
152 	{
153 		if ( !isAsciiAlpha( *p ) )
154 			return sal_False;
155 	} while ( ++p < pStop );
156 	return sal_True;
157 }
158 
159 
160 // static
161 sal_Bool CharClass::isAsciiAlphaNumeric( const String& rStr )
162 {
163 	if ( !rStr.Len() )
164 		return sal_False;
165 	register const sal_Unicode* p = rStr.GetBuffer();
166 	register const sal_Unicode* const pStop = p + rStr.Len();
167 	do
168 	{
169 		if ( !isAsciiAlphaNumeric( *p ) )
170 			return sal_False;
171 	} while ( ++p < pStop );
172 	return sal_True;
173 }
174 
175 
176 sal_Bool CharClass::isAlpha( const String& rStr, xub_StrLen nPos ) const
177 {
178     sal_Unicode c = rStr.GetChar( nPos );
179     if ( c < 128 )
180         return isAsciiAlpha( c );
181 
182 	try
183 	{
184 		if ( xCC.is() )
185             return  (xCC->getCharacterType( rStr, nPos, getLocale() ) &
186 				nCharClassAlphaType) != 0;
187 		else
188 			return sal_False;
189 	}
190 	catch ( Exception& )
191 	{
192 		DBG_ERRORFILE( "isAlpha: Exception caught!" );
193 		return sal_False;
194 	}
195 }
196 
197 
198 sal_Bool CharClass::isAlpha( const String& rStr ) const
199 {
200 	try
201 	{
202 		if ( xCC.is() )
203             return isAlphaType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) );
204 		else
205 			return sal_False;
206 	}
207 	catch ( Exception& )
208 	{
209 		DBG_ERRORFILE( "isAlpha: Exception caught!" );
210 		return sal_False;
211 	}
212 }
213 
214 
215 sal_Bool CharClass::isLetter( const String& rStr, xub_StrLen nPos ) const
216 {
217     sal_Unicode c = rStr.GetChar( nPos );
218     if ( c < 128 )
219         return isAsciiAlpha( c );
220 
221 	try
222 	{
223 		if ( xCC.is() )
224             return  (xCC->getCharacterType( rStr, nPos, getLocale() ) &
225 				nCharClassLetterType) != 0;
226 		else
227 			return sal_False;
228 	}
229 	catch ( Exception& )
230 	{
231 		DBG_ERRORFILE( "isLetter: Exception caught!" );
232 		return sal_False;
233 	}
234 }
235 
236 
237 sal_Bool CharClass::isLetter( const String& rStr ) const
238 {
239 	try
240 	{
241 		if ( xCC.is() )
242             return isLetterType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) );
243 		else
244 			return sal_False;
245 	}
246 	catch ( Exception& )
247 	{
248 		DBG_ERRORFILE( "isLetter: Exception caught!" );
249 		return sal_False;
250 	}
251 }
252 
253 
254 sal_Bool CharClass::isDigit( const String& rStr, xub_StrLen nPos ) const
255 {
256     sal_Unicode c = rStr.GetChar( nPos );
257     if ( c < 128 )
258         return isAsciiDigit( c );
259 
260 	try
261 	{
262 		if ( xCC.is() )
263             return  (xCC->getCharacterType( rStr, nPos, getLocale() ) &
264 				KCharacterType::DIGIT) != 0;
265 		else
266 			return sal_False;
267 	}
268 	catch ( Exception& )
269 	{
270 		DBG_ERRORFILE( "isDigit: Exception caught!" );
271 		return sal_False;
272 	}
273 }
274 
275 
276 sal_Bool CharClass::isNumeric( const String& rStr ) const
277 {
278 	try
279 	{
280 		if ( xCC.is() )
281             return isNumericType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) );
282 		else
283 			return sal_False;
284 	}
285 	catch ( Exception& )
286 	{
287 		DBG_ERRORFILE( "isNumeric: Exception caught!" );
288 		return sal_False;
289 	}
290 }
291 
292 
293 sal_Bool CharClass::isAlphaNumeric( const String& rStr,	xub_StrLen nPos ) const
294 {
295     sal_Unicode c = rStr.GetChar( nPos );
296     if ( c < 128 )
297         return isAsciiAlphaNumeric( c );
298 
299 	try
300 	{
301 		if ( xCC.is() )
302             return  (xCC->getCharacterType( rStr, nPos, getLocale() ) &
303 				(nCharClassAlphaType | KCharacterType::DIGIT)) != 0;
304 		else
305 			return sal_False;
306 	}
307 	catch ( Exception& )
308 	{
309 		DBG_ERRORFILE( "isAlphaNumeric: Exception caught!" );
310 		return sal_False;
311 	}
312 }
313 
314 
315 sal_Bool CharClass::isAlphaNumeric( const String& rStr ) const
316 {
317 	try
318 	{
319 		if ( xCC.is() )
320             return isAlphaNumericType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) );
321 		else
322 			return sal_False;
323 	}
324 	catch ( Exception& )
325 	{
326 		DBG_ERRORFILE( "isAlphaNumeric: Exception caught!" );
327 		return sal_False;
328 	}
329 }
330 
331 
332 sal_Bool CharClass::isLetterNumeric( const String& rStr, xub_StrLen nPos ) const
333 {
334     sal_Unicode c = rStr.GetChar( nPos );
335     if ( c < 128 )
336         return isAsciiAlphaNumeric( c );
337 
338 	try
339 	{
340 		if ( xCC.is() )
341             return  (xCC->getCharacterType( rStr, nPos, getLocale() ) &
342 				(nCharClassLetterType | KCharacterType::DIGIT)) != 0;
343 		else
344 			return sal_False;
345 	}
346 	catch ( Exception& )
347 	{
348 		DBG_ERRORFILE( "isLetterNumeric: Exception caught!" );
349 		return sal_False;
350 	}
351 }
352 
353 
354 sal_Bool CharClass::isLetterNumeric( const String& rStr ) const
355 {
356 	try
357 	{
358 		if ( xCC.is() )
359             return isLetterNumericType( xCC->getStringType( rStr, 0, rStr.Len(), getLocale() ) );
360 		else
361 			return sal_False;
362 	}
363 	catch ( Exception& )
364 	{
365 		DBG_ERRORFILE( "isLetterNumeric: Exception caught!" );
366 		return sal_False;
367 	}
368 }
369 
370 
371 String CharClass::toUpper( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const
372 {
373 	return toUpper_rtl(rStr, nPos, nCount);
374 }
375 
376 
377 String CharClass::toLower( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const
378 {
379 	return toLower_rtl(::rtl::OUString(rStr), nPos, nCount);
380 }
381 
382 
383 String CharClass::toTitle( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const
384 {
385 	try
386 	{
387 		if ( xCC.is() )
388             return xCC->toTitle( rStr, nPos, nCount, getLocale() );
389 		else
390 			return rStr.Copy( nPos, nCount );
391 	}
392 	catch ( Exception& )
393 	{
394 		DBG_ERRORFILE( "toTitle: Exception caught!" );
395 		return rStr.Copy( nPos, nCount );
396 	}
397 }
398 
399 
400 ::rtl::OUString CharClass::toUpper_rtl( const ::rtl::OUString& rStr, sal_Int32 nPos, sal_Int32 nCount ) const
401 {
402 	try
403 	{
404 		if ( xCC.is() )
405             return xCC->toUpper( rStr, nPos, nCount, getLocale() );
406 		else
407 			return rStr.copy( nPos, nCount );
408 	}
409 	catch ( Exception& )
410 	{
411 		DBG_ERRORFILE( "toUpper: Exception caught!" );
412 		return rStr.copy( nPos, nCount );
413 	}
414 }
415 
416 
417 ::rtl::OUString CharClass::toLower_rtl( const ::rtl::OUString& rStr, sal_Int32 nPos, sal_Int32 nCount ) const
418 {
419 	try
420 	{
421 		if ( xCC.is() )
422             return xCC->toLower( rStr, nPos, nCount, getLocale() );
423 		else
424 			return rStr.copy( nPos, nCount );
425 	}
426 	catch ( Exception& )
427 	{
428 		DBG_ERRORFILE( "toLower: Exception caught!" );
429 		return rStr.copy( nPos, nCount );
430 	}
431 }
432 
433 
434 sal_Int16 CharClass::getType( const String& rStr, xub_StrLen nPos ) const
435 {
436 	try
437 	{
438 		if ( xCC.is() )
439 			return xCC->getType( rStr, nPos );
440 		else
441 			return 0;
442 	}
443 	catch ( Exception& )
444 	{
445 		DBG_ERRORFILE( "getType: Exception caught!" );
446 		return 0;
447 	}
448 }
449 
450 
451 sal_Int16 CharClass::getCharacterDirection( const String& rStr, xub_StrLen nPos ) const
452 {
453 	try
454 	{
455 		if ( xCC.is() )
456 			return xCC->getCharacterDirection( rStr, nPos );
457 		else
458 			return 0;
459 	}
460 	catch ( Exception& )
461 	{
462 		DBG_ERRORFILE( "getCharacterDirection: Exception caught!" );
463 		return 0;
464 	}
465 }
466 
467 
468 sal_Int16 CharClass::getScript( const String& rStr, xub_StrLen nPos ) const
469 {
470 	try
471 	{
472 		if ( xCC.is() )
473 			return xCC->getScript( rStr, nPos );
474 		else
475 			return 0;
476 	}
477 	catch ( Exception& )
478 	{
479 		DBG_ERRORFILE( "getScript: Exception caught!" );
480 		return 0;
481 	}
482 }
483 
484 
485 sal_Int32 CharClass::getCharacterType( const String& rStr, xub_StrLen nPos ) const
486 {
487 	try
488 	{
489 		if ( xCC.is() )
490             return xCC->getCharacterType( rStr, nPos, getLocale() );
491 		else
492 			return 0;
493 	}
494 	catch ( Exception& )
495 	{
496 		DBG_ERRORFILE( "getCharacterType: Exception caught!" );
497 		return 0;
498 	}
499 }
500 
501 
502 sal_Int32 CharClass::getStringType( const String& rStr, xub_StrLen nPos, xub_StrLen nCount ) const
503 {
504 	try
505 	{
506 		if ( xCC.is() )
507             return xCC->getStringType( rStr, nPos, nCount, getLocale() );
508 		else
509 			return 0;
510 	}
511 	catch ( Exception& )
512 	{
513 		DBG_ERRORFILE( "getStringType: Exception caught!" );
514 		return 0;
515 	}
516 }
517 
518 
519 ::com::sun::star::i18n::ParseResult CharClass::parseAnyToken(
520 			const String& rStr,
521 			sal_Int32 nPos,
522 			sal_Int32 nStartCharFlags,
523 			const String& userDefinedCharactersStart,
524 			sal_Int32 nContCharFlags,
525 			const String& userDefinedCharactersCont ) const
526 {
527 	try
528 	{
529 		if ( xCC.is() )
530             return xCC->parseAnyToken( rStr, nPos, getLocale(),
531 				nStartCharFlags, userDefinedCharactersStart,
532 				nContCharFlags, userDefinedCharactersCont );
533 		else
534 			return ParseResult();
535 	}
536 	catch ( Exception& e )
537 	{
538 #ifdef DBG_UTIL
539         ByteString aMsg( "parseAnyToken: Exception caught\n" );
540         aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
541         DBG_ERRORFILE( aMsg.GetBuffer() );
542 #else
543         (void)e;
544 #endif
545 		return ParseResult();
546 	}
547 }
548 
549 
550 ::com::sun::star::i18n::ParseResult CharClass::parsePredefinedToken(
551 			sal_Int32 nTokenType,
552 			const String& rStr,
553 			sal_Int32 nPos,
554 			sal_Int32 nStartCharFlags,
555 			const String& userDefinedCharactersStart,
556 			sal_Int32 nContCharFlags,
557 			const String& userDefinedCharactersCont ) const
558 {
559 	try
560 	{
561 		if ( xCC.is() )
562             return xCC->parsePredefinedToken( nTokenType, rStr, nPos, getLocale(),
563 				nStartCharFlags, userDefinedCharactersStart,
564 				nContCharFlags, userDefinedCharactersCont );
565 		else
566 			return ParseResult();
567 	}
568 	catch ( Exception& e )
569 	{
570 #ifdef DBG_UTIL
571         ByteString aMsg( "parsePredefinedToken: Exception caught\n" );
572         aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
573         DBG_ERRORFILE( aMsg.GetBuffer() );
574 #else
575         (void)e;
576 #endif
577 		return ParseResult();
578 	}
579 }
580 
581 
582 
583