Re: boost base64->bin, bin->base64 (интересная фигня)
От: nen777w Украина  
Дата: 23.06.11 13:51
Оценка: 2 (1)
Короче кому будет нужно или интересно.
Публикую "правильные" итераторы для работы с:

boost::archive::iterators::base64_from_binary
boost::archive::iterators::binary_from_base64
boost::archive::iterators::transform_width

  "Файл base64.h"

#ifndef __base64_h__ #define __base64_h__ #include <cstddef> // NULL #include <istream> #include <boost/iterator/iterator_facade.hpp> namespace boost { namespace archive { namespace iterators { // given a type, make an input iterator based on a pointer to that type template<class Elem = char> class istream_iterator_bin_to_base64 : public boost::iterator_facade< istream_iterator_bin_to_base64<Elem>, Elem, std::input_iterator_tag, Elem > { friend class boost::iterator_core_access; typedef istream_iterator_bin_to_base64 this_t ; typedef BOOST_DEDUCED_TYPENAME boost::iterator_facade< istream_iterator_bin_to_base64<Elem>, Elem, std::input_iterator_tag, Elem > super_t; typedef BOOST_DEDUCED_TYPENAME std::basic_istream<Elem> istream_type; //Access the value referred to Elem dereference() const { return m_current_value; } bool equal(const this_t & rhs) const { // note: only works for comparison against end of stream return m_istream == rhs.m_istream; } void increment(){ if(NULL != m_istream){ m_current_value = static_cast<Elem>(m_istream->get()); if(! m_istream->good()){ const_cast<this_t *>(this)->m_istream = NULL; m_current_value = 0; } } } istream_type *m_istream; Elem m_current_value; public: istream_iterator_bin_to_base64(istream_type & is) : m_istream(& is) { increment(); } istream_iterator_bin_to_base64() : m_istream(NULL) {} istream_iterator_bin_to_base64(const istream_iterator_bin_to_base64<Elem> & rhs) : m_istream(rhs.m_istream), m_current_value(rhs.m_current_value) {} }; // given a type, make an input iterator based on a pointer to that type template<class Elem = char> class istream_iterator_base64_to_bin : public boost::iterator_facade< istream_iterator_base64_to_bin<Elem>, Elem, std::input_iterator_tag, Elem > { friend class boost::iterator_core_access; typedef istream_iterator_base64_to_bin this_t ; typedef BOOST_DEDUCED_TYPENAME boost::iterator_facade< istream_iterator_base64_to_bin<Elem>, Elem, std::input_iterator_tag, Elem > super_t; typedef BOOST_DEDUCED_TYPENAME std::basic_istream<Elem> istream_type; //Access the value referred to Elem dereference() const { return m_current_value; } bool equal(const this_t & rhs) const { // note: only works for comparison against end of stream return m_istream == rhs.m_istream; } void increment(){ if(NULL != m_istream){ m_current_value = static_cast<Elem>(m_istream->get()); if(! m_istream->good()){ const_cast<this_t *>(this)->m_istream = NULL; m_current_value = 65; } } } istream_type *m_istream; Elem m_current_value; public: istream_iterator_base64_to_bin(istream_type & is) : m_istream(& is) { increment(); } istream_iterator_base64_to_bin() : m_istream(NULL) {} istream_iterator_base64_to_bin(const istream_iterator_base64_to_bin<Elem> & rhs) : m_istream(rhs.m_istream), m_current_value(rhs.m_current_value) {} }; template<class InIt, class OutIt> inline void __CLRCALL_OR_CDECL copy_base64_to_bin(InIt First, InIt Last, OutIt Dest) { for (; First != Last; ++Dest, ++First) { typename InIt::value_type val = *First; if( First != Last ) *Dest = val; else break; } } } // namespace iterators } // namespace archive } // namespace boost #endif



И
  "пример использования"

#include "boost/archive/iterators/base64_from_binary.hpp" #include "boost/archive/iterators/binary_from_base64.hpp" #include "boost/archive/iterators/transform_width.hpp" #include "base64.h" //typedefs typedef boost::archive::iterators::istream_iterator_bin_to_base64<char> my_istream_iterator_bin_to_base64; typedef boost::archive::iterators::istream_iterator_base64_to_bin<char> my_istream_iterator_base64_to_bin; typedef boost::archive::iterators::ostream_iterator<char> my_ostream_iterator; typedef boost::archive::iterators::base64_from_binary< boost::archive::iterators::transform_width<my_istream_iterator_bin_to_base64, 6, 8> > bin_to_base64; typedef boost::archive::iterators::transform_width< boost::archive::iterators::binary_from_base64< my_istream_iterator_base64_to_bin >, 8, 6 > base64_to_bin; void test() { { std::ifstream ifs("test.zip", std::ios_base::in|std::ios_base::binary); std::ofstream ofs("test.arc", std::ios_base::out|std::ios_base::binary); std::copy( bin_to_base64( my_istream_iterator_bin_to_base64(ifs >> std::noskipws) ), bin_to_base64( my_istream_iterator_bin_to_base64() ), my_ostream_iterator(ofs) ); } { std::ifstream ifs("test.arc", std::ios_base::in|std::ios_base::binary); std::ofstream ofs("test.rez", std::ios_base::out|std::ios_base::binary); boost::archive::iterators::copy_base64_to_bin( base64_to_bin( my_istream_iterator_base64_to_bin(ifs >> std::noskipws) ), base64_to_bin( my_istream_iterator_base64_to_bin() ), my_ostream_iterator(ofs) ); } }



Почему это было сделано и для чего есть в этом топике.
Теги: 
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.