1 | // |
---|---|
2 | // RowIterator.cpp |
3 | // |
4 | // Library: Data |
5 | // Package: DataCore |
6 | // Module: RowIterator |
7 | // |
8 | // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/Data/RowIterator.h" |
16 | #include "Poco/Data/RecordSet.h" |
17 | #undef min |
18 | #undef max |
19 | #include <limits> |
20 | |
21 | |
22 | namespace Poco { |
23 | namespace Data { |
24 | |
25 | |
26 | const std::size_t RowIterator::POSITION_END = std::numeric_limits<std::size_t>::max(); |
27 | |
28 | |
29 | RowIterator::RowIterator(RecordSet* pRecordSet, bool positionEnd): |
30 | _pRecordSet(pRecordSet), |
31 | _position(positionEnd ? POSITION_END : 0) |
32 | { |
33 | } |
34 | |
35 | |
36 | RowIterator::RowIterator(const RowIterator& other): |
37 | _pRecordSet(other._pRecordSet), |
38 | _position(other._position) |
39 | { |
40 | } |
41 | |
42 | |
43 | RowIterator::~RowIterator() |
44 | { |
45 | } |
46 | |
47 | |
48 | RowIterator& RowIterator::operator = (const RowIterator& other) |
49 | { |
50 | RowIterator tmp(other); |
51 | swap(tmp); |
52 | return *this; |
53 | } |
54 | |
55 | |
56 | void RowIterator::swap(RowIterator& other) |
57 | { |
58 | using std::swap; |
59 | |
60 | swap(_pRecordSet, other._pRecordSet); |
61 | swap(_position, other._position); |
62 | } |
63 | |
64 | |
65 | void RowIterator::increment() const |
66 | { |
67 | if (POSITION_END == _position) |
68 | throw RangeException("End of iterator reached."); |
69 | |
70 | if (_position < _pRecordSet->storageRowCount() - 1) |
71 | ++_position; |
72 | else |
73 | _position = POSITION_END; |
74 | |
75 | if (_pRecordSet->getFilter() && POSITION_END != _position) |
76 | { |
77 | while (!_pRecordSet->isAllowed(_position)) |
78 | { |
79 | increment(); |
80 | if (POSITION_END == _position) break; |
81 | } |
82 | } |
83 | } |
84 | |
85 | |
86 | void RowIterator::decrement() const |
87 | { |
88 | if (0 == _position) |
89 | throw RangeException("Beginning of iterator reached."); |
90 | else if (POSITION_END == _position) |
91 | _position = _pRecordSet->storageRowCount() - 1; |
92 | else |
93 | --_position; |
94 | |
95 | if (_pRecordSet->getFilter() && 0 != _position) |
96 | { |
97 | while (!_pRecordSet->isAllowed(_position)) |
98 | { |
99 | decrement(); |
100 | if (0 == _position) break; |
101 | } |
102 | } |
103 | } |
104 | |
105 | |
106 | void RowIterator::setPosition(std::size_t pos) const |
107 | { |
108 | if (_position == pos) return; |
109 | |
110 | if (_pRecordSet->getFilter()) |
111 | { |
112 | std::size_t start = _position; |
113 | if (_position > pos) |
114 | { |
115 | std::size_t end = _position - pos; |
116 | for (; start > end; --start) |
117 | { |
118 | if (pos) --pos; |
119 | else throw RangeException("Invalid position argument."); |
120 | } |
121 | } |
122 | else |
123 | { |
124 | std::size_t end = pos - _position; |
125 | for (; start < end; ++start) |
126 | { |
127 | if (_pRecordSet->storageRowCount() != pos) ++pos; |
128 | else throw RangeException("Invalid position argument."); |
129 | } |
130 | } |
131 | } |
132 | |
133 | if (pos < _pRecordSet->storageRowCount()) |
134 | _position = pos; |
135 | else if (pos == _pRecordSet->storageRowCount()) |
136 | _position = POSITION_END; |
137 | else |
138 | throw RangeException("Invalid position argument."); |
139 | } |
140 | |
141 | |
142 | Row& RowIterator::operator * () const |
143 | { |
144 | if (POSITION_END == _position) |
145 | throw InvalidAccessException("End of iterator reached."); |
146 | |
147 | return _pRecordSet->row(_position); |
148 | } |
149 | |
150 | |
151 | Row* RowIterator::operator -> () const |
152 | { |
153 | if (POSITION_END == _position) |
154 | throw InvalidAccessException("End of iterator reached."); |
155 | |
156 | return &_pRecordSet->row(_position); |
157 | } |
158 | |
159 | |
160 | const RowIterator& RowIterator::operator ++ () const |
161 | { |
162 | increment(); |
163 | return *this; |
164 | } |
165 | |
166 | |
167 | RowIterator RowIterator::operator ++ (int) const |
168 | { |
169 | RowIterator old(*this); |
170 | increment(); |
171 | return old; |
172 | } |
173 | |
174 | |
175 | const RowIterator& RowIterator::operator -- () const |
176 | { |
177 | decrement(); |
178 | return *this; |
179 | } |
180 | |
181 | |
182 | RowIterator RowIterator::operator -- (int) const |
183 | { |
184 | RowIterator old(*this); |
185 | decrement(); |
186 | return old; |
187 | } |
188 | |
189 | |
190 | RowIterator RowIterator::operator + (std::size_t diff) const |
191 | { |
192 | RowIterator ri(*this); |
193 | ri.setPosition(_position + diff); |
194 | return ri; |
195 | } |
196 | |
197 | |
198 | RowIterator RowIterator::operator - (std::size_t diff) const |
199 | { |
200 | if (diff > _position) throw RangeException("Invalid position argument."); |
201 | RowIterator ri(*this); |
202 | ri.setPosition(_position - diff); |
203 | return ri; |
204 | } |
205 | |
206 | |
207 | } } // namespace Poco::Data |
208 |