[MODERATOR: I tried to post this a week ago, but for some reason the word SPAM was prefixed to the subject line and so it didn't show up on the GMane server. I don't think many people actually saw it.] - - - - WHY I NEEDED THIS: I wanted to open a file using "ifstream", and then I wanted to read 32 bytes from the file and feed them directly into boost::algorithm::hex. Unfortunately I couldn't do this because 'hex' takes two iterators [begin,end), and there's no alternative function "hex_n". So I had to read the file into a string first, and then pass the string to 'hex'. - - - - THE IDEA I CAME UP WITH: Open the file using "ifstream", and then use a special iterator that will stop reading from the file after 32 bytes, with syntax like this: ifstream logfile("log.txt"); hex( istream_iterator_limited<char>(logfile,32), istream_iterator_limited<char>(), g_some_global_container.begin() ); - - - - SAMPLE CODE: #include <cstddef> /* size_t */ #include <iterator> /* istream_iterator */ template <typename T> class istream_iterator_limited : public std::istream_iterator<T> { protected: std::size_t const m_limit; std::size_t m_current_count; public: /* Shorter names */ typedef std::istream_iterator<T> Base; typedef istream_iterator_limited<T> This; istream_iterator_limited(typename Base::istream_type &obj_stream, size_t const arg_limit) : Base(obj_stream), m_limit(arg_limit), m_current_count (1) { /* The initialiser list above does all the construction work */ } istream_iterator_limited(void) /* This gives the End-Of-Stream iterator */ : Base() , m_limit(0), m_current_count(1) { /* The initialiser list above does all the construction work */ } This &operator++(void) { if ( m_limit <= m_current_count ) { Base::operator=( Base() ); /* Becomes End-Of- Stream iterator */ } else { ++m_current_count; Base::operator++(); } return *this; } }; #include <algorithm> /* copy */ #include <string> /* string */ #include <sstream> /* istringstream */ #include <iostream> /* cout, endl */ #include <iterator> /* back_inserter */ auto main(void) -> int { std::istringstream iss("123456789"); std::string str; /* Let's use copy to read 5 char's into our string */ std::copy( istream_iterator_limited<char>(iss,5), istream_iterator_limited<char>(), std::back_inserter(str) ); std::cout << str << std::endl; str.clear(); /* Get another 3 */ std::copy( istream_iterator_limited<char>(iss,3), istream_iterator_limited<char>(), std::back_inserter(str) ); std::cout << str << std::endl; }
Frederick Gotham wrote:
- - - - THE IDEA I CAME UP WITH:
Open the file using "ifstream", and then use a special iterator that will stop reading from the file after 32 bytes, with syntax like this:
ifstream logfile("log.txt");
hex( istream_iterator_limited<char>(logfile,32), istream_iterator_limited<char>(), g_some_global_container.begin() );
No takers on this? For the time being I have it in my own personal Boost stash and I use it from time to time when inputting from a file directly into a function like "hex".
participants (1)
-
Frederick Gotham