C++ equivalent of Java ByteBuffer?

不打扰是莪最后的温柔 提交于 2019-12-18 11:06:14

问题


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.

回答1:


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);
}



回答2:


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.




回答3:


std::vector<char> bytes;

bytes.push_back( some_val ); // put

char x = bytes[N];           // get

const char* ptr = &bytes[0]; // pointer to array



回答4:


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

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




回答5:


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);
}



回答6:


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.



来源:https://stackoverflow.com/questions/1466756/c-equivalent-of-java-bytebuffer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!