C++ equivalent of Java ByteBuffer?

2020-02-19 03:04发布

I'm looking for a C++ "equivalent" of Java ByteBuffer.

I'm probably missing the obvious or just need an isolated usage example to clarify. I've looked through the iostream family & it looks like it may provide a basis. Specifically, I want to be able to:

  • build a buffer from a byte array/point and get primitives from the buffer, e.g. getByte, getInt
  • build a buffer using primitives e.g. putByte, putInt and then get the byte array/pointer.

6条回答
甜甜的少女心
2楼-- · 2020-02-19 03:33
std::vector<char> bytes;

bytes.push_back( some_val ); // put

char x = bytes[N];           // get

const char* ptr = &bytes[0]; // pointer to array
查看更多
爷、活的狠高调
3楼-- · 2020-02-19 03:33

I wrote this awhile back to do exactly what you're asking for. Give it a shot:

https://code.google.com/p/bytebuffer-cpp/

查看更多
混吃等死
4楼-- · 2020-02-19 03:44

stringstream provides basic unformatted get and write operations to write blocks of chars. To specialise on T either subclass or wrap it, or provide free standing template functions to use the get/write appropriately sized memory.

template <typename T>
std::stringstream& put ( std::stringstream& str, const T& value )
{
    union coercion { T value; char   data[ sizeof ( T ) ]; };

    coercion    c;

    c.value = value;

    str.write ( c.data, sizeof ( T ) );

    return str;
}

template <typename T>
std::stringstream& get ( std::stringstream& str, T& value )
{
    union coercion { T value; char   data[ sizeof ( T ) ]; };

    coercion    c;

    c.value = value;

    str.read ( c.data, sizeof ( T ) );

    value = c.value;

    return str;
}

You could write such templates for whatever other stream or vector you want - in the vector's case, it would need to use insert rather than write.

查看更多
\"骚年 ilove
5楼-- · 2020-02-19 03:53

Thanks for all the input, it has lead to this pretty simple solution:


class ByteBuffer : std::stringbuf
{
public:
    template 
    size_t get( T &out)
    {
        union coercion { T value; char data[ sizeof ( T ) ]; };

        coercion c;

        size_t s= xsgetn( c.data, sizeof(T));

        out= c.value;

        return s;
    }

    template 
    size_t put( T &in)
    {   
        union coercion { T value; char data[ sizeof ( T ) ]; };

        coercion c;

        c.value= in;

        return xsputn( c.data, sizeof(T));
    }

    size_t get( uint8_t *out, size_t count)
    {
        return xsgetn((char *)out, count);
    }

    size_t put( uint8_t *out, size_t count)
    {
        return xsputn((char *)out, count);
    }
};

To use eg:


void ByteBufferTest( void)
{
    ByteBuffer bb;

    float f= 4;
    uint8_t u8= 1;
    uint16_t u16= 2;
    uint32_t u32= 4;
    uint64_t u64= 8;

    bb.put(f);
    bb.put(u8);
    bb.put(u16);
    bb.put(u32);
    bb.put(u64);

    uint8_t array[19];

    bb.get( array, 19);

    // or

    bb.get(f);
    bb.get(u8);
    bb.get(u16);
    bb.get(u32);
    bb.get(u64);
}
查看更多
▲ chillily
6楼-- · 2020-02-19 03:55

for std::vector more efficient is method

push_back(T) 

You can find more here:

http://www.cppreference.com/wiki/stl/vector/start

and general about cpp stl libs

http://www.cppreference.com/wiki/stl/start

There are many containers, depends what do You need it for,

  • speed aggregation (fast writing capabilities) or
  • fast read

take a look at std::list, std::vector.

查看更多
霸刀☆藐视天下
7楼-- · 2020-02-19 03:56

You have stringbuf, filebuf or you could use vector<char>.


This is a simple example using stringbuf:

std::stringbuf buf;
char data[] = {0, 1, 2, 3, 4, 5};
char tempbuf[sizeof data];

buf.sputn(data, sizeof data); // put data
buf.sgetn(tempbuf, sizeof data); // get data

Thanks @Pete Kirkham for the idea of generic functions.

#include <sstream>

template <class Type>
std::stringbuf& put(std::stringbuf& buf, const Type& var)
{
    buf.sputn(reinterpret_cast<const char*>(&var), sizeof var);

    return buf;
}

template <class Type>
std::stringbuf& get(std::stringbuf& buf, Type& var)
{
    buf.sgetn(reinterpret_cast<char*>(&var), sizeof(var));

    return buf;
}

int main()
{
    std::stringbuf mybuf;
    char byte = 0;
    int var;

    put(mybuf, byte++);
    put(mybuf, byte++);
    put(mybuf, byte++);
    put(mybuf, byte++);

    get(mybuf, var);
}
查看更多
登录 后发表回答