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