Короче кому будет нужно или интересно.
Публикую "правильные" итераторы для работы с:
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)
);
}
}
|
| |
Почему это было сделано и для чего есть в этом топике.