From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- src/io/base64.hh | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 src/io/base64.hh (limited to 'src/io/base64.hh') diff --git a/src/io/base64.hh b/src/io/base64.hh new file mode 100644 index 0000000..7091fe7 --- /dev/null +++ b/src/io/base64.hh @@ -0,0 +1,200 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2007 Jonas Latt + * E-mail contact: info@openlb.net + * The most recent release of OpenLB can be downloaded at + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +/* Acknowledgment: The strategy adopted here to encode + * and decode Base64, and in particular the expression of the + * arrays Base64Encoder::enc64 and Base64Decoder::dec64, + * is inspired by the open source library b64 by Bob Trower, + * which is distributed with a MIT license at the address + * http://base64.sourceforge.net/b64.c + */ + +#ifndef BASE64_HH +#define BASE64_HH + +#include "base64.h" +#include "core/olbDebug.h" +#include +#include + + +namespace olb { + +////////////// class Base64Encoder //////////////////////////////////////////// + +template +const char Base64Encoder::enc64[65]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + +template +Base64Encoder::Base64Encoder(std::ostream& ostr_, size_t fullLength_) + : ostr(ostr_), + charFullLength(fullLength_ * sizeof(T)), + numWritten(0), + numOverflow(0) +{ } + +template +void Base64Encoder::encode(const T* data, size_t length) +{ + const unsigned char* charData = reinterpret_cast(data); + size_t charLength = length * sizeof(T); + OLB_PRECONDITION( numWritten+charLength <= charFullLength ); + + size_t pos=0; + fillOverflow(charData, charLength, pos); + while (pos+3 <= charLength) { + encodeBlock(charData+pos); + pos += 3; + } + fillOverflow(charData, charLength, pos); + numWritten += charLength; + if (numWritten == charFullLength) { + flushOverflow(); + } +} + +template +void Base64Encoder::fillOverflow(const unsigned char* charData, size_t charLength, size_t& pos) +{ + while (numOverflow < 3 && pos < charLength) { + overflow[numOverflow] = charData[pos]; + ++numOverflow; + ++pos; + } + if (numOverflow == 3) { + encodeBlock(overflow); + numOverflow = 0; + } +} + +template +void Base64Encoder::flushOverflow() +{ + if (numOverflow > 0) { + for (int iOverflow = numOverflow; iOverflow<3; ++iOverflow) { + overflow[iOverflow] = 0; + } + encodeUnfinishedBlock(overflow, numOverflow); + numOverflow = 0; + } +} + +template +void Base64Encoder::encodeBlock( const unsigned char* data) +{ + ostr << enc64[ data[0] >> 2 ]; + ostr << enc64[ ((data[0] & 0x03) << 4) | ((data[1] & 0xf0) >> 4) ]; + ostr << (unsigned char) (enc64[ ((data[1] & 0x0f) << 2) | ((data[2] & 0xc0) >> 6) ]); + ostr << (unsigned char) (enc64[ data[2] & 0x3f ]); +} + +template +void Base64Encoder::encodeUnfinishedBlock( const unsigned char* data, int length ) +{ + ostr << enc64[ data[0] >> 2 ]; + ostr << enc64[ ((data[0] & 0x03) << 4) | ((data[1] & 0xf0) >> 4) ]; + ostr << (unsigned char) ( + length == 2 ? + enc64[ ((data[1] & 0x0f) << 2) | ((data[2] & 0xc0) >> 6) ] : + '=' + ); + ostr << (unsigned char) ( '=' ); +} + + +////////////// struct Base64Decoder //////////////////////////////////////////// + +template +const char Base64Decoder::dec64[82]= + "|###}rstuvwxyz{#######>?@"\ + "ABCDEFGHIJKLMNOPQRSTUVW######XYZ"\ + "[\\]^_`abcdefghijklmnopq"; + + +template +Base64Decoder::Base64Decoder(std::istream& istr_, size_t fullLength_) + : istr(istr_), + charFullLength(fullLength_ * sizeof(T)), + numRead(0), + posOverflow(3) +{ } + +template +void Base64Decoder::decode(T* data, size_t length) +{ + unsigned char* charData = reinterpret_cast(data); + size_t charLength = length * sizeof(T); + OLB_PRECONDITION( numRead+charLength <= charFullLength ); + + size_t pos = 0; + flushOverflow(charData, charLength, pos); + while (pos+3 <= charLength) { + decodeBlock(charData+pos); + pos += 3; + } + if (pos < charLength) { + decodeBlock(overflow); + posOverflow=0; + flushOverflow(charData, charLength, pos); + } + numRead += charLength; +} + +template +void Base64Decoder::flushOverflow(unsigned char* charData, size_t charLength, size_t& pos) +{ + while (posOverflow < 3 && pos < charLength) { + charData[pos] = overflow[posOverflow]; + ++pos; + ++posOverflow; + } +} + +template +unsigned char Base64Decoder::getNext() +{ + unsigned char nextChar; + istr >> nextChar; + return (unsigned char) (dec64[nextChar - 43] - 62); +} + +template +void Base64Decoder::decodeBlock(unsigned char* data) +{ + unsigned char input[4]; + input[0] = getNext(); + input[1] = getNext(); + input[2] = getNext(); + input[3] = getNext(); + data[0] = (unsigned char) (input[0] << 2 | input[1] >> 4); + data[1] = (unsigned char) (input[1] << 4 | input[2] >> 2); + data[2] = (unsigned char) (((input[2] << 6) & 0xc0) | input[3]); +} + +} // namespace olb + +#endif + + -- cgit v1.2.3