Reputation: 19622
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
and the value which I am getting is also correct.. Now I am not sure how to extract other things from it...
uint16_t schemaId;
uint64_t lastModifiedDate;
uint16_t attributeLength; // or it should be uint32_t?
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);
// I cannot just "cast" the byte array into a String
// value = reinterpret_cast<char*>(byteData);
// this works fine
schemaId = ntohs(*reinterpret_cast<uint16_t*>(byteData));
// now how to retrieve lastModifiedDate, length of binary value and actual_binary_value from byteData?
// the below doesn't works..
lastModifiedDate = be64toh(*reinterpret_cast<uint64_t*>(data));
// And how to extract other things as well?
}
// this prints out `9223090561897746107` but it should print out `1289811105109`
cout<< lastModifiedDate <<endl;
// And print out other things..
}
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 lastModifiedDate
properly from it and other fields as well? As I understand lastModifiedDate
is 64 bit integer, so is there any way to swap out 64 bit integer here? Or some other better way to do the conversion?
In short, I am trying to extract schemaId
, lastModifiedDate
, avroBinaryValue.length
and avroBinaryValue
from that byte array in C++..
I am able to extract schemaId
but I am stuck on other things now...
Upvotes: 0
Views: 1601
Reputation: 3511
Your method looks fine, there are just two possible issues I see.
Your code as shown is simply casting an undefined variable data
as a uint64_t
. Make sure that you are actually advancing through the data buffer and converting the correct data.
Platform dependency. From what I've seen, the 64-bit byte swapping functions (be64toh, betoh64, ntohll, etc), are not universally supported on all platforms. You may need to use a different function on your platform, and/or automatically detect what works if you want the code to be platform independent. See similar questions here and here, for example.
As to how to get the data, something like this should work:
int index=0;
schemaId = ntohs(*reinterpret_cast<uint16_t*>(&byteData[index]));
index += 2;
lastModifiedDate = be64toh(*reinterpret_cast<uint64_t*>(&byteData[index]));
index += 8;
attributeLength = ntohl(*reinterpret_cast<uint32_t*>(&byteData[index]));
index += 4;
actual_binary_data = (const char *)&byteData[index];
Upvotes: 1