Commit a35c7bc8 authored by Max Kellermann's avatar Max Kellermann

db/upnp: move the LibUPnP instance to class UpnpDatabase

Delete the object when closing the database.
parent 02769929
...@@ -159,14 +159,18 @@ UpnpDatabase::Configure(const config_param &, Error &) ...@@ -159,14 +159,18 @@ UpnpDatabase::Configure(const config_param &, Error &)
bool bool
UpnpDatabase::Open(Error &error) UpnpDatabase::Open(Error &error)
{ {
m_lib = LibUPnP::getLibUPnP(error); m_lib = new LibUPnP();
if (!m_lib) if (!m_lib->ok()) {
error.Set(m_lib->GetInitError());
delete m_lib;
return false; return false;
}
m_superdir = new UPnPDeviceDirectory(); m_superdir = new UPnPDeviceDirectory(m_lib);
if (!m_superdir->ok()) { if (!m_superdir->ok()) {
error.Set(m_superdir->GetError()); error.Set(m_superdir->GetError());
delete m_superdir; delete m_superdir;
delete m_lib;
return false; return false;
} }
...@@ -182,7 +186,7 @@ UpnpDatabase::Close() ...@@ -182,7 +186,7 @@ UpnpDatabase::Close()
{ {
delete m_root; delete m_root;
delete m_superdir; delete m_superdir;
// TBD decide what we do with the lib object delete m_lib;
} }
void void
...@@ -285,7 +289,7 @@ UpnpDatabase::SearchSongs(ContentDirectoryService* server, ...@@ -285,7 +289,7 @@ UpnpDatabase::SearchSongs(ContentDirectoryService* server,
return true; return true;
std::set<std::string> searchcaps; std::set<std::string> searchcaps;
if (!server->getSearchCapabilities(searchcaps, error)) if (!server->getSearchCapabilities(m_lib->getclh(), searchcaps, error))
return false; return false;
if (searchcaps.empty()) if (searchcaps.empty())
...@@ -352,7 +356,9 @@ UpnpDatabase::SearchSongs(ContentDirectoryService* server, ...@@ -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 static bool
...@@ -433,7 +439,7 @@ UpnpDatabase::ReadNode(ContentDirectoryService *server, ...@@ -433,7 +439,7 @@ UpnpDatabase::ReadNode(ContentDirectoryService *server,
Error &error) const Error &error) const
{ {
UPnPDirContent dirbuf; UPnPDirContent dirbuf;
if (!server->getMetadata(objid, dirbuf, error)) if (!server->getMetadata(m_lib->getclh(), objid, dirbuf, error))
return false; return false;
if (dirbuf.objects.size() == 1) { if (dirbuf.objects.size() == 1) {
...@@ -484,10 +490,12 @@ UpnpDatabase::Namei(ContentDirectoryService* server, ...@@ -484,10 +490,12 @@ UpnpDatabase::Namei(ContentDirectoryService* server,
return true; return true;
} }
const UpnpClient_Handle handle = m_lib->getclh();
// Walk the path elements, read each directory and try to find the next one // Walk the path elements, read each directory and try to find the next one
for (unsigned int i = 0; i < vpath.size(); i++) { for (unsigned int i = 0; i < vpath.size(); i++) {
UPnPDirContent dirbuf; UPnPDirContent dirbuf;
if (!server->readDir(objid.c_str(), dirbuf, error)) if (!server->readDir(handle, objid.c_str(), dirbuf, error))
return false; return false;
// Look for the name in the sub-container list // Look for the name in the sub-container list
...@@ -611,7 +619,7 @@ UpnpDatabase::VisitServer(ContentDirectoryService* server, ...@@ -611,7 +619,7 @@ UpnpDatabase::VisitServer(ContentDirectoryService* server,
and loop here, but it's not useful as mpd will only return and loop here, but it's not useful as mpd will only return
data to the client when we're done anyway. */ data to the client when we're done anyway. */
UPnPDirContent dirbuf; UPnPDirContent dirbuf;
if (!server->readDir(objid.c_str(), dirbuf, error)) if (!server->readDir(m_lib->getclh(), objid.c_str(), dirbuf, error))
return false; return false;
for (const auto &dirent : dirbuf.objects) { for (const auto &dirent : dirbuf.objects) {
......
...@@ -24,12 +24,10 @@ ...@@ -24,12 +24,10 @@
#include "ixmlwrap.hxx" #include "ixmlwrap.hxx"
#include "Directory.hxx" #include "Directory.hxx"
#include "Util.hxx" #include "Util.hxx"
#include "upnpplib.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include <stdio.h> #include <stdio.h>
#include <upnp/upnp.h>
#include <upnp/upnptools.h> #include <upnp/upnptools.h>
ContentDirectoryService::ContentDirectoryService(const UPnPDevice &device, ContentDirectoryService::ContentDirectoryService(const UPnPDevice &device,
...@@ -64,17 +62,12 @@ public: ...@@ -64,17 +62,12 @@ public:
}; };
bool bool
ContentDirectoryService::readDirSlice(const char *objectId, int offset, ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
const char *objectId, int offset,
int count, UPnPDirContent &dirbuf, int count, UPnPDirContent &dirbuf,
int *didreadp, int *totalp, int *didreadp, int *totalp,
Error &error) Error &error)
{ {
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *request(0); IXML_Document *request(0);
IXML_Document *response(0); IXML_Document *response(0);
DirBResFree cleaner(&request, &response); DirBResFree cleaner(&request, &response);
...@@ -132,7 +125,8 @@ ContentDirectoryService::readDirSlice(const char *objectId, int offset, ...@@ -132,7 +125,8 @@ ContentDirectoryService::readDirSlice(const char *objectId, int offset,
} }
bool bool
ContentDirectoryService::readDir(const char *objectId, ContentDirectoryService::readDir(UpnpClient_Handle handle,
const char *objectId,
UPnPDirContent &dirbuf, UPnPDirContent &dirbuf,
Error &error) Error &error)
{ {
...@@ -141,7 +135,7 @@ ContentDirectoryService::readDir(const char *objectId, ...@@ -141,7 +135,7 @@ ContentDirectoryService::readDir(const char *objectId,
while (offset < total) { while (offset < total) {
int count; int count;
if (!readDirSlice(objectId, offset, m_rdreqcnt, dirbuf, if (!readDirSlice(handle, objectId, offset, m_rdreqcnt, dirbuf,
&count, &total, error)) &count, &total, error))
return false; return false;
...@@ -152,17 +146,12 @@ ContentDirectoryService::readDir(const char *objectId, ...@@ -152,17 +146,12 @@ ContentDirectoryService::readDir(const char *objectId,
} }
bool bool
ContentDirectoryService::search(const char *objectId, ContentDirectoryService::search(UpnpClient_Handle hdl,
const char *objectId,
const char *ss, const char *ss,
UPnPDirContent &dirbuf, UPnPDirContent &dirbuf,
Error &error) Error &error)
{ {
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *request(0); IXML_Document *request(0);
IXML_Document *response(0); IXML_Document *response(0);
...@@ -226,15 +215,10 @@ ContentDirectoryService::search(const char *objectId, ...@@ -226,15 +215,10 @@ ContentDirectoryService::search(const char *objectId,
} }
bool bool
ContentDirectoryService::getSearchCapabilities(std::set<std::string> &result, ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl,
std::set<std::string> &result,
Error &error) Error &error)
{ {
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *request(0); IXML_Document *request(0);
IXML_Document *response(0); IXML_Document *response(0);
...@@ -272,16 +256,11 @@ ContentDirectoryService::getSearchCapabilities(std::set<std::string> &result, ...@@ -272,16 +256,11 @@ ContentDirectoryService::getSearchCapabilities(std::set<std::string> &result,
} }
bool bool
ContentDirectoryService::getMetadata(const char *objectId, ContentDirectoryService::getMetadata(UpnpClient_Handle hdl,
const char *objectId,
UPnPDirContent &dirbuf, UPnPDirContent &dirbuf,
Error &error) Error &error)
{ {
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
UpnpClient_Handle hdl = lib->getclh();
IXML_Document *response(0); IXML_Document *response(0);
// Create request // Create request
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#ifndef _UPNPDIR_HXX_INCLUDED_ #ifndef _UPNPDIR_HXX_INCLUDED_
#define _UPNPDIR_HXX_INCLUDED_ #define _UPNPDIR_HXX_INCLUDED_
#include <upnp/upnp.h>
#include <string> #include <string>
#include <set> #include <set>
...@@ -71,10 +73,12 @@ public: ...@@ -71,10 +73,12 @@ public:
* @param objectId the UPnP object Id for the container. Root has Id "0" * @param objectId the UPnP object Id for the container. Root has Id "0"
* @param[out] dirbuf stores the entries we read. * @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); Error &error);
bool readDirSlice(const char *objectId, int offset, bool readDirSlice(UpnpClient_Handle handle,
const char *objectId, int offset,
int count, UPnPDirContent& dirbuf, int count, UPnPDirContent& dirbuf,
int *didread, int *total, int *didread, int *total,
Error &error); Error &error);
...@@ -89,7 +93,8 @@ public: ...@@ -89,7 +93,8 @@ public:
* section 2.5.5. Maybe we'll provide an easier way some day... * section 2.5.5. Maybe we'll provide an easier way some day...
* @param[out] dirbuf stores the entries we read. * @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, UPnPDirContent &dirbuf,
Error &error); Error &error);
...@@ -99,7 +104,8 @@ public: ...@@ -99,7 +104,8 @@ public:
* @param[out] dirbuf stores the entries we read. At most one entry will be * @param[out] dirbuf stores the entries we read. At most one entry will be
* returned. * returned.
*/ */
bool getMetadata(const char *objectId, UPnPDirContent &dirbuf, bool getMetadata(UpnpClient_Handle handle,
const char *objectId, UPnPDirContent &dirbuf,
Error &error); Error &error);
/** Retrieve search capabilities /** Retrieve search capabilities
...@@ -107,7 +113,8 @@ public: ...@@ -107,7 +113,8 @@ public:
* @param[out] result an empty vector: no search, or a single '*' element: * @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. * 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); Error &error);
/** Retrieve the "friendly name" for this server, useful for display. */ /** Retrieve the "friendly name" for this server, useful for display. */
......
...@@ -216,18 +216,14 @@ UPnPDeviceDirectory::expireDevices() ...@@ -216,18 +216,14 @@ UPnPDeviceDirectory::expireDevices()
search(); search();
} }
UPnPDeviceDirectory::UPnPDeviceDirectory() UPnPDeviceDirectory::UPnPDeviceDirectory(LibUPnP *_lib)
:m_searchTimeout(2), m_lastSearch(0) :lib(_lib), m_searchTimeout(2), m_lastSearch(0)
{ {
if (!discoveredQueue.start(1, discoExplorer, 0)) { if (!discoveredQueue.start(1, discoExplorer, 0)) {
error.Set(upnp_domain, "Discover work queue start failed"); error.Set(upnp_domain, "Discover work queue start failed");
return; return;
} }
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return;
lib->SetHandler([](Upnp_EventType type, void *event){ lib->SetHandler([](Upnp_EventType type, void *event){
cluCallBack(type, event); cluCallBack(type, event);
}); });
...@@ -243,10 +239,6 @@ UPnPDeviceDirectory::search() ...@@ -243,10 +239,6 @@ UPnPDeviceDirectory::search()
return true; return true;
m_lastSearch = now; m_lastSearch = now;
LibUPnP *lib = LibUPnP::getLibUPnP(error);
if (lib == nullptr)
return false;
// We search both for device and service just in case. // We search both for device and service just in case.
int code = UpnpSearchAsync(lib->getclh(), m_searchTimeout, int code = UpnpSearchAsync(lib->getclh(), m_searchTimeout,
ContentDirectorySType, lib); ContentDirectorySType, lib);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <time.h> #include <time.h>
class LibUPnP;
class ContentDirectoryService; class ContentDirectoryService;
/** /**
...@@ -35,6 +36,8 @@ class ContentDirectoryService; ...@@ -35,6 +36,8 @@ class ContentDirectoryService;
* for now, but this could be made more general, by removing the filtering. * for now, but this could be made more general, by removing the filtering.
*/ */
class UPnPDeviceDirectory { class UPnPDeviceDirectory {
LibUPnP *const lib;
Error error; Error error;
/** /**
...@@ -47,7 +50,7 @@ class UPnPDeviceDirectory { ...@@ -47,7 +50,7 @@ class UPnPDeviceDirectory {
time_t m_lastSearch; time_t m_lastSearch;
public: public:
UPnPDeviceDirectory(); UPnPDeviceDirectory(LibUPnP *_lib);
UPnPDeviceDirectory(const UPnPDeviceDirectory &) = delete; UPnPDeviceDirectory(const UPnPDeviceDirectory &) = delete;
UPnPDeviceDirectory& operator=(const UPnPDeviceDirectory &) = delete; UPnPDeviceDirectory& operator=(const UPnPDeviceDirectory &) = delete;
......
...@@ -27,20 +27,6 @@ ...@@ -27,20 +27,6 @@
static LibUPnP *theLib; 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() LibUPnP::LibUPnP()
{ {
auto code = UpnpInit(0, 0); auto code = UpnpInit(0, 0);
......
...@@ -35,19 +35,16 @@ class LibUPnP { ...@@ -35,19 +35,16 @@ class LibUPnP {
Handler handler; Handler handler;
static int o_callback(Upnp_EventType, void *, void *);
public:
LibUPnP(); LibUPnP();
LibUPnP(const LibUPnP &) = delete; LibUPnP(const LibUPnP &) = delete;
LibUPnP &operator=(const LibUPnP &) = delete; LibUPnP &operator=(const LibUPnP &) = delete;
static int o_callback(Upnp_EventType, void *, void *);
public:
~LibUPnP(); ~LibUPnP();
/** Retrieve the singleton LibUPnP object */
static LibUPnP *getLibUPnP(Error &error);
/** Check state after initialization */ /** Check state after initialization */
bool ok() const bool ok() const
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment