rev
rev

Reputation: 1861

Dynamic (type) binary buffer in C++?

Currently, I'm using std::vector<char> like this:

char data, data2, data3;

vec.push_back(data);
vec.push_back(data2);
vec.push_back(data3);

However, since I'm storing binary data, sometimes I need to push data of different sizes (i.e. not a single char), and I need to manually split that data into single bytes, which is not convenient or readable.

Something like this would be perfect:

buffer.push<int>(some_int); // some_int = 0xAABBCCDD
buffer.push<char>(some_char); // some_char = 0xFF
buffer.push("arbitrary_data", arbitrary_length);

The resulting memory would be:

AA BB CC DD FF ...........
// ^ int
//          ^ char

Is there any standard way of doing it, or I need libraries / own implementation?

Upvotes: 0

Views: 366

Answers (3)

3442
3442

Reputation: 8576

What about this? It works even for non-POD types! (Note: C++11 code!)

#include <new>
#include <vector>
#include <utility>

class BinaryVector : public std::vector<unsigned char> {
    public:
        template<typename T>
        void push(const T &what) {
            this->resize(this->size() + sizeof(T));
            new(this->data() + this->size() - sizeof(T)) T(what);
        }

        template<typename T>
        void push(T &&what) {
            this->resize(this->size() + sizeof(T));
            new((T*)(this->data() + this->size() - sizeof(T))) T(XValue(what));
        }

        template<typename T>
        T pop() {
            T tmp(std::move(*(T*)(this->data() + this->size() - sizeof(T))));
            ((T*)(this->data() + this->size() - sizeof(T)))->~T();
            this->resize(this->size - sizeof(T));

            return tmp;
        }
};

Upvotes: 0

MSalters
MSalters

Reputation: 179819

What you're looking for is called serialization, and it's not part of the ISO standard. Boost does have a library for it, though.

Upvotes: 1

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42899

You could use pointer arithmetic in combine with reinterpret_cast like the example bellow:

std::vector<char> v;
v.push_back('a');
v.push_back('b');
int a = 20;
v.insert(v.end(), reinterpret_cast<char*>(&a), reinterpret_cast<char*>(&a) + sizeof(a));

or if you have a class/struct:

struct foo {int a = 1 , b = 2, c = 3;};

std::vector<char> v;
foo b;
v.insert(v.end(), reinterpret_cast<char*>(&b), reinterpret_cast<char*>(&b) + sizeof(b));

Upvotes: 0

Related Questions