herzl shemuelian
herzl shemuelian

Reputation: 3508

How do I copy binary data to a stringstream

I have a std::vector<int> and I want serialize it. For this purpose I am trying to use a std::stringstream

 vector<int> v;
 v.resize(10);
 for (int i=0;i<10;i++)
 v[i]=i;


 stringstream ss (stringstream::in | stringstream::out |stringstream::binary);

However when I copy the vector to the stringstream this copy it as character

ostream_iterator<int> it(ss);
copy(v.begin(),v.end(),it);

the value that inserted to buffer(_Strbuf) is "123456789"

I sucssesed to write a workaround solution

for (int i=1;i<10;i++)
   ss.write((char*)&p[i],sizeof(int));

I want to do it something like first way by using std function like copy

thanks Herzl

Upvotes: 11

Views: 10678

Answers (4)

Nim
Nim

Reputation: 33645

Like Fred, I don't see the point of this, what you are effectively trying to do is:

ss.rdbuf()->sputn(reinterpret_cast<char*>(&v[0]), sizeof(int) * v.size());

Upvotes: 1

Stas
Stas

Reputation: 11761

Actually, this is your workaround but it may be used with std::copy() algorithm.

   template<class T>
   struct serialize
   {
      serialize(const T & i_value) : value(i_value) {}
      T value;
   };

   template<class T>
   ostream& operator <<(ostream &os, const serialize<T> & obj)
   {
      os.write((char*)&obj.value,sizeof(T));
      return os;
   }

Usage

ostream_iterator<serialize<int> > it(ss);
copy(v.begin(),v.end(),it);

Upvotes: 10

Fred Nurk
Fred Nurk

Reputation: 14212

To use std::copy with ostream::write, you'd need to write your own output iterator that knows how to correctly serialize the type. That said, I'm not sure what you expect to gain from this approach, but here's a first pass at that for an example:

struct ostream_write_int
  : std::iterator<std::output_iterator_tag, int, void, void, void>
{
  std::ostream *s;
  ostream_write_int(std::ostream &s) : s (&s) {}

  ostream_write_int& operator++() { return *this; }
  ostream_write_int& operator++(int) { return *this; }
  ostream_write_int& operator*() { return *this; }

  void operator=(int x) {
    s->write(reinterpret_cast<char*>(&x), sizeof(x));
  }
};

This could be templated only if you defer the serialization logic to some other function (as the formatted stream iterators do to operator<<).

Upvotes: 1

Martin
Martin

Reputation: 1028

I know this is not an answer to your problem, but if you are not limited to the STL you could try (boost serialization) or google protocol buffers

Boost even has build-in support for de-/serializing STL containers (http://www.boost.org/doc/libs/1_45_0/libs/serialization/doc/tutorial.html#stl)

Upvotes: 2

Related Questions