db/upnp: move the LibUPnP instance to class UpnpDatabase

Delete the object when closing the database.
This commit is contained in:
Max Kellermann 2014-01-16 09:06:01 +01:00
parent 02769929b3
commit a35c7bc81a
7 changed files with 49 additions and 77 deletions

View File

@ -159,14 +159,18 @@ UpnpDatabase::Configure(const config_param &, Error &)
bool
UpnpDatabase::Open(Error &error)
{
m_lib = LibUPnP::getLibUPnP(error);
if (!m_lib)
m_lib = new LibUPnP();
if (!m_lib->ok()) {
error.Set(m_lib->GetInitError());
delete m_lib;
return false;
}
m_superdir = new UPnPDeviceDirectory();
m_superdir = new UPnPDeviceDirectory(m_lib);
if (!m_superdir->ok()) {
error.Set(m_superdir->GetError());
delete m_superdir;
delete m_lib;
return false;
}
@ -182,7 +186,7 @@ UpnpDatabase::Close()
{
delete m_root;
delete m_superdir;
// TBD decide what we do with the lib object
delete m_lib;
}
void
@ -285,7 +289,7 @@ UpnpDatabase::SearchSongs(ContentDirectoryService* server,
return true;
std::set<std::string> searchcaps;
if (!server->getSearchCapabilities(searchcaps, error))
if (!server->getSearchCapabilities(m_lib->getclh(), searchcaps, error))
return false;
if (searchcaps.empty())
@ -352,7 +356,9 @@ UpnpDatabase::SearchSongs(ContentDirectoryService* server,
}
}
return server->search(objid, cond.c_str(), dirbuf, error);
return server->search(m_lib->getclh(),
objid, cond.c_str(), dirbuf,
error);
}
static bool
@ -433,7 +439,7 @@ UpnpDatabase::ReadNode(ContentDirectoryService *server,
Error &error) const
{
UPnPDirContent dirbuf;
if (!server->getMetadata(objid, dirbuf, error))
if (!server->getMetadata(m_lib->getclh(), objid, dirbuf, error))
return false;
if (dirbuf.objects.size() == 1) {
@ -484,10 +490,12 @@ UpnpDatabase::Namei(ContentDirectoryService* server,
return true;
}
const UpnpClient_Handle handle = m_lib->getclh();
// Walk the path elements, read each directory and try to find the next one
for (unsigned int i = 0; i < vpath.size(); i++) {
UPnPDirContent dirbuf;
if (!server->readDir(objid.c_str(), dirbuf, error))
if (!server->readDir(handle, objid.c_str(), dirbuf, error))
return false;
// Look for the name in the sub-container list
@ -611,7 +619,7 @@ UpnpDatabase::VisitServer(ContentDirectoryService* server,
and loop here, but it's not useful as mpd will only return
data to the client when we're done anyway. */
UPnPDirContent dirbuf;
if (!server->readDir(objid.c_str(), dirbuf, error))
if (!server->readDir(m_lib->getclh(), objid.c_str(), dirbuf, error))
return false;
for (const auto &dirent : dirbuf.objects) {

View File

@ -24,12 +24,10 @@
#include "ixmlwrap.hxx"
#include "Directory.hxx"
#include "Util.hxx"
#include "upnpplib.hxx"
#include "util/Error.hxx"
#include <stdio.h>
#include <upnp/upnp.h>
#include <upnp/upnptools.h>
ContentDirectoryService::ContentDirectoryService(const UPnPDevice &device,
@ -64,17 +62,12 @@ public:
};
bool
ContentDirectoryService::readDirSlice(const char *objectId, int offset,
ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
const char *objectId, int offset,
int count, UPnPDirContent &dirbuf,
int *didreadp, int *totalp,
Error &error)
{
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *request(0);
IXML_Document *response(0);
DirBResFree cleaner(&request, &response);
@ -132,7 +125,8 @@ ContentDirectoryService::readDirSlice(const char *objectId, int offset,
}
bool
ContentDirectoryService::readDir(const char *objectId,
ContentDirectoryService::readDir(UpnpClient_Handle handle,
const char *objectId,
UPnPDirContent &dirbuf,
Error &error)
{
@ -141,7 +135,7 @@ ContentDirectoryService::readDir(const char *objectId,
while (offset < total) {
int count;
if (!readDirSlice(objectId, offset, m_rdreqcnt, dirbuf,
if (!readDirSlice(handle, objectId, offset, m_rdreqcnt, dirbuf,
&count, &total, error))
return false;
@ -152,17 +146,12 @@ ContentDirectoryService::readDir(const char *objectId,
}
bool
ContentDirectoryService::search(const char *objectId,
ContentDirectoryService::search(UpnpClient_Handle hdl,
const char *objectId,
const char *ss,
UPnPDirContent &dirbuf,
Error &error)
{
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *request(0);
IXML_Document *response(0);
@ -226,15 +215,10 @@ ContentDirectoryService::search(const char *objectId,
}
bool
ContentDirectoryService::getSearchCapabilities(std::set<std::string> &result,
ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl,
std::set<std::string> &result,
Error &error)
{
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *request(0);
IXML_Document *response(0);
@ -272,16 +256,11 @@ ContentDirectoryService::getSearchCapabilities(std::set<std::string> &result,
}
bool
ContentDirectoryService::getMetadata(const char *objectId,
ContentDirectoryService::getMetadata(UpnpClient_Handle hdl,
const char *objectId,
UPnPDirContent &dirbuf,
Error &error)
{
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *response(0);
// Create request

View File

@ -20,6 +20,8 @@
#ifndef _UPNPDIR_HXX_INCLUDED_
#define _UPNPDIR_HXX_INCLUDED_
#include <upnp/upnp.h>
#include <string>
#include <set>
@ -71,10 +73,12 @@ public:
* @param objectId the UPnP object Id for the container. Root has Id "0"
* @param[out] dirbuf stores the entries we read.
*/
bool readDir(const char *objectId, UPnPDirContent &dirbuf,
bool readDir(UpnpClient_Handle handle,
const char *objectId, UPnPDirContent &dirbuf,
Error &error);
bool readDirSlice(const char *objectId, int offset,
bool readDirSlice(UpnpClient_Handle handle,
const char *objectId, int offset,
int count, UPnPDirContent& dirbuf,
int *didread, int *total,
Error &error);
@ -89,7 +93,8 @@ public:
* section 2.5.5. Maybe we'll provide an easier way some day...
* @param[out] dirbuf stores the entries we read.
*/
bool search(const char *objectId, const char *searchstring,
bool search(UpnpClient_Handle handle,
const char *objectId, const char *searchstring,
UPnPDirContent &dirbuf,
Error &error);
@ -99,7 +104,8 @@ public:
* @param[out] dirbuf stores the entries we read. At most one entry will be
* returned.
*/
bool getMetadata(const char *objectId, UPnPDirContent &dirbuf,
bool getMetadata(UpnpClient_Handle handle,
const char *objectId, UPnPDirContent &dirbuf,
Error &error);
/** Retrieve search capabilities
@ -107,7 +113,8 @@ public:
* @param[out] result an empty vector: no search, or a single '*' element:
* any tag can be used in a search, or a list of usable tag names.
*/
bool getSearchCapabilities(std::set<std::string> &result,
bool getSearchCapabilities(UpnpClient_Handle handle,
std::set<std::string> &result,
Error &error);
/** Retrieve the "friendly name" for this server, useful for display. */

View File

@ -216,18 +216,14 @@ UPnPDeviceDirectory::expireDevices()
search();
}
UPnPDeviceDirectory::UPnPDeviceDirectory()
:m_searchTimeout(2), m_lastSearch(0)
UPnPDeviceDirectory::UPnPDeviceDirectory(LibUPnP *_lib)
:lib(_lib), m_searchTimeout(2), m_lastSearch(0)
{
if (!discoveredQueue.start(1, discoExplorer, 0)) {
error.Set(upnp_domain, "Discover work queue start failed");
return;
}
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return;
lib->SetHandler([](Upnp_EventType type, void *event){
cluCallBack(type, event);
});
@ -243,10 +239,6 @@ UPnPDeviceDirectory::search()
return true;
m_lastSearch = now;
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
// We search both for device and service just in case.
int code = UpnpSearchAsync(lib->getclh(), m_searchTimeout,
ContentDirectorySType, lib);

View File

@ -26,6 +26,7 @@
#include <time.h>
class LibUPnP;
class ContentDirectoryService;
/**
@ -35,6 +36,8 @@ class ContentDirectoryService;
* for now, but this could be made more general, by removing the filtering.
*/
class UPnPDeviceDirectory {
LibUPnP *const lib;
Error error;
/**
@ -47,7 +50,7 @@ class UPnPDeviceDirectory {
time_t m_lastSearch;
public:
UPnPDeviceDirectory();
UPnPDeviceDirectory(LibUPnP *_lib);
UPnPDeviceDirectory(const UPnPDeviceDirectory &) = delete;
UPnPDeviceDirectory& operator=(const UPnPDeviceDirectory &) = delete;

View File

@ -27,20 +27,6 @@
static LibUPnP *theLib;
LibUPnP *
LibUPnP::getLibUPnP(Error &error)
{
if (theLib == nullptr)
theLib = new LibUPnP;
if (!theLib->ok()) {
error.Set(theLib->GetInitError());
return nullptr;
}
return theLib;
}
LibUPnP::LibUPnP()
{
auto code = UpnpInit(0, 0);

View File

@ -35,19 +35,16 @@ class LibUPnP {
Handler handler;
static int o_callback(Upnp_EventType, void *, void *);
public:
LibUPnP();
LibUPnP(const LibUPnP &) = delete;
LibUPnP &operator=(const LibUPnP &) = delete;
static int o_callback(Upnp_EventType, void *, void *);
public:
~LibUPnP();
/** Retrieve the singleton LibUPnP object */
static LibUPnP *getLibUPnP(Error &error);
/** Check state after initialization */
bool ok() const
{