web-dev-qa-db-ja.com

Java ByteBuffer?

Java ByteBufferのC++「同等」」を探しています。

私はおそらく明白なものを見逃しているか、明確にするために分離された使用例が必要です。私はiostreamファミリーを調べましたが、それが基礎を提供しているようです。具体的には、次のことができるようにしたいと思います。

  • バイト配列/ポイントからバッファを構築し、バッファからプリミティブを取得します。 getByte、getInt
  • プリミティブを使用してバッファを構築します。 putByte、putInt、そしてバイト配列/ポインタを取得します。
22
user172783

stringbuffilebufがあるか、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

ジェネリック関数のアイデアを提供してくれた@PeteKirkhamに感謝します。

#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);
}
15
AraK

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

このようなテンプレートは、他の任意のストリームまたはベクター用に作成できます。ベクターの場合、書き込みではなく挿入を使用する必要があります。

8
Pete Kirkham
std::vector<char> bytes;

bytes.Push_back( some_val ); // put

char x = bytes[N];           // get

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

私はあなたが求めていることを正確に行うためにしばらく前にこれを書きました。試してみます:

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

4
Ramsey

すべての入力に感謝します、それはこの非常に単純な解決策につながりました:


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

std :: vectorの場合、より効率的なのはメソッドです

Push_back(T) 

あなたはここでもっと見つけることができます:

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

およびcppstllibsについての一般

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

多くのコンテナがあります、あなたがそれを何のために必要とするかに依存します、

  • 速度集約(高速書き込み機能)または
  • 高速読み取り

std :: list、std :: vectorを見てください。

1
bua