我正在写一个Buffer类,它只是在C++中保存字节。它有各种类型的常用读写方法; 16位,32位和64位整数,浮点数和双精度数。我主要用它来进行内存加载/处理和文件I/O,可能以后也会用到一些网络用途。
与完全依赖于主机的字节序不同,该类有一个内置的字节序开关,因此所有的读和写方法都将以所需的顺序将给定值的底层字节读/写到它们的目的地。
我的问题是,我是否应该考虑运行这个程序的机器的字节顺序,同时也观察缓冲区的所选字节顺序模式?
范例:
void Buffer::WriteInt32(int _int)
{
bvec bytes;
for (int i = 0; i < SIZE_INT32; i++)
{
bytes.push_back
(
_int >> (m_Endianness == Endian::BIG ? ((SIZE_INT32 * 8) - ((i + 1) * 8)) : i * 8)
);
}
m_Bytes.insert(std::end(m_Bytes), std::begin(bytes), std::end(bytes));
m_Length += SIZE_INT32;
}
字符串
这个例子的方法是有效的,并根据用户的喜好以大或小的字节顺序写入。然而,我有一个潜在的怀疑,我应该检查运行此代码的机器的字节顺序,如果系统的字节顺序和缓冲区的设置匹配,我应该直接写入字节而不改变.这是我应该做的吗?由于我实际上没有在另一台机器上进行测试的选项,所以我对这种情况可能会如何发展感到困惑。
同样,对于阅读:
bool Buffer::ReadInt32(int& dest, bool useOffset, size_t offset)
{
int val = 0;
size_t index = useOffset ? offset : m_ReadOffset;
if (ReadableRemaining(index) < SIZE_INT32)
return false;
for (auto i = 0; i < SIZE_INT32; i++)
{
val <<= 8;
val |= m_Bytes[m_Endianness == Endian::BIG ? F_VAL(index, i) : R_VAL(index, i, SIZE_INT32)];
}
dest = val;
m_LastReadSize = SIZE_INT32;
if (!useOffset)
AdvanceReadOffset();
return true;
}
型
这段代码将从4个字节中检索到的值存储到给定的整数目标中;观察字节的顺序基于缓冲区的字节顺序设置。同样,所有工作都很好,但是运行这段代码的机器是否可以反转val的输出?我是否需要在这里添加代码以根据主机交换内容?
1条答案
按热度按时间ugmeyewa1#
我想了想,也回答了自己的问题,只是当时有一种模糊的感觉,让我看不清楚:)
鉴于:
1.大、小端机器根据它们指定的布局将它们的值存储在内存中;
1.我的缓冲区类只按照给定的顺序存储原始字节,供以后在内存和其他地方使用;
1.该类的用户可以单独选择写入缓冲区/从缓冲区读取的每个值的字节序,而不考虑机器的字节序;
显然,在确定每个操作的给定字节范围是否需要反转顺序之前,我需要观察机器的字节顺序。如果机器顺序与所需的操作顺序匹配,则不进行反转;否则,进行反转。
我也考虑了你的一些建议: