NCBI C++ ToolKit
node_set.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * Redistribution and use in source and binary forms, with or without
3  * modification, are permitted provided that the following conditions
4  * are met:
5  *
6  * 1. Redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in
10  * the documentation and/or other materials provided with the
11  * distribution.
12  * 3. Neither the name of the Author nor the names of its contributors
13  * may be used to endorse or promote products derived from this software
14  * without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
20  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * $Id: node_set.cpp 79080 2017-08-09 18:22:55Z satskyse $
32  */
33 
34 /** @file
35  * This file contains the implementation of the xml::node_set class.
36 **/
37 
38 // xmlwrapp includes
41 
42 #include "deref_impl.hpp"
43 #include "node_set_impl.hpp"
44 
45 // standard includes
46 #include <stdexcept>
47 
48 // libxml2
49 #include <libxml/xpath.h>
50 
51 namespace xml
52 {
53  namespace impl
54  {
55  //
56  // xml::impl::nset_impl implementation
57  //
58 
59  nset_impl::nset_impl(void* results) :
60  results_(reinterpret_cast<xmlXPathObjectPtr>(results)),
61  refcnt_(1), owe_(true)
62  {}
63 
65  {
66  ++refcnt_;
67  }
68 
70  {
71  if (--refcnt_ == 0) {
72  if (owe_ && results_)
73  xmlXPathFreeObject(results_);
74  delete this;
75  }
76  }
77 
79  {
80  /* The index range is checked by the caller */
81 
83  results_->nodesetval->nodeTab[index]);
84  return node_data->node_instance_;
85  }
86 
87  void nset_impl::set_ownership(bool owe)
88  {
89  owe_ = owe;
90  }
91 
93  {}
94 
95  } // End of namespace impl
96 
97 
98  //
99  // node_set
100  //
101 
102  const char* kDerefError = "dereferencing non initialised or out of range iterator";
103  const char* kRefError = "referencing non initialised or out of range iterator";
104  const char* kAdvError = "advancing non initialised or out of range iterator";
105 
107  pimpl_(NULL)
108  {
109  /* Avoid compiler warnings */
110  pimpl_ = new impl::nset_impl(0);
111  }
112 
113  node_set::node_set(void* result_set) :
114  pimpl_(NULL)
115  {
116  /* Avoid compiler warnings */
117  pimpl_ = new impl::nset_impl(result_set);
118  }
119 
120  node_set::node_set(const node_set& other) :
121  pimpl_(other.pimpl_)
122  {
123  pimpl_->inc_ref();
124  }
125 
127  {
128  if (pimpl_)
129  pimpl_->dec_ref();
130  }
131 
133  {
134  if (this != &other) {
135  pimpl_->dec_ref();
136  pimpl_ = other.pimpl_;
137  pimpl_->inc_ref();
138  }
139  return *this;
140  }
141 
143  pimpl_(other.pimpl_)
144  {
145  other.pimpl_ = NULL;
146  }
147 
149  {
150  if (this != &other) {
151  if (pimpl_)
152  pimpl_->dec_ref();
153  pimpl_ = other.pimpl_;
154 
155  other.pimpl_ = NULL;
156  }
157  return *this;
158  }
159 
160  bool node_set::empty() const
161  {
162  return !pimpl_->results_ ||
163  !pimpl_->results_->nodesetval ||
164  pimpl_->results_->nodesetval->nodeNr == 0;
165  }
166 
167  size_t node_set::size() const
168  {
169  if (empty()) return 0;
170  return pimpl_->results_->nodesetval->nodeNr;
171  }
172 
174  {
175  if (empty()) return iterator(this, -1);
176  return iterator(this, 0);
177  }
178 
180  {
181  if (empty()) return const_iterator(this, -1);
182  return const_iterator(this, 0);
183  }
184 
186  {
187  return iterator(this, -1);
188  }
189 
191  {
192  return const_iterator(this, -1);
193  }
194 
195  //
196  // node_set::iterator
197  //
198 
200  {
201  parent_ = other.parent_;
203  }
204 
206  {
207  iterator tmp(other);
208  swap(tmp);
209  return *this;
210  }
211 
213  {
214  if (!parent_ || current_index_ == -1)
216  return parent_->pimpl_->get_reference(current_index_);
217  }
218 
220  {
221  if (!parent_ || current_index_ == -1)
222  throw xml::exception(kRefError);
223  return &parent_->pimpl_->get_reference(current_index_);
224  }
225 
227  {
228  if (!parent_ || current_index_ == -1)
229  throw xml::exception(kAdvError);
230  if (static_cast<size_t>(++current_index_) >= parent_->size())
231  current_index_ = -1;
232  return *this;
233  }
234 
236  {
237  iterator tmp(*this);
238  ++(*this);
239  return tmp;
240  }
241 
243  {
244  std::swap(parent_, other.parent_);
245  std::swap(current_index_, other.current_index_);
246  }
247 
248  //
249  // node_set::const_iterator
250  //
251 
253  {
254  parent_ = other.parent_;
255  current_index_ = other.current_index_;
256  }
257 
259  {
260  parent_ = other.parent_;
261  current_index_ = other.current_index_;
262  }
263 
265  {
266  const_iterator tmp(other);
267  swap(tmp);
268  return *this;
269  }
270 
272  {
273  const_iterator tmp(other);
274  swap(tmp);
275  return *this;
276  }
277 
279  {
280  if (!parent_ || current_index_ == -1)
282  return parent_->pimpl_->get_reference(current_index_);
283  }
284 
286  {
287  if (!parent_ || current_index_ == -1)
288  throw xml::exception(kRefError);
289  return &parent_->pimpl_->get_reference(current_index_);
290  }
291 
293  {
294  if (!parent_ || current_index_ == -1)
295  throw xml::exception(kAdvError);
296  if (static_cast<size_t>(++current_index_) >= parent_->size())
297  current_index_ = -1;
298  return *this;
299  }
300 
302  {
303  const_iterator tmp(*this);
304  ++(*this);
305  return tmp;
306  }
307 
309  {
310  std::swap(parent_, other.parent_);
311  std::swap(current_index_, other.current_index_);
312  }
313 
314 } // namespace xml
315 
This exception class is thrown by xmlwrapp for all runtime XML-related errors along with the xml::par...
Definition: exception.hpp:64
The xml::node_set::const_iterator class is used to iterate over nodes in a node set.
Definition: node_set.hpp:226
const_iterator & operator++()
Prefix increment.
Definition: node_set.cpp:292
const_iterator()
Create a new uninitialised xml::node_set::const_iterator object.
Definition: node_set.hpp:237
reference operator*() const
Provide a const reference to the node.
Definition: node_set.cpp:278
pointer operator->() const
Provide a const pointer to the node.
Definition: node_set.cpp:285
void swap(const_iterator &other)
Definition: node_set.cpp:308
const node_set * parent_
Definition: node_set.hpp:334
const_iterator & operator=(const const_iterator &other)
Create a copy of the xml::node_set::const_iterator object.
Definition: node_set.cpp:264
The xml::node_set::iterator class is used to iterate over nodes in a node set.
Definition: node_set.hpp:120
iterator & operator=(const iterator &other)
Create a copy of the xml::node_set::iterator object.
Definition: node_set.cpp:205
iterator & operator++()
Prefix increment.
Definition: node_set.cpp:226
reference operator*() const
Provide a reference to the node.
Definition: node_set.cpp:212
void swap(iterator &other)
Definition: node_set.cpp:242
iterator()
Create a new uninitialised xml::node_set::iterator object.
Definition: node_set.hpp:131
pointer operator->() const
Provide a pointer to the node.
Definition: node_set.cpp:219
The xml::node_set class is used to store xpath query result set.
Definition: node_set.hpp:68
iterator begin()
Get an iterator that points to the beginning of the xpath query result node set.
Definition: node_set.cpp:173
friend class iterator
Definition: node_set.hpp:401
bool empty() const
Inform if the xpath query result node set is empty.
Definition: node_set.cpp:160
size_t size() const
Get the number of nodes in the xpath query result node set.
Definition: node_set.cpp:167
virtual ~node_set()
Destroy the object and clean up the memory.
Definition: node_set.cpp:126
impl::nset_impl * pimpl_
Definition: node_set.hpp:398
friend class const_iterator
Definition: node_set.hpp:402
node_set & operator=(const node_set &other)
Creates a copy of the xml::node_set object.
Definition: node_set.cpp:132
iterator end()
Get an iterator that points one past the last node in the xpath query result node set.
Definition: node_set.cpp:185
node_set()
Create a new empty xml::node_set object.
Definition: node_set.cpp:106
The xml::node class is used to hold information about one XML node.
Definition: node.hpp:106
This file contains declarations required for iterators dereferencing support.
#define true
Definition: bool.h:35
static char tmp[3200]
Definition: utf8.c:42
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NULL
Definition: ncbistd.hpp:225
This file contains the definition of the xml::exception class.
node_private_data * attach_node_private_data(void *)
Definition: deref_impl.cpp:95
XML library namespace.
Definition: attributes.hpp:57
const char * kAdvError
Definition: node_set.cpp:104
const char * kDerefError
Definition: node_set.cpp:102
const char * kRefError
Definition: node_set.cpp:103
XPath execution result set for XmlWrapp.
This file contains the definition of the xml::impl::nset_impl class.
xmlXPathObjectPtr results_
nset_impl(void *results)
Definition: node_set.cpp:59
node & get_reference(int index)
Definition: node_set.cpp:78
void set_ownership(bool owe)
Definition: node_set.cpp:87
Modified on Sat May 18 11:41:45 2024 by modify_doxy.py rev. 669887