OpenLB 1.7
Loading...
Searching...
No Matches
base64.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2007 Jonas Latt
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24/* Acknowledgment: The strategy adopted here to encode
25 * and decode Base64, and in particular the expression of the
26 * arrays Base64Encoder::enc64 and Base64Decoder::dec64,
27 * is inspired by the open source library b64 by Bob Trower,
28 * which is distributed with a MIT license at the address
29 * http://base64.sourceforge.net/b64.c
30 */
31
32#ifndef BASE64_HH
33#define BASE64_HH
34
35#include "base64.h"
36#include "core/olbDebug.h"
37#include <ostream>
38#include <istream>
39
40
41namespace olb {
42
44
45template<typename T>
46const char Base64Encoder<T>::enc64[65]=
47 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
48 "abcdefghijklmnopqrstuvwxyz0123456789+/";
49
50template<typename T>
51Base64Encoder<T>::Base64Encoder(std::ostream& ostr_, size_t fullLength_)
52 : ostr(ostr_),
53 charFullLength(fullLength_ * sizeof(T)),
54 numWritten(0),
55 numOverflow(0)
56{ }
57
58template<typename T>
59void Base64Encoder<T>::encode(const T* data, size_t length)
60{
61 const unsigned char* charData = reinterpret_cast<const unsigned char*>(data);
62 size_t charLength = length * sizeof(T);
63 OLB_PRECONDITION( numWritten+charLength <= charFullLength );
64
65 size_t pos=0;
66 fillOverflow(charData, charLength, pos);
67 while (pos+3 <= charLength) {
68 encodeBlock(charData+pos);
69 pos += 3;
70 }
71 fillOverflow(charData, charLength, pos);
72 numWritten += charLength;
73 if (numWritten == charFullLength) {
74 flushOverflow();
75 }
76}
77
78template<typename T>
79void Base64Encoder<T>::fillOverflow(const unsigned char* charData, size_t charLength, size_t& pos)
80{
81 while (numOverflow < 3 && pos < charLength) {
82 overflow[numOverflow] = charData[pos];
83 ++numOverflow;
84 ++pos;
85 }
86 if (numOverflow == 3) {
87 encodeBlock(overflow);
88 numOverflow = 0;
89 }
90}
91
92template<typename T>
93void Base64Encoder<T>::flushOverflow()
94{
95 if (numOverflow > 0) {
96 for (int iOverflow = numOverflow; iOverflow<3; ++iOverflow) {
97 overflow[iOverflow] = 0;
98 }
99 encodeUnfinishedBlock(overflow, numOverflow);
100 numOverflow = 0;
101 }
102}
103
104template<typename T>
105void Base64Encoder<T>::encodeBlock( const unsigned char* data)
106{
107 ostr << enc64[ data[0] >> 2 ];
108 ostr << enc64[ ((data[0] & 0x03) << 4) | ((data[1] & 0xf0) >> 4) ];
109 ostr << (unsigned char) (enc64[ ((data[1] & 0x0f) << 2) | ((data[2] & 0xc0) >> 6) ]);
110 ostr << (unsigned char) (enc64[ data[2] & 0x3f ]);
111}
112
113template<typename T>
114void Base64Encoder<T>::encodeUnfinishedBlock( const unsigned char* data, int length )
115{
116 ostr << enc64[ data[0] >> 2 ];
117 ostr << enc64[ ((data[0] & 0x03) << 4) | ((data[1] & 0xf0) >> 4) ];
118 ostr << (unsigned char) (
119 length == 2 ?
120 enc64[ ((data[1] & 0x0f) << 2) | ((data[2] & 0xc0) >> 6) ] :
121 '='
122 );
123 ostr << (unsigned char) ( '=' );
124}
125
126
128
129template<typename T>
130const char Base64Decoder<T>::dec64[82]=
131 "|###}rstuvwxyz{#######>?@"\
132 "ABCDEFGHIJKLMNOPQRSTUVW######XYZ"\
133 "[\\]^_`abcdefghijklmnopq";
134
135
136template<typename T>
137Base64Decoder<T>::Base64Decoder(std::istream& istr_, size_t fullLength_)
138 : istr(istr_),
139 charFullLength(fullLength_ * sizeof(T)),
140 numRead(0),
141 posOverflow(3)
142{ }
143
144template<typename T>
145void Base64Decoder<T>::decode(T* data, size_t length)
146{
147 unsigned char* charData = reinterpret_cast<unsigned char*>(data);
148 size_t charLength = length * sizeof(T);
149 OLB_PRECONDITION( numRead+charLength <= charFullLength );
150
151 size_t pos = 0;
152 flushOverflow(charData, charLength, pos);
153 while (pos+3 <= charLength) {
154 decodeBlock(charData+pos);
155 pos += 3;
156 }
157 if (pos < charLength) {
158 decodeBlock(overflow);
159 posOverflow=0;
160 flushOverflow(charData, charLength, pos);
161 }
162 numRead += charLength;
163}
164
165template<typename T>
166void Base64Decoder<T>::flushOverflow(unsigned char* charData, size_t charLength, size_t& pos)
167{
168 while (posOverflow < 3 && pos < charLength) {
169 charData[pos] = overflow[posOverflow];
170 ++pos;
171 ++posOverflow;
172 }
173}
174
175template<typename T>
176unsigned char Base64Decoder<T>::getNext()
177{
178 unsigned char nextChar;
179 istr >> nextChar;
180 return (unsigned char) (dec64[nextChar - 43] - 62);
181}
182
183template<typename T>
184void Base64Decoder<T>::decodeBlock(unsigned char* data)
185{
186 unsigned char input[4];
187 input[0] = getNext();
188 input[1] = getNext();
189 input[2] = getNext();
190 input[3] = getNext();
191 data[0] = (unsigned char) (input[0] << 2 | input[1] >> 4);
192 data[1] = (unsigned char) (input[1] << 4 | input[2] >> 2);
193 data[2] = (unsigned char) (((input[2] << 6) & 0xc0) | input[3]);
194}
195
196} // namespace olb
197
198#endif
199
200
Base64Decoder(std::istream &istr_, size_t fullLength_)
Definition base64.hh:137
void decode(T *data, size_t length)
Definition base64.hh:145
Base64Encoder(std::ostream &ostr_, size_t fullLength_)
Definition base64.hh:51
void encode(const T *data, size_t length)
Definition base64.hh:59
Top level namespace for all of OpenLB.
#define OLB_PRECONDITION(COND)
Definition olbDebug.h:46