LibreOffice Module ucb (master)  1
regexpmap.hxx
Go to the documentation of this file.
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 <vector>
26 #include <memory>
27 
28 #include <rtl/ustring.hxx>
29 #include <sal/types.h>
30 
31 #include "regexp.hxx"
32 
33 namespace ucb_impl {
34 
35 template< typename Val > class RegexpMap;
36 template< typename Val > class RegexpMapIter;
37 
38 
39 template< typename Val >
41 {
42 public:
43  RegexpMapEntry(OUString const & rTheRegexp,
44  Val * pTheValue):
45  m_aRegexp(rTheRegexp), m_pValue(pTheValue) {}
46 
47  const OUString& getRegexp() const { return m_aRegexp; }
48 
49  Val const & getValue() const { return *m_pValue; }
50 
51  Val & getValue() { return *m_pValue; }
52 
53 private:
54  OUString m_aRegexp;
55  Val * m_pValue;
56 };
57 
58 
59 template< typename Val >
60 struct Entry
61 {
63  Val m_aValue;
64 
65  Entry(Regexp const & rTheRegexp, Val const & rTheValue):
66  m_aRegexp(rTheRegexp), m_aValue(rTheValue) {}
67 };
68 
69 
70 template< typename Val >
72 {
73  friend class RegexpMap< Val >; // to access m_pImpl, ctor
74  friend class RegexpMapIter< Val >; // to access m_pImpl, ctor
75 
76 public:
77  typedef typename std::vector< Entry< Val > >::iterator ListIterator;
78 
80 
81  RegexpMapConstIter(RegexpMap< Val > * pTheMap, bool bBegin);
82 
83  RegexpMapConstIter(RegexpMap< Val > * pTheMap, int nTheList,
84  ListIterator aTheIndex);
85 
86  RegexpMapConstIter(RegexpMapConstIter const & rOther);
87 
89 
91 
92  RegexpMapEntry< Val > const * operator ->() const;
93 
94  bool equals(RegexpMapConstIter const & rOther) const;
95  // for free operator ==(), operator !=()
96 
97 protected:
98  RegexpMapEntry< Val > & get() const;
99 
100 private:
102  typename std::vector< Entry< Val > >::iterator m_aIndex;
104  int m_nList;
105  mutable bool m_bEntrySet;
106 };
107 
108 template< typename Val >
110  m_aEntry(OUString(), 0),
111  m_pMap(nullptr),
112  m_nList(-1),
113  m_bEntrySet(false)
114 {}
115 
116 template< typename Val >
118  bool bBegin):
119  m_aEntry(OUString(), 0),
120  m_pMap(pTheMap),
121  m_bEntrySet(false)
122 {
123  if (bBegin)
124  {
125  m_nList = -1;
126  if (!m_pMap->m_pDefault)
127  operator++();
128  }
129  else
130  {
132  m_aIndex = m_pMap->m_aList[Regexp::KIND_DOMAIN].end();
133  }
134 }
135 
136 template< typename Val >
138  int nTheList,
139  ListIterator aTheIndex):
140  m_aEntry(OUString(), 0),
141  m_aIndex(aTheIndex),
142  m_pMap(pTheMap),
143  m_nList(nTheList),
144  m_bEntrySet(false)
145 {}
146 
147 template< typename Val >
149  rOther):
150  m_aEntry(rOther.m_aEntry), m_pMap(rOther.m_pMap), m_nList(rOther.m_nList),
151  m_bEntrySet(rOther.m_bEntrySet)
152 {
153  if (m_nList != -1)
154  m_aIndex = rOther.m_aIndex;
155 }
156 
157 template< typename Val >
160 {
161  if (this != &rOther)
162  {
163  m_aEntry = rOther.m_aEntry;
164  m_pMap = rOther.m_pMap;
165  m_nList = rOther.m_nList;
166  m_bEntrySet = rOther.m_bEntrySet;
167  if (m_nList == -1)
168  m_aIndex = typename std::vector< Entry<Val> >::iterator();
169  else
170  m_aIndex = rOther.m_aIndex;
171  }
172  return *this;
173 }
174 
175 template< typename Val >
177 {
178  switch (m_nList)
179  {
180  case Regexp::KIND_DOMAIN:
181  if (m_aIndex == m_pMap->m_aList[m_nList].end())
182  return *this;
183  [[fallthrough]];
184  default:
185  ++m_aIndex;
186  if (m_nList == Regexp::KIND_DOMAIN
187  || m_aIndex != m_pMap->m_aList[m_nList].end())
188  break;
189  [[fallthrough]];
190  case -1:
191  do
192  {
193  ++m_nList;
194  m_aIndex = m_pMap->m_aList[m_nList].begin();
195  }
196  while (m_nList < Regexp::KIND_DOMAIN
197  && m_aIndex == m_pMap->m_aList[m_nList].end());
198  break;
199  }
200  m_bEntrySet = false;
201  return *this;
202 }
203 
204 template< typename Val >
206 {
207  if (!m_bEntrySet)
208  {
209  Entry< Val > const & rTheEntry
210  = m_nList == -1 ? *m_pMap->m_pDefault : *m_aIndex;
211  m_aEntry
213  const_cast< Val * >(&rTheEntry.m_aValue));
214  m_bEntrySet = true;
215  }
216  return m_aEntry;
217 }
218 
219 template< typename Val >
221 {
222  return &get();
223 }
224 
225 template< typename Val >
227  const
228 {
229  return m_pMap == rOther.m_pMap
230  && m_nList == rOther.m_nList
231  && (m_nList == -1 || m_aIndex == rOther.m_aIndex);
232 }
233 
234 
235 template< typename Val >
236 class RegexpMapIter: public RegexpMapConstIter< Val >
237 {
238  friend class RegexpMap< Val >; // to access ctor
239 
240 public:
242 
243  RegexpMapIter(RegexpMap< Val > * pTheMap, bool bBegin):
244  RegexpMapConstIter<Val>(pTheMap, bBegin)
245  {}
246 
247  RegexpMapIter(RegexpMap< Val > * pTheMap, int nTheList, typename RegexpMapConstIter< Val >::ListIterator aTheIndex):
248  RegexpMapConstIter<Val>(pTheMap, nTheList, aTheIndex)
249  {}
250 
252 
253  RegexpMapEntry< Val > const * operator ->() const;
254 };
255 
256 template< typename Val >
258 {
260 }
261 
262 template< typename Val >
264 {
266 }
267 
268 
269 template< typename Val >
270 class RegexpMap
271 {
272 friend class RegexpMapConstIter<Val>;
273 public:
274  typedef sal_uInt32 size_type;
277 
278  void add(OUString const & rKey, Val const & rValue);
279 
280  iterator find(OUString const & rKey);
281 
282  void erase(iterator const & rPos);
283 
284  iterator begin();
285 
286  const_iterator begin() const;
287 
288  iterator end();
289 
290  const_iterator end() const;
291 
292  size_type size() const;
293 
294  Val const * map(OUString const & rString) const;
295 
296 private:
297  std::vector< Entry<Val> > m_aList[Regexp::KIND_DOMAIN + 1];
298  std::unique_ptr<Entry< Val >> m_pDefault;
299 };
300 
301 template< typename Val >
302 void RegexpMap< Val >::add(OUString const & rKey, Val const & rValue)
303 {
304  Regexp aRegexp(Regexp::parse(rKey));
305 
306  if (aRegexp.isDefault())
307  {
308  if (m_pDefault)
309  {
310  return;
311  }
312  m_pDefault.reset( new Entry< Val >(aRegexp, rValue) );
313  }
314  else
315  {
316  std::vector< Entry<Val> > & rTheList = m_aList[aRegexp.getKind()];
317 
318  for (auto const& elem : rTheList)
319  {
320  if (elem.m_aRegexp == aRegexp)
321  {
322  return;
323  }
324  }
325 
326  rTheList.push_back(Entry< Val >(aRegexp, rValue));
327  }
328 }
329 
330 template< typename Val >
331 typename RegexpMap< Val >::iterator RegexpMap< Val >::find(OUString const & rKey)
332 {
333  Regexp aRegexp(Regexp::parse(rKey));
334 
335  if (aRegexp.isDefault())
336  {
337  if (m_pDefault)
338  return RegexpMapIter< Val >(this, true);
339  }
340  else
341  {
342  std::vector< Entry<Val> > & rTheList = m_aList[aRegexp.getKind()];
343 
344  typename std::vector< Entry<Val> >::iterator aEnd(rTheList.end());
345  for (typename std::vector< Entry<Val> >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
346  if (aIt->m_aRegexp == aRegexp)
347  return RegexpMapIter< Val >(this, aRegexp.getKind(), aIt);
348  }
349 
350  return RegexpMapIter< Val >(this, false);
351 }
352 
353 template< typename Val >
355 {
356  assert(rPos.m_pMap == this);
357  if (rPos.m_pMap == this)
358  {
359  if (rPos.m_nList == -1)
360  {
361  m_pDefault.reset();
362  }
363  else
364  m_aList[rPos.m_nList].erase(rPos.m_aIndex);
365  }
366 }
367 
368 template< typename Val >
370 {
371  return RegexpMapIter< Val >(this, true);
372 }
373 
374 template< typename Val >
376 {
377  return RegexpMapConstIter< Val >(this, true);
378 }
379 
380 template< typename Val >
382 {
383  return RegexpMapIter< Val >(this, false);
384 }
385 
386 template< typename Val >
388 {
389  return RegexpMapConstIter< Val >(this, false);
390 }
391 
392 template< typename Val >
394 {
395  return (m_pDefault ? 1 : 0)
396  + m_aList[Regexp::KIND_PREFIX].size()
397  + m_aList[Regexp::KIND_AUTHORITY].size()
398  + m_aList[Regexp::KIND_DOMAIN].size();
399 }
400 
401 template< typename Val >
402 Val const * RegexpMap< Val >::map(OUString const & rString) const
403 {
404  for (int n = Regexp::KIND_DOMAIN; n >= Regexp::KIND_PREFIX; --n)
405  {
406  std::vector< Entry<Val> > const & rTheList = m_aList[n];
407 
408  for (auto const & rItem : rTheList)
409  if (rItem.m_aRegexp.matches(rString))
410  return &rItem.m_aValue;
411  }
412  if (m_pDefault
413  && m_pDefault->m_aRegexp.matches(rString))
414  return &m_pDefault->m_aValue;
415  return 0;
416 }
417 
418 }
419 
420 
421 template< typename Val >
424 {
425  return rIter1.equals(rIter2);
426 }
427 
428 template< typename Val >
431 {
432  return !rIter1.equals(rIter2);
433 }
434 
435 #endif // INCLUDED_UCB_SOURCE_INC_REGEXPMAP_HXX
436 
437 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Entry(Regexp const &rTheRegexp, Val const &rTheValue)
Definition: regexpmap.hxx:65
RegexpMapConstIter< Val > const_iterator
Definition: regexpmap.hxx:276
Val const & getValue() const
Definition: regexpmap.hxx:49
bool operator==(ucb_impl::RegexpMapConstIter< Val > const &rIter1, ucb_impl::RegexpMapConstIter< Val > const &rIter2)
Definition: regexpmap.hxx:422
RegexpMapEntry(OUString const &rTheRegexp, Val *pTheValue)
Definition: regexpmap.hxx:43
Regexp m_aRegexp
Definition: regexpmap.hxx:62
const OUString & getRegexp() const
Definition: regexpmap.hxx:47
RegexpMapConstIter & operator=(RegexpMapConstIter const &rOther)
Definition: regexpmap.hxx:159
RegexpMapIter< Val > iterator
Definition: regexpmap.hxx:275
size_type size() const
Definition: regexpmap.hxx:393
bool isDefault() const
Definition: regexp.hxx:40
RegexpMapIter(RegexpMap< Val > *pTheMap, int nTheList, typename RegexpMapConstIter< Val >::ListIterator aTheIndex)
Definition: regexpmap.hxx:247
RegexpMapEntry< Val > m_aEntry
Definition: regexpmap.hxx:101
sal_uInt32 size_type
Definition: regexpmap.hxx:274
bool operator!=(ucb_impl::RegexpMapConstIter< Val > const &rIter1, ucb_impl::RegexpMapConstIter< Val > const &rIter2)
Definition: regexpmap.hxx:429
RegexpMapEntry< Val > const * operator->() const
Definition: regexpmap.hxx:220
RegexpMap< Val > * m_pMap
Definition: regexpmap.hxx:103
Kind getKind() const
Definition: regexp.hxx:43
std::vector< Entry< Val > >::iterator m_aIndex
Definition: regexpmap.hxx:102
void erase(iterator const &rPos)
Definition: regexpmap.hxx:354
std::vector< Entry< Val > >::iterator ListIterator
Definition: regexpmap.hxx:77
RegexpMapEntry< Val > * operator->()
Definition: regexpmap.hxx:257
bool equals(RegexpMapConstIter const &rOther) const
Definition: regexpmap.hxx:226
void add(OUString const &rKey, Val const &rValue)
Definition: regexpmap.hxx:302
static Regexp parse(OUString const &rRegexp)
Definition: regexp.cxx:293
std::vector< Entry< Val > > m_aList[Regexp::KIND_DOMAIN+1]
Definition: regexpmap.hxx:297
iterator find(OUString const &rKey)
Definition: regexpmap.hxx:331
std::unique_ptr< Entry< Val > > m_pDefault
Definition: regexpmap.hxx:298
Val const * map(OUString const &rString) const
Definition: regexpmap.hxx:402
RegexpMapIter(RegexpMap< Val > *pTheMap, bool bBegin)
Definition: regexpmap.hxx:243
RegexpMapEntry< Val > & get() const
Definition: regexpmap.hxx:205
RegexpMapConstIter & operator++()
Definition: regexpmap.hxx:176
OUString getRegexp() const
Definition: regexp.cxx:173