Coverage Report

Created: 2025-06-13 06:07

/src/poco/XML/src/NamePool.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// NamePool.cpp
3
//
4
// Library: XML
5
// Package: XML
6
// Module:  NamePool
7
//
8
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9
// and Contributors.
10
//
11
// SPDX-License-Identifier: BSL-1.0
12
//
13
14
15
#include "Poco/XML/NamePool.h"
16
#include "Poco/Exception.h"
17
#include "Poco/Random.h"
18
19
20
namespace Poco {
21
namespace XML {
22
23
24
class NamePoolItem
25
{
26
public:
27
13.2M
  NamePoolItem(): _used(false)
28
13.2M
  {
29
13.2M
  }
30
31
  ~NamePoolItem()
32
13.2M
  {
33
13.2M
  }
34
35
  bool set(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName)
36
791k
  {
37
791k
    if (!_used)
38
44.0k
    {
39
44.0k
      _name.assign(qname, namespaceURI, localName);
40
44.0k
      _used = true;
41
44.0k
      return true;
42
44.0k
    }
43
746k
    else return _name.equals(qname, namespaceURI, localName);
44
791k
  }
45
46
  const Name& get() const
47
783k
  {
48
783k
    return _name;
49
783k
  }
50
51
  bool used() const
52
0
  {
53
0
    return _used;
54
0
  }
55
56
private:
57
  Name _name;
58
  bool _used;
59
};
60
61
62
NamePool::NamePool(unsigned long size):
63
26.1k
  _size(size),
64
26.1k
  _salt(0),
65
26.1k
  _rc(1)
66
26.1k
{
67
26.1k
  poco_assert (size > 1);
68
69
26.1k
  _pItems = new NamePoolItem[size];
70
71
26.1k
  Poco::Random rnd;
72
26.1k
  rnd.seed();
73
26.1k
  _salt = rnd.next();
74
26.1k
}
75
76
77
NamePool::~NamePool()
78
26.1k
{
79
26.1k
  delete [] _pItems;
80
26.1k
}
81
82
83
void NamePool::duplicate()
84
0
{
85
0
  ++_rc;
86
0
}
87
88
89
void NamePool::release()
90
26.1k
{
91
26.1k
  if (--_rc == 0)
92
26.1k
    delete this;
93
26.1k
}
94
95
96
const Name& NamePool::insert(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName)
97
783k
{
98
783k
  unsigned long i = 0;
99
783k
  unsigned long n = (hash(qname, namespaceURI, localName) ^ _salt) % _size;
100
101
791k
  while (!_pItems[n].set(qname, namespaceURI, localName) && i++ < _size)
102
7.08k
    n = (n + 1) % _size;
103
104
783k
  if (i > _size) throw Poco::PoolOverflowException("XML name pool");
105
106
783k
  return _pItems[n].get();
107
783k
}
108
109
110
const Name& NamePool::insert(const Name& name)
111
0
{
112
0
  return insert(name.qname(), name.namespaceURI(), name.localName());
113
0
}
114
115
116
unsigned long NamePool::hash(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName)
117
783k
{
118
783k
  unsigned long h = 0;
119
783k
  XMLString::const_iterator it  = qname.begin();
120
783k
  XMLString::const_iterator end = qname.end();
121
23.3M
  while (it != end) h = (h << 5) + h + (unsigned long) *it++;
122
783k
  it =  namespaceURI.begin();
123
783k
  end = namespaceURI.end();
124
888M
  while (it != end) h = (h << 5) + h + (unsigned long) *it++;
125
783k
  it  = localName.begin();
126
783k
  end = localName.end();
127
22.3M
  while (it != end) h = (h << 5) + h + (unsigned long) *it++;
128
783k
  return h;
129
783k
}
130
131
132
} } // namespace Poco::XML