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