1//
2// TextConverter.cpp
3//
4// Library: Foundation
5// Package: Text
6// Module: TextConverter
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/TextConverter.h"
16#include "Poco/TextIterator.h"
17#include "Poco/TextEncoding.h"
18
19
20namespace {
21 int nullTransform(int ch)
22 {
23 return ch;
24 }
25}
26
27
28namespace Poco {
29
30
31TextConverter::TextConverter(const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar):
32 _inEncoding(inEncoding),
33 _outEncoding(outEncoding),
34 _defaultChar(defaultChar)
35{
36}
37
38
39TextConverter::~TextConverter()
40{
41}
42
43
44int TextConverter::convert(const std::string& source, std::string& destination, Transform trans)
45{
46 int errors = 0;
47 TextIterator it(source, _inEncoding);
48 TextIterator end(source);
49 unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH];
50
51 while (it != end)
52 {
53 int c = *it;
54 if (c == -1) { ++errors; c = _defaultChar; }
55 c = trans(c);
56 int n = _outEncoding.convert(c, buffer, sizeof(buffer));
57 if (n == 0) n = _outEncoding.convert(_defaultChar, buffer, sizeof(buffer));
58 poco_assert (n <= sizeof(buffer));
59 destination.append((const char*) buffer, n);
60 ++it;
61 }
62 return errors;
63}
64
65
66int TextConverter::convert(const void* source, int length, std::string& destination, Transform trans)
67{
68 poco_check_ptr (source);
69
70 int errors = 0;
71 const unsigned char* it = (const unsigned char*) source;
72 const unsigned char* end = (const unsigned char*) source + length;
73 unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH];
74
75 while (it < end)
76 {
77 int n = _inEncoding.queryConvert(it, 1);
78 int uc;
79 int read = 1;
80
81 while (-1 > n && (end - it) >= -n)
82 {
83 read = -n;
84 n = _inEncoding.queryConvert(it, read);
85 }
86
87 if (-1 > n)
88 {
89 it = end;
90 }
91 else
92 {
93 it += read;
94 }
95
96 if (-1 >= n)
97 {
98 uc = _defaultChar;
99 ++errors;
100 }
101 else
102 {
103 uc = n;
104 }
105
106 uc = trans(uc);
107 n = _outEncoding.convert(uc, buffer, sizeof(buffer));
108 if (n == 0) n = _outEncoding.convert(_defaultChar, buffer, sizeof(buffer));
109 poco_assert (n <= sizeof(buffer));
110 destination.append((const char*) buffer, n);
111 }
112 return errors;
113}
114
115
116int TextConverter::convert(const std::string& source, std::string& destination)
117{
118 return convert(source, destination, nullTransform);
119}
120
121
122int TextConverter::convert(const void* source, int length, std::string& destination)
123{
124 return convert(source, length, destination, nullTransform);
125}
126
127
128} // namespace Poco
129