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

扶醉桌前 提交于 2020-01-06 08:08:18

问题


I am tring to read couple of bytes from byteData as mentioned below in my C++ code. The actual value within byteData is a binary blob byte array in BIG-ENDIAN byte order format. So I cannot simply just "cast" the byte array into a String..

byteData byte array is composed of these three things -

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...

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 -

    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?

Update:-

After using this -

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

I started getting the value back properly for schemaId.

But now how to extract other things such as lastModifiedDate, length of actual byteArray withinbyteDataand actual value of thatbyteArrayinbyteData`.

I was using this for lastModifiedDate but it doesn't work somehow--

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

回答1:


32767 is 0x7fff. 65407 is 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. 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.

On a little endian machine, this macro or function swaps the two bytes that form a 16 bit integer. 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.



来源:https://stackoverflow.com/questions/19392004/how-to-extract-individual-fields-from-byte-array-which-is-in-big-endian-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!