xref: /trunk/main/ucb/source/inc/regexpmap.tpt (revision 6a302a70)
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