MediaFiles support added
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5324 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+167
-15
@@ -1,34 +1,73 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* AUTHOR: Marcus Overhagen
|
* AUTHOR: Marcus Overhagen, Jérôme Duval
|
||||||
* FILE: MediaFiles.cpp
|
* FILE: MediaFiles.cpp
|
||||||
* DESCR:
|
* DESCR:
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
#include <MediaFiles.h>
|
#include <MediaFiles.h>
|
||||||
|
#include "DataExchange.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* public BMediaFiles
|
* public BMediaFiles
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
const char BMediaFiles::B_SOUNDS[] = "XXX fixme"; /* for "types" */
|
const char BMediaFiles::B_SOUNDS[] = "Sounds"; /* for "types" */
|
||||||
|
|
||||||
BMediaFiles::BMediaFiles()
|
BMediaFiles::BMediaFiles()
|
||||||
|
: m_type_index(-1),
|
||||||
|
m_cur_type(""),
|
||||||
|
m_item_index(-1)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* virtual */
|
/* virtual */
|
||||||
BMediaFiles::~BMediaFiles()
|
BMediaFiles::~BMediaFiles()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ status_t
|
/* virtual */ status_t
|
||||||
BMediaFiles::RewindTypes()
|
BMediaFiles::RewindTypes()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
CALLED();
|
||||||
|
status_t rv;
|
||||||
|
server_rewindtypes_request request;
|
||||||
|
server_rewindtypes_reply reply;
|
||||||
|
|
||||||
|
for(int32 i = 0; i < m_types.CountItems(); i++)
|
||||||
|
delete m_types.ItemAt(i);
|
||||||
|
|
||||||
|
m_types.MakeEmpty();
|
||||||
|
|
||||||
|
TRACE("BMediaFiles::RewindTypes: sending SERVER_REWINDTYPES\n");
|
||||||
|
|
||||||
|
rv = QueryServer(SERVER_REWINDTYPES, &request, sizeof(request), &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK) {
|
||||||
|
ERROR("BMediaFiles::RewindTypes: failed to rewindtypes (error %#lx)\n", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *types;
|
||||||
|
area_id clone;
|
||||||
|
|
||||||
|
clone = clone_area("rewind types clone", reinterpret_cast<void **>(&types), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, reply.area);
|
||||||
|
if (clone < B_OK) {
|
||||||
|
ERROR("BMediaFiles::RewindTypes failed to clone area, %#lx\n", clone);
|
||||||
|
delete_area(reply.area);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 i = 0; i < reply.count; i++) {
|
||||||
|
m_types.AddItem(new BString(types + i * B_MEDIA_NAME_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_area(clone);
|
||||||
|
delete_area(reply.area);
|
||||||
|
|
||||||
|
m_type_index = 0;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -37,16 +76,62 @@ BMediaFiles::RewindTypes()
|
|||||||
/* virtual */ status_t
|
/* virtual */ status_t
|
||||||
BMediaFiles::GetNextType(BString *out_type)
|
BMediaFiles::GetNextType(BString *out_type)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
CALLED();
|
||||||
|
if(m_type_index < 0 || m_type_index >= m_types.CountItems()) {
|
||||||
|
m_type_index = -1;
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_type = *(BString*)m_types.ItemAt(m_type_index);
|
||||||
|
m_type_index++;
|
||||||
|
|
||||||
return B_ERROR;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ status_t
|
/* virtual */ status_t
|
||||||
BMediaFiles::RewindRefs(const char *type)
|
BMediaFiles::RewindRefs(const char *type)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
CALLED();
|
||||||
|
status_t rv;
|
||||||
|
server_rewindrefs_request request;
|
||||||
|
server_rewindrefs_reply reply;
|
||||||
|
|
||||||
|
for(int32 i = 0; i < m_items.CountItems(); i++)
|
||||||
|
delete m_items.ItemAt(i);
|
||||||
|
|
||||||
|
m_items.MakeEmpty();
|
||||||
|
|
||||||
|
TRACE("BMediaFiles::RewindRefs: sending SERVER_REWINDREFS for type %s\n", type);
|
||||||
|
strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
|
||||||
|
|
||||||
|
rv = QueryServer(SERVER_REWINDREFS, &request, sizeof(request), &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK) {
|
||||||
|
ERROR("BMediaFiles::RewindRefs: failed to rewindrefs (error %#lx)\n", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(reply.count>0) {
|
||||||
|
char *items;
|
||||||
|
area_id clone;
|
||||||
|
|
||||||
|
clone = clone_area("rewind refs clone", reinterpret_cast<void **>(&items), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, reply.area);
|
||||||
|
if (clone < B_OK) {
|
||||||
|
ERROR("BMediaFiles::RewindRefs failed to clone area, %#lx\n", clone);
|
||||||
|
delete_area(reply.area);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 i = 0; i < reply.count; i++) {
|
||||||
|
m_items.AddItem(new BString(items + i * B_MEDIA_NAME_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_area(clone);
|
||||||
|
delete_area(reply.area);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cur_type = BString(type);
|
||||||
|
m_item_index = 0;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -56,9 +141,18 @@ BMediaFiles::RewindRefs(const char *type)
|
|||||||
BMediaFiles::GetNextRef(BString *out_type,
|
BMediaFiles::GetNextRef(BString *out_type,
|
||||||
entry_ref *out_ref)
|
entry_ref *out_ref)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
CALLED();
|
||||||
|
if(m_item_index < 0 || m_item_index >= m_items.CountItems()) {
|
||||||
|
m_item_index = -1;
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_type = *(BString*)m_items.ItemAt(m_item_index);
|
||||||
|
m_item_index++;
|
||||||
|
|
||||||
|
GetRefFor(m_cur_type.String(), out_type->String(), out_ref);
|
||||||
|
|
||||||
return B_ERROR;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -67,9 +161,25 @@ BMediaFiles::GetRefFor(const char *type,
|
|||||||
const char *item,
|
const char *item,
|
||||||
entry_ref *out_ref)
|
entry_ref *out_ref)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
CALLED();
|
||||||
|
status_t rv;
|
||||||
|
server_getreffor_request request;
|
||||||
|
server_getreffor_reply reply;
|
||||||
|
|
||||||
|
strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
|
||||||
|
strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
|
||||||
|
|
||||||
|
TRACE("BMediaFiles::GetRefFor: sending SERVER_GETREFFOR\n");
|
||||||
|
|
||||||
|
rv = QueryServer(SERVER_GETREFFOR, &request, sizeof(request), &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK) {
|
||||||
|
ERROR("BMediaFiles::GetRefFor: failed to getreffor (error %#lx)\n", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return B_ERROR;
|
*out_ref = reply.ref;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -78,7 +188,22 @@ BMediaFiles::SetRefFor(const char *type,
|
|||||||
const char *item,
|
const char *item,
|
||||||
const entry_ref &ref)
|
const entry_ref &ref)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
CALLED();
|
||||||
|
status_t rv;
|
||||||
|
server_setreffor_request request;
|
||||||
|
server_setreffor_reply reply;
|
||||||
|
|
||||||
|
strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
|
||||||
|
strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
|
||||||
|
request.ref = ref;
|
||||||
|
|
||||||
|
TRACE("BMediaFiles::SetRefFor: sending SERVER_SETREFFOR\n");
|
||||||
|
|
||||||
|
rv = QueryServer(SERVER_SETREFFOR, &request, sizeof(request), &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK) {
|
||||||
|
ERROR("BMediaFiles::SetRefFor: failed to setreffor (error %#lx)\n", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -89,7 +214,21 @@ BMediaFiles::RemoveRefFor(const char *type,
|
|||||||
const char *item,
|
const char *item,
|
||||||
const entry_ref &ref)
|
const entry_ref &ref)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
status_t rv;
|
||||||
|
server_removereffor_request request;
|
||||||
|
server_removereffor_reply reply;
|
||||||
|
|
||||||
|
strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
|
||||||
|
strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
|
||||||
|
request.ref = ref;
|
||||||
|
|
||||||
|
TRACE("BMediaFiles::RemoveRefFor: sending SERVER_REMOVEREFFOR\n");
|
||||||
|
|
||||||
|
rv = QueryServer(SERVER_REMOVEREFFOR, &request, sizeof(request), &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK) {
|
||||||
|
ERROR("BMediaFiles::RemoveRefFor: failed to removereffor (error %#lx)\n", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -99,7 +238,20 @@ BMediaFiles::RemoveRefFor(const char *type,
|
|||||||
BMediaFiles::RemoveItem(const char *type,
|
BMediaFiles::RemoveItem(const char *type,
|
||||||
const char *item)
|
const char *item)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
status_t rv;
|
||||||
|
server_removeitem_request request;
|
||||||
|
server_removeitem_reply reply;
|
||||||
|
|
||||||
|
strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
|
||||||
|
strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
|
||||||
|
|
||||||
|
TRACE("BMediaFiles::RemoveItem: sending SERVER_REMOVEITEM\n");
|
||||||
|
|
||||||
|
rv = QueryServer(SERVER_REMOVEITEM, &request, sizeof(request), &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK) {
|
||||||
|
ERROR("BMediaFiles::RemoveItem: failed to removeitem (error %#lx)\n", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ Server media_server :
|
|||||||
AppManager.cpp
|
AppManager.cpp
|
||||||
BufferManager.cpp
|
BufferManager.cpp
|
||||||
DefaultManager.cpp
|
DefaultManager.cpp
|
||||||
|
MMediaFilesManager.cpp
|
||||||
NodeManager.cpp
|
NodeManager.cpp
|
||||||
NotificationManager.cpp
|
NotificationManager.cpp
|
||||||
Queue.cpp
|
Queue.cpp
|
||||||
|
|||||||
@@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003, Jérôme Duval. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <storage/FindDirectory.h>
|
||||||
|
#include <storage/Path.h>
|
||||||
|
#include "MMediaFilesManager.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
MMediaFilesManager::MMediaFilesManager()
|
||||||
|
: fLocker(new BLocker("media files manager locker")),
|
||||||
|
fRegistryMap(new Map<BString, Map<BString, entry_ref> >)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
LoadState();
|
||||||
|
#if DEBUG >=3
|
||||||
|
Dump();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MMediaFilesManager::~MMediaFilesManager()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
SaveState();
|
||||||
|
delete fRegistryMap;
|
||||||
|
delete fLocker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
MMediaFilesManager::ReadPascalString(BFile &file, char **str)
|
||||||
|
{
|
||||||
|
uint32 len;
|
||||||
|
*str=NULL;
|
||||||
|
if (file.Read(&len, 4) < 4)
|
||||||
|
return -1;
|
||||||
|
if (len == 0)
|
||||||
|
return 0;
|
||||||
|
*str = (char *)malloc(len);
|
||||||
|
if (file.Read(*str, len) < (int32)len) {
|
||||||
|
free(*str);
|
||||||
|
*str = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (int32)len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
MMediaFilesManager::WritePascalString(BFile &file, const char *str)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(str == NULL)
|
||||||
|
return -1;
|
||||||
|
uint32 len = strlen(str) + 1;
|
||||||
|
if (file.Write(&len, 4) < 4)
|
||||||
|
return -1;
|
||||||
|
if (len == 0)
|
||||||
|
return 0;
|
||||||
|
if (file.Write(str, len) < (int32)len) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (int32)len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this is called by the media_server *before* any add-ons have been loaded
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::LoadState()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
status_t err = B_OK;
|
||||||
|
BPath path;
|
||||||
|
if((err = find_directory(B_USER_SETTINGS_DIRECTORY, &path))!=B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
path.Append("Media/MMediaFilesManager");
|
||||||
|
|
||||||
|
BFile file(path.Path(), B_READ_ONLY);
|
||||||
|
|
||||||
|
uint32 category_count;
|
||||||
|
if (file.Read(header, sizeof(uint32)*3) < (int32)sizeof(uint32)*3)
|
||||||
|
return B_ERROR;
|
||||||
|
TRACE("0x%08lx %ld\n", header[0], header[0]);
|
||||||
|
TRACE("0x%08lx %ld\n", header[1], header[1]);
|
||||||
|
TRACE("0x%08lx %ld\n", header[2], header[2]);
|
||||||
|
if (file.Read(&category_count, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||||
|
return B_ERROR;
|
||||||
|
while (category_count--) {
|
||||||
|
char *str;
|
||||||
|
char *key, *val;
|
||||||
|
int32 len;
|
||||||
|
len = ReadPascalString(file, &str);
|
||||||
|
if (len < 0)
|
||||||
|
return B_ERROR;
|
||||||
|
if (len == 0)
|
||||||
|
break;
|
||||||
|
TRACE("%s {\n", str);
|
||||||
|
do {
|
||||||
|
int32 vol = 0;
|
||||||
|
len = ReadPascalString(file, &key);
|
||||||
|
if (len < 0)
|
||||||
|
return B_ERROR;
|
||||||
|
if (len == 0)
|
||||||
|
break;
|
||||||
|
len = ReadPascalString(file, &val);
|
||||||
|
if (len == 1) {
|
||||||
|
free(val);
|
||||||
|
val = strdup("(null)");
|
||||||
|
}
|
||||||
|
/*if (file.Read(&vol, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||||
|
return B_ERROR;*/
|
||||||
|
TRACE(" %s: %s, volume: %f\n", key, val, *(float *)&vol);
|
||||||
|
|
||||||
|
entry_ref ref;
|
||||||
|
if(len>1) {
|
||||||
|
BEntry entry(val);
|
||||||
|
entry.GetRef(&ref);
|
||||||
|
}
|
||||||
|
SetRefFor(str, key, ref);
|
||||||
|
|
||||||
|
free(key);
|
||||||
|
free(val);
|
||||||
|
} while (true);
|
||||||
|
TRACE("}\n");
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::SaveState()
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
BPath path;
|
||||||
|
if((err = find_directory(B_USER_SETTINGS_DIRECTORY, &path))!=B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
path.Append("Media/MMediaFilesManager");
|
||||||
|
|
||||||
|
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
|
||||||
|
uint32 zero = 0;
|
||||||
|
|
||||||
|
if (file.Write(header, sizeof(uint32)*3) < (int32)sizeof(uint32)*3)
|
||||||
|
return B_ERROR;
|
||||||
|
uint32 category_count = fRegistryMap->CountItems();
|
||||||
|
if (file.Write(&category_count, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
BString *type;
|
||||||
|
Map<BString, entry_ref> *map;
|
||||||
|
BString *item;
|
||||||
|
entry_ref *ref;
|
||||||
|
for (fRegistryMap->Rewind(); fRegistryMap->GetNext(&map); ) {
|
||||||
|
fRegistryMap->GetCurrentKey(&type);
|
||||||
|
|
||||||
|
WritePascalString(file, type->String());
|
||||||
|
|
||||||
|
for (map->Rewind(); map->GetNext(&ref);) {
|
||||||
|
map->GetCurrentKey(&item);
|
||||||
|
BPath path(ref);
|
||||||
|
|
||||||
|
WritePascalString(file, item->String());
|
||||||
|
WritePascalString(file, path.Path() ? path.Path() : "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Write(&zero, sizeof(uint32));
|
||||||
|
}
|
||||||
|
file.Write(&zero, sizeof(uint32));
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MMediaFilesManager::Dump()
|
||||||
|
{
|
||||||
|
BAutolock lock(fLocker);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
/* for each type, the registry map contains a map of item/entry_ref
|
||||||
|
*/
|
||||||
|
printf("MMediaFilesManager: registry map follows\n");
|
||||||
|
BString *type;
|
||||||
|
Map<BString, entry_ref> *map;
|
||||||
|
BString *item;
|
||||||
|
entry_ref *ref;
|
||||||
|
for (fRegistryMap->Rewind(); fRegistryMap->GetNext(&map); ) {
|
||||||
|
fRegistryMap->GetCurrentKey(&type);
|
||||||
|
|
||||||
|
for (map->Rewind(); map->GetNext(&ref);) {
|
||||||
|
map->GetCurrentKey(&item);
|
||||||
|
BPath path(ref);
|
||||||
|
printf(" type \"%s\", item \"%s\", path \"%s\"\n",
|
||||||
|
type->String(), item->String(), (path.InitCheck() == B_OK) ? path.Path() : "INVALID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("MMediaFilesManager: list end\n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::RewindTypes(BString ***types, int32 *count)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
if(types==NULL || count == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
Map<BString, entry_ref> *map;
|
||||||
|
BString *type;
|
||||||
|
|
||||||
|
*count = fRegistryMap->CountItems();
|
||||||
|
*types = new (BString*)[*count];
|
||||||
|
int32 i=0;
|
||||||
|
|
||||||
|
for (fRegistryMap->Rewind(); i<*count && fRegistryMap->GetNext(&map); i++) {
|
||||||
|
fRegistryMap->GetCurrentKey(&type);
|
||||||
|
(*types)[i] = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::RewindRefs(const char* type, BString ***items, int32 *count)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
if(type == NULL || items==NULL || count == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
Map<BString, entry_ref> *map;
|
||||||
|
entry_ref *ref;
|
||||||
|
BString *item;
|
||||||
|
|
||||||
|
fRegistryMap->Get(BString(type), &map);
|
||||||
|
|
||||||
|
*count = map->CountItems();
|
||||||
|
*items = new (BString*)[*count];
|
||||||
|
int32 i=0;
|
||||||
|
|
||||||
|
for (map->Rewind(); i<*count && map->GetNext(&ref); i++) {
|
||||||
|
map->GetCurrentKey(&item);
|
||||||
|
(*items)[i] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::GetRefFor(const char *type,
|
||||||
|
const char *item,
|
||||||
|
entry_ref **out_ref)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
Map <BString, entry_ref> *map;
|
||||||
|
if(!fRegistryMap->Get(BString(type), &map))
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
if(!map->Get(BString(item), out_ref))
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::SetRefFor(const char *type,
|
||||||
|
const char *item,
|
||||||
|
const entry_ref &ref)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
TRACE("MMediaFilesManager::SetRefFor %s %s\n", type, item);
|
||||||
|
|
||||||
|
BString itemString(item);
|
||||||
|
itemString.Truncate(B_MEDIA_NAME_LENGTH);
|
||||||
|
BString typeString(type);
|
||||||
|
Map <BString, entry_ref> *map;
|
||||||
|
if(!fRegistryMap->Get(typeString, &map)) {
|
||||||
|
map = new Map<BString, entry_ref>;
|
||||||
|
fRegistryMap->Insert(typeString, *map);
|
||||||
|
fRegistryMap->Get(typeString, &map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(map->Has(itemString))
|
||||||
|
map->Remove(itemString);
|
||||||
|
map->Insert(itemString, ref);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::RemoveRefFor(const char *type,
|
||||||
|
const char *item,
|
||||||
|
const entry_ref &ref)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
BString itemString(item);
|
||||||
|
BString typeString(type);
|
||||||
|
Map <BString, entry_ref> *map;
|
||||||
|
if(!fRegistryMap->Get(typeString, &map))
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
map->Remove(itemString);
|
||||||
|
map->Insert(itemString, *(new entry_ref));
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MMediaFilesManager::RemoveItem(const char *type,
|
||||||
|
const char *item)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
BString itemString(item);
|
||||||
|
BString typeString(type);
|
||||||
|
Map <BString, entry_ref> *map;
|
||||||
|
if(!fRegistryMap->Get(typeString, &map))
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
map->Remove(itemString);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003, Jérôme Duval. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include "TMap.h"
|
||||||
|
#include "DataExchange.h"
|
||||||
|
|
||||||
|
class MMediaFilesManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MMediaFilesManager();
|
||||||
|
~MMediaFilesManager();
|
||||||
|
|
||||||
|
status_t LoadState();
|
||||||
|
status_t SaveState();
|
||||||
|
|
||||||
|
void Dump();
|
||||||
|
|
||||||
|
status_t RewindTypes(
|
||||||
|
BString ***types,
|
||||||
|
int32 *count);
|
||||||
|
status_t RewindRefs(
|
||||||
|
const char * type,
|
||||||
|
BString ***items,
|
||||||
|
int32 *count);
|
||||||
|
status_t GetRefFor(
|
||||||
|
const char * type,
|
||||||
|
const char * item,
|
||||||
|
entry_ref ** out_ref);
|
||||||
|
status_t SetRefFor(
|
||||||
|
const char * type,
|
||||||
|
const char * item,
|
||||||
|
const entry_ref & ref);
|
||||||
|
status_t RemoveRefFor( // This might better be called "ClearRefFor"
|
||||||
|
const char * type, // but it's too late now...
|
||||||
|
const char * item,
|
||||||
|
const entry_ref & ref);
|
||||||
|
|
||||||
|
status_t RemoveItem( // new in 4.1, removes the whole item.
|
||||||
|
const char * type,
|
||||||
|
const char * item);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int32 ReadPascalString(BFile &file, char **str);
|
||||||
|
static int32 WritePascalString(BFile &file, const char *str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BLocker *fLocker;
|
||||||
|
|
||||||
|
Map<BString, Map<BString, entry_ref> > * fRegistryMap;
|
||||||
|
|
||||||
|
uint32 header[3];
|
||||||
|
};
|
||||||
@@ -37,6 +37,7 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Ov
|
|||||||
#include <MediaFormats.h>
|
#include <MediaFormats.h>
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "MMediaFilesManager.h"
|
||||||
#include "NotificationManager.h"
|
#include "NotificationManager.h"
|
||||||
#include "ServerInterface.h"
|
#include "ServerInterface.h"
|
||||||
#include "DataExchange.h"
|
#include "DataExchange.h"
|
||||||
@@ -58,6 +59,7 @@ NotificationManager *gNotificationManager;
|
|||||||
BufferManager *gBufferManager;
|
BufferManager *gBufferManager;
|
||||||
AppManager *gAppManager;
|
AppManager *gAppManager;
|
||||||
NodeManager *gNodeManager;
|
NodeManager *gNodeManager;
|
||||||
|
MMediaFilesManager *gMMediaFilesManager;
|
||||||
|
|
||||||
namespace BPrivate { namespace media {
|
namespace BPrivate { namespace media {
|
||||||
extern team_id team;
|
extern team_id team;
|
||||||
@@ -118,6 +120,7 @@ ServerApp::ServerApp()
|
|||||||
gBufferManager = new BufferManager;
|
gBufferManager = new BufferManager;
|
||||||
gAppManager = new AppManager;
|
gAppManager = new AppManager;
|
||||||
gNodeManager = new NodeManager;
|
gNodeManager = new NodeManager;
|
||||||
|
gMMediaFilesManager = new MMediaFilesManager;
|
||||||
|
|
||||||
control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
|
control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
|
||||||
control_thread = spawn_thread(controlthread, "media_server control", 105, this);
|
control_thread = spawn_thread(controlthread, "media_server control", 105, this);
|
||||||
@@ -135,6 +138,7 @@ ServerApp::~ServerApp()
|
|||||||
delete gBufferManager;
|
delete gBufferManager;
|
||||||
delete gAppManager;
|
delete gAppManager;
|
||||||
delete gNodeManager;
|
delete gNodeManager;
|
||||||
|
delete gMMediaFilesManager;
|
||||||
delete fLocker;
|
delete fLocker;
|
||||||
delete_port(control_port);
|
delete_port(control_port);
|
||||||
status_t err;
|
status_t err;
|
||||||
@@ -149,6 +153,7 @@ void ServerApp::ArgvReceived(int32 argc, char **argv)
|
|||||||
gNodeManager->Dump();
|
gNodeManager->Dump();
|
||||||
gBufferManager->Dump();
|
gBufferManager->Dump();
|
||||||
gNotificationManager->Dump();
|
gNotificationManager->Dump();
|
||||||
|
gMMediaFilesManager->Dump();
|
||||||
}
|
}
|
||||||
if (strstr(argv[arg], "buffer")) {
|
if (strstr(argv[arg], "buffer")) {
|
||||||
gBufferManager->Dump();
|
gBufferManager->Dump();
|
||||||
@@ -554,7 +559,117 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
|||||||
gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
|
gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SERVER_REWINDTYPES:
|
||||||
|
{
|
||||||
|
const server_rewindtypes_request *request = reinterpret_cast<const server_rewindtypes_request *>(data);
|
||||||
|
server_rewindtypes_reply reply;
|
||||||
|
|
||||||
|
BString **types = NULL;
|
||||||
|
|
||||||
|
rv = gMMediaFilesManager->RewindTypes(
|
||||||
|
&types, &reply.count);
|
||||||
|
if(reply.count>0) {
|
||||||
|
// we create an area here, and pass it to the library, where it will be deleted.
|
||||||
|
char *start_addr;
|
||||||
|
size_t size = ((reply.count * B_MEDIA_NAME_LENGTH) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||||
|
reply.area = create_area("rewind types", reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||||
|
if (reply.area < B_OK) {
|
||||||
|
ERROR("SERVER_REWINDTYPES: failed to create area, error %s\n", strerror(reply.area));
|
||||||
|
reply.count = 0;
|
||||||
|
rv = B_ERROR;
|
||||||
|
} else {
|
||||||
|
for (int32 index = 0; index < reply.count; index++)
|
||||||
|
strncpy(start_addr + B_MEDIA_NAME_LENGTH * index, types[index]->String(), B_MEDIA_NAME_LENGTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete types;
|
||||||
|
|
||||||
|
rv = request->SendReply(rv, &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK)
|
||||||
|
delete_area(reply.area); // if we couldn't send the message, delete the area
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SERVER_REWINDREFS:
|
||||||
|
{
|
||||||
|
const server_rewindrefs_request *request = reinterpret_cast<const server_rewindrefs_request *>(data);
|
||||||
|
server_rewindrefs_reply reply;
|
||||||
|
|
||||||
|
BString **items = NULL;
|
||||||
|
|
||||||
|
rv = gMMediaFilesManager->RewindRefs(request->type,
|
||||||
|
&items, &reply.count);
|
||||||
|
// we create an area here, and pass it to the library, where it will be deleted.
|
||||||
|
if(reply.count>0) {
|
||||||
|
char *start_addr;
|
||||||
|
size_t size = ((reply.count * B_MEDIA_NAME_LENGTH) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||||
|
reply.area = create_area("rewind refs", reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||||
|
if (reply.area < B_OK) {
|
||||||
|
ERROR("SERVER_REWINDREFS: failed to create area, error %s\n", strerror(reply.area));
|
||||||
|
reply.count = 0;
|
||||||
|
rv = B_ERROR;
|
||||||
|
} else {
|
||||||
|
for (int32 index = 0; index < reply.count; index++)
|
||||||
|
strncpy(start_addr + B_MEDIA_NAME_LENGTH * index, items[index]->String(), B_MEDIA_NAME_LENGTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete items;
|
||||||
|
|
||||||
|
rv = request->SendReply(rv, &reply, sizeof(reply));
|
||||||
|
if (rv != B_OK)
|
||||||
|
delete_area(reply.area); // if we couldn't send the message, delete the area
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SERVER_GETREFFOR:
|
||||||
|
{
|
||||||
|
const server_getreffor_request *request = reinterpret_cast<const server_getreffor_request *>(data);
|
||||||
|
server_getreffor_reply reply;
|
||||||
|
entry_ref *ref;
|
||||||
|
|
||||||
|
rv = gMMediaFilesManager->GetRefFor(request->type, request->item, &ref);
|
||||||
|
if(rv==B_OK) {
|
||||||
|
reply.ref = *ref;
|
||||||
|
}
|
||||||
|
request->SendReply(rv, &reply, sizeof(reply));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SERVER_SETREFFOR:
|
||||||
|
{
|
||||||
|
const server_setreffor_request *request = reinterpret_cast<const server_setreffor_request *>(data);
|
||||||
|
server_setreffor_reply reply;
|
||||||
|
entry_ref ref = request->ref;
|
||||||
|
|
||||||
|
rv = gMMediaFilesManager->SetRefFor(request->type, request->item, ref);
|
||||||
|
request->SendReply(rv, &reply, sizeof(reply));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SERVER_REMOVEREFFOR:
|
||||||
|
{
|
||||||
|
const server_removereffor_request *request = reinterpret_cast<const server_removereffor_request *>(data);
|
||||||
|
server_removereffor_reply reply;
|
||||||
|
entry_ref ref = request->ref;
|
||||||
|
|
||||||
|
rv = gMMediaFilesManager->RemoveRefFor(request->type, request->item, ref);
|
||||||
|
request->SendReply(rv, &reply, sizeof(reply));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SERVER_REMOVEITEM:
|
||||||
|
{
|
||||||
|
const server_removeitem_request *request = reinterpret_cast<const server_removeitem_request *>(data);
|
||||||
|
server_removeitem_reply reply;
|
||||||
|
|
||||||
|
rv = gMMediaFilesManager->RemoveItem(request->type, request->item);
|
||||||
|
request->SendReply(rv, &reply, sizeof(reply));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("media_server: received unknown message code %#08lx\n",code);
|
printf("media_server: received unknown message code %#08lx\n",code);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ class AppManager;
|
|||||||
class NodeManager;
|
class NodeManager;
|
||||||
class BufferManager;
|
class BufferManager;
|
||||||
class NotificationManager;
|
class NotificationManager;
|
||||||
|
class MMediaFilesManager;
|
||||||
|
|
||||||
extern AppManager * gAppManager;
|
extern AppManager * gAppManager;
|
||||||
extern NodeManager * gNodeManager;
|
extern NodeManager * gNodeManager;
|
||||||
extern BufferManager * gBufferManager;
|
extern BufferManager * gBufferManager;
|
||||||
extern NotificationManager * gNotificationManager;
|
extern NotificationManager * gNotificationManager;
|
||||||
|
extern MMediaFilesManager * gMMediaFilesManager;
|
||||||
Reference in New Issue
Block a user