简体   繁体   English

读取二进制的 UInt 类型

[英]Read UInt types in binary

I am implementing a MidiReader And it need me to read weather MSB First or LSB First UInts(8, 16, 32 or 64).我正在实现一个MidiReader ,它需要我读取天气 MSB First 或 LSB First UInts(8、16、32 或 64)。 I know little about binary and types so I'm currently copying other's code from C#.我对二进制和类型知之甚少,所以我目前正在从 C# 复制其他人的代码。

class ByteArrayReader
{
public:
    unsigned char* ByteArray;
    unsigned int Size;
    unsigned int Index = 0;

    ByteArrayReader(unsigned char* byteArray)
    {
        if (byteArray == NULL)
        {
            throw byteArray;
        }
        ByteArray = byteArray;
        Size = (unsigned int)sizeof(byteArray);
        Index = 0;
    }

    char inline Read()
    {
        return ByteArray[Index++];
    }

    void inline Forward(unsigned int length = 1)
    {
        Index += length;
    }

    void inline Backward(unsigned int length = 1)
    {
        if (length > Index)
        {
            throw length;
        }

        Index -= length;
    }

    bool operator==(ByteArrayReader) = delete;
};

These are what I copied:这些是我复制的:


    uint16_t inline ReadUInt16()
    {
        return (uint16_t)((Read() << 8) | Read());
    }

    uint32_t inline ReadUInt32()
    {
        return (uint32_t)((((((Read() << 8) | Read()) << 8) | Read()) << 8) | Read());
    }


But it's said that one of it reads MSB First UInt.但据说其中一个读取 MSB First UInt。 So I want to ask how to read UInt types from binaries elegantly, also learning how uint is represented in bytes.所以我想问一下如何优雅地从二进制文件中读取 UInt 类型,同时了解 uint 是如何以字节表示的。

The part那个部分

(uint32_t)((((((Read() << 8) | Read()) << 8) | Read()) << 8) | Read());

is undefined behavior because each call to Read method increments a counter called Index and there is no strict order of computation of them by compiler.是未定义的行为,因为每次调用Read方法都会增加一个名为Index的计数器,并且编译器没有严格的计算顺序。

It would be better if they were computed in order like this:如果按这样的顺序计算它们会更好:

auto chunk1 = Read(); // Index=x
auto chunk2 = Read(); // Index=x+1
auto chunk3 = Read(); // Index=x+2
...
auto result = chunk1 << 8 | chunk2<<8 ...

to be sure incrementations are happening in order.确保增量按顺序发生。

Order of bytes is different between little-endian and big-endian systems.小端和大端系统之间的字节顺序不同。 Here it is asked: Detecting endianness programmatically in a C++ program这里要求: 在 C++ 程序中以编程方式检测字节顺序

Try this:尝试这个:

uint32_t inline ReadUInt32MSBfirst()
{
    auto b1 = Read();
    auto b2 = Read();
    auto b3 = Read();
    auto b4 = Read();
    return (uint32_t)((b1 << 24) | (b2 << 16) | (b3 << 8) | b4);
}

uint32_t inline ReadUInt32LSBfirst()
{
    auto b1 = Read();
    auto b2 = Read();
    auto b3 = Read();
    auto b4 = Read();
    return (uint32_t)(b1 | (b2 << 8) | (b3 << 16) | (b4 << 24));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM