1 #ifndef BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP 2 #define BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP 3 4 // MS compatible compilers support #pragma once 5 #if defined(_MSC_VER) 6 # pragma once 7 #endif 8 9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 10 // binary_from_base64.hpp 11 12 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 13 // Use, modification and distribution is subject to the Boost Software 14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 15 // http://www.boost.org/LICENSE_1_0.txt) 16 17 // See http://www.boost.org for updates, documentation, and revision history. 18 19 #include <boost/assert.hpp> 20 21 #include <boost/serialization/throw_exception.hpp> 22 #include <boost/static_assert.hpp> 23 24 #include <boost/iterator/transform_iterator.hpp> 25 #include <boost/archive/iterators/dataflow_exception.hpp> 26 27 namespace boost { 28 namespace archive { 29 namespace iterators { 30 31 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 32 // convert base64 characters to binary data 33 34 namespace detail { 35 36 template<class CharType> 37 struct to_6_bit { 38 typedef CharType result_type; operator ()boost::archive::iterators::detail::to_6_bit39 CharType operator()(CharType t) const{ 40 static const signed char lookup_table[] = { 41 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 42 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 43 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, 44 52,53,54,55,56,57,58,59,60,61,-1,-1,-1, 0,-1,-1, // render '=' as 0 45 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 46 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, 47 -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 48 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 49 }; 50 // metrowerks trips this assertion - how come? 51 #if ! defined(__MWERKS__) 52 BOOST_STATIC_ASSERT(128 == sizeof(lookup_table)); 53 #endif 54 signed char value = -1; 55 if((unsigned)t <= 127) 56 value = lookup_table[(unsigned)t]; 57 if(-1 == value) 58 boost::serialization::throw_exception( 59 dataflow_exception(dataflow_exception::invalid_base64_character) 60 ); 61 return value; 62 } 63 }; 64 65 } // namespace detail 66 67 // note: what we would like to do is 68 // template<class Base, class CharType = typename Base::value_type> 69 // typedef transform_iterator< 70 // from_6_bit<CharType>, 71 // transform_width<Base, 6, sizeof(Base::value_type) * 8, CharType> 72 // > base64_from_binary; 73 // but C++ won't accept this. Rather than using a "type generator" and 74 // using a different syntax, make a derivation which should be equivalent. 75 // 76 // Another issue addressed here is that the transform_iterator doesn't have 77 // a templated constructor. This makes it incompatible with the dataflow 78 // ideal. This is also addressed here. 79 80 template< 81 class Base, 82 class CharType = typename boost::iterator_value<Base>::type 83 > 84 class binary_from_base64 : public 85 transform_iterator< 86 detail::to_6_bit<CharType>, 87 Base 88 > 89 { 90 friend class boost::iterator_core_access; 91 typedef transform_iterator< 92 detail::to_6_bit<CharType>, 93 Base 94 > super_t; 95 public: 96 // make composible buy using templated constructor 97 template<class T> binary_from_base64(T start)98 binary_from_base64(T start) : 99 super_t( 100 Base(static_cast< T >(start)), 101 detail::to_6_bit<CharType>() 102 ) 103 {} 104 // intel 7.1 doesn't like default copy constructor binary_from_base64(const binary_from_base64 & rhs)105 binary_from_base64(const binary_from_base64 & rhs) : 106 super_t( 107 Base(rhs.base_reference()), 108 detail::to_6_bit<CharType>() 109 ) 110 {} 111 // binary_from_base64(){}; 112 }; 113 114 } // namespace iterators 115 } // namespace archive 116 } // namespace boost 117 118 #endif // BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP 119