我正在编写一个 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 的输出吗?我需要在这里添加代码来根据主机交换内容吗?
经过一段时间的思考,我已经回答了我自己的问题。我当时只是有一种迷茫的感觉,无法看清事情:)
鉴于:
在确定每个操作的给定字节范围是否需要反转顺序之前,我显然需要观察机器的字节顺序。如果机器指令与期望的操作指令相符,则不进行反转;否则,就是这样。
我也考虑了您的一些建议: