| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| #ifndef _UCB_REGEXPMAP_TPT_ |
| #define _UCB_REGEXPMAP_TPT_ |
| |
| #ifndef _UCB_REGEXPMAP_HXX_ |
| #include <regexpmap.hxx> |
| #endif |
| |
| #include <list> |
| |
| #ifndef _RTL_USTRING_HXX_ |
| #include <rtl/ustring.hxx> |
| #endif |
| |
| #ifndef _UCB_REGEXP_HXX_ |
| #include "regexp.hxx" |
| #endif |
| |
| using namespace ucb_impl; |
| |
| namespace ucb_impl { |
| |
| //============================================================================ |
| |
| template< typename Val > |
| struct Entry |
| { |
| Regexp m_aRegexp; |
| Val m_aValue; |
| |
| inline Entry(Regexp const & rTheRegexp, Val const & rTheValue): |
| m_aRegexp(rTheRegexp), m_aValue(rTheValue) {} |
| }; |
| |
| //============================================================================ |
| template< typename Val > class List: public std::list< Entry< Val > > {}; |
| |
| //============================================================================ |
| // |
| // RegexpMapIterImpl |
| // |
| //============================================================================ |
| |
| template< typename Val > |
| class RegexpMapIterImpl |
| { |
| public: |
| typedef RegexpMapImpl< Val > MapImpl; |
| typedef typename List< Val >::iterator ListIterator; |
| |
| // Solaris needs these for the ctor... |
| |
| inline RegexpMapIterImpl(); |
| |
| inline RegexpMapIterImpl(MapImpl * pTheMap, int nTheList, |
| ListIterator aTheIndex); |
| |
| RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap, bool bBegin); |
| |
| bool operator ==(RegexpMapIterImpl const & rOther) const; |
| |
| RegexpMapImpl< Val > const * getMap() const { return m_pMap; } |
| |
| int getList() const { return m_nList; } |
| |
| typename List< Val >::iterator const & getIndex() const { return m_aIndex; } |
| |
| void next(); |
| |
| RegexpMapEntry< Val > & get(); |
| |
| private: |
| mutable RegexpMapEntry< Val > m_aEntry; |
| typename List< Val >::iterator m_aIndex; |
| RegexpMapImpl< Val > * m_pMap; |
| int m_nList; |
| mutable bool m_bEntrySet; |
| |
| void setEntry() const; |
| }; |
| |
| } |
| |
| template< typename Val > |
| inline RegexpMapIterImpl< Val >::RegexpMapIterImpl(): |
| m_aEntry(rtl::OUString(), 0), |
| m_pMap(0), |
| m_nList(-1), |
| m_bEntrySet(false) |
| {} |
| |
| template< typename Val > |
| inline RegexpMapIterImpl< Val >::RegexpMapIterImpl(MapImpl * pTheMap, |
| int nTheList, |
| ListIterator aTheIndex): |
| m_aEntry(rtl::OUString(), 0), |
| m_aIndex(aTheIndex), |
| m_pMap(pTheMap), |
| m_nList(nTheList), |
| m_bEntrySet(false) |
| {} |
| |
| //============================================================================ |
| template< typename Val > |
| void RegexpMapIterImpl< Val >::setEntry() const |
| { |
| if (!m_bEntrySet) |
| { |
| Entry< Val > const & rTheEntry |
| = m_nList == -1 ? *m_pMap->m_pDefault : *m_aIndex; |
| m_aEntry |
| = RegexpMapEntry< Val >(rTheEntry.m_aRegexp.getRegexp(false), |
| const_cast< Val * >(&rTheEntry.m_aValue)); |
| m_bEntrySet = true; |
| } |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap, |
| bool bBegin): |
| m_aEntry(rtl::OUString(), 0), |
| m_pMap(pTheMap), |
| m_bEntrySet(false) |
| { |
| if (bBegin) |
| { |
| m_nList = -1; |
| m_aIndex = typename List< Val >::iterator(); |
| if (!m_pMap->m_pDefault) |
| next(); |
| } |
| else |
| { |
| m_nList = Regexp::KIND_DOMAIN; |
| m_aIndex = m_pMap->m_aList[Regexp::KIND_DOMAIN].end(); |
| } |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| bool RegexpMapIterImpl< Val >::operator ==(RegexpMapIterImpl const & rOther) |
| const |
| { |
| return m_pMap == rOther.m_pMap |
| && m_nList == rOther.m_nList |
| && m_aIndex == rOther.m_aIndex; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| void RegexpMapIterImpl< Val >::next() |
| { |
| switch (m_nList) |
| { |
| case Regexp::KIND_DOMAIN: |
| if (m_aIndex == m_pMap->m_aList[m_nList].end()) |
| return; |
| default: |
| ++m_aIndex; |
| if (m_nList == Regexp::KIND_DOMAIN |
| || m_aIndex != m_pMap->m_aList[m_nList].end()) |
| break; |
| case -1: |
| do |
| { |
| ++m_nList; |
| m_aIndex = m_pMap->m_aList[m_nList].begin(); |
| } |
| while (m_nList < Regexp::KIND_DOMAIN |
| && m_aIndex == m_pMap->m_aList[m_nList].end()); |
| break; |
| } |
| m_bEntrySet = false; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapEntry< Val > & RegexpMapIterImpl< Val >::get() |
| { |
| setEntry(); |
| return m_aEntry; |
| } |
| |
| //============================================================================ |
| // |
| // RegexpMapConstIter |
| // |
| //============================================================================ |
| |
| template< typename Val > |
| RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapIterImpl< Val > * |
| pTheImpl): |
| m_pImpl(pTheImpl) |
| {} |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapConstIter< Val >::RegexpMapConstIter(): |
| m_pImpl(new RegexpMapIterImpl< Val >) |
| {} |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapConstIter const & |
| rOther): |
| m_pImpl(new RegexpMapIterImpl< Val >(*rOther.m_pImpl)) |
| {} |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapConstIter< Val >::~RegexpMapConstIter() |
| { |
| delete m_pImpl; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapConstIter< Val > & |
| RegexpMapConstIter< Val >::operator =(RegexpMapConstIter const & rOther) |
| { |
| *m_pImpl = *rOther.m_pImpl; |
| return *this; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapConstIter< Val > & RegexpMapConstIter< Val >::operator ++() |
| { |
| m_pImpl->next(); |
| return *this; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapConstIter< Val > RegexpMapConstIter< Val >::operator ++(int) |
| { |
| RegexpMapConstIter aTemp(*this); |
| m_pImpl->next(); |
| return aTemp; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapEntry< Val > const & RegexpMapConstIter< Val >::operator *() const |
| { |
| return m_pImpl->get(); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapEntry< Val > const * RegexpMapConstIter< Val >::operator ->() const |
| { |
| return &m_pImpl->get(); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| bool RegexpMapConstIter< Val >::equals(RegexpMapConstIter const & rOther) |
| const |
| { |
| return *m_pImpl == *rOther.m_pImpl; |
| } |
| |
| //============================================================================ |
| // |
| // RegexpMapIter |
| // |
| //============================================================================ |
| |
| template< typename Val > |
| RegexpMapIter< Val >::RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl): |
| RegexpMapConstIter< Val >(pTheImpl) |
| {} |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapIter< Val > & RegexpMapIter< Val >::operator ++() |
| { |
| this->m_pImpl->next(); |
| return *this; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapIter< Val > RegexpMapIter< Val >::operator ++(int) |
| { |
| RegexpMapIter aTemp(*this); |
| this->m_pImpl->next(); |
| return aTemp; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapEntry< Val > & RegexpMapIter< Val >::operator *() |
| { |
| return this->m_pImpl->get(); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapEntry< Val > const & RegexpMapIter< Val >::operator *() const |
| { |
| return this->m_pImpl->get(); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapEntry< Val > * RegexpMapIter< Val >::operator ->() |
| { |
| return &this->m_pImpl->get(); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMapEntry< Val > const * RegexpMapIter< Val >::operator ->() const |
| { |
| return &this->m_pImpl->get(); |
| } |
| |
| //============================================================================ |
| // |
| // RegexpMap |
| // |
| //============================================================================ |
| |
| namespace ucb_impl { |
| |
| template< typename Val > |
| struct RegexpMapImpl |
| { |
| List< Val > m_aList[Regexp::KIND_DOMAIN + 1]; |
| Entry< Val > * m_pDefault; |
| |
| RegexpMapImpl(): m_pDefault(0) {} |
| |
| ~RegexpMapImpl() { delete m_pDefault; } |
| }; |
| |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMap< Val >::RegexpMap(): |
| m_pImpl(new RegexpMapImpl< Val >) |
| {} |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMap< Val >::RegexpMap(RegexpMap const & rOther): |
| m_pImpl(new RegexpMapImpl< Val >(*rOther.m_pImpl)) |
| {} |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMap< Val >::~RegexpMap() |
| { |
| delete m_pImpl; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| RegexpMap< Val > & RegexpMap< Val >::operator =(RegexpMap const & rOther) |
| { |
| *m_pImpl = *rOther.m_pImpl; |
| return *this; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| bool RegexpMap< Val >::add(rtl::OUString const & rKey, Val const & rValue, |
| bool bOverwrite, rtl::OUString * pReverse) |
| { |
| Regexp aRegexp(Regexp::parse(rKey)); |
| |
| if (aRegexp.isDefault()) |
| { |
| if (m_pImpl->m_pDefault) |
| { |
| if (!bOverwrite) |
| return false; |
| delete m_pImpl->m_pDefault; |
| } |
| m_pImpl->m_pDefault = new Entry< Val >(aRegexp, rValue); |
| } |
| else |
| { |
| List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()]; |
| |
| typename List< Val >::iterator aEnd(rTheList.end()); |
| for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt) |
| { |
| if (aIt->m_aRegexp == aRegexp) |
| { |
| if (bOverwrite) |
| { |
| rTheList.erase(aIt); |
| break; |
| } |
| else |
| return false; |
| } |
| } |
| |
| rTheList.push_back(Entry< Val >(aRegexp, rValue)); |
| } |
| |
| if (pReverse) |
| *pReverse = aRegexp.getRegexp(true); |
| |
| return true; |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| typename RegexpMap< Val >::iterator RegexpMap< Val >::find(rtl::OUString const & rKey, |
| rtl::OUString * pReverse) |
| { |
| Regexp aRegexp(Regexp::parse(rKey)); |
| |
| if (pReverse) |
| *pReverse = aRegexp.getRegexp(true); |
| |
| if (aRegexp.isDefault()) |
| { |
| if (m_pImpl->m_pDefault) |
| return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, |
| true)); |
| } |
| else |
| { |
| List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()]; |
| |
| typename List< Val > ::iterator aEnd(rTheList.end()); |
| for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt) |
| if (aIt->m_aRegexp == aRegexp) |
| return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >( |
| m_pImpl, |
| aRegexp.getKind(), aIt)); |
| } |
| |
| return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false)); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| void RegexpMap< Val >::erase(iterator const & rPos) |
| { |
| if (rPos.m_pImpl->getMap() == m_pImpl) |
| { |
| if (rPos.m_pImpl->getList() == -1) |
| { |
| if (m_pImpl->m_pDefault) |
| { |
| delete m_pImpl->m_pDefault; |
| m_pImpl->m_pDefault = 0; |
| } |
| } |
| else |
| m_pImpl->m_aList[rPos.m_pImpl->getList()]. |
| erase(rPos.m_pImpl->getIndex()); |
| } |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| typename RegexpMap< Val >::iterator RegexpMap< Val >::begin() |
| { |
| return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, true)); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| typename RegexpMap< Val >::const_iterator RegexpMap< Val >::begin() const |
| { |
| return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, |
| true)); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| typename RegexpMap< Val >::iterator RegexpMap< Val >::end() |
| { |
| return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false)); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| typename RegexpMap< Val >::const_iterator RegexpMap< Val >::end() const |
| { |
| return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, |
| false)); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| bool RegexpMap< Val >::empty() const |
| { |
| return !m_pImpl->m_pDefault |
| && m_pImpl->m_aList[Regexp::KIND_PREFIX].empty() |
| && m_pImpl->m_aList[Regexp::KIND_AUTHORITY].empty() |
| && m_pImpl->m_aList[Regexp::KIND_DOMAIN].empty(); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| typename RegexpMap< Val >::size_type RegexpMap< Val >::size() const |
| { |
| return (m_pImpl->m_pDefault ? 1 : 0) |
| + m_pImpl->m_aList[Regexp::KIND_PREFIX].size() |
| + m_pImpl->m_aList[Regexp::KIND_AUTHORITY].size() |
| + m_pImpl->m_aList[Regexp::KIND_DOMAIN].size(); |
| } |
| |
| //============================================================================ |
| template< typename Val > |
| Val const * RegexpMap< Val >::map(rtl::OUString const & rString, |
| rtl::OUString * pTranslation, |
| bool * pTranslated) const |
| { |
| for (int n = Regexp::KIND_DOMAIN; n >= Regexp::KIND_PREFIX; --n) |
| { |
| List< Val > const & rTheList = m_pImpl->m_aList[n]; |
| |
| typename List< Val >::const_iterator aEnd(rTheList.end()); |
| for (typename List< Val >::const_iterator aIt(rTheList.begin()); aIt != aEnd; |
| ++aIt) |
| if (aIt->m_aRegexp.matches(rString, pTranslation, pTranslated)) |
| return &aIt->m_aValue; |
| } |
| if (m_pImpl->m_pDefault |
| && m_pImpl->m_pDefault->m_aRegexp.matches(rString, pTranslation, |
| pTranslated)) |
| return &m_pImpl->m_pDefault->m_aValue; |
| return 0; |
| } |
| |
| #endif // _UCB_REGEXPMAP_TPT_ |