如何从C ++中的字节数组(在BIG-ENDIAN中)中提取单个字段

时间:2013-10-15 22:12:36

标签: c++ bytearray bytebuffer endianness

我想从byteData中读取几个字节,如下面C ++代码中所述。 byteData内的实际值是BIG-ENDIAN字节顺序格式的二进制blob字节数组。所以我不能简单地将字节数组“转换”为String ..

byteData字节数组由这三件事组成 -

First is `schemaId` which is of two bytes (short datatype in Java)
Second is `lastModifiedDate` which is of eight bytes (long datatype in Java)
Third is the length of actual `byteArray` within `byteData` which we need from `byteData`.
Fourth is the actual value of that `byteArray` in `byteData`.

现在我试图从C ++中的byteData中提取上述特定信息...不知怎的,我能够提取schemaId,但是即将到来的值是错误的。我不是确定如何从中提取其他东西......

uint16_t schemaId;
uint64_t lastModifiedDate;
uint16_t attributeLength;
const char* actual_binary_value;

while (result.next()) {
    for (size_t i = 0; i < result.column_count(); ++i) {
        cql::cql_byte_t* byteData = NULL;
        cql::cql_int_t size = 0;
        result.get_data(i, &byteData, size);

        if (!flag) {

            // I cannot just "cast" the byte array into a String
            // value = reinterpret_cast<char*>(byteData);

            // now how to retrieve schemaId, lastModifiedDate and actual_binary_value from byteData?

            schemaId = *reinterpret_cast<uint16_t*>(byteData);

            flag = false;
        }
    }

// this prints out 65407 somehow but it should be printing out 32767
    cout<< schemaId <<endl;
}

如果有人需要查看我的java代码,那么这是我的java代码 -

    byte[] avroBinaryValue = text.getBytes();

    long lastModifiedDate = 1289811105109L;
    short schemaId = 32767;

    int size = 2 + 8 + 4 + avroBinaryValue.length; // short is 2 bytes, long 8 and int 4

    ByteBuffer bbuf = ByteBuffer.allocate(size); 
    bbuf.order(ByteOrder.BIG_ENDIAN);

    bbuf.putShort(schemaId);
    bbuf.putLong(lastModifiedDate);
    bbuf.putInt(avroBinaryValue.length);
    bbuf.put(avroBinaryValue);

    // merge everything into one bytearray.
    byte[] bytesToStore = bbuf.array();

            Hex.encodeHexString(bytesToStore)

任何人都可以帮助我在C ++代码中做错了什么,以及为什么我也无法从它和其他领域正确提取schemaId?

更新: -

使用后 -

schemaId = ntohs(*reinterpret_cast<uint16_t*>(data));

我开始正确地为schemaId获取值。

但现在如何提取其他内容,例如lastModifiedDate,实际byteArray within byteData and actual value of that byteArray in byteData`的长度。

我在lastModifiedDate使用它,但它不能以某种方式工作 -

std::copy(reinterpret_cast<uint8_t*>(byteData + 2), reinterpret_cast<uint8_t*>(byteData + 10), lastModifiedDate);

1 个答案:

答案 0 :(得分:2)

32767是0x7fff。 65407是0xff7f。请注意,交换高阶和低阶字节。您需要交换这些字节以将数字恢复为原始值。幸运的是,有一个名为ntohs的宏或函数(主机短路网络)可以完全满足您的需求。这是宏还是函数,以及定义的头,取决于您的系统。但是,无论是使用Windows,Linux,Sun还是Mac,宏/函数的名称始终为ntohs

在小端机器上,此宏或函数交换形成16位整数的两个字节。在大端机器上,这个宏/函数什么都不做(这正是所需的)。请注意,现在大多数家用电脑都是小端。