Base64Encoder
An encoder that uses the base64 scheme to encode data written to output streams. See the unit test suite for sample usage.
UnbufferedStreamBuf.h
A base interface for unbuffered I/O streams.
/* * UnufferedStreamBuf.h * * $Id: *poco/1.4/Foundation/include/Poco/UnbufferedStreamBuf.h#1 $ * * Library: Foundation * Package: Streams * Module: StreamBuf * * Definition of template BasicUnbufferedStreamBuf and class UnbufferedStreamBuf. * * Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. * and Contributors. * * Permission is hereby granted, free of charge, to any person or organization * obtaining a copy of the software and accompanying documentation covered by * this license (the "Software") to use, reproduce, display, distribute, * execute, and transmit the Software, and to prepare derivative works of the * Software, and to permit third-parties to whom the Software is furnished to * do so, all subject to the following: * * The copyright notices in the Software and this entire statement, including * the above license grant, this restriction and the following disclaimer, * must be included in all copies of the Software, in whole or in part, and * all derivative works of the Software, unless such copies or derivative * works are solely in the form of machine-executable object code generated by * a source language processor. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef SPT_UNBUFFEREDSTREAMBUF #define SPT_UNBUFFEREDSTREAMBUF #if defined( ARDUINO ) #include "../StandardCplusplus/streambuf" #include "../StandardCplusplus/iosfwd" #include "../StandardCplusplus/ios" #else #include <streambuf> #include <iosfwd> #include <ios> #endif namespace spt { /// This is an implementation of an unbuffered streambuf /// that greatly simplifies the implementation of /// custom streambufs of various kinds. /// Derived classes only have to override the methods /// readFromDevice() or writeToDevice(). template <typename ch, typename tr> class BasicUnbufferedStreamBuf: public std::basic_streambuf<ch, tr> { protected: typedef std::basic_streambuf<ch, tr> Base; typedef std::basic_ios<ch, tr> IOS; typedef ch char_type; typedef tr char_traits; typedef typename Base::int_type int_type; typedef typename Base::pos_type pos_type; typedef typename Base::off_type off_type; typedef typename IOS::openmode openmode; public: BasicUnbufferedStreamBuf() : pb( char_traits::eof() ), ispb( false ) { this->setg( 0, 0, 0 ); this->setp( 0, 0 ); } ~BasicUnbufferedStreamBuf() {} virtual int_type overflow( int_type c ) { if ( c != char_traits::eof() ) return writeToDevice( char_traits::to_char_type( c ) ); else return c; } virtual int_type underflow() { if ( ispb ) return pb; else { int_type c = readFromDevice(); if ( c != char_traits::eof() ) { ispb = true; pb = c; } return c; } } virtual int_type uflow() { if (ispb) { ispb = false; return pb; } else { int_type c = readFromDevice(); if ( c != char_traits::eof() ) pb = c; return c; } } virtual int_type pbackfail( int_type c ) { if ( ispb ) return char_traits::eof(); else { ispb = true; pb = c; return c; } } /// Some platforms (for example, Compaq C++) have buggy implementations of /// xsgetn that handle null buffers incorrectly. /// Anyway, it does not hurt to provide an optimized implementation /// of xsgetn for this streambuf implementation. virtual std::streamsize xsgetn( char_type* p, std::streamsize count ) { std::streamsize copied = 0; while ( count > 0 ) { int_type c = uflow(); if ( c == char_traits::eof() ) break; *p++ = char_traits::to_char_type(c); ++copied; --count; } return copied; } protected: static int_type charToInt( char_type c ) { return char_traits::to_int_type( c ); } private: virtual int_type readFromDevice() { return char_traits::eof(); } virtual int_type writeToDevice( char_type ) { return char_traits::eof(); } int_type pb; bool ispb; BasicUnbufferedStreamBuf( const BasicUnbufferedStreamBuf& ); BasicUnbufferedStreamBuf& operator = ( const BasicUnbufferedStreamBuf& ); }; // We provide an instantiation for char typedef BasicUnbufferedStreamBuf<char, std::char_traits<char> > UnbufferedStreamBuf; } // namespace spt #endif // SPT_UNBUFFEREDSTREAMBUF
Base64Encoder.h
Interfaces for the stream buffer, IO stream and encoder classes.
/* * Base64Encoder.h * * Definition of class Base64Encoder. * * Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. * and Contributors. * * Permission is hereby granted, free of charge, to any person or organization * obtaining a copy of the software and accompanying documentation covered by * this license (the "Software") to use, reproduce, display, distribute, * execute, and transmit the Software, and to prepare derivative works of the * Software, and to permit third-parties to whom the Software is furnished to * do so, all subject to the following: * * The copyright notices in the Software and this entire statement, including * the above license grant, this restriction and the following disclaimer, * must be included in all copies of the Software, in whole or in part, and * all derivative works of the Software, unless such copies or derivative * works are solely in the form of machine-executable object code generated by * a source language processor. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef SPT_BASE64ENCODER #define SPT_BASE64ENCODER #include "SPT.h" #include "UnbufferedStreamBuf.h" #include "UnbufferedStreamBuf.h" #if defined( ARDUINO ) #include "../StandardCplusplus/ostream" #else #include <ostream> #endif namespace spt { /// This streambuf base64-encodes all data written /// to it and forwards it to a connected /// ostream. /// /// Note: The characters are directly written /// to the ostream's streambuf, thus bypassing /// the ostream. The ostream's state is therefore /// not updated to match the buffer's state. class Base64EncoderBuf: public UnbufferedStreamBuf { public: Base64EncoderBuf(std::ostream& ostr); ~Base64EncoderBuf(); /// Closes the stream buffer. int close(); /// Specify the line length. /// /// After the given number of characters have been written, /// a newline character will be written. /// /// Specify 0 for an unlimited line length. void setLineLength( int32_t lineLength ); /// Returns the currently set line length. int32_t getLineLength() const; private: int_type writeToDevice( char c ); Byte group[3]; int32_t groupLength; int32_t pos; int32_t lineLength; std::streambuf& buf; static const Byte OUT_ENCODING[64]; friend class Base64DecoderBuf; Base64EncoderBuf( const Base64EncoderBuf& ); Base64EncoderBuf& operator = ( const Base64EncoderBuf& ); }; /// The base class for Base64Encoder. /// /// This class is needed to ensure the correct initialization /// order of the stream buffer and base classes. class Base64EncoderIOS: public virtual std::ios { public: Base64EncoderIOS( std::ostream& ostr ); ~Base64EncoderIOS(); int close(); Base64EncoderBuf* rdbuf(); protected: Base64EncoderBuf buf; private: Base64EncoderIOS( const Base64EncoderIOS& ); Base64EncoderIOS& operator = ( const Base64EncoderIOS& ); }; /// This ostream base64-encodes all data /// written to it and forwards it to /// a connected ostream. /// Always call close() when done /// writing data, to ensure proper /// completion of the encoding operation. /// /// Note: The characters are directly written /// to the ostream's streambuf, thus bypassing /// the ostream. The ostream's state is therefore /// not updated to match the buffer's state. class Base64Encoder: public Base64EncoderIOS, public std::ostream { public: Base64Encoder( std::ostream& ostr ); ~Base64Encoder(); private: Base64Encoder( const Base64Encoder& ); Base64Encoder& operator = ( const Base64Encoder& ); }; } // namespace spt #endif // SPT_BASE64ENCODER
Base64Encoder.cpp
Implementation of the base 64 stream encoder.
/* * Base64Encoder.cpp * * $Id: *poco/1.4/Foundation/src/Base64Encoder.cpp#2 $ * * Library: Foundation * Package: Streams * Module: Base64 * * Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. * and Contributors. * * Permission is hereby granted, free of charge, to any person or organization * obtaining a copy of the software and accompanying documentation covered by * this license (the "Software") to use, reproduce, display, distribute, * execute, and transmit the Software, and to prepare derivative works of the * Software, and to permit third-parties to whom the Software is furnished to * do so, all subject to the following: * * The copyright notices in the Software and this entire statement, including * the above license grant, this restriction and the following disclaimer, * must be included in all copies of the Software, in whole or in part, and * all derivative works of the Software, unless such copies or derivative * works are solely in the form of machine-executable object code generated by * a source language processor. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "Base64Encoder.h" using spt::Byte; using spt::Base64Encoder; using spt::Base64EncoderBuf; using spt::Base64EncoderIOS; const Byte Base64EncoderBuf::OUT_ENCODING[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; Base64EncoderBuf::Base64EncoderBuf(std::ostream& ostr) : groupLength(0), pos(0), lineLength(72), buf( *ostr.rdbuf() ) {} Base64EncoderBuf::~Base64EncoderBuf() { #if !defined( ARDUINO ) try { #endif close(); #if !defined( ARDUINO ) } catch (...) {} #endif } void Base64EncoderBuf::setLineLength( int32_t ll ) { lineLength = ll; } int32_t Base64EncoderBuf::getLineLength() const { return lineLength; } Base64EncoderBuf::int_type Base64EncoderBuf::writeToDevice( char c ) { static const int eof = std::char_traits<char>::eof(); group[groupLength++] = static_cast<Byte>( c ); if ( groupLength == 3 ) { Byte idx; idx = group[0] >> 2; if ( buf.sputc(OUT_ENCODING[idx]) == eof ) return eof; idx = ( ( group[0] & 0x03 ) << 4 ) | ( group[1] >> 4 ); if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; idx = ( ( group[1] & 0x0F ) << 2 ) | ( group[2] >> 6 ); if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; idx = group[2] & 0x3F; if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; pos += 4; if ( lineLength > 0 && pos >= lineLength ) { if ( buf.sputc( '\r' ) == eof ) return eof; if ( buf.sputc( '\n' ) == eof) return eof; pos = 0; } groupLength = 0; } return charToInt( c ); } int Base64EncoderBuf::close() { static const int eof = std::char_traits<char>::eof(); if ( sync() == eof ) return eof; if ( groupLength == 1 ) { group[1] = 0; Byte idx; idx = group[0] >> 2; if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; idx = ( ( group[0] & 0x03 ) << 4 ) | ( group[1] >> 4 ); if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; if ( buf.sputc( '=' ) == eof ) return eof; if ( buf.sputc( '=' ) == eof ) return eof; } else if ( groupLength == 2 ) { group[2] = 0; Byte idx; idx = group[0] >> 2; if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; idx = ( (group[0] & 0x03) << 4 ) | ( group[1] >> 4 ); if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; idx = ( ( group[1] & 0x0F ) << 2 ) | ( group[2] >> 6 ); if ( buf.sputc( OUT_ENCODING[idx] ) == eof ) return eof; if ( buf.sputc( '=' ) == eof ) return eof; } groupLength = 0; return buf.pubsync(); } Base64EncoderIOS::Base64EncoderIOS( std::ostream& ostr ): buf( ostr ) { init( &buf ); } Base64EncoderIOS::~Base64EncoderIOS() {} int Base64EncoderIOS::close() { return buf.close(); } Base64EncoderBuf* Base64EncoderIOS::rdbuf() { return &buf; } Base64Encoder::Base64Encoder( std::ostream& ostr ) : Base64EncoderIOS( ostr ), std::ostream( &buf ) {} Base64Encoder::~Base64Encoder() {}
Adapted for use on Arduino from Poco.