Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_UCB_SOURCE_INC_REGEXPMAP_HXX
21 : #define INCLUDED_UCB_SOURCE_INC_REGEXPMAP_HXX
22 :
23 : #include "sal/config.h"
24 :
25 : #include <list>
26 :
27 : #include <rtl/ustring.hxx>
28 : #include <sal/types.h>
29 :
30 : #include "regexp.hxx"
31 :
32 : namespace ucb_impl {
33 :
34 : template< typename Val > class RegexpMap;
35 : template< typename Val > class RegexpMapIter;
36 :
37 :
38 : template< typename Val >
39 29350 : class RegexpMapEntry
40 : {
41 : public:
42 20254 : inline RegexpMapEntry(OUString const & rTheRegexp,
43 : Val * pTheValue):
44 20254 : m_aRegexp(rTheRegexp), m_pValue(pTheValue) {}
45 :
46 47 : OUString getRegexp() const { return m_aRegexp; }
47 :
48 47 : Val const & getValue() const { return *m_pValue; }
49 :
50 3455 : Val & getValue() { return *m_pValue; }
51 :
52 : private:
53 : OUString m_aRegexp;
54 : Val * m_pValue;
55 : };
56 :
57 :
58 :
59 : template< typename Val >
60 6110 : struct Entry
61 : {
62 : Regexp m_aRegexp;
63 : Val m_aValue;
64 :
65 2126 : inline Entry(Regexp const & rTheRegexp, Val const & rTheValue):
66 2126 : m_aRegexp(rTheRegexp), m_aValue(rTheValue) {}
67 : };
68 :
69 :
70 1326 : template< typename Val > class List: public std::list< Entry< Val > > {};
71 :
72 :
73 : template< typename Val >
74 : struct RegexpMapImpl
75 : {
76 : List< Val > m_aList[Regexp::KIND_DOMAIN + 1];
77 : Entry< Val > * m_pDefault;
78 :
79 222 : RegexpMapImpl(): m_pDefault(0) {}
80 :
81 220 : ~RegexpMapImpl() { delete m_pDefault; }
82 : };
83 :
84 :
85 : template< typename Val >
86 16758 : class RegexpMapIterImpl
87 : {
88 : public:
89 : typedef RegexpMapImpl< Val > MapImpl;
90 : typedef typename List< Val >::iterator ListIterator;
91 :
92 : // Solaris needs these for the ctor...
93 :
94 : inline RegexpMapIterImpl();
95 :
96 : inline RegexpMapIterImpl(MapImpl * pTheMap, int nTheList,
97 : ListIterator aTheIndex);
98 :
99 : RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap, bool bBegin);
100 :
101 : RegexpMapIterImpl(RegexpMapIterImpl const & rOther);
102 :
103 : RegexpMapIterImpl & operator =(RegexpMapIterImpl const & rOther);
104 :
105 : bool operator ==(RegexpMapIterImpl const & rOther) const;
106 :
107 1 : RegexpMapImpl< Val > const * getMap() const { return m_pMap; }
108 :
109 2 : int getList() const { return m_nList; }
110 :
111 1 : typename List< Val >::iterator const & getIndex() const { return m_aIndex; }
112 :
113 : void next();
114 :
115 : RegexpMapEntry< Val > & get();
116 :
117 : private:
118 : mutable RegexpMapEntry< Val > m_aEntry;
119 : typename List< Val >::iterator m_aIndex;
120 : RegexpMapImpl< Val > * m_pMap;
121 : int m_nList;
122 : mutable bool m_bEntrySet;
123 :
124 : void setEntry() const;
125 : };
126 :
127 : template< typename Val >
128 5582 : inline RegexpMapIterImpl< Val >::RegexpMapIterImpl():
129 : m_aEntry(rtl::OUString(), 0),
130 : m_pMap(0),
131 : m_nList(-1),
132 5582 : m_bEntrySet(false)
133 5582 : {}
134 :
135 : template< typename Val >
136 3456 : inline RegexpMapIterImpl< Val >::RegexpMapIterImpl(MapImpl * pTheMap,
137 : int nTheList,
138 : ListIterator aTheIndex):
139 : m_aEntry(rtl::OUString(), 0),
140 : m_aIndex(aTheIndex),
141 : m_pMap(pTheMap),
142 : m_nList(nTheList),
143 3456 : m_bEntrySet(false)
144 3456 : {}
145 :
146 : template< typename Val >
147 3549 : void RegexpMapIterImpl< Val >::setEntry() const
148 : {
149 3549 : if (!m_bEntrySet)
150 : {
151 : Entry< Val > const & rTheEntry
152 3502 : = m_nList == -1 ? *m_pMap->m_pDefault : *m_aIndex;
153 3502 : m_aEntry
154 7004 : = RegexpMapEntry< Val >(rTheEntry.m_aRegexp.getRegexp(false),
155 : const_cast< Val * >(&rTheEntry.m_aValue));
156 3502 : m_bEntrySet = true;
157 : }
158 3549 : }
159 :
160 : template< typename Val >
161 7714 : RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap,
162 : bool bBegin):
163 : m_aEntry(rtl::OUString(), 0),
164 : m_pMap(pTheMap),
165 7714 : m_bEntrySet(false)
166 : {
167 7714 : if (bBegin)
168 : {
169 3 : m_nList = -1;
170 3 : if (!m_pMap->m_pDefault)
171 0 : next();
172 : }
173 : else
174 : {
175 7711 : m_nList = Regexp::KIND_DOMAIN;
176 7711 : m_aIndex = m_pMap->m_aList[Regexp::KIND_DOMAIN].end();
177 : }
178 7714 : }
179 :
180 : template< typename Val >
181 6 : RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapIterImpl const & rOther):
182 : m_aEntry(rOther.m_aEntry), m_pMap(rOther.m_pMap), m_nList(rOther.m_nList),
183 6 : m_bEntrySet(rOther.m_bEntrySet)
184 : {
185 6 : if (m_nList != -1)
186 3 : m_aIndex = rOther.m_aIndex;
187 6 : }
188 :
189 : template< typename Val >
190 5582 : RegexpMapIterImpl< Val > & RegexpMapIterImpl< Val >::operator =(
191 : RegexpMapIterImpl const & rOther)
192 : {
193 5582 : if (this != &rOther)
194 : {
195 5582 : m_aEntry = rOther.m_aEntry;
196 5582 : m_pMap = rOther.m_pMap;
197 5582 : m_nList = rOther.m_nList;
198 5582 : m_bEntrySet = rOther.m_bEntrySet;
199 5582 : if (m_nList == -1)
200 0 : m_aIndex = typename List< Val >::iterator();
201 : else
202 5582 : m_aIndex = rOther.m_aIndex;
203 : }
204 5582 : return *this;
205 : }
206 :
207 : template< typename Val >
208 5632 : bool RegexpMapIterImpl< Val >::operator ==(RegexpMapIterImpl const & rOther)
209 : const
210 : {
211 : return m_pMap == rOther.m_pMap
212 : && m_nList == rOther.m_nList
213 5632 : && (m_nList == -1 || m_aIndex == rOther.m_aIndex);
214 : }
215 :
216 : template< typename Val >
217 47 : void RegexpMapIterImpl< Val >::next()
218 : {
219 47 : switch (m_nList)
220 : {
221 : case Regexp::KIND_DOMAIN:
222 0 : if (m_aIndex == m_pMap->m_aList[m_nList].end())
223 47 : return;
224 : //fall-through
225 : default:
226 44 : ++m_aIndex;
227 176 : if (m_nList == Regexp::KIND_DOMAIN
228 176 : || m_aIndex != m_pMap->m_aList[m_nList].end())
229 41 : break;
230 : //fall-through
231 : case -1:
232 33 : do
233 : {
234 9 : ++m_nList;
235 9 : m_aIndex = m_pMap->m_aList[m_nList].begin();
236 : }
237 : while (m_nList < Regexp::KIND_DOMAIN
238 27 : && m_aIndex == m_pMap->m_aList[m_nList].end());
239 6 : break;
240 : }
241 47 : m_bEntrySet = false;
242 : }
243 :
244 : template< typename Val >
245 3549 : RegexpMapEntry< Val > & RegexpMapIterImpl< Val >::get()
246 : {
247 3549 : setEntry();
248 3549 : return m_aEntry;
249 : }
250 :
251 :
252 : template< typename Val >
253 : class RegexpMapConstIter
254 : {
255 : friend class RegexpMap< Val >; // to access m_pImpl, ctor
256 : friend class RegexpMapIter< Val >; // to access m_pImpl, ctor
257 :
258 : public:
259 : RegexpMapConstIter();
260 :
261 : RegexpMapConstIter(RegexpMapConstIter const & rOther);
262 :
263 : ~RegexpMapConstIter();
264 :
265 : RegexpMapConstIter & operator =(RegexpMapConstIter const & rOther);
266 :
267 : RegexpMapConstIter & operator ++();
268 :
269 : RegexpMapConstIter operator ++(int);
270 :
271 : RegexpMapEntry< Val > const & operator *() const;
272 :
273 : RegexpMapEntry< Val > const * operator ->() const;
274 :
275 : bool equals(RegexpMapConstIter const & rOther) const;
276 : // for free operator ==(), operator !=()
277 :
278 : private:
279 : RegexpMapIterImpl< Val > * m_pImpl;
280 :
281 : RegexpMapConstIter(RegexpMapIterImpl< Val > * pTheImpl);
282 : };
283 :
284 : template< typename Val >
285 11170 : RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapIterImpl< Val > *
286 : pTheImpl):
287 11170 : m_pImpl(pTheImpl)
288 11170 : {}
289 :
290 : template< typename Val >
291 5582 : RegexpMapConstIter< Val >::RegexpMapConstIter():
292 5582 : m_pImpl(new RegexpMapIterImpl< Val >)
293 5582 : {}
294 :
295 : template< typename Val >
296 6 : RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapConstIter const &
297 : rOther):
298 6 : m_pImpl(new RegexpMapIterImpl< Val >(*rOther.m_pImpl))
299 6 : {}
300 :
301 : template< typename Val >
302 16758 : RegexpMapConstIter< Val >::~RegexpMapConstIter()
303 : {
304 16758 : delete m_pImpl;
305 16758 : }
306 :
307 : template< typename Val >
308 : RegexpMapConstIter< Val > &
309 5582 : RegexpMapConstIter< Val >::operator =(RegexpMapConstIter const & rOther)
310 : {
311 5582 : *m_pImpl = *rOther.m_pImpl;
312 5582 : return *this;
313 : }
314 :
315 : template< typename Val >
316 47 : RegexpMapConstIter< Val > & RegexpMapConstIter< Val >::operator ++()
317 : {
318 47 : m_pImpl->next();
319 47 : return *this;
320 : }
321 :
322 : template< typename Val >
323 : RegexpMapConstIter< Val > RegexpMapConstIter< Val >::operator ++(int)
324 : {
325 : RegexpMapConstIter aTemp(*this);
326 : m_pImpl->next();
327 : return aTemp;
328 : }
329 :
330 : template< typename Val >
331 : RegexpMapEntry< Val > const & RegexpMapConstIter< Val >::operator *() const
332 : {
333 : return m_pImpl->get();
334 : }
335 :
336 : template< typename Val >
337 94 : RegexpMapEntry< Val > const * RegexpMapConstIter< Val >::operator ->() const
338 : {
339 94 : return &m_pImpl->get();
340 : }
341 :
342 : template< typename Val >
343 5632 : bool RegexpMapConstIter< Val >::equals(RegexpMapConstIter const & rOther)
344 : const
345 : {
346 5632 : return *m_pImpl == *rOther.m_pImpl;
347 : }
348 :
349 :
350 : template< typename Val >
351 22334 : class RegexpMapIter: public RegexpMapConstIter< Val >
352 : {
353 : friend class RegexpMap< Val >; // to access ctor
354 :
355 : public:
356 5582 : RegexpMapIter() {}
357 :
358 : RegexpMapIter & operator ++();
359 :
360 : RegexpMapIter operator ++(int);
361 :
362 : RegexpMapEntry< Val > & operator *();
363 :
364 : RegexpMapEntry< Val > const & operator *() const;
365 :
366 : RegexpMapEntry< Val > * operator ->();
367 :
368 : RegexpMapEntry< Val > const * operator ->() const;
369 :
370 : private:
371 : RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl);
372 : };
373 :
374 : template< typename Val >
375 11170 : RegexpMapIter< Val >::RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl):
376 11170 : RegexpMapConstIter< Val >(pTheImpl)
377 11170 : {}
378 :
379 : template< typename Val >
380 : RegexpMapIter< Val > & RegexpMapIter< Val >::operator ++()
381 : {
382 : this->m_pImpl->next();
383 : return *this;
384 : }
385 :
386 : template< typename Val >
387 : RegexpMapIter< Val > RegexpMapIter< Val >::operator ++(int)
388 : {
389 : RegexpMapIter aTemp(*this);
390 : this->m_pImpl->next();
391 : return aTemp;
392 : }
393 :
394 : template< typename Val >
395 : RegexpMapEntry< Val > & RegexpMapIter< Val >::operator *()
396 : {
397 : return this->m_pImpl->get();
398 : }
399 :
400 : template< typename Val >
401 : RegexpMapEntry< Val > const & RegexpMapIter< Val >::operator *() const
402 : {
403 : return this->m_pImpl->get();
404 : }
405 :
406 : template< typename Val >
407 3455 : RegexpMapEntry< Val > * RegexpMapIter< Val >::operator ->()
408 : {
409 3455 : return &this->m_pImpl->get();
410 : }
411 :
412 : template< typename Val >
413 : RegexpMapEntry< Val > const * RegexpMapIter< Val >::operator ->() const
414 : {
415 : return &this->m_pImpl->get();
416 : }
417 :
418 :
419 : template< typename Val >
420 : class RegexpMap
421 : {
422 : public:
423 : typedef sal_uInt32 size_type;
424 : typedef RegexpMapIter< Val > iterator;
425 : typedef RegexpMapConstIter< Val > const_iterator;
426 :
427 : RegexpMap();
428 :
429 : RegexpMap(RegexpMap const & rOther);
430 :
431 : ~RegexpMap();
432 :
433 : RegexpMap & operator =(RegexpMap const & rOther);
434 :
435 : bool add(OUString const & rKey, Val const & rValue, bool bOverwrite,
436 : OUString * pReverse = 0);
437 : // throws com::sun::star::lang::IllegalArgumentException
438 :
439 : iterator find(OUString const & rKey, OUString * pReverse = 0);
440 : // throws com::sun::star::lang::IllegalArgumentException
441 :
442 : void erase(iterator const & rPos);
443 :
444 : iterator begin();
445 :
446 : const_iterator begin() const;
447 :
448 : iterator end();
449 :
450 : const_iterator end() const;
451 :
452 : bool empty() const;
453 :
454 : size_type size() const;
455 :
456 : Val const * map(OUString const & rString,
457 : OUString * pTranslation = 0, bool * pTranslated = 0)
458 : const;
459 :
460 : private:
461 : RegexpMapImpl< Val > * m_pImpl;
462 : };
463 :
464 : template< typename Val >
465 222 : RegexpMap< Val >::RegexpMap():
466 222 : m_pImpl(new RegexpMapImpl< Val >)
467 222 : {}
468 :
469 : template< typename Val >
470 : RegexpMap< Val >::RegexpMap(RegexpMap const & rOther):
471 : m_pImpl(new RegexpMapImpl< Val >(*rOther.m_pImpl))
472 : {}
473 :
474 : template< typename Val >
475 220 : RegexpMap< Val >::~RegexpMap()
476 : {
477 220 : delete m_pImpl;
478 220 : }
479 :
480 : template< typename Val >
481 : RegexpMap< Val > & RegexpMap< Val >::operator =(RegexpMap const & rOther)
482 : {
483 : *m_pImpl = *rOther.m_pImpl;
484 : return *this;
485 : }
486 :
487 : template< typename Val >
488 2126 : bool RegexpMap< Val >::add(rtl::OUString const & rKey, Val const & rValue,
489 : bool bOverwrite, rtl::OUString * pReverse)
490 : {
491 2126 : Regexp aRegexp(Regexp::parse(rKey));
492 :
493 2126 : if (aRegexp.isDefault())
494 : {
495 132 : if (m_pImpl->m_pDefault)
496 : {
497 0 : if (!bOverwrite)
498 0 : return false;
499 0 : delete m_pImpl->m_pDefault;
500 : }
501 132 : m_pImpl->m_pDefault = new Entry< Val >(aRegexp, rValue);
502 : }
503 : else
504 : {
505 1994 : List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
506 :
507 1994 : typename List< Val >::iterator aEnd(rTheList.end());
508 14075 : for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
509 : {
510 12081 : if (aIt->m_aRegexp == aRegexp)
511 : {
512 0 : if (bOverwrite)
513 : {
514 0 : rTheList.erase(aIt);
515 0 : break;
516 : }
517 : else
518 0 : return false;
519 : }
520 : }
521 :
522 1994 : rTheList.push_back(Entry< Val >(aRegexp, rValue));
523 : }
524 :
525 2126 : if (pReverse)
526 0 : *pReverse = aRegexp.getRegexp(true);
527 :
528 2126 : return true;
529 : }
530 :
531 : template< typename Val >
532 5582 : typename RegexpMap< Val >::iterator RegexpMap< Val >::find(rtl::OUString const & rKey,
533 : rtl::OUString * pReverse)
534 : {
535 5582 : Regexp aRegexp(Regexp::parse(rKey));
536 :
537 5582 : if (pReverse)
538 0 : *pReverse = aRegexp.getRegexp(true);
539 :
540 5582 : if (aRegexp.isDefault())
541 : {
542 132 : if (m_pImpl->m_pDefault)
543 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
544 0 : true));
545 : }
546 : else
547 : {
548 5450 : List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
549 :
550 5450 : typename List< Val > ::iterator aEnd(rTheList.end());
551 18483 : for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
552 16489 : if (aIt->m_aRegexp == aRegexp)
553 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(
554 : m_pImpl,
555 3456 : aRegexp.getKind(), aIt));
556 : }
557 :
558 2126 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false));
559 : }
560 :
561 : template< typename Val >
562 1 : void RegexpMap< Val >::erase(iterator const & rPos)
563 : {
564 1 : if (rPos.m_pImpl->getMap() == m_pImpl)
565 : {
566 1 : if (rPos.m_pImpl->getList() == -1)
567 : {
568 0 : if (m_pImpl->m_pDefault)
569 : {
570 0 : delete m_pImpl->m_pDefault;
571 0 : m_pImpl->m_pDefault = 0;
572 : }
573 : }
574 : else
575 1 : m_pImpl->m_aList[rPos.m_pImpl->getList()].
576 : erase(rPos.m_pImpl->getIndex());
577 : }
578 1 : }
579 :
580 : template< typename Val >
581 3 : typename RegexpMap< Val >::iterator RegexpMap< Val >::begin()
582 : {
583 3 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, true));
584 : }
585 :
586 : template< typename Val >
587 : typename RegexpMap< Val >::const_iterator RegexpMap< Val >::begin() const
588 : {
589 : return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
590 : true));
591 : }
592 :
593 : template< typename Val >
594 5585 : typename RegexpMap< Val >::iterator RegexpMap< Val >::end()
595 : {
596 5585 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false));
597 : }
598 :
599 : template< typename Val >
600 : typename RegexpMap< Val >::const_iterator RegexpMap< Val >::end() const
601 : {
602 : return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
603 : false));
604 : }
605 :
606 : template< typename Val >
607 : bool RegexpMap< Val >::empty() const
608 : {
609 : return !m_pImpl->m_pDefault
610 : && m_pImpl->m_aList[Regexp::KIND_PREFIX].empty()
611 : && m_pImpl->m_aList[Regexp::KIND_AUTHORITY].empty()
612 : && m_pImpl->m_aList[Regexp::KIND_DOMAIN].empty();
613 : }
614 :
615 : template< typename Val >
616 3 : typename RegexpMap< Val >::size_type RegexpMap< Val >::size() const
617 : {
618 : return (m_pImpl->m_pDefault ? 1 : 0)
619 3 : + m_pImpl->m_aList[Regexp::KIND_PREFIX].size()
620 3 : + m_pImpl->m_aList[Regexp::KIND_AUTHORITY].size()
621 9 : + m_pImpl->m_aList[Regexp::KIND_DOMAIN].size();
622 : }
623 :
624 : template< typename Val >
625 409485 : Val const * RegexpMap< Val >::map(rtl::OUString const & rString,
626 : rtl::OUString * pTranslation,
627 : bool * pTranslated) const
628 : {
629 1276446 : for (int n = Regexp::KIND_DOMAIN; n >= Regexp::KIND_PREFIX; --n)
630 : {
631 1228455 : List< Val > const & rTheList = m_pImpl->m_aList[n];
632 :
633 1228455 : typename List< Val >::const_iterator aEnd(rTheList.end());
634 1554530 : for (typename List< Val >::const_iterator aIt(rTheList.begin()); aIt != aEnd;
635 : ++aIt)
636 687569 : if (aIt->m_aRegexp.matches(rString, pTranslation, pTranslated))
637 361494 : return &aIt->m_aValue;
638 : }
639 54778 : if (m_pImpl->m_pDefault
640 6787 : && m_pImpl->m_pDefault->m_aRegexp.matches(rString, pTranslation,
641 : pTranslated))
642 6787 : return &m_pImpl->m_pDefault->m_aValue;
643 41204 : return 0;
644 : }
645 :
646 : }
647 :
648 :
649 : template< typename Val >
650 5580 : inline bool operator ==(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
651 : ucb_impl::RegexpMapConstIter< Val > const & rIter2)
652 : {
653 5580 : return rIter1.equals(rIter2);
654 : }
655 :
656 : template< typename Val >
657 52 : inline bool operator !=(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
658 : ucb_impl::RegexpMapConstIter< Val > const & rIter2)
659 : {
660 52 : return !rIter1.equals(rIter2);
661 : }
662 :
663 : #endif // INCLUDED_UCB_SOURCE_INC_REGEXPMAP_HXX
664 :
665 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|