Implemented BMediaRoster::GetParameterWebFor().
Unfortunately, BParameterWeb flattening seems to be broken. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3013 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -5,7 +5,9 @@
|
||||
***********************************************************************/
|
||||
#include <OS.h>
|
||||
#include <Controllable.h>
|
||||
#include <ParameterWeb.h>
|
||||
#include "debug.h"
|
||||
#include "DataExchange.h"
|
||||
#include "Notifications.h"
|
||||
|
||||
/*************************************************************
|
||||
@@ -17,6 +19,8 @@ BControllable::~BControllable()
|
||||
CALLED();
|
||||
if (fSem > 0)
|
||||
delete_sem(fSem);
|
||||
if (fWeb)
|
||||
delete fWeb;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
@@ -66,7 +70,7 @@ BControllable::UnlockParameterWeb()
|
||||
|
||||
|
||||
BControllable::BControllable() :
|
||||
BMediaNode("XXX fixme"),
|
||||
BMediaNode("this one is never called"),
|
||||
fWeb(0),
|
||||
fSem(create_sem(0, "BControllable lock")),
|
||||
fBen(0)
|
||||
@@ -88,18 +92,59 @@ BControllable::SetParameterWeb(BParameterWeb *web)
|
||||
UnlockParameterWeb();
|
||||
if (old != web && web != 0)
|
||||
BPrivate::media::notifications::WebChanged(Node());
|
||||
|
||||
if (old)
|
||||
delete old;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BControllable::HandleMessage(int32 message,
|
||||
const void *data,
|
||||
size_t size)
|
||||
BControllable::HandleMessage(int32 message, const void *data, size_t size)
|
||||
{
|
||||
INFO("BControllable::HandleMessage %#lx, node %ld\n", message, ID());
|
||||
|
||||
status_t rv;
|
||||
switch (message) {
|
||||
case CONTROLLABLE_GET_PARAMETER_WEB:
|
||||
{
|
||||
const controllable_get_parameter_web_request *request = static_cast<const controllable_get_parameter_web_request *>(data);
|
||||
controllable_get_parameter_web_reply reply;
|
||||
bool waslocked = LockParameterWeb();
|
||||
if (fWeb != NULL && fWeb->FlattenedSize() > request->maxsize) {
|
||||
reply.code = 0;
|
||||
reply.size = -1; // parameter web too large
|
||||
rv = B_OK;
|
||||
} else if (fWeb != NULL && fWeb->FlattenedSize() <= request->maxsize) {
|
||||
void *buffer;
|
||||
area_id area;
|
||||
area = clone_area("cloned parameter web", &buffer, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, request->area);
|
||||
if (area < B_OK) {
|
||||
FATAL("BControllable::HandleMessage CONTROLLABLE_GET_PARAMETER_WEB clone_area failed\n");
|
||||
rv = B_ERROR;
|
||||
} else {
|
||||
reply.code = fWeb->TypeCode();
|
||||
reply.size = fWeb->FlattenedSize();
|
||||
rv = fWeb->Flatten(buffer, reply.size);
|
||||
if (rv != B_OK) {
|
||||
FATAL("BControllable::HandleMessage CONTROLLABLE_GET_PARAMETER_WEB Flatten failed\n");
|
||||
} else {
|
||||
printf("BControllable::HandleMessage CONTROLLABLE_GET_PARAMETER_WEB %ld bytes, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
|
||||
reply.size, ((uint32*)buffer)[0], ((uint32*)buffer)[1], ((uint32*)buffer)[2], ((uint32*)buffer)[3]);
|
||||
}
|
||||
delete_area(area);
|
||||
}
|
||||
} else {
|
||||
reply.code = 0;
|
||||
reply.size = 0; // no parameter web
|
||||
rv = B_OK;
|
||||
}
|
||||
if (waslocked)
|
||||
UnlockParameterWeb();
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -1692,10 +1692,69 @@ status_t
|
||||
BMediaRoster::GetParameterWebFor(const media_node & node,
|
||||
BParameterWeb ** out_web)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
// return B_ERROR;
|
||||
*out_web = new BParameterWeb;
|
||||
return B_OK;
|
||||
CALLED();
|
||||
if (out_web == NULL)
|
||||
return B_BAD_VALUE;
|
||||
if (IS_INVALID_NODE(node))
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if ((node.kind & B_CONTROLLABLE) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
controllable_get_parameter_web_request request;
|
||||
controllable_get_parameter_web_reply reply;
|
||||
int32 requestsize[] = {B_PAGE_SIZE, 4*B_PAGE_SIZE, 16*B_PAGE_SIZE, 64*B_PAGE_SIZE, 128*B_PAGE_SIZE, 256*B_PAGE_SIZE, 0};
|
||||
int32 size;
|
||||
|
||||
// XXX it might be better to query the node for the (current) parameter size first
|
||||
for (int i = 0; (size = requestsize[i]) != 0; i++) {
|
||||
status_t rv;
|
||||
area_id area;
|
||||
void *data;
|
||||
area = create_area("parameter web data", &data, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (area < B_OK) {
|
||||
FATAL("BMediaRoster::GetParameterWebFor couldn't create area of size %ld\n", size);
|
||||
return B_ERROR;
|
||||
}
|
||||
request.maxsize = size;
|
||||
request.area = area;
|
||||
rv = QueryPort(node.port, CONTROLLABLE_GET_PARAMETER_WEB, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv != B_OK) {
|
||||
FATAL("BMediaRoster::GetParameterWebFor CONTROLLABLE_GET_PARAMETER_WEB failed\n");
|
||||
delete_area(area);
|
||||
return B_ERROR;
|
||||
}
|
||||
if (reply.size == 0) {
|
||||
// no parameter web available
|
||||
// XXX should we return an error?
|
||||
FATAL("BMediaRoster::GetParameterWebFor node %ld has no parameter web\n", node.node);
|
||||
*out_web = new BParameterWeb();
|
||||
delete_area(area);
|
||||
return B_OK;
|
||||
}
|
||||
if (reply.size > 0) {
|
||||
// we got a flattened parameter web!
|
||||
*out_web = new BParameterWeb();
|
||||
|
||||
printf("BMediaRoster::GetParameterWebFor Unflattening %ld bytes, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
|
||||
reply.size, ((uint32*)data)[0], ((uint32*)data)[1], ((uint32*)data)[2], ((uint32*)data)[3]);
|
||||
|
||||
rv = (*out_web)->Unflatten(reply.code, data, reply.size);
|
||||
if (rv != B_OK) {
|
||||
FATAL("BMediaRoster::GetParameterWebFor Unflatten failed, %s\n", strerror(rv));
|
||||
delete_area(area);
|
||||
delete *out_web;
|
||||
return B_ERROR;
|
||||
}
|
||||
delete_area(area);
|
||||
return B_OK;
|
||||
}
|
||||
delete_area(area);
|
||||
ASSERT(reply.size == -1);
|
||||
// parameter web data was too large
|
||||
// loop and try a larger size
|
||||
}
|
||||
FATAL("BMediaRoster::GetParameterWebFor node %ld has no parameter web larger than %ld\n", node.node, size);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -599,16 +599,20 @@ BParameterWeb::Unflatten(type_code c,
|
||||
const void *buf,
|
||||
ssize_t size)
|
||||
{
|
||||
if(!this->AllowsTypeCode(c))
|
||||
if(!this->AllowsTypeCode(c)) {
|
||||
FATAL("BParameterWeb::Unflatten wrong type code\n");
|
||||
return B_BAD_TYPE;
|
||||
|
||||
if(buf == NULL)
|
||||
}
|
||||
if(buf == NULL) {
|
||||
FATAL("BParameterWeb::Unflatten NULL buffer pointer\n");
|
||||
return B_NO_INIT;
|
||||
}
|
||||
|
||||
//if the buffer is smaller than the size needed to read the
|
||||
//signature field, the mystery field, the group count, and the Node, then there is a problem
|
||||
if(size < static_cast<ssize_t>(sizeof(int32) + sizeof(int32) + sizeof(ssize_t) + sizeof(media_node)) )
|
||||
{
|
||||
FATAL("BParameterWeb::Unflatten size to small\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -618,6 +622,7 @@ BParameterWeb::Unflatten(type_code c,
|
||||
//being read in the correct byte order.
|
||||
if( *(reinterpret_cast<const int32 *>(CurrentPos)) != 0x010300506)
|
||||
{
|
||||
FATAL("BParameterWeb::Unflatten magic 1 wrong\n");
|
||||
return B_BAD_TYPE;
|
||||
}
|
||||
CurrentPos += sizeof(int32);
|
||||
@@ -626,6 +631,7 @@ BParameterWeb::Unflatten(type_code c,
|
||||
//being read in the correct byte order. THIS SURELY HAS SOME MEANING I'M NOT AWARE OF.
|
||||
if( *(reinterpret_cast<const int32 *>(CurrentPos)) != 1)
|
||||
{
|
||||
FATAL("BParameterWeb::Unflatten magic 2 wrong\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
CurrentPos += sizeof(int32);
|
||||
@@ -702,6 +708,7 @@ BParameterWeb::Unflatten(type_code c,
|
||||
|
||||
if(RetVal != B_OK)
|
||||
{
|
||||
FATAL("BParameterWeb::Unflatten sub.grup Unflatten failed\n");
|
||||
delete NewSubGroup;
|
||||
//don't return, because we should still fix references...
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user