1//
2// Base64Encoder.cpp
3//
4// Library: Foundation
5// Package: Streams
6// Module: Base64
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/Base64Encoder.h"
16
17
18namespace Poco {
19
20
21const unsigned char Base64EncoderBuf::OUT_ENCODING[64] =
22{
23 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
24 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
25 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
26 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
27 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
28 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
29 'w', 'x', 'y', 'z', '0', '1', '2', '3',
30 '4', '5', '6', '7', '8', '9', '+', '/'
31};
32
33
34const unsigned char Base64EncoderBuf::OUT_ENCODING_URL[64] =
35{
36 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
37 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
38 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
39 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
40 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
41 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
42 'w', 'x', 'y', 'z', '0', '1', '2', '3',
43 '4', '5', '6', '7', '8', '9', '-', '_'
44};
45
46
47Base64EncoderBuf::Base64EncoderBuf(std::ostream& ostr, int options):
48 _options(options),
49 _groupLength(0),
50 _pos(0),
51 _lineLength((options & BASE64_URL_ENCODING) ? 0 : 72),
52 _buf(*ostr.rdbuf()),
53 _pOutEncoding((options & BASE64_URL_ENCODING) ? OUT_ENCODING_URL : OUT_ENCODING)
54{
55}
56
57
58Base64EncoderBuf::~Base64EncoderBuf()
59{
60 try
61 {
62 close();
63 }
64 catch (...)
65 {
66 }
67}
68
69
70void Base64EncoderBuf::setLineLength(int lineLength)
71{
72 _lineLength = lineLength;
73}
74
75
76int Base64EncoderBuf::getLineLength() const
77{
78 return _lineLength;
79}
80
81
82int Base64EncoderBuf::writeToDevice(char c)
83{
84 static const int eof = std::char_traits<char>::eof();
85
86 _group[_groupLength++] = (unsigned char) c;
87 if (_groupLength == 3)
88 {
89 unsigned char idx;
90 idx = _group[0] >> 2;
91 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
92 idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
93 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
94 idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6);
95 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
96 idx = _group[2] & 0x3F;
97 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
98 _pos += 4;
99 if (_lineLength > 0 && _pos >= _lineLength)
100 {
101 if (_buf.sputc('\r') == eof) return eof;
102 if (_buf.sputc('\n') == eof) return eof;
103 _pos = 0;
104 }
105 _groupLength = 0;
106 }
107 return charToInt(c);
108}
109
110
111int Base64EncoderBuf::close()
112{
113 static const int eof = std::char_traits<char>::eof();
114
115 if (sync() == eof) return eof;
116 if (_groupLength == 1)
117 {
118 _group[1] = 0;
119 unsigned char idx;
120 idx = _group[0] >> 2;
121 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
122 idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
123 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
124 if (!(_options & BASE64_NO_PADDING))
125 {
126 if (_buf.sputc('=') == eof) return eof;
127 if (_buf.sputc('=') == eof) return eof;
128 }
129 }
130 else if (_groupLength == 2)
131 {
132 _group[2] = 0;
133 unsigned char idx;
134 idx = _group[0] >> 2;
135 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
136 idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
137 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
138 idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6);
139 if (_buf.sputc(_pOutEncoding[idx]) == eof) return eof;
140 if (!(_options & BASE64_NO_PADDING))
141 {
142 if (_buf.sputc('=') == eof) return eof;
143 }
144 }
145 _groupLength = 0;
146 return _buf.pubsync();
147}
148
149
150Base64EncoderIOS::Base64EncoderIOS(std::ostream& ostr, int options): _buf(ostr, options)
151{
152 poco_ios_init(&_buf);
153}
154
155
156Base64EncoderIOS::~Base64EncoderIOS()
157{
158}
159
160
161int Base64EncoderIOS::close()
162{
163 return _buf.close();
164}
165
166
167Base64EncoderBuf* Base64EncoderIOS::rdbuf()
168{
169 return &_buf;
170}
171
172
173Base64Encoder::Base64Encoder(std::ostream& ostr, int options): Base64EncoderIOS(ostr, options), std::ostream(&_buf)
174{
175}
176
177
178Base64Encoder::~Base64Encoder()
179{
180}
181
182
183} // namespace Poco
184