1 //
2 // TextIterator.cpp
3 //
4 // Library: Foundation
5 // Package: Text
6 // Module: TextIterator
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/TextIterator.h"
16 #include "Poco/TextEncoding.h"
17 #include <algorithm>
18
19
20 namespace Poco {
21
22
TextIterator()23 TextIterator::TextIterator():
24 _pEncoding(0)
25 {
26 }
27
28
TextIterator(const std::string & str,const TextEncoding & encoding)29 TextIterator::TextIterator(const std::string& str, const TextEncoding& encoding):
30 _pEncoding(&encoding),
31 _it(str.begin()),
32 _end(str.end())
33 {
34 }
35
36
TextIterator(const std::string::const_iterator & begin,const std::string::const_iterator & end,const TextEncoding & encoding)37 TextIterator::TextIterator(const std::string::const_iterator& begin, const std::string::const_iterator& end, const TextEncoding& encoding):
38 _pEncoding(&encoding),
39 _it(begin),
40 _end(end)
41 {
42 }
43
44
TextIterator(const std::string & str)45 TextIterator::TextIterator(const std::string& str):
46 _pEncoding(0),
47 _it(str.end()),
48 _end(str.end())
49 {
50 }
51
52
TextIterator(const std::string::const_iterator & end)53 TextIterator::TextIterator(const std::string::const_iterator& end):
54 _pEncoding(0),
55 _it(end),
56 _end(end)
57 {
58 }
59
60
~TextIterator()61 TextIterator::~TextIterator()
62 {
63 }
64
65
TextIterator(const TextIterator & it)66 TextIterator::TextIterator(const TextIterator& it):
67 _pEncoding(it._pEncoding),
68 _it(it._it),
69 _end(it._end)
70 {
71 }
72
73
operator =(const TextIterator & it)74 TextIterator& TextIterator::operator = (const TextIterator& it)
75 {
76 if (&it != this)
77 {
78 _pEncoding = it._pEncoding;
79 _it = it._it;
80 _end = it._end;
81 }
82 return *this;
83 }
84
85
swap(TextIterator & it)86 void TextIterator::swap(TextIterator& it)
87 {
88 std::swap(_pEncoding, it._pEncoding);
89 std::swap(_it, it._it);
90 std::swap(_end, it._end);
91 }
92
93
operator *() const94 int TextIterator::operator * () const
95 {
96 poco_check_ptr (_pEncoding);
97 poco_assert (_it != _end);
98 std::string::const_iterator it = _it;
99
100 unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH];
101 unsigned char* p = buffer;
102
103 if (it != _end)
104 *p++ = *it++;
105 else
106 *p++ = 0;
107
108 int read = 1;
109 int n = _pEncoding->queryConvert(buffer, 1);
110
111 while (-1 > n && (_end - it) >= -n - read)
112 {
113 while (read < -n && it != _end)
114 {
115 *p++ = *it++;
116 read++;
117 }
118 n = _pEncoding->queryConvert(buffer, read);
119 }
120
121 if (-1 > n)
122 {
123 return -1;
124 }
125 else
126 {
127 return n;
128 }
129 }
130
131
operator ++()132 TextIterator& TextIterator::operator ++ ()
133 {
134 poco_check_ptr (_pEncoding);
135 poco_assert (_it != _end);
136
137 unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH];
138 unsigned char* p = buffer;
139
140 if (_it != _end)
141 *p++ = *_it++;
142 else
143 *p++ = 0;
144
145 int read = 1;
146 int n = _pEncoding->sequenceLength(buffer, 1);
147
148 while (-1 > n && (_end - _it) >= -n - read)
149 {
150 while (read < -n && _it != _end)
151 {
152 *p++ = *_it++;
153 read++;
154 }
155 n = _pEncoding->sequenceLength(buffer, read);
156 }
157 while (read < n && _it != _end)
158 {
159 _it++;
160 read++;
161 }
162
163 return *this;
164 }
165
166
operator ++(int)167 TextIterator TextIterator::operator ++ (int)
168 {
169 TextIterator prev(*this);
170 operator ++ ();
171 return prev;
172 }
173
174
175 } // namespace Poco
176