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 _UCB_REGEXPMAP_HXX_
21 : #define _UCB_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 9758 : class RegexpMapEntry
40 : {
41 : public:
42 7049 : inline RegexpMapEntry(OUString const & rTheRegexp,
43 : Val * pTheValue):
44 7049 : m_aRegexp(rTheRegexp), m_pValue(pTheValue) {}
45 :
46 53 : OUString getRegexp() const { return m_aRegexp; }
47 :
48 53 : Val const & getValue() const { return *m_pValue; }
49 :
50 471 : 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 4913 : struct Entry
61 : {
62 : Regexp m_aRegexp;
63 : Val m_aValue;
64 :
65 1701 : inline Entry(Regexp const & rTheRegexp, Val const & rTheValue):
66 1701 : m_aRegexp(rTheRegexp), m_aValue(rTheValue) {}
67 : };
68 :
69 : //============================================================================
70 843 : 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 141 : RegexpMapImpl(): m_pDefault(0) {}
80 :
81 140 : ~RegexpMapImpl() { delete m_pDefault; }
82 : };
83 :
84 : //============================================================================
85 : template< typename Val >
86 6531 : 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 2173 : inline RegexpMapIterImpl< Val >::RegexpMapIterImpl():
129 : m_aEntry(rtl::OUString(), 0),
130 : m_pMap(0),
131 : m_nList(-1),
132 2173 : m_bEntrySet(false)
133 2173 : {}
134 :
135 : template< typename Val >
136 472 : 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 472 : m_bEntrySet(false)
144 472 : {}
145 :
146 : template< typename Val >
147 577 : void RegexpMapIterImpl< Val >::setEntry() const
148 : {
149 577 : if (!m_bEntrySet)
150 : {
151 : Entry< Val > const & rTheEntry
152 524 : = m_nList == -1 ? *m_pMap->m_pDefault : *m_aIndex;
153 524 : m_aEntry
154 1048 : = RegexpMapEntry< Val >(rTheEntry.m_aRegexp.getRegexp(false),
155 : const_cast< Val * >(&rTheEntry.m_aValue));
156 524 : m_bEntrySet = true;
157 : }
158 577 : }
159 :
160 : template< typename Val >
161 3880 : RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap,
162 : bool bBegin):
163 : m_aEntry(rtl::OUString(), 0),
164 : m_pMap(pTheMap),
165 3880 : m_bEntrySet(false)
166 : {
167 3880 : if (bBegin)
168 : {
169 3 : m_nList = -1;
170 3 : if (!m_pMap->m_pDefault)
171 0 : next();
172 : }
173 : else
174 : {
175 3877 : m_nList = Regexp::KIND_DOMAIN;
176 3877 : m_aIndex = m_pMap->m_aList[Regexp::KIND_DOMAIN].end();
177 : }
178 3880 : }
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 2173 : RegexpMapIterImpl< Val > & RegexpMapIterImpl< Val >::operator =(
191 : RegexpMapIterImpl const & rOther)
192 : {
193 2173 : if (this != &rOther)
194 : {
195 2173 : m_aEntry = rOther.m_aEntry;
196 2173 : m_pMap = rOther.m_pMap;
197 2173 : m_nList = rOther.m_nList;
198 2173 : m_bEntrySet = rOther.m_bEntrySet;
199 2173 : if (m_nList == -1)
200 0 : m_aIndex = typename List< Val >::iterator();
201 : else
202 2173 : m_aIndex = rOther.m_aIndex;
203 : }
204 2173 : return *this;
205 : }
206 :
207 : template< typename Val >
208 2229 : bool RegexpMapIterImpl< Val >::operator ==(RegexpMapIterImpl const & rOther)
209 : const
210 : {
211 : return m_pMap == rOther.m_pMap
212 : && m_nList == rOther.m_nList
213 2229 : && (m_nList == -1 || m_aIndex == rOther.m_aIndex);
214 : }
215 :
216 : template< typename Val >
217 53 : void RegexpMapIterImpl< Val >::next()
218 : {
219 53 : switch (m_nList)
220 : {
221 : case Regexp::KIND_DOMAIN:
222 0 : if (m_aIndex == m_pMap->m_aList[m_nList].end())
223 53 : return;
224 : default:
225 50 : ++m_aIndex;
226 200 : if (m_nList == Regexp::KIND_DOMAIN
227 200 : || m_aIndex != m_pMap->m_aList[m_nList].end())
228 47 : break;
229 : case -1:
230 33 : do
231 : {
232 9 : ++m_nList;
233 9 : m_aIndex = m_pMap->m_aList[m_nList].begin();
234 : }
235 : while (m_nList < Regexp::KIND_DOMAIN
236 27 : && m_aIndex == m_pMap->m_aList[m_nList].end());
237 6 : break;
238 : }
239 53 : m_bEntrySet = false;
240 : }
241 :
242 : template< typename Val >
243 577 : RegexpMapEntry< Val > & RegexpMapIterImpl< Val >::get()
244 : {
245 577 : setEntry();
246 577 : return m_aEntry;
247 : }
248 :
249 : //============================================================================
250 : template< typename Val >
251 : class RegexpMapConstIter
252 : {
253 : friend class RegexpMap< Val >; // to access m_pImpl, ctor
254 : friend class RegexpMapIter< Val >; // to access m_pImpl, ctor
255 :
256 : public:
257 : RegexpMapConstIter();
258 :
259 : RegexpMapConstIter(RegexpMapConstIter const & rOther);
260 :
261 : ~RegexpMapConstIter();
262 :
263 : RegexpMapConstIter & operator =(RegexpMapConstIter const & rOther);
264 :
265 : RegexpMapConstIter & operator ++();
266 :
267 : RegexpMapConstIter operator ++(int);
268 :
269 : RegexpMapEntry< Val > const & operator *() const;
270 :
271 : RegexpMapEntry< Val > const * operator ->() const;
272 :
273 : bool equals(RegexpMapConstIter const & rOther) const;
274 : // for free operator ==(), operator !=()
275 :
276 : private:
277 : RegexpMapIterImpl< Val > * m_pImpl;
278 :
279 : RegexpMapConstIter(RegexpMapIterImpl< Val > * pTheImpl);
280 : };
281 :
282 : template< typename Val >
283 4352 : RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapIterImpl< Val > *
284 : pTheImpl):
285 4352 : m_pImpl(pTheImpl)
286 4352 : {}
287 :
288 : template< typename Val >
289 2173 : RegexpMapConstIter< Val >::RegexpMapConstIter():
290 2173 : m_pImpl(new RegexpMapIterImpl< Val >)
291 2173 : {}
292 :
293 : template< typename Val >
294 6 : RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapConstIter const &
295 : rOther):
296 6 : m_pImpl(new RegexpMapIterImpl< Val >(*rOther.m_pImpl))
297 6 : {}
298 :
299 : template< typename Val >
300 6531 : RegexpMapConstIter< Val >::~RegexpMapConstIter()
301 : {
302 6531 : delete m_pImpl;
303 6531 : }
304 :
305 : template< typename Val >
306 : RegexpMapConstIter< Val > &
307 2173 : RegexpMapConstIter< Val >::operator =(RegexpMapConstIter const & rOther)
308 : {
309 2173 : *m_pImpl = *rOther.m_pImpl;
310 2173 : return *this;
311 : }
312 :
313 : template< typename Val >
314 53 : RegexpMapConstIter< Val > & RegexpMapConstIter< Val >::operator ++()
315 : {
316 53 : m_pImpl->next();
317 53 : return *this;
318 : }
319 :
320 : template< typename Val >
321 : RegexpMapConstIter< Val > RegexpMapConstIter< Val >::operator ++(int)
322 : {
323 : RegexpMapConstIter aTemp(*this);
324 : m_pImpl->next();
325 : return aTemp;
326 : }
327 :
328 : template< typename Val >
329 : RegexpMapEntry< Val > const & RegexpMapConstIter< Val >::operator *() const
330 : {
331 : return m_pImpl->get();
332 : }
333 :
334 : template< typename Val >
335 106 : RegexpMapEntry< Val > const * RegexpMapConstIter< Val >::operator ->() const
336 : {
337 106 : return &m_pImpl->get();
338 : }
339 :
340 : template< typename Val >
341 2229 : bool RegexpMapConstIter< Val >::equals(RegexpMapConstIter const & rOther)
342 : const
343 : {
344 2229 : return *m_pImpl == *rOther.m_pImpl;
345 : }
346 :
347 : //============================================================================
348 : template< typename Val >
349 8698 : class RegexpMapIter: public RegexpMapConstIter< Val >
350 : {
351 : friend class RegexpMap< Val >; // to access ctor
352 :
353 : public:
354 2173 : RegexpMapIter() {}
355 :
356 : RegexpMapIter & operator ++();
357 :
358 : RegexpMapIter operator ++(int);
359 :
360 : RegexpMapEntry< Val > & operator *();
361 :
362 : RegexpMapEntry< Val > const & operator *() const;
363 :
364 : RegexpMapEntry< Val > * operator ->();
365 :
366 : RegexpMapEntry< Val > const * operator ->() const;
367 :
368 : private:
369 : RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl);
370 : };
371 :
372 : template< typename Val >
373 4352 : RegexpMapIter< Val >::RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl):
374 4352 : RegexpMapConstIter< Val >(pTheImpl)
375 4352 : {}
376 :
377 : template< typename Val >
378 : RegexpMapIter< Val > & RegexpMapIter< Val >::operator ++()
379 : {
380 : this->m_pImpl->next();
381 : return *this;
382 : }
383 :
384 : template< typename Val >
385 : RegexpMapIter< Val > RegexpMapIter< Val >::operator ++(int)
386 : {
387 : RegexpMapIter aTemp(*this);
388 : this->m_pImpl->next();
389 : return aTemp;
390 : }
391 :
392 : template< typename Val >
393 : RegexpMapEntry< Val > & RegexpMapIter< Val >::operator *()
394 : {
395 : return this->m_pImpl->get();
396 : }
397 :
398 : template< typename Val >
399 : RegexpMapEntry< Val > const & RegexpMapIter< Val >::operator *() const
400 : {
401 : return this->m_pImpl->get();
402 : }
403 :
404 : template< typename Val >
405 471 : RegexpMapEntry< Val > * RegexpMapIter< Val >::operator ->()
406 : {
407 471 : return &this->m_pImpl->get();
408 : }
409 :
410 : template< typename Val >
411 : RegexpMapEntry< Val > const * RegexpMapIter< Val >::operator ->() const
412 : {
413 : return &this->m_pImpl->get();
414 : }
415 :
416 : //============================================================================
417 : template< typename Val >
418 : class RegexpMap
419 : {
420 : public:
421 : typedef sal_uInt32 size_type;
422 : typedef RegexpMapIter< Val > iterator;
423 : typedef RegexpMapConstIter< Val > const_iterator;
424 :
425 : RegexpMap();
426 :
427 : RegexpMap(RegexpMap const & rOther);
428 :
429 : ~RegexpMap();
430 :
431 : RegexpMap & operator =(RegexpMap const & rOther);
432 :
433 : bool add(OUString const & rKey, Val const & rValue, bool bOverwrite,
434 : OUString * pReverse = 0);
435 : // throws com::sun::star::lang::IllegalArgumentException
436 :
437 : iterator find(OUString const & rKey, OUString * pReverse = 0);
438 : // throws com::sun::star::lang::IllegalArgumentException
439 :
440 : void erase(iterator const & rPos);
441 :
442 : iterator begin();
443 :
444 : const_iterator begin() const;
445 :
446 : iterator end();
447 :
448 : const_iterator end() const;
449 :
450 : bool empty() const;
451 :
452 : size_type size() const;
453 :
454 : Val const * map(OUString const & rString,
455 : OUString * pTranslation = 0, bool * pTranslated = 0)
456 : const;
457 :
458 : private:
459 : RegexpMapImpl< Val > * m_pImpl;
460 : };
461 :
462 : template< typename Val >
463 141 : RegexpMap< Val >::RegexpMap():
464 141 : m_pImpl(new RegexpMapImpl< Val >)
465 141 : {}
466 :
467 : template< typename Val >
468 : RegexpMap< Val >::RegexpMap(RegexpMap const & rOther):
469 : m_pImpl(new RegexpMapImpl< Val >(*rOther.m_pImpl))
470 : {}
471 :
472 : template< typename Val >
473 140 : RegexpMap< Val >::~RegexpMap()
474 : {
475 140 : delete m_pImpl;
476 140 : }
477 :
478 : template< typename Val >
479 : RegexpMap< Val > & RegexpMap< Val >::operator =(RegexpMap const & rOther)
480 : {
481 : *m_pImpl = *rOther.m_pImpl;
482 : return *this;
483 : }
484 :
485 : template< typename Val >
486 1701 : bool RegexpMap< Val >::add(rtl::OUString const & rKey, Val const & rValue,
487 : bool bOverwrite, rtl::OUString * pReverse)
488 : {
489 1701 : Regexp aRegexp(Regexp::parse(rKey));
490 :
491 1701 : if (aRegexp.isDefault())
492 : {
493 94 : if (m_pImpl->m_pDefault)
494 : {
495 0 : if (!bOverwrite)
496 0 : return false;
497 0 : delete m_pImpl->m_pDefault;
498 : }
499 94 : m_pImpl->m_pDefault = new Entry< Val >(aRegexp, rValue);
500 : }
501 : else
502 : {
503 1607 : List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
504 :
505 1607 : typename List< Val >::iterator aEnd(rTheList.end());
506 13093 : for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
507 : {
508 11486 : if (aIt->m_aRegexp == aRegexp)
509 : {
510 0 : if (bOverwrite)
511 : {
512 0 : rTheList.erase(aIt);
513 0 : break;
514 : }
515 : else
516 0 : return false;
517 : }
518 : }
519 :
520 1607 : rTheList.push_back(Entry< Val >(aRegexp, rValue));
521 : }
522 :
523 1701 : if (pReverse)
524 0 : *pReverse = aRegexp.getRegexp(true);
525 :
526 1701 : return true;
527 : }
528 :
529 : template< typename Val >
530 2173 : typename RegexpMap< Val >::iterator RegexpMap< Val >::find(rtl::OUString const & rKey,
531 : rtl::OUString * pReverse)
532 : {
533 2173 : Regexp aRegexp(Regexp::parse(rKey));
534 :
535 2173 : if (pReverse)
536 0 : *pReverse = aRegexp.getRegexp(true);
537 :
538 2173 : if (aRegexp.isDefault())
539 : {
540 94 : if (m_pImpl->m_pDefault)
541 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
542 0 : true));
543 : }
544 : else
545 : {
546 2079 : List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
547 :
548 2079 : typename List< Val > ::iterator aEnd(rTheList.end());
549 13808 : for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
550 12201 : if (aIt->m_aRegexp == aRegexp)
551 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(
552 : m_pImpl,
553 472 : aRegexp.getKind(), aIt));
554 : }
555 :
556 1701 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false));
557 : }
558 :
559 : template< typename Val >
560 1 : void RegexpMap< Val >::erase(iterator const & rPos)
561 : {
562 1 : if (rPos.m_pImpl->getMap() == m_pImpl)
563 : {
564 1 : if (rPos.m_pImpl->getList() == -1)
565 : {
566 0 : if (m_pImpl->m_pDefault)
567 : {
568 0 : delete m_pImpl->m_pDefault;
569 0 : m_pImpl->m_pDefault = 0;
570 : }
571 : }
572 : else
573 1 : m_pImpl->m_aList[rPos.m_pImpl->getList()].
574 : erase(rPos.m_pImpl->getIndex());
575 : }
576 1 : }
577 :
578 : template< typename Val >
579 3 : typename RegexpMap< Val >::iterator RegexpMap< Val >::begin()
580 : {
581 3 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, true));
582 : }
583 :
584 : template< typename Val >
585 : typename RegexpMap< Val >::const_iterator RegexpMap< Val >::begin() const
586 : {
587 : return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
588 : true));
589 : }
590 :
591 : template< typename Val >
592 2176 : typename RegexpMap< Val >::iterator RegexpMap< Val >::end()
593 : {
594 2176 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false));
595 : }
596 :
597 : template< typename Val >
598 : typename RegexpMap< Val >::const_iterator RegexpMap< Val >::end() const
599 : {
600 : return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
601 : false));
602 : }
603 :
604 : template< typename Val >
605 : bool RegexpMap< Val >::empty() const
606 : {
607 : return !m_pImpl->m_pDefault
608 : && m_pImpl->m_aList[Regexp::KIND_PREFIX].empty()
609 : && m_pImpl->m_aList[Regexp::KIND_AUTHORITY].empty()
610 : && m_pImpl->m_aList[Regexp::KIND_DOMAIN].empty();
611 : }
612 :
613 : template< typename Val >
614 3 : typename RegexpMap< Val >::size_type RegexpMap< Val >::size() const
615 : {
616 : return (m_pImpl->m_pDefault ? 1 : 0)
617 3 : + m_pImpl->m_aList[Regexp::KIND_PREFIX].size()
618 3 : + m_pImpl->m_aList[Regexp::KIND_AUTHORITY].size()
619 9 : + m_pImpl->m_aList[Regexp::KIND_DOMAIN].size();
620 : }
621 :
622 : template< typename Val >
623 132519 : Val const * RegexpMap< Val >::map(rtl::OUString const & rString,
624 : rtl::OUString * pTranslation,
625 : bool * pTranslated) const
626 : {
627 408623 : for (int n = Regexp::KIND_DOMAIN; n >= Regexp::KIND_PREFIX; --n)
628 : {
629 397557 : List< Val > const & rTheList = m_pImpl->m_aList[n];
630 :
631 397557 : typename List< Val >::const_iterator aEnd(rTheList.end());
632 1008982 : for (typename List< Val >::const_iterator aIt(rTheList.begin()); aIt != aEnd;
633 : ++aIt)
634 732878 : if (aIt->m_aRegexp.matches(rString, pTranslation, pTranslated))
635 121453 : return &aIt->m_aValue;
636 : }
637 18637 : if (m_pImpl->m_pDefault
638 7571 : && m_pImpl->m_pDefault->m_aRegexp.matches(rString, pTranslation,
639 : pTranslated))
640 7571 : return &m_pImpl->m_pDefault->m_aValue;
641 3495 : return 0;
642 : }
643 :
644 : }
645 :
646 : //============================================================================
647 : template< typename Val >
648 2171 : inline bool operator ==(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
649 : ucb_impl::RegexpMapConstIter< Val > const & rIter2)
650 : {
651 2171 : return rIter1.equals(rIter2);
652 : }
653 :
654 : template< typename Val >
655 58 : inline bool operator !=(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
656 : ucb_impl::RegexpMapConstIter< Val > const & rIter2)
657 : {
658 58 : return !rIter1.equals(rIter2);
659 : }
660 :
661 : #endif // _UCB_REGEXPMAP_HXX_
662 :
663 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|