From c079d8d6d9048763ce2daab04f7d9474711775c8 Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Sun, 12 Jul 2015 18:17:25 +0200 Subject: [PATCH] Implement BMediaRoster::GetNodeAttributesFor --- headers/private/media/ServerInterface.h | 10 +++++++ src/kits/media/MediaNode.cpp | 39 ++++++++++++++++++++++++- src/kits/media/MediaRoster.cpp | 37 +++++++++++++++++++++-- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/headers/private/media/ServerInterface.h b/headers/private/media/ServerInterface.h index 6c126dbc9f..116de33d82 100644 --- a/headers/private/media/ServerInterface.h +++ b/headers/private/media/ServerInterface.h @@ -93,6 +93,7 @@ enum { NODE_SYNC_TO, NODE_SET_TIMESOURCE, NODE_GET_TIMESOURCE, + NODE_GET_ATTRIBUTES_FOR, NODE_REQUEST_COMPLETED, NODE_FINAL_RELEASE, NODE_MESSAGE_END, @@ -946,6 +947,15 @@ struct node_get_timesource_reply : reply_data { media_node_id timesource_id; }; +struct node_get_attributes_for_request : request_data { + size_t count; + area_id area; +}; + +struct node_get_attributes_for_reply : reply_data { + size_t filled_count; +}; + struct node_final_release_command : command_data { }; diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index f146d040d6..bece94a000 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -707,6 +708,42 @@ BMediaNode::HandleMessage(int32 message, const void* data, size_t size) return B_OK; } + case NODE_GET_ATTRIBUTES_FOR: + { + const node_get_attributes_for_request *request = + (const node_get_attributes_for_request*) data; + + TRACE("BMediaNode::HandleMessage NODE_GET_ATTRIBUTES_FOR," + "node %ld\n", fNodeID); + + node_get_attributes_for_reply reply; + + media_node_attribute* addr; + area_id dataArea = clone_area("client attributes area", + (void**)&addr, B_ANY_ADDRESS, B_WRITE_AREA, + request->area); + + if (dataArea < 0) { + ERROR("NODE_GET_ATTRIBUTES_FOR can't clone area\n"); + return B_NO_MEMORY; + } + + status_t status = GetNodeAttributes(addr, request->count); + if (status == B_OK) { + // NOTE: we do it because there's not an easy way + // to guess the number of attributes filled. + size_t i; + for (i = 0; i < request->count; i++) { + if (addr[i].what <= 0) + break; + } + reply.filled_count = i; + } + request->SendReply(status, &reply, sizeof(reply)); + delete_area(dataArea); + return B_OK; + } + case NODE_REQUEST_COMPLETED: { const node_request_completed_command* command @@ -831,7 +868,7 @@ BMediaNode::GetNodeAttributes(media_node_attribute* outAttributes, { CALLED(); // This is implemented by derived classes that fills - // it's own attributes to a max of inMaxCount size. + // it's own attributes to a max of inMaxCount elements. return B_ERROR; } diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 52bc59af26..e0e65dbf8f 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -3123,8 +3123,41 @@ ssize_t BMediaRoster::GetNodeAttributesFor(const media_node& node, media_node_attribute* _array, size_t maxCount) { - UNIMPLEMENTED(); - return B_ERROR; + CALLED(); + + if (IS_INVALID_NODE(node)) + return B_MEDIA_BAD_NODE; + + node_get_attributes_for_request request; + node_get_attributes_for_reply reply; + status_t status; + + media_node_attribute* addr = NULL; + size_t totalSize = maxCount*sizeof(media_node_attribute); + size_t size = (totalSize + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1); + + area_id dataArea = create_area("attributes area", (void**)&addr, + B_ANY_ADDRESS, size, B_NO_LOCK, + B_READ_AREA | B_WRITE_AREA); + // No need to memset the padding + memset(addr, 0, totalSize); + + if (dataArea < 0) + return B_NO_MEMORY; + + request.count = maxCount; + request.area = dataArea; + + status = QueryPort(node.port, NODE_GET_ATTRIBUTES_FOR, &request, + sizeof(request), &reply, sizeof(reply)); + if (status != B_OK) + return status; + + memcpy(_array, addr, reply.filled_count + * sizeof(media_node_attribute)); + + delete_area(dataArea); + return reply.filled_count; }