xref: /trunk/main/unotools/source/i18n/charclass.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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