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
20namespace Poco {
21
22
23TextIterator::TextIterator():
24 _pEncoding(0)
25{
26}
27
28
29TextIterator::TextIterator(const std::string& str, const TextEncoding& encoding):
30 _pEncoding(&encoding),
31 _it(str.begin()),
32 _end(str.end())
33{
34}
35
36
37TextIterator::TextIterator(const std::string::const_iterator& begin, const std::string::const_iterator& rEnd, const TextEncoding& encoding):
38 _pEncoding(&encoding),
39 _it(begin),
40 _end(rEnd)
41{
42}
43
44
45TextIterator::TextIterator(const std::string& str):
46 _pEncoding(0),
47 _it(str.end()),
48 _end(str.end())
49{
50}
51
52
53TextIterator::TextIterator(const std::string::const_iterator& rEnd):
54 _pEncoding(0),
55 _it(rEnd),
56 _end(rEnd)
57{
58}
59
60
61TextIterator::~TextIterator()
62{
63}
64
65
66TextIterator::TextIterator(const TextIterator& it):
67 _pEncoding(it._pEncoding),
68 _it(it._it),
69 _end(it._end)
70{
71}
72
73
74TextIterator& 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
86void 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
94int 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
132TextIterator& 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
167TextIterator TextIterator::operator ++ (int)
168{
169 TextIterator prev(*this);
170 operator ++ ();
171 return prev;
172}
173
174
175} // namespace Poco
176