upnp/ContentDirectoryService: use AtScopeExit() for ixmlDocument_free()
For exception-safety.
This commit is contained in:
parent
3ee5093b03
commit
cd2f65aafc
@ -21,12 +21,14 @@
|
|||||||
#include "lib/upnp/ContentDirectoryService.hxx"
|
#include "lib/upnp/ContentDirectoryService.hxx"
|
||||||
#include "lib/upnp/Domain.hxx"
|
#include "lib/upnp/Domain.hxx"
|
||||||
#include "lib/upnp/ixmlwrap.hxx"
|
#include "lib/upnp/ixmlwrap.hxx"
|
||||||
|
#include "lib/upnp/UniqueIxml.hxx"
|
||||||
#include "lib/upnp/Action.hxx"
|
#include "lib/upnp/Action.hxx"
|
||||||
#include "Directory.hxx"
|
#include "Directory.hxx"
|
||||||
#include "util/NumberParser.hxx"
|
#include "util/NumberParser.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
|
#include "util/ScopeExit.hxx"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -63,14 +65,17 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
|
|||||||
if (request == nullptr)
|
if (request == nullptr)
|
||||||
throw std::runtime_error("UpnpMakeAction() failed");
|
throw std::runtime_error("UpnpMakeAction() failed");
|
||||||
|
|
||||||
|
AtScopeExit(request) { ixmlDocument_free(request); };
|
||||||
|
|
||||||
IXML_Document *response;
|
IXML_Document *response;
|
||||||
int code = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(),
|
int code = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(),
|
||||||
0 /*devUDN*/, request, &response);
|
0 /*devUDN*/, request, &response);
|
||||||
ixmlDocument_free(request);
|
|
||||||
if (code != UPNP_E_SUCCESS)
|
if (code != UPNP_E_SUCCESS)
|
||||||
throw FormatRuntimeError("UpnpSendAction() failed: %s",
|
throw FormatRuntimeError("UpnpSendAction() failed: %s",
|
||||||
UpnpGetErrorMessage(code));
|
UpnpGetErrorMessage(code));
|
||||||
|
|
||||||
|
AtScopeExit(response) { ixmlDocument_free(response); };
|
||||||
|
|
||||||
const char *value = ixmlwrap::getFirstElementValue(response, "NumberReturned");
|
const char *value = ixmlwrap::getFirstElementValue(response, "NumberReturned");
|
||||||
didreadp = value != nullptr
|
didreadp = value != nullptr
|
||||||
? ParseUnsigned(value)
|
? ParseUnsigned(value)
|
||||||
@ -80,9 +85,7 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
|
|||||||
if (value != nullptr)
|
if (value != nullptr)
|
||||||
totalp = ParseUnsigned(value);
|
totalp = ParseUnsigned(value);
|
||||||
|
|
||||||
bool success = ReadResultTag(dirbuf, response, error);
|
return ReadResultTag(dirbuf, response, error);
|
||||||
ixmlDocument_free(response);
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -117,41 +120,42 @@ ContentDirectoryService::search(UpnpClient_Handle hdl,
|
|||||||
char ofbuf[100];
|
char ofbuf[100];
|
||||||
sprintf(ofbuf, "%d", offset);
|
sprintf(ofbuf, "%d", offset);
|
||||||
|
|
||||||
IXML_Document *request =
|
UniqueIxmlDocument request(MakeActionHelper("Search", m_serviceType.c_str(),
|
||||||
MakeActionHelper("Search", m_serviceType.c_str(),
|
|
||||||
"ContainerID", objectId,
|
"ContainerID", objectId,
|
||||||
"SearchCriteria", ss,
|
"SearchCriteria", ss,
|
||||||
"Filter", "*",
|
"Filter", "*",
|
||||||
"SortCriteria", "",
|
"SortCriteria", "",
|
||||||
"StartingIndex", ofbuf,
|
"StartingIndex", ofbuf,
|
||||||
"RequestedCount", "0"); // Setting a value here gets twonky into fits
|
"RequestedCount", "0")); // Setting a value here gets twonky into fits
|
||||||
if (request == 0)
|
if (!request)
|
||||||
throw std::runtime_error("UpnpMakeAction() failed");
|
throw std::runtime_error("UpnpMakeAction() failed");
|
||||||
|
|
||||||
IXML_Document *response;
|
IXML_Document *_response;
|
||||||
auto code = UpnpSendAction(hdl, m_actionURL.c_str(),
|
auto code = UpnpSendAction(hdl, m_actionURL.c_str(),
|
||||||
m_serviceType.c_str(),
|
m_serviceType.c_str(),
|
||||||
0 /*devUDN*/, request, &response);
|
0 /*devUDN*/,
|
||||||
ixmlDocument_free(request);
|
request.get(), &_response);
|
||||||
if (code != UPNP_E_SUCCESS)
|
if (code != UPNP_E_SUCCESS)
|
||||||
throw FormatRuntimeError("UpnpSendAction() failed: %s",
|
throw FormatRuntimeError("UpnpSendAction() failed: %s",
|
||||||
UpnpGetErrorMessage(code));
|
UpnpGetErrorMessage(code));
|
||||||
|
|
||||||
|
UniqueIxmlDocument response(_response);
|
||||||
|
|
||||||
const char *value =
|
const char *value =
|
||||||
ixmlwrap::getFirstElementValue(response, "NumberReturned");
|
ixmlwrap::getFirstElementValue(response.get(),
|
||||||
|
"NumberReturned");
|
||||||
count = value != nullptr
|
count = value != nullptr
|
||||||
? ParseUnsigned(value)
|
? ParseUnsigned(value)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
offset += count;
|
offset += count;
|
||||||
|
|
||||||
value = ixmlwrap::getFirstElementValue(response, "TotalMatches");
|
value = ixmlwrap::getFirstElementValue(response.get(),
|
||||||
|
"TotalMatches");
|
||||||
if (value != nullptr)
|
if (value != nullptr)
|
||||||
total = ParseUnsigned(value);
|
total = ParseUnsigned(value);
|
||||||
|
|
||||||
bool success = ReadResultTag(dirbuf, response, error);
|
if (!ReadResultTag(dirbuf, response.get(), error))
|
||||||
ixmlDocument_free(response);
|
|
||||||
if (!success)
|
|
||||||
return false;
|
return false;
|
||||||
} while (count > 0 && offset < total);
|
} while (count > 0 && offset < total);
|
||||||
|
|
||||||
@ -165,27 +169,24 @@ ContentDirectoryService::getMetadata(UpnpClient_Handle hdl,
|
|||||||
Error &error) const
|
Error &error) const
|
||||||
{
|
{
|
||||||
// Create request
|
// Create request
|
||||||
IXML_Document *request =
|
UniqueIxmlDocument request(MakeActionHelper("Browse", m_serviceType.c_str(),
|
||||||
MakeActionHelper("Browse", m_serviceType.c_str(),
|
|
||||||
"ObjectID", objectId,
|
"ObjectID", objectId,
|
||||||
"BrowseFlag", "BrowseMetadata",
|
"BrowseFlag", "BrowseMetadata",
|
||||||
"Filter", "*",
|
"Filter", "*",
|
||||||
"SortCriteria", "",
|
"SortCriteria", "",
|
||||||
"StartingIndex", "0",
|
"StartingIndex", "0",
|
||||||
"RequestedCount", "1");
|
"RequestedCount", "1"));
|
||||||
if (request == nullptr)
|
if (request == nullptr)
|
||||||
throw std::runtime_error("UpnpMakeAction() failed");
|
throw std::runtime_error("UpnpMakeAction() failed");
|
||||||
|
|
||||||
IXML_Document *response;
|
IXML_Document *_response;
|
||||||
auto code = UpnpSendAction(hdl, m_actionURL.c_str(),
|
auto code = UpnpSendAction(hdl, m_actionURL.c_str(),
|
||||||
m_serviceType.c_str(),
|
m_serviceType.c_str(),
|
||||||
0 /*devUDN*/, request, &response);
|
0 /*devUDN*/, request.get(), &_response);
|
||||||
ixmlDocument_free(request);
|
|
||||||
if (code != UPNP_E_SUCCESS)
|
if (code != UPNP_E_SUCCESS)
|
||||||
throw FormatRuntimeError("UpnpSendAction() failed: %s",
|
throw FormatRuntimeError("UpnpSendAction() failed: %s",
|
||||||
UpnpGetErrorMessage(code));
|
UpnpGetErrorMessage(code));
|
||||||
|
|
||||||
bool success = ReadResultTag(dirbuf, response, error);
|
UniqueIxmlDocument response(_response);
|
||||||
ixmlDocument_free(response);
|
return ReadResultTag(dirbuf, response.get(), error);
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user