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 0 : class RegexpMapEntry
40 : {
41 : public:
42 0 : inline RegexpMapEntry(OUString const & rTheRegexp,
43 : Val * pTheValue):
44 0 : m_aRegexp(rTheRegexp), m_pValue(pTheValue) {}
45 :
46 0 : OUString getRegexp() const { return m_aRegexp; }
47 :
48 0 : Val const & getValue() const { return *m_pValue; }
49 :
50 0 : 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 0 : struct Entry
61 : {
62 : Regexp m_aRegexp;
63 : Val m_aValue;
64 :
65 0 : inline Entry(Regexp const & rTheRegexp, Val const & rTheValue):
66 0 : m_aRegexp(rTheRegexp), m_aValue(rTheValue) {}
67 : };
68 :
69 :
70 0 : 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 0 : RegexpMapImpl(): m_pDefault(0) {}
80 :
81 0 : ~RegexpMapImpl() { delete m_pDefault; }
82 : };
83 :
84 :
85 : template< typename Val >
86 0 : 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 0 : RegexpMapImpl< Val > const * getMap() const { return m_pMap; }
108 :
109 0 : int getList() const { return m_nList; }
110 :
111 0 : 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 0 : inline RegexpMapIterImpl< Val >::RegexpMapIterImpl():
129 : m_aEntry(rtl::OUString(), 0),
130 : m_pMap(0),
131 : m_nList(-1),
132 0 : m_bEntrySet(false)
133 0 : {}
134 :
135 : template< typename Val >
136 0 : 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 0 : m_bEntrySet(false)
144 0 : {}
145 :
146 : template< typename Val >
147 0 : void RegexpMapIterImpl< Val >::setEntry() const
148 : {
149 0 : if (!m_bEntrySet)
150 : {
151 : Entry< Val > const & rTheEntry
152 0 : = m_nList == -1 ? *m_pMap->m_pDefault : *m_aIndex;
153 0 : m_aEntry
154 0 : = RegexpMapEntry< Val >(rTheEntry.m_aRegexp.getRegexp(false),
155 : const_cast< Val * >(&rTheEntry.m_aValue));
156 0 : m_bEntrySet = true;
157 : }
158 0 : }
159 :
160 : template< typename Val >
161 0 : RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap,
162 : bool bBegin):
163 : m_aEntry(rtl::OUString(), 0),
164 : m_pMap(pTheMap),
165 0 : m_bEntrySet(false)
166 : {
167 0 : if (bBegin)
168 : {
169 0 : m_nList = -1;
170 0 : if (!m_pMap->m_pDefault)
171 0 : next();
172 : }
173 : else
174 : {
175 0 : m_nList = Regexp::KIND_DOMAIN;
176 0 : m_aIndex = m_pMap->m_aList[Regexp::KIND_DOMAIN].end();
177 : }
178 0 : }
179 :
180 : template< typename Val >
181 0 : RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapIterImpl const & rOther):
182 : m_aEntry(rOther.m_aEntry), m_pMap(rOther.m_pMap), m_nList(rOther.m_nList),
183 0 : m_bEntrySet(rOther.m_bEntrySet)
184 : {
185 0 : if (m_nList != -1)
186 0 : m_aIndex = rOther.m_aIndex;
187 0 : }
188 :
189 : template< typename Val >
190 0 : RegexpMapIterImpl< Val > & RegexpMapIterImpl< Val >::operator =(
191 : RegexpMapIterImpl const & rOther)
192 : {
193 0 : if (this != &rOther)
194 : {
195 0 : m_aEntry = rOther.m_aEntry;
196 0 : m_pMap = rOther.m_pMap;
197 0 : m_nList = rOther.m_nList;
198 0 : m_bEntrySet = rOther.m_bEntrySet;
199 0 : if (m_nList == -1)
200 0 : m_aIndex = typename List< Val >::iterator();
201 : else
202 0 : m_aIndex = rOther.m_aIndex;
203 : }
204 0 : return *this;
205 : }
206 :
207 : template< typename Val >
208 0 : bool RegexpMapIterImpl< Val >::operator ==(RegexpMapIterImpl const & rOther)
209 : const
210 : {
211 : return m_pMap == rOther.m_pMap
212 : && m_nList == rOther.m_nList
213 0 : && (m_nList == -1 || m_aIndex == rOther.m_aIndex);
214 : }
215 :
216 : template< typename Val >
217 0 : void RegexpMapIterImpl< Val >::next()
218 : {
219 0 : switch (m_nList)
220 : {
221 : case Regexp::KIND_DOMAIN:
222 0 : if (m_aIndex == m_pMap->m_aList[m_nList].end())
223 0 : return;
224 : //fall-through
225 : default:
226 0 : ++m_aIndex;
227 0 : if (m_nList == Regexp::KIND_DOMAIN
228 0 : || m_aIndex != m_pMap->m_aList[m_nList].end())
229 0 : break;
230 : //fall-through
231 : case -1:
232 0 : do
233 : {
234 0 : ++m_nList;
235 0 : m_aIndex = m_pMap->m_aList[m_nList].begin();
236 : }
237 : while (m_nList < Regexp::KIND_DOMAIN
238 0 : && m_aIndex == m_pMap->m_aList[m_nList].end());
239 0 : break;
240 : }
241 0 : m_bEntrySet = false;
242 : }
243 :
244 : template< typename Val >
245 0 : RegexpMapEntry< Val > & RegexpMapIterImpl< Val >::get()
246 : {
247 0 : setEntry();
248 0 : 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 0 : RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapIterImpl< Val > *
286 : pTheImpl):
287 0 : m_pImpl(pTheImpl)
288 0 : {}
289 :
290 : template< typename Val >
291 0 : RegexpMapConstIter< Val >::RegexpMapConstIter():
292 0 : m_pImpl(new RegexpMapIterImpl< Val >)
293 0 : {}
294 :
295 : template< typename Val >
296 0 : RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapConstIter const &
297 : rOther):
298 0 : m_pImpl(new RegexpMapIterImpl< Val >(*rOther.m_pImpl))
299 0 : {}
300 :
301 : template< typename Val >
302 0 : RegexpMapConstIter< Val >::~RegexpMapConstIter()
303 : {
304 0 : delete m_pImpl;
305 0 : }
306 :
307 : template< typename Val >
308 : RegexpMapConstIter< Val > &
309 0 : RegexpMapConstIter< Val >::operator =(RegexpMapConstIter const & rOther)
310 : {
311 0 : *m_pImpl = *rOther.m_pImpl;
312 0 : return *this;
313 : }
314 :
315 : template< typename Val >
316 0 : RegexpMapConstIter< Val > & RegexpMapConstIter< Val >::operator ++()
317 : {
318 0 : m_pImpl->next();
319 0 : 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 0 : RegexpMapEntry< Val > const * RegexpMapConstIter< Val >::operator ->() const
338 : {
339 0 : return &m_pImpl->get();
340 : }
341 :
342 : template< typename Val >
343 0 : bool RegexpMapConstIter< Val >::equals(RegexpMapConstIter const & rOther)
344 : const
345 : {
346 0 : return *m_pImpl == *rOther.m_pImpl;
347 : }
348 :
349 :
350 : template< typename Val >
351 0 : class RegexpMapIter: public RegexpMapConstIter< Val >
352 : {
353 : friend class RegexpMap< Val >; // to access ctor
354 :
355 : public:
356 0 : 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 0 : RegexpMapIter< Val >::RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl):
376 0 : RegexpMapConstIter< Val >(pTheImpl)
377 0 : {}
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 0 : RegexpMapEntry< Val > * RegexpMapIter< Val >::operator ->()
408 : {
409 0 : 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 0 : RegexpMap< Val >::RegexpMap():
466 0 : m_pImpl(new RegexpMapImpl< Val >)
467 0 : {}
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 0 : RegexpMap< Val >::~RegexpMap()
476 : {
477 0 : delete m_pImpl;
478 0 : }
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 0 : bool RegexpMap< Val >::add(rtl::OUString const & rKey, Val const & rValue,
489 : bool bOverwrite, rtl::OUString * pReverse)
490 : {
491 0 : Regexp aRegexp(Regexp::parse(rKey));
492 :
493 0 : if (aRegexp.isDefault())
494 : {
495 0 : if (m_pImpl->m_pDefault)
496 : {
497 0 : if (!bOverwrite)
498 0 : return false;
499 0 : delete m_pImpl->m_pDefault;
500 : }
501 0 : m_pImpl->m_pDefault = new Entry< Val >(aRegexp, rValue);
502 : }
503 : else
504 : {
505 0 : List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
506 :
507 0 : typename List< Val >::iterator aEnd(rTheList.end());
508 0 : for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
509 : {
510 0 : 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 0 : rTheList.push_back(Entry< Val >(aRegexp, rValue));
523 : }
524 :
525 0 : if (pReverse)
526 0 : *pReverse = aRegexp.getRegexp(true);
527 :
528 0 : return true;
529 : }
530 :
531 : template< typename Val >
532 0 : typename RegexpMap< Val >::iterator RegexpMap< Val >::find(rtl::OUString const & rKey,
533 : rtl::OUString * pReverse)
534 : {
535 0 : Regexp aRegexp(Regexp::parse(rKey));
536 :
537 0 : if (pReverse)
538 0 : *pReverse = aRegexp.getRegexp(true);
539 :
540 0 : if (aRegexp.isDefault())
541 : {
542 0 : if (m_pImpl->m_pDefault)
543 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
544 0 : true));
545 : }
546 : else
547 : {
548 0 : List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
549 :
550 0 : typename List< Val > ::iterator aEnd(rTheList.end());
551 0 : for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
552 0 : if (aIt->m_aRegexp == aRegexp)
553 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(
554 : m_pImpl,
555 0 : aRegexp.getKind(), aIt));
556 : }
557 :
558 0 : return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false));
559 : }
560 :
561 : template< typename Val >
562 0 : void RegexpMap< Val >::erase(iterator const & rPos)
563 : {
564 0 : if (rPos.m_pImpl->getMap() == m_pImpl)
565 : {
566 0 : 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 0 : m_pImpl->m_aList[rPos.m_pImpl->getList()].
576 : erase(rPos.m_pImpl->getIndex());
577 : }
578 0 : }
579 :
580 : template< typename Val >
581 0 : typename RegexpMap< Val >::iterator RegexpMap< Val >::begin()
582 : {
583 0 : 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 0 : typename RegexpMap< Val >::iterator RegexpMap< Val >::end()
595 : {
596 0 : 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 0 : typename RegexpMap< Val >::size_type RegexpMap< Val >::size() const
617 : {
618 : return (m_pImpl->m_pDefault ? 1 : 0)
619 0 : + m_pImpl->m_aList[Regexp::KIND_PREFIX].size()
620 0 : + m_pImpl->m_aList[Regexp::KIND_AUTHORITY].size()
621 0 : + m_pImpl->m_aList[Regexp::KIND_DOMAIN].size();
622 : }
623 :
624 : template< typename Val >
625 0 : Val const * RegexpMap< Val >::map(rtl::OUString const & rString,
626 : rtl::OUString * pTranslation,
627 : bool * pTranslated) const
628 : {
629 0 : for (int n = Regexp::KIND_DOMAIN; n >= Regexp::KIND_PREFIX; --n)
630 : {
631 0 : List< Val > const & rTheList = m_pImpl->m_aList[n];
632 :
633 0 : typename List< Val >::const_iterator aEnd(rTheList.end());
634 0 : for (typename List< Val >::const_iterator aIt(rTheList.begin()); aIt != aEnd;
635 : ++aIt)
636 0 : if (aIt->m_aRegexp.matches(rString, pTranslation, pTranslated))
637 0 : return &aIt->m_aValue;
638 : }
639 0 : if (m_pImpl->m_pDefault
640 0 : && m_pImpl->m_pDefault->m_aRegexp.matches(rString, pTranslation,
641 : pTranslated))
642 0 : return &m_pImpl->m_pDefault->m_aValue;
643 0 : return 0;
644 : }
645 :
646 : }
647 :
648 :
649 : template< typename Val >
650 0 : inline bool operator ==(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
651 : ucb_impl::RegexpMapConstIter< Val > const & rIter2)
652 : {
653 0 : return rIter1.equals(rIter2);
654 : }
655 :
656 : template< typename Val >
657 0 : inline bool operator !=(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
658 : ucb_impl::RegexpMapConstIter< Val > const & rIter2)
659 : {
660 0 : return !rIter1.equals(rIter2);
661 : }
662 :
663 : #endif // _UCB_REGEXPMAP_HXX_
664 :
665 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|