1//
2// UTFString.h
3//
4// Library: Foundation
5// Package: Text
6// Module: UTFString
7//
8// Definitions of strings for UTF encodings.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_UTFString_INCLUDED
18#define Foundation_UTFString_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/Types.h"
23#include <string>
24
25
26namespace Poco {
27
28
29struct UTF16CharTraits
30{
31 typedef std::fpos<std::mbstate_t> u16streampos;
32 typedef UInt16 char_type;
33 typedef int int_type;
34 typedef std::streamoff off_type;
35 typedef u16streampos pos_type;
36 typedef std::mbstate_t state_type;
37
38 static void assign(char_type& c1, const char_type& c2)
39 {
40 c1 = c2;
41 }
42
43 static bool eq(char_type c1, char_type c2)
44 {
45 return c1 == c2;
46 }
47
48 static bool lt(char_type c1, char_type c2)
49 {
50 return c1 < c2;
51 }
52
53 static int compare(const char_type* s1, const char_type* s2, size_t n)
54 {
55 for (; n; --n, ++s1, ++s2)
56 {
57 if (lt(*s1, *s2))
58 return -1;
59 if (lt(*s2, *s1))
60 return 1;
61 }
62 return 0;
63 }
64
65 static size_t length(const char_type* s)
66 {
67 size_t len = 0;
68 for (; !eq(*s, char_type(0)); ++s)
69 ++len;
70 return len;
71 }
72
73 static const char_type* find(const char_type* s, size_t n, const char_type& a)
74 {
75 for (; n; --n)
76 {
77 if (eq(*s, a))
78 return s;
79 ++s;
80 }
81 return 0;
82 }
83
84 static char_type* move(char_type* s1, const char_type* s2, size_t n)
85 {
86 char_type* r = s1;
87 if (s1 < s2)
88 {
89 for (; n; --n, ++s1, ++s2)
90 assign(*s1, *s2);
91 }
92 else if (s2 < s1)
93 {
94 s1 += n;
95 s2 += n;
96 for (; n; --n)
97 assign(*--s1, *--s2);
98 }
99 return r;
100 }
101
102 static char_type* copy(char_type* s1, const char_type* s2, size_t n)
103 {
104 poco_assert(s2 < s1 || s2 >= s1 + n);
105 char_type* r = s1;
106 for (; n; --n, ++s1, ++s2)
107 assign(*s1, *s2);
108 return r;
109 }
110
111 static char_type* assign(char_type* s, size_t n, char_type a)
112 {
113 char_type* r = s;
114 for (; n; --n, ++s)
115 assign(*s, a);
116 return r;
117 }
118
119 static int_type not_eof(int_type c)
120 {
121 return eq_int_type(c, eof()) ? ~eof() : c;
122 }
123
124 static char_type to_char_type(int_type c)
125 {
126 return char_type(c);
127 }
128
129 static int_type to_int_type(char_type c)
130 {
131 return int_type(c);
132 }
133
134 static bool eq_int_type(int_type c1, int_type c2)
135 {
136 return c1 == c2;
137 }
138
139 static int_type eof()
140 {
141 return int_type(0xDFFF);
142 }
143};
144
145
146struct UTF32CharTraits
147{
148 typedef std::fpos<std::mbstate_t> u32streampos;
149 typedef UInt32 char_type;
150 typedef int int_type;
151 typedef std::streamoff off_type;
152 typedef u32streampos pos_type;
153 typedef std::mbstate_t state_type;
154
155 static void assign(char_type& c1, const char_type& c2)
156 {
157 c1 = c2;
158 }
159
160 static bool eq(char_type c1, char_type c2)
161 {
162 return c1 == c2;
163 }
164
165 static bool lt(char_type c1, char_type c2)
166 {
167 return c1 < c2;
168 }
169
170 static int compare(const char_type* s1, const char_type* s2, size_t n)
171 {
172 for (; n; --n, ++s1, ++s2)
173 {
174 if (lt(*s1, *s2))
175 return -1;
176 if (lt(*s2, *s1))
177 return 1;
178 }
179 return 0;
180 }
181
182 static size_t length(const char_type* s)
183 {
184 size_t len = 0;
185 for (; !eq(*s, char_type(0)); ++s)
186 ++len;
187 return len;
188 }
189
190 static const char_type* find(const char_type* s, size_t n, const char_type& a)
191 {
192 for (; n; --n)
193 {
194 if (eq(*s, a))
195 return s;
196 ++s;
197 }
198 return 0;
199 }
200
201 static char_type* move(char_type* s1, const char_type* s2, size_t n)
202 {
203 char_type* r = s1;
204 if (s1 < s2)
205 {
206 for (; n; --n, ++s1, ++s2)
207 assign(*s1, *s2);
208 }
209 else if (s2 < s1)
210 {
211 s1 += n;
212 s2 += n;
213 for (; n; --n)
214 assign(*--s1, *--s2);
215 }
216 return r;
217 }
218
219 static char_type* copy(char_type* s1, const char_type* s2, size_t n)
220 {
221 poco_assert(s2 < s1 || s2 >= s1 + n);
222 char_type* r = s1;
223 for (; n; --n, ++s1, ++s2)
224 assign(*s1, *s2);
225 return r;
226 }
227
228 static char_type* assign(char_type* s, size_t n, char_type a)
229 {
230 char_type* r = s;
231 for (; n; --n, ++s)
232 assign(*s, a);
233 return r;
234 }
235
236 static int_type not_eof(int_type c)
237 {
238 return eq_int_type(c, eof()) ? ~eof() : c;
239 }
240
241 static char_type to_char_type(int_type c)
242 {
243 return char_type(c);
244 }
245
246 static int_type to_int_type(char_type c)
247 {
248 return int_type(c);
249 }
250
251 static bool eq_int_type(int_type c1, int_type c2)
252 {
253 return c1 == c2;
254 }
255
256 static int_type eof()
257 {
258 return int_type(0xDFFF);
259 }
260};
261
262
263#if defined(POCO_OS_FAMILY_WINDOWS)
264typedef wchar_t UTF16Char;
265typedef std::wstring UTF16String;
266#else
267typedef char16_t UTF16Char;
268typedef std::u16string UTF16String;
269#endif // POCO_OS_FAMILY_WINDOWS
270typedef char32_t UTF32Char;
271typedef std::u32string UTF32String;
272
273
274} // namespace Poco
275
276
277#endif // Foundation_UTFString_INCLUDED
278