问题
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 within
byteDataand actual value of that
byteArrayin
byteData`.
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