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#ifndef _UCB_REGEXPMAP_TPT_ 29#define _UCB_REGEXPMAP_TPT_ 30 31#ifndef _UCB_REGEXPMAP_HXX_ 32#include <regexpmap.hxx> 33#endif 34 35#include <list> 36 37#ifndef _RTL_USTRING_HXX_ 38#include <rtl/ustring.hxx> 39#endif 40 41#ifndef _UCB_REGEXP_HXX_ 42#include "regexp.hxx" 43#endif 44 45using namespace ucb_impl; 46 47namespace ucb_impl { 48 49//============================================================================ 50 51template< typename Val > 52struct Entry 53{ 54 Regexp m_aRegexp; 55 Val m_aValue; 56 57 inline Entry(Regexp const & rTheRegexp, Val const & rTheValue): 58 m_aRegexp(rTheRegexp), m_aValue(rTheValue) {} 59}; 60 61//============================================================================ 62template< typename Val > class List: public std::list< Entry< Val > > {}; 63 64//============================================================================ 65// 66// RegexpMapIterImpl 67// 68//============================================================================ 69 70template< typename Val > 71class RegexpMapIterImpl 72{ 73public: 74 typedef RegexpMapImpl< Val > MapImpl; 75 typedef typename List< Val >::iterator ListIterator; 76 77 // Solaris needs these for the ctor... 78 79 inline RegexpMapIterImpl(); 80 81 inline RegexpMapIterImpl(MapImpl * pTheMap, int nTheList, 82 ListIterator aTheIndex); 83 84 RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap, bool bBegin); 85 86 bool operator ==(RegexpMapIterImpl const & rOther) const; 87 88 RegexpMapImpl< Val > const * getMap() const { return m_pMap; } 89 90 int getList() const { return m_nList; } 91 92 typename List< Val >::iterator const & getIndex() const { return m_aIndex; } 93 94 void next(); 95 96 RegexpMapEntry< Val > & get(); 97 98private: 99 mutable RegexpMapEntry< Val > m_aEntry; 100 typename List< Val >::iterator m_aIndex; 101 RegexpMapImpl< Val > * m_pMap; 102 int m_nList; 103 mutable bool m_bEntrySet; 104 105 void setEntry() const; 106}; 107 108} 109 110template< typename Val > 111inline RegexpMapIterImpl< Val >::RegexpMapIterImpl(): 112 m_aEntry(rtl::OUString(), 0), 113 m_pMap(0), 114 m_nList(-1), 115 m_bEntrySet(false) 116{} 117 118template< typename Val > 119inline RegexpMapIterImpl< Val >::RegexpMapIterImpl(MapImpl * pTheMap, 120 int nTheList, 121 ListIterator aTheIndex): 122 m_aEntry(rtl::OUString(), 0), 123 m_aIndex(aTheIndex), 124 m_pMap(pTheMap), 125 m_nList(nTheList), 126 m_bEntrySet(false) 127{} 128 129//============================================================================ 130template< typename Val > 131void RegexpMapIterImpl< Val >::setEntry() const 132{ 133 if (!m_bEntrySet) 134 { 135 Entry< Val > const & rTheEntry 136 = m_nList == -1 ? *m_pMap->m_pDefault : *m_aIndex; 137 m_aEntry 138 = RegexpMapEntry< Val >(rTheEntry.m_aRegexp.getRegexp(false), 139 const_cast< Val * >(&rTheEntry.m_aValue)); 140 m_bEntrySet = true; 141 } 142} 143 144//============================================================================ 145template< typename Val > 146RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap, 147 bool bBegin): 148 m_aEntry(rtl::OUString(), 0), 149 m_pMap(pTheMap), 150 m_bEntrySet(false) 151{ 152 if (bBegin) 153 { 154 m_nList = -1; 155 m_aIndex = typename List< Val >::iterator(); 156 if (!m_pMap->m_pDefault) 157 next(); 158 } 159 else 160 { 161 m_nList = Regexp::KIND_DOMAIN; 162 m_aIndex = m_pMap->m_aList[Regexp::KIND_DOMAIN].end(); 163 } 164} 165 166//============================================================================ 167template< typename Val > 168bool RegexpMapIterImpl< Val >::operator ==(RegexpMapIterImpl const & rOther) 169 const 170{ 171 return m_pMap == rOther.m_pMap 172 && m_nList == rOther.m_nList 173 && m_aIndex == rOther.m_aIndex; 174} 175 176//============================================================================ 177template< typename Val > 178void RegexpMapIterImpl< Val >::next() 179{ 180 switch (m_nList) 181 { 182 case Regexp::KIND_DOMAIN: 183 if (m_aIndex == m_pMap->m_aList[m_nList].end()) 184 return; 185 default: 186 ++m_aIndex; 187 if (m_nList == Regexp::KIND_DOMAIN 188 || m_aIndex != m_pMap->m_aList[m_nList].end()) 189 break; 190 case -1: 191 do 192 { 193 ++m_nList; 194 m_aIndex = m_pMap->m_aList[m_nList].begin(); 195 } 196 while (m_nList < Regexp::KIND_DOMAIN 197 && m_aIndex == m_pMap->m_aList[m_nList].end()); 198 break; 199 } 200 m_bEntrySet = false; 201} 202 203//============================================================================ 204template< typename Val > 205RegexpMapEntry< Val > & RegexpMapIterImpl< Val >::get() 206{ 207 setEntry(); 208 return m_aEntry; 209} 210 211//============================================================================ 212// 213// RegexpMapConstIter 214// 215//============================================================================ 216 217template< typename Val > 218RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapIterImpl< Val > * 219 pTheImpl): 220 m_pImpl(pTheImpl) 221{} 222 223//============================================================================ 224template< typename Val > 225RegexpMapConstIter< Val >::RegexpMapConstIter(): 226 m_pImpl(new RegexpMapIterImpl< Val >) 227{} 228 229//============================================================================ 230template< typename Val > 231RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapConstIter const & 232 rOther): 233 m_pImpl(new RegexpMapIterImpl< Val >(*rOther.m_pImpl)) 234{} 235 236//============================================================================ 237template< typename Val > 238RegexpMapConstIter< Val >::~RegexpMapConstIter() 239{ 240 delete m_pImpl; 241} 242 243//============================================================================ 244template< typename Val > 245RegexpMapConstIter< Val > & 246RegexpMapConstIter< Val >::operator =(RegexpMapConstIter const & rOther) 247{ 248 *m_pImpl = *rOther.m_pImpl; 249 return *this; 250} 251 252//============================================================================ 253template< typename Val > 254RegexpMapConstIter< Val > & RegexpMapConstIter< Val >::operator ++() 255{ 256 m_pImpl->next(); 257 return *this; 258} 259 260//============================================================================ 261template< typename Val > 262RegexpMapConstIter< Val > RegexpMapConstIter< Val >::operator ++(int) 263{ 264 RegexpMapConstIter aTemp(*this); 265 m_pImpl->next(); 266 return aTemp; 267} 268 269//============================================================================ 270template< typename Val > 271RegexpMapEntry< Val > const & RegexpMapConstIter< Val >::operator *() const 272{ 273 return m_pImpl->get(); 274} 275 276//============================================================================ 277template< typename Val > 278RegexpMapEntry< Val > const * RegexpMapConstIter< Val >::operator ->() const 279{ 280 return &m_pImpl->get(); 281} 282 283//============================================================================ 284template< typename Val > 285bool RegexpMapConstIter< Val >::equals(RegexpMapConstIter const & rOther) 286 const 287{ 288 return *m_pImpl == *rOther.m_pImpl; 289} 290 291//============================================================================ 292// 293// RegexpMapIter 294// 295//============================================================================ 296 297template< typename Val > 298RegexpMapIter< Val >::RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl): 299 RegexpMapConstIter< Val >(pTheImpl) 300{} 301 302//============================================================================ 303template< typename Val > 304RegexpMapIter< Val > & RegexpMapIter< Val >::operator ++() 305{ 306 this->m_pImpl->next(); 307 return *this; 308} 309 310//============================================================================ 311template< typename Val > 312RegexpMapIter< Val > RegexpMapIter< Val >::operator ++(int) 313{ 314 RegexpMapIter aTemp(*this); 315 this->m_pImpl->next(); 316 return aTemp; 317} 318 319//============================================================================ 320template< typename Val > 321RegexpMapEntry< Val > & RegexpMapIter< Val >::operator *() 322{ 323 return this->m_pImpl->get(); 324} 325 326//============================================================================ 327template< typename Val > 328RegexpMapEntry< Val > const & RegexpMapIter< Val >::operator *() const 329{ 330 return this->m_pImpl->get(); 331} 332 333//============================================================================ 334template< typename Val > 335RegexpMapEntry< Val > * RegexpMapIter< Val >::operator ->() 336{ 337 return &this->m_pImpl->get(); 338} 339 340//============================================================================ 341template< typename Val > 342RegexpMapEntry< Val > const * RegexpMapIter< Val >::operator ->() const 343{ 344 return &this->m_pImpl->get(); 345} 346 347//============================================================================ 348// 349// RegexpMap 350// 351//============================================================================ 352 353namespace ucb_impl { 354 355template< typename Val > 356struct RegexpMapImpl 357{ 358 List< Val > m_aList[Regexp::KIND_DOMAIN + 1]; 359 Entry< Val > * m_pDefault; 360 361 RegexpMapImpl(): m_pDefault(0) {} 362 363 ~RegexpMapImpl() { delete m_pDefault; } 364}; 365 366} 367 368//============================================================================ 369template< typename Val > 370RegexpMap< Val >::RegexpMap(): 371 m_pImpl(new RegexpMapImpl< Val >) 372{} 373 374//============================================================================ 375template< typename Val > 376RegexpMap< Val >::RegexpMap(RegexpMap const & rOther): 377 m_pImpl(new RegexpMapImpl< Val >(*rOther.m_pImpl)) 378{} 379 380//============================================================================ 381template< typename Val > 382RegexpMap< Val >::~RegexpMap() 383{ 384 delete m_pImpl; 385} 386 387//============================================================================ 388template< typename Val > 389RegexpMap< Val > & RegexpMap< Val >::operator =(RegexpMap const & rOther) 390{ 391 *m_pImpl = *rOther.m_pImpl; 392 return *this; 393} 394 395//============================================================================ 396template< typename Val > 397bool RegexpMap< Val >::add(rtl::OUString const & rKey, Val const & rValue, 398 bool bOverwrite, rtl::OUString * pReverse) 399{ 400 Regexp aRegexp(Regexp::parse(rKey)); 401 402 if (aRegexp.isDefault()) 403 { 404 if (m_pImpl->m_pDefault) 405 { 406 if (!bOverwrite) 407 return false; 408 delete m_pImpl->m_pDefault; 409 } 410 m_pImpl->m_pDefault = new Entry< Val >(aRegexp, rValue); 411 } 412 else 413 { 414 List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()]; 415 416 typename List< Val >::iterator aEnd(rTheList.end()); 417 for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt) 418 { 419 if (aIt->m_aRegexp == aRegexp) 420 { 421 if (bOverwrite) 422 { 423 rTheList.erase(aIt); 424 break; 425 } 426 else 427 return false; 428 } 429 } 430 431 rTheList.push_back(Entry< Val >(aRegexp, rValue)); 432 } 433 434 if (pReverse) 435 *pReverse = aRegexp.getRegexp(true); 436 437 return true; 438} 439 440//============================================================================ 441template< typename Val > 442typename RegexpMap< Val >::iterator RegexpMap< Val >::find(rtl::OUString const & rKey, 443 rtl::OUString * pReverse) 444{ 445 Regexp aRegexp(Regexp::parse(rKey)); 446 447 if (pReverse) 448 *pReverse = aRegexp.getRegexp(true); 449 450 if (aRegexp.isDefault()) 451 { 452 if (m_pImpl->m_pDefault) 453 return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, 454 true)); 455 } 456 else 457 { 458 List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()]; 459 460 typename List< Val > ::iterator aEnd(rTheList.end()); 461 for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt) 462 if (aIt->m_aRegexp == aRegexp) 463 return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >( 464 m_pImpl, 465 aRegexp.getKind(), aIt)); 466 } 467 468 return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false)); 469} 470 471//============================================================================ 472template< typename Val > 473void RegexpMap< Val >::erase(iterator const & rPos) 474{ 475 if (rPos.m_pImpl->getMap() == m_pImpl) 476 { 477 if (rPos.m_pImpl->getList() == -1) 478 { 479 if (m_pImpl->m_pDefault) 480 { 481 delete m_pImpl->m_pDefault; 482 m_pImpl->m_pDefault = 0; 483 } 484 } 485 else 486 m_pImpl->m_aList[rPos.m_pImpl->getList()]. 487 erase(rPos.m_pImpl->getIndex()); 488 } 489} 490 491//============================================================================ 492template< typename Val > 493typename RegexpMap< Val >::iterator RegexpMap< Val >::begin() 494{ 495 return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, true)); 496} 497 498//============================================================================ 499template< typename Val > 500typename RegexpMap< Val >::const_iterator RegexpMap< Val >::begin() const 501{ 502 return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, 503 true)); 504} 505 506//============================================================================ 507template< typename Val > 508typename RegexpMap< Val >::iterator RegexpMap< Val >::end() 509{ 510 return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false)); 511} 512 513//============================================================================ 514template< typename Val > 515typename RegexpMap< Val >::const_iterator RegexpMap< Val >::end() const 516{ 517 return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, 518 false)); 519} 520 521//============================================================================ 522template< typename Val > 523bool RegexpMap< Val >::empty() const 524{ 525 return !m_pImpl->m_pDefault 526 && m_pImpl->m_aList[Regexp::KIND_PREFIX].empty() 527 && m_pImpl->m_aList[Regexp::KIND_AUTHORITY].empty() 528 && m_pImpl->m_aList[Regexp::KIND_DOMAIN].empty(); 529} 530 531//============================================================================ 532template< typename Val > 533typename RegexpMap< Val >::size_type RegexpMap< Val >::size() const 534{ 535 return (m_pImpl->m_pDefault ? 1 : 0) 536 + m_pImpl->m_aList[Regexp::KIND_PREFIX].size() 537 + m_pImpl->m_aList[Regexp::KIND_AUTHORITY].size() 538 + m_pImpl->m_aList[Regexp::KIND_DOMAIN].size(); 539} 540 541//============================================================================ 542template< typename Val > 543Val const * RegexpMap< Val >::map(rtl::OUString const & rString, 544 rtl::OUString * pTranslation, 545 bool * pTranslated) const 546{ 547 for (int n = Regexp::KIND_DOMAIN; n >= Regexp::KIND_PREFIX; --n) 548 { 549 List< Val > const & rTheList = m_pImpl->m_aList[n]; 550 551 typename List< Val >::const_iterator aEnd(rTheList.end()); 552 for (typename List< Val >::const_iterator aIt(rTheList.begin()); aIt != aEnd; 553 ++aIt) 554 if (aIt->m_aRegexp.matches(rString, pTranslation, pTranslated)) 555 return &aIt->m_aValue; 556 } 557 if (m_pImpl->m_pDefault 558 && m_pImpl->m_pDefault->m_aRegexp.matches(rString, pTranslation, 559 pTranslated)) 560 return &m_pImpl->m_pDefault->m_aValue; 561 return 0; 562} 563 564#endif // _UCB_REGEXPMAP_TPT_ 565