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