我正在寻找一个与Java ByteBuffer“等价”的C++工具。
我可能忽略了一些明显的东西,或者只需要一个独立的用例来澄清。我已经查看了iostream系列,并且看起来它可能提供了一个基础。具体来说,我想要能够:
- 从字节数组/指针构建缓冲区并从缓冲区获取原语,例如getByte、getInt
- 使用基元构建缓冲区,例如putByte、putInt,然后获取字节数组/指针。
我正在寻找一个与Java ByteBuffer“等价”的C++工具。
我可能忽略了一些明显的东西,或者只需要一个独立的用例来澄清。我已经查看了iostream系列,并且看起来它可能提供了一个基础。具体来说,我想要能够:
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);
}
ByteBuffer
允许从字节缓冲区中提取其他原始类型,而不仅仅是字节。http://java.sun.com/j2se/1.4.2/docs/api/java/nio/ByteBuffer.html - Rob Kennedystringstream
提供基本的未格式化的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;
}
std::vector<char> bytes;
bytes.push_back( some_val ); // put
char x = bytes[N]; // get
const char* ptr = &bytes[0]; // pointer to array
感谢所有的意见,这些意见带来了一个非常简单的解决方案:
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 ∈)
{
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);
}
对于 std::vector 来说,更高效的方法是
push_back(T)
您可以在这里找到更多信息:
http://www.cppreference.com/wiki/stl/vector/start
关于C++ STL库的一般内容
http://www.cppreference.com/wiki/stl/start
有许多容器,取决于您需要它做什么,
看一下std::list、std::vector。
get(T)
е’Ңput(T)
дёӯпјҢT
дёҚжҳҜbyte
пјҢиҖҢжҳҜе…¶д»–еҺҹе§Ӣзұ»еһӢпјҢжҜ”еҰӮint
гҖҒfloat
е’Ңshort
гҖӮ - Rob Kennedy