
Question:
how can i create an istream from a buffer unsigned char* or vector.
basically i want :
void Func(vector<unsigned char> data) { someSortOfIstream x (data); x >> something; }
using boost too....
Solution:1
I would recommend:
use a
std::string
(a fancy vector ofchar
s) instead of astd::vector<unsigned char>
, because that's what it's for. You can then use the readily availablestd::stringstream
in the<sstream>
header.-
You can subclass a
std::vector<unsigned char>
and overload theoperator>>()
for what you need it.OR
(harder but theoretically better) You can subclass
std::iostream
for your case and tell it what to do when you useoperator>>()
on it
Personnally I'd go with 1, and if you must, with 2a) because frankly, I'd have no idea how to subclass an iostream
.
Solution:2
This can be done using Boost.IOStreams:
#include <iosfwd> // streamsize #include <boost/iostreams/categories.hpp> // seekable_device_tag #include <boost/iostreams/positioning.hpp> // stream_offset template<typename Container> class container_device { public: typedef typename Container::value_type char_type; typedef boost::iostreams::seekable_device_tag category; container_device(Container& container) : container_(container), pos_(0) {} /// Read up to n characters from the underlying data source into the /// buffer s, returning the number of characters read; return -1 to /// indicate EOF std::streamsize read(char_type* s, std::streamsize n) { std::streamsize amt = static_cast<std::streamsize>(container_.size() - pos_); std::streamsize result = (std::min)(n, amt); if (result != 0) { std::copy(container_.begin() + pos_, container_.begin() + pos_ + result, s); pos_ += result; return result; } else { return -1; // EOF } } /// Write up to n characters to the underlying data sink into the /// buffer s, returning the number of characters written std::streamsize write(const char_type* s, std::streamsize n) { std::streamsize result = 0; if (pos_ != container_.size()) { std::streamsize amt = static_cast<std::streamsize>(container_.size() - pos_); std::streamsize result = (std::min)(n, amt); std::copy(s, s + result, container_.begin() + pos_); pos_ += result; } if (result < n) { container_.insert(container_.end(), s, s + n); pos_ = container_.size(); } return n; } /// Seek to position off and return the new stream position. The /// argument 'way' indicates how off is interpreted: /// - std::ios_base::beg indicates an offset from the sequence /// beginning /// - std::ios_base::cur indicates an offset from the current /// character position /// - std::ios_base::end indicates an offset from the sequence end boost::iostreams::stream_offset seek( boost::iostreams::stream_offset off, std::ios_base::seekdir way) { // Determine new value of pos_ boost::iostreams::stream_offset next; if (way == std::ios_base::beg) { next = off; } else if (way == std::ios_base::cur) { next = pos_ + off; } else if (way == std::ios_base::end) { next = container_.size() + off - 1; } // Check for errors if (next < ((boost::iostreams::stream_offset)0) || next >= ((boost::iostreams::stream_offset)container_.size())) throw std::ios_base::failure("bad seek offset"); pos_ = (size_type)next; return pos_; } Container& container() { return container_; } private: typedef typename Container::size_type size_type; Container& container_; size_type pos_; };
which can be used as:
std::vector<char> data; boost::iostreams::stream<container_device<std::vector<char> > > io(data);
and:
io << foo; io >> bar;
Solution:3
A non deprecated solution using Boost:
#include <boost/iostreams/stream.hpp> #include <boost/iostreams/device/array.hpp> using namespace boost::iostreams; basic_array_source<char> input_source(&my_vector[0], my_vector.size()); stream<basic_array_source<char> > input_stream(input_source);
or even simpler:
#include <boost/interprocess/streams/bufferstream.hpp> using namespace boost::interprocess; bufferstream input_stream(&my_vector[0], my_vector.size());
Solution:4
You could also take a look at std::stringstream.
Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
EmoticonEmoticon