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