简体   繁体   English

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

[英]How to extract individual fields from byte array (which is in BIG-ENDIAN) in C++

I am tring to read couple of bytes from byteData as mentioned below in my C++ code. 我特林读取几个字节byteData在我的C ++代码如下所述。 The actual value within byteData is a binary blob byte array in BIG-ENDIAN byte order format. byteData的实际值是BIG-ENDIAN字节顺序格式的二进制blob字节数组。 So I cannot simply just "cast" the byte array into a String.. 所以我不能简单地将字节数组“转换”为字符串..

byteData byte array is composed of these three things - 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`.

Now I am trying to extract the above particular information from the byteData in C++... Somehow I am able to extract schemaId but the value which is coming is wrong.. And I am not sure how to extract other things from it... 现在我试图从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;
}

If somebody needs to see my java code then this is my java code - 如果有人需要查看我的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)

Can anybody help me what wrong I am doing in my C++ code and why I am not able to extract schemaId properly from it and other fields as well? 任何人都可以帮助我在我的C ++代码中做错了什么以及为什么我无法从它和其他领域正确提取schemaId?

Update:- 更新: -

After using this - 用完之后 -

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

I started getting the value back properly for schemaId. 我开始正确地为schemaId获取值。

But now how to extract other things such as lastModifiedDate , length of actual byteArray within byteData and actual value of that byteArray in byteData`. 但现在如何提取其他的东西,如lastModifiedDate ,实际的长度byteArray within byteData and actual value of that的ByteArray in byteData`。

I was using this for lastModifiedDate but it doesn't work somehow-- 我正在将它用于lastModifiedDate但它不能以某种方式工作 -

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

32767 is 0x7fff. 32767是0x7fff。 65407 is 0xff7f. 65407是0xff7f。 Note that the high order and low order bytes are swapped. 请注意,交换高阶和低阶字节。 You need to swap those bytes to restore the number to the original value. 您需要交换这些字节以将数字恢复为原始值。 Fortunately, there is a macro or function called ntohs (network to host short) that does exactly what you want. 幸运的是,有一个名为ntohs (网络到主机短路)的宏或函数可以完全满足您的需求。 Whether this is a macro or function, and in which header it is defined, depends on your system. 这是宏还是函数,以及定义的头,取决于您的系统。 But the name of the macro/function is always ntohs , whether one is using Windows, Linux, Sun, or a Mac. 但是,无论是使用Windows,Linux,Sun还是Mac,宏/函数的名称总是ntohs

On a little endian machine, this macro or function swaps the two bytes that form a 16 bit integer. 在小端机器上,此宏或函数交换形成16位整数的两个字节。 On a big endian machine, this macro/function does nothing (which is exactly what is wanted). 在大端机器上,这个宏/函数什么都不做(这正是所需的)。 Note that most home computers nowadays are little endian. 请注意,现在大多数家用电脑都是小端。

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

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