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:
beveloper
2003-03-23 23:58:17 +00:00
parent d1c90ca8b2
commit 28ad138ac9
3 changed files with 123 additions and 12 deletions
+50 -5
View File
@@ -5,7 +5,9 @@
***********************************************************************/ ***********************************************************************/
#include <OS.h> #include <OS.h>
#include <Controllable.h> #include <Controllable.h>
#include <ParameterWeb.h>
#include "debug.h" #include "debug.h"
#include "DataExchange.h"
#include "Notifications.h" #include "Notifications.h"
/************************************************************* /*************************************************************
@@ -17,6 +19,8 @@ BControllable::~BControllable()
CALLED(); CALLED();
if (fSem > 0) if (fSem > 0)
delete_sem(fSem); delete_sem(fSem);
if (fWeb)
delete fWeb;
} }
/************************************************************* /*************************************************************
@@ -66,7 +70,7 @@ BControllable::UnlockParameterWeb()
BControllable::BControllable() : BControllable::BControllable() :
BMediaNode("XXX fixme"), BMediaNode("this one is never called"),
fWeb(0), fWeb(0),
fSem(create_sem(0, "BControllable lock")), fSem(create_sem(0, "BControllable lock")),
fBen(0) fBen(0)
@@ -88,18 +92,59 @@ BControllable::SetParameterWeb(BParameterWeb *web)
UnlockParameterWeb(); UnlockParameterWeb();
if (old != web && web != 0) if (old != web && web != 0)
BPrivate::media::notifications::WebChanged(Node()); BPrivate::media::notifications::WebChanged(Node());
if (old)
delete old;
return B_OK; return B_OK;
} }
status_t status_t
BControllable::HandleMessage(int32 message, BControllable::HandleMessage(int32 message, const void *data, size_t size)
const void *data,
size_t size)
{ {
INFO("BControllable::HandleMessage %#lx, node %ld\n", message, ID()); 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; return B_ERROR;
} }
+63 -4
View File
@@ -1692,10 +1692,69 @@ status_t
BMediaRoster::GetParameterWebFor(const media_node & node, BMediaRoster::GetParameterWebFor(const media_node & node,
BParameterWeb ** out_web) BParameterWeb ** out_web)
{ {
UNIMPLEMENTED(); CALLED();
// return B_ERROR; if (out_web == NULL)
*out_web = new BParameterWeb; return B_BAD_VALUE;
return B_OK; 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;
} }
+10 -3
View File
@@ -599,16 +599,20 @@ BParameterWeb::Unflatten(type_code c,
const void *buf, const void *buf,
ssize_t size) ssize_t size)
{ {
if(!this->AllowsTypeCode(c)) if(!this->AllowsTypeCode(c)) {
FATAL("BParameterWeb::Unflatten wrong type code\n");
return B_BAD_TYPE; return B_BAD_TYPE;
}
if(buf == NULL) if(buf == NULL) {
FATAL("BParameterWeb::Unflatten NULL buffer pointer\n");
return B_NO_INIT; return B_NO_INIT;
}
//if the buffer is smaller than the size needed to read the //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 //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)) ) 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; return B_ERROR;
} }
@@ -618,6 +622,7 @@ BParameterWeb::Unflatten(type_code c,
//being read in the correct byte order. //being read in the correct byte order.
if( *(reinterpret_cast<const int32 *>(CurrentPos)) != 0x010300506) if( *(reinterpret_cast<const int32 *>(CurrentPos)) != 0x010300506)
{ {
FATAL("BParameterWeb::Unflatten magic 1 wrong\n");
return B_BAD_TYPE; return B_BAD_TYPE;
} }
CurrentPos += sizeof(int32); 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. //being read in the correct byte order. THIS SURELY HAS SOME MEANING I'M NOT AWARE OF.
if( *(reinterpret_cast<const int32 *>(CurrentPos)) != 1) if( *(reinterpret_cast<const int32 *>(CurrentPos)) != 1)
{ {
FATAL("BParameterWeb::Unflatten magic 2 wrong\n");
return B_ERROR; return B_ERROR;
} }
CurrentPos += sizeof(int32); CurrentPos += sizeof(int32);
@@ -702,6 +708,7 @@ BParameterWeb::Unflatten(type_code c,
if(RetVal != B_OK) if(RetVal != B_OK)
{ {
FATAL("BParameterWeb::Unflatten sub.grup Unflatten failed\n");
delete NewSubGroup; delete NewSubGroup;
//don't return, because we should still fix references... //don't return, because we should still fix references...
break; break;