AKIWEB
AKIWEB

Reputation: 19612

How to represent binary byte array data in C++?

I am trying to retrieve data from Cassandra using libCQL library in C++.... The table that I have created in Cassandra is like this -

create table test_cql (user_id text, column_name text, column_value blob, primary key (id, column_name));

And below is the data that is there in the above table -

cqlsh:testks> select column_name, column_value from test_cql where user_id = '1';

 column_name              | column_value
--------------------------+--------------------------------------------------------------------------------------------
 @hello.1381780131229.dc1 | 0x7fff0000012c4ebb95550000001e42797465204172726179205465737420466f722042696720456e6469616e

Here column_value is the actual blob value which is what I am trying to retrieve...

Now below is the C++ code I have which will try to retrieve the data from Cassandra for user_id = 1 in which I am trying to print out column_name and column_value details.

    bool flag = false;
    std::map<std::string, std::string> m;
    std::string key, value;

    string query = "select column_name, column_value from test_cql where user_id ='1';";
    std::cout << query << endl;

// the below line will execute the query
    cql_result_t& result = execute_query(query);

// this will print out the result after executing the above query

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

            if (!flag) {
                key = reinterpret_cast<char*>(data);
                flag = true;
            } else if (flag) {
                value = reinterpret_cast<char*>(data);
                m[key] = value;
                flag = false;
            }
        }

        cout<<key << "-" << value <<endl;

    }

The above code only prints out key as @hello.1381780131229.dc1 but not the value somehow.. It should be printing out value as 0x7fff0000012c4ebb95550000001e42797465204172726179205465737420466f722042696720456e6469616e since the value is the byte array (binary blob) in Cassandra table which is column_value.

And I have declared key and value both as string which might be the problem I guess in my above code.. But I believe value is actual blob in Cassandra table (column_value).. So I am not sure how to retrieve the binary blob (byte array) using the above C++ code?

And also this binary byte array blob value can be of any variable length and it is always stored in BIG-ENDIAN byte order format.

Coming from Java background, I am having little bit problem... Any help will be appreciated on this... As I guess, its totally C++ question like which datatype I should use to represent binary byte array..

Upvotes: 0

Views: 3567

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409166

Because the binary blob isn't a string, so you can't print it as a string. You have to manually print each byte in the "string".

If you wonder why, lets look at the three first bytes: 0x7f, 0xff and 0x00. Neither the first nor the second byte are printable, and the third byte is the string terminator so if you print it as a string the printing would stop there.

If you have C++11 you could do something like

std::cout << "Value = 0x";
for (const char& byte : value)
    std::cout << std::hex << static_cast<int>(byte);
std::cout << std::endl;

There is also a problem that you try to cast it as a string, which wont work (as described above). You can use std::string, but you have to use a constructor:

value = str::string(reinterpret_cast<char*>(data), size);

If the data is actually a structure, then you can use a structure for it:

struct employee
{
    uint16_t id;
    uint8_t lastModifiedDate[8];
    std::string value;
};

...

std::map<std::string, employee> m;

...

m[key].id = *reinterpret_cast<uint16_t*>(data);
std::copy(reinterpret_cast<uint8_t*>(data + 2),
          reinterpret_cast<uint8_t*>(data + 10),
          m[key].lastModifiedData);
m[key].value = std::string(reinterpret_cast<char*>(data + 10), size - 10);

Upvotes: 1

Related Questions