db/upnp: move the LibUPnP instance to class UpnpDatabase
Delete the object when closing the database.
This commit is contained in:
		@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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. */
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user