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