diff options
author | Pierre Langlois <pierre.langlois@arm.com> | 2015-03-02 15:12:49 +0000 |
---|---|---|
committer | Pierre Langlois <pierre.langlois@arm.com> | 2016-03-04 17:42:20 +0000 |
commit | 6a2e6cf43c8ee587b19b9ca06a657a13e3b9c43e (patch) | |
tree | f0dbab923793a7ba2462ac1f894ca2970fef476d | |
parent | f73e43de9673821391d60d06b3d092f775b87f0c (diff) | |
download | kdbinder-6a2e6cf43c8ee587b19b9ca06a657a13e3b9c43e.tar.gz |
libkdbinder: kdbus: return a vector when dequeuing a message.
When dequeuing a message with either `dequeue_message` or `transact`, we
would only return a pointer and a size corresponding to one item
received. However, we could have received a message with several items
so it makes sense to return a vector in DataReply.
Change-Id: I9a845ab6f8387f14bdc141596e0fe6939e243055
-rw-r--r-- | include/kdbinder/kdbus/KDBinder.h | 18 | ||||
-rw-r--r-- | libs/kdbinder/kdbus/connection.cpp | 35 | ||||
-rw-r--r-- | libs/kdbinder/tests/kdbus/connection.cpp | 22 |
3 files changed, 43 insertions, 32 deletions
diff --git a/include/kdbinder/kdbus/KDBinder.h b/include/kdbinder/kdbus/KDBinder.h index 0902378..c024cc3 100644 --- a/include/kdbinder/kdbus/KDBinder.h +++ b/include/kdbinder/kdbus/KDBinder.h @@ -105,29 +105,33 @@ struct Reply { }; struct DataReply : Reply { + struct Data { + Data(const uint8_t *data, const uint64_t size) + : data(data), size(size) {} + const uint8_t *data; + const uint64_t size; + }; + + DataReply(const Reply& reply) : Reply(reply), - data(nullptr), - size(0), + data({}), offset(0), src_id(0), cookie(0) {} DataReply(const Reply& reply, - const uint8_t *data, - const uint64_t size, + const std::vector<Data> data, const uint64_t offset, const uint64_t src_id, const uint64_t cookie) : Reply(reply), data(data), - size(size), offset(offset), src_id(src_id), cookie(cookie) {} - const uint8_t *data; + const std::vector<Data> data; const uint64_t offset; - const uint64_t size; const uint64_t src_id; const uint64_t cookie; }; diff --git a/libs/kdbinder/kdbus/connection.cpp b/libs/kdbinder/kdbus/connection.cpp index 5560ecd..1210dd9 100644 --- a/libs/kdbinder/kdbus/connection.cpp +++ b/libs/kdbinder/kdbus/connection.cpp @@ -183,23 +183,20 @@ const DataReply Connection::dequeue_message() const { struct kdbus_msg *msg = reinterpret_cast<struct kdbus_msg *>( reinterpret_cast<uint8_t *>(buf_.get()) + reply.offset); struct kdbus_item *item = nullptr; - uint64_t size; - uint8_t *data; + std::vector<DataReply::Data> vecs; - // TODO: parse the rest of the items for extra information. - for_each_item(msg, [&data, this, &size](struct kdbus_item *item) { + for_each_item(msg, [&vecs, this](struct kdbus_item *item) { switch (item->type) { case KDBUS_ITEM_PAYLOAD_OFF: { - // This is potentially unsafe, as we are returning a pointer to the buffer - // owned by the connection. - size = item->vec.size; - data = reinterpret_cast<uint8_t *>(buf_.get()) + item->vec.offset; + uint8_t *data = reinterpret_cast<uint8_t *>(buf_.get()) + item->vec.offset; + + vecs.emplace_back(data, item->vec.size); break; } } }); - return DataReply(reply, data, size, reply.offset, msg->src_id, msg->cookie); + return DataReply(reply, vecs, reply.offset, msg->src_id, msg->cookie); } const DataReply Connection::dequeue_message_blocking(int timeout_ms) const { @@ -242,20 +239,22 @@ const DataReply Connection::transact(const MessageSync& message) const { struct kdbus_msg *msg = reinterpret_cast<struct kdbus_msg *>( reinterpret_cast<uint8_t *>(buf_.get()) + reply.offset); struct kdbus_item *item = nullptr; - uint8_t *data_out; - uint64_t size_out; + std::vector<DataReply::Data> vecs; // TODO: parse the rest of the items for extra information. - for_each_item(msg, [&data_out, this, &size_out](struct kdbus_item *item) { - if (item->type == KDBUS_ITEM_PAYLOAD_OFF) { - size_out = item->vec.size; - data_out = reinterpret_cast<uint8_t *>(buf_.get()) + item->vec.offset; + for_each_item(msg, [&vecs, address = buf_.get()](struct kdbus_item *item) { + switch (item->type) { + case KDBUS_ITEM_PAYLOAD_OFF: { + uint8_t *data = reinterpret_cast<uint8_t *>(address) + item->vec.offset; + + vecs.emplace_back(data, item->vec.size); + break; + } } }); return DataReply(reply, - data_out, - size_out, + vecs, reply.offset, msg->src_id, msg->cookie); @@ -314,7 +313,7 @@ const DataReply Connection::dequeue_death_notification() const { } }); - return DataReply(reply, nullptr, 0, reply.offset, src_id, 0); + return DataReply(reply, {}, reply.offset, src_id, 0); } const DataReply Connection::dequeue_death_notification_blocking(int timeout_ms) const { diff --git a/libs/kdbinder/tests/kdbus/connection.cpp b/libs/kdbinder/tests/kdbus/connection.cpp index af557f3..c78c9ac 100644 --- a/libs/kdbinder/tests/kdbus/connection.cpp +++ b/libs/kdbinder/tests/kdbus/connection.cpp @@ -180,9 +180,10 @@ TEST(Connection, dequeue_message_blocking) { auto reply = c2->dequeue_message_blocking(); ASSERT_TRUE(reply.error_code == 0); - ASSERT_TRUE(reply.size == sizeof(uint8_t)); + ASSERT_TRUE(reply.data.size() == 1); + auto first = reply.data.front(); - memcpy(&data_out, reply.data, reply.size); + memcpy(&data_out, first.data, first.size); ASSERT_TRUE(data_in == data_out); @@ -202,11 +203,14 @@ TEST(Connection, source_id) { auto reply = c2->dequeue_message_blocking(); ASSERT_TRUE(reply.error_code == 0); + ASSERT_TRUE(reply.data.size() == 1); ASSERT_TRUE(reply.src_id == c1->id); - ASSERT_TRUE(reply.size == sizeof(uint8_t)); + auto front = reply.data.front(); - memcpy(&data_out, reply.data, reply.size); + ASSERT_TRUE(front.size == sizeof(uint8_t)); + + memcpy(&data_out, front.data, front.size); ASSERT_TRUE(data_in == data_out); @@ -223,7 +227,8 @@ TEST(Connection, transact) { std::thread server([&c1, &c2]{ auto reply = c2->dequeue_message_blocking(); - MessageReply message(c1->id, c2->id, reply.cookie, ItemPayloadVec(reply.data, reply.size)); + auto front = reply.data.front(); + MessageReply message(c1->id, c2->id, reply.cookie, ItemPayloadVec(front.data, front.size)); c2->reply(message); c2->free(reply); @@ -239,9 +244,12 @@ TEST(Connection, transact) { auto reply = c1->transact(message); ASSERT_TRUE(reply.error_code == 0); - ASSERT_TRUE(reply.size == sizeof(uint8_t)); + ASSERT_TRUE(reply.data.size() == 1); + auto front = reply.data.front(); + + ASSERT_TRUE(front.size == sizeof(uint8_t)); - memcpy(&data_out, reply.data, reply.size); + memcpy(&data_out, front.data, front.size); ASSERT_TRUE(data_in == data_out); server.join(); |