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