Re: boost base64->bin, bin->base64 (интересная фигня)
От: nen777w 
Дата: 23.06.11 12: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...
Пока на собственное сообщение не было ответов, его можно удалить.