Подтвердить что ты не робот

С++ эквивалент Java ByteBuffer?

Я ищу С++-эквивалент Java ByteBuffer.

Мне, вероятно, не хватает очевидного или просто нужно использовать изолированный пример использования, чтобы уточнить. Я просмотрел семейство iostream, и похоже, что это может послужить основой. В частности, я хочу иметь возможность:

  • создать буфер из байтового массива/точки и получить примитивы из буфера, например. getByte, getInt
  • создать буфер с использованием примитивов, например. putByte, putInt, а затем получить байтовый массив/указатель.
4b9b3361

Ответ 1

У вас есть stringbuf, filebuf или вы можете использовать vector<char>.


Это простой пример, используя 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

Спасибо @Pete Kirkham за идею общих функций.

#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 предоставляет основные неформатированные операции get и write для записи блоков символов. Специализировать на T любом подклассе или обернуть его или предоставить бесплатные постоянные функции шаблонов для использования памяти с соответствующим размером.

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

Вы можете написать такие шаблоны для любого другого потока или вектора, который вы хотите - в векторном случае ему нужно будет использовать вставку, а не запись.

Ответ 3

Я написал это некоторое время назад, чтобы сделать именно то, о чем вы просите. Сделайте снимок:

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

Ответ 4

std::vector<char> bytes;

bytes.push_back( some_val ); // put

char x = bytes[N];           // get

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

Ответ 5

Спасибо за все входные данные, это привело к этому довольно простому решению:


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

Чтобы использовать, например:


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

для std::vector более эффективным является метод

push_back(T) 

Вы можете найти больше здесь:

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

и вообще о cpp stl libs

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

Существует много контейнеров, зависит от того, что вам нужно,

  • агрегация скорости (возможность быстрой записи) или
  • быстрый просмотр

взгляните на std:: list, std::vector.