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