summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/tools.cpp76
-rw-r--r--include/media/mediaManager.h2
-rw-r--r--include/plugin.h26
-rw-r--r--include/tools.h6
-rw-r--r--media/mediaManager.cpp85
-rw-r--r--media/pluginManager.cpp50
6 files changed, 131 insertions, 114 deletions
diff --git a/common/tools.cpp b/common/tools.cpp
index f519276..015f998 100644
--- a/common/tools.cpp
+++ b/common/tools.cpp
@@ -328,32 +328,26 @@ int IxmlGetFirstDocumentItem( IN IXML_Document * doc, IN std::string item, std::
return error;
}
-//TODO const char* mit std::string ersetzen
-IXML_Element* IxmlAddProperty(IXML_Document* document, IXML_Element* node, const char* upnpproperty, const char* value){
+IXML_Element* IxmlAddProperty(IXML_Document* document, IXML_Element* node, const string& upnpproperty, const string& value){
if(!node) return NULL;
IXML_Element* PropertyNode = NULL;
- //TODO Bug #887
- char tvalue[MAX_METADATA_LENGTH];
- // trim the value to max metadata size
- if(value){
- strncpy(tvalue, value, MAX_METADATA_LENGTH);
- }
+ string tvalue = value.substr(MAX_METADATA_LENGTH);
+ string attribute = upnpproperty.substr(upnpproperty.find('@')+1);
+ string property = upnpproperty.substr(0, upnpproperty.find('@'));
- const char* attribute = att(upnpproperty);
- const char* property = prop(upnpproperty);
- if(attribute){
- if(!strcmp(property,"")){
- if(ixmlElement_setAttribute(node, attribute, tvalue)!=IXML_SUCCESS){
+ if(!attribute.empty()){
+ if(property.empty()){
+ if(ixmlElement_setAttribute(node, attribute.c_str(), tvalue.c_str())!=IXML_SUCCESS){
return NULL;
}
}
else {
- IXML_NodeList* NodeList = ixmlElement_getElementsByTagName(node, property);
+ IXML_NodeList* NodeList = ixmlElement_getElementsByTagName(node, property.c_str());
if(NodeList!=NULL){
PropertyNode = (IXML_Element*) ixmlNodeList_item(NodeList, 0);
if(PropertyNode){
- if(ixmlElement_setAttribute(PropertyNode, attribute, tvalue)!=IXML_SUCCESS){
+ if(ixmlElement_setAttribute(PropertyNode, attribute.c_str(), tvalue.c_str())!=IXML_SUCCESS){
return NULL;
}
}
@@ -368,64 +362,58 @@ IXML_Element* IxmlAddProperty(IXML_Document* document, IXML_Element* node, const
}
}
else {
- PropertyNode = ixmlDocument_createElement(document, property);
- IXML_Node* PropertyText = ixmlDocument_createTextNode(document, tvalue);
+ PropertyNode = ixmlDocument_createElement(document, property.c_str());
+ IXML_Node* PropertyText = ixmlDocument_createTextNode(document, tvalue.c_str());
ixmlNode_appendChild((IXML_Node*) PropertyNode, PropertyText);
ixmlNode_appendChild((IXML_Node*) node, (IXML_Node*) PropertyNode);
}
return PropertyNode;
}
-//TODO const char* mit std::string ersetzen
-IXML_Element* IxmlAddFilteredProperty(cStringList* Filter, IXML_Document* document, IXML_Element* node, const char* upnpproperty, const char* value){
+IXML_Element* IxmlAddFilteredProperty(const StringList& Filter, IXML_Document* document, IXML_Element* node, const string& upnpproperty, const string& value){
// leave out empty values.
- if(!value || !strcmp(value, "") || !strcmp(value, "0")){
+ if(value.empty() || !value.compare("0")){
return NULL;
}
- if(!Filter || Filter->Find(upnpproperty))
- return IxmlAddProperty(document, node, upnpproperty, value);
- else
- return NULL;
+ for(StringList::const_iterator it = Filter.begin(); it != Filter.end(); ++it){
+ if((*it).compare(upnpproperty) == 0) return IxmlAddProperty(document, node, upnpproperty, value);
+ }
+
+ return NULL;
}
-//TODO const char* mit std::string ersetzen
-IXML_Element* IxmlReplaceProperty(IXML_Document* document, IXML_Element* node, const char* upnpproperty, const char* newValue){
+IXML_Element* IxmlReplaceProperty(IXML_Document* document, IXML_Element* node, const string& upnpproperty, const string& newValue){
if(!node) return NULL;
IXML_Element* PropertyNode = NULL;
- //TODO Bug #887
- char tvalue[MAX_METADATA_LENGTH];
- // trim the value to max metadata size
- if(newValue){
- strncpy(tvalue, newValue, MAX_METADATA_LENGTH);
- }
+ string tvalue = newValue.substr(0, MAX_METADATA_LENGTH);
+ string attribute = upnpproperty.substr(upnpproperty.find('@')+1);
+ string property = upnpproperty.substr(0, upnpproperty.find('@'));
- const char* attribute = att(upnpproperty);
- const char* property = prop(upnpproperty);
- if(attribute){
- if(!strcmp(property,"")){
- if(newValue){
- if(ixmlElement_setAttribute(node, attribute, tvalue)!=IXML_SUCCESS){
+ if(!attribute.empty()){
+ if(property.empty()){
+ if(tvalue.empty()){
+ if(ixmlElement_setAttribute(node, attribute.c_str(), tvalue.c_str())!=IXML_SUCCESS){
return NULL;
}
}
else {
- ixmlElement_removeAttribute(node, attribute);
+ ixmlElement_removeAttribute(node, attribute.c_str());
}
}
else {
- IXML_NodeList* NodeList = ixmlElement_getElementsByTagName(node, property);
+ IXML_NodeList* NodeList = ixmlElement_getElementsByTagName(node, property.c_str());
if(NodeList!=NULL){
PropertyNode = (IXML_Element*) ixmlNodeList_item(NodeList, 0);
if(PropertyNode){
if(newValue){
- if(ixmlElement_setAttribute(PropertyNode, attribute, tvalue)!=IXML_SUCCESS){
+ if(ixmlElement_setAttribute(PropertyNode, attribute.c_str(), tvalue.c_str())!=IXML_SUCCESS){
return NULL;
}
}
else {
- ixmlElement_removeAttribute(PropertyNode, attribute);
+ ixmlElement_removeAttribute(PropertyNode, attribute.c_str());
}
}
else {
@@ -439,7 +427,7 @@ IXML_Element* IxmlReplaceProperty(IXML_Document* document, IXML_Element* node, c
}
}
else {
- IXML_NodeList* NodeList = ixmlElement_getElementsByTagName(node, property);
+ IXML_NodeList* NodeList = ixmlElement_getElementsByTagName(node, property.c_str());
if(NodeList!=NULL){
PropertyNode = (IXML_Element*) ixmlNodeList_item(NodeList, 0);
IXML_Node* PropertyText = ixmlNode_getFirstChild((IXML_Node*) PropertyNode);
@@ -448,7 +436,7 @@ IXML_Element* IxmlReplaceProperty(IXML_Document* document, IXML_Element* node, c
return NULL;
}
if(newValue){
- PropertyText = ixmlDocument_createTextNode(document, tvalue);
+ PropertyText = ixmlDocument_createTextNode(document, tvalue.c_str());
}
ixmlNode_appendChild((IXML_Node*) PropertyNode, PropertyText);
}
diff --git a/include/media/mediaManager.h b/include/media/mediaManager.h
index 8a8473f..929181f 100644
--- a/include/media/mediaManager.h
+++ b/include/media/mediaManager.h
@@ -72,6 +72,8 @@ private:
void Action();
bool CheckIntegrity();
+ void CreateResponse(MediaRequest&, const string&);
+
void OnContainerUpdate(string uri, long updateID);
uint32_t mSystemUpdateID;
diff --git a/include/plugin.h b/include/plugin.h
index 3da08ef..fe2c5f6 100644
--- a/include/plugin.h
+++ b/include/plugin.h
@@ -27,6 +27,7 @@ namespace object {
static const char* KEY_CREATOR = "dc:creator";
static const char* KEY_CLASS = "upnp:class";
static const char* KEY_RESTRICTED = "@restricted";
+ static const char* KEY_CHILD_COUNT = "@childCount";
static const char* KEY_DESCRIPTION = "dc:description";
static const char* KEY_LONG_DESCRIPTION = "upnp:longDescription";
static const char* KEY_DATE = "dc:date";
@@ -35,6 +36,8 @@ namespace object {
static const char* KEY_CHANNEL_NAME = "upnp:channelName";
static const char* KEY_SCHEDULED_START = "upnp:scheduledStartTime";
static const char* KEY_SCHEDULED_END = "upnp:scheduledEndTime";
+ static const char* KEY_OBJECT_UPDATE_ID = "upnp:objectUpdateID";
+ static const char* KEY_CONTAINER_UPDATE_ID= "upnp:containerUpdateID";
}
@@ -87,6 +90,7 @@ class PropertyValidator;
*
*/
class cMetadata {
+ friend class cMediaManager;
public:
/**
@@ -170,19 +174,15 @@ public:
typedef list<Resource> ResourceList;
typedef map<string, PropertyValidator*> ValidatorMap;
- bool AddProperty(Property property);
- bool SetProperty(Property property, int index = 0);
+ bool AddProperty(const Property& property);
+ bool SetProperty(const Property& property, int index = 0);
- Property& GetPropertyByKey(string property);
- PropertyRange GetPropertiesByKey(string property);
+ Property& GetPropertyByKey(const string& property);
+ PropertyRange GetPropertiesByKey(const string& property);
PropertyRange GetAllProperties();
- bool SetObjectID(string objectID);
- bool SetObjectIDByUri(string uri);
- string GetObjectID();
- bool SetParentID(string parentID);
- bool SetParentIDByUri(string uri);
- string GetParentID();
+ bool SetObjectIDByUri(const string& uri);
+ bool SetParentIDByUri(const string& uri);
private:
@@ -309,7 +309,7 @@ public:
/**
* Returns the meta data of a specific container.
*
- * This function is used to retrieve meta informatio about a
+ * This function is used to retrieve meta information about a
* container. It is NOT used to get information about files or
* resources, as this is done by the media plugins.
*
@@ -329,7 +329,7 @@ public:
* - Restricted: true
*
*/
- virtual cMetadata* GetMetadata(string uri);
+ virtual cMetadata GetMetadata(string uri);
/**
* Get the HTTP Uri.
@@ -502,7 +502,7 @@ public:
* @param uri the absolute path to the resource.
* @return the media resource information.
*/
- virtual cMetadata* GetMetadata(string uri) = 0;
+ virtual cMetadata GetMetadata(string uri) = 0;
protected:
};
diff --git a/include/tools.h b/include/tools.h
index b12f6be..3c2fcd3 100644
--- a/include/tools.h
+++ b/include/tools.h
@@ -150,11 +150,11 @@ namespace ixml {
* @param upnpproperty the upnp property
* @param value the value of the upnp property
*/
- IXML_Element* IxmlAddProperty(IN IXML_Document* document, IN IXML_Element* node, IN const char* upnpproperty, IN const char* value );
+ IXML_Element* IxmlAddProperty(IN IXML_Document* document, IN IXML_Element* node, IN const string& upnpproperty, IN const string& value );
- IXML_Element* IxmlAddFilteredProperty(IN cStringList* Filter, IN IXML_Document* document, IN IXML_Element* node, IN const char* upnpproperty, IN const char* value );
+ IXML_Element* IxmlAddFilteredProperty(IN const StringList& Filter, IN IXML_Document* document, IN IXML_Element* node, IN const string& upnpproperty, IN const string& value );
- IXML_Element* IxmlReplaceProperty(IN IXML_Document* document, IN IXML_Element* node, IN const char* upnpproperty, IN const char* newValue );
+ IXML_Element* IxmlReplaceProperty(IN IXML_Document* document, IN IXML_Element* node, IN const string& upnpproperty, IN const string& newValue );
}
}
diff --git a/media/mediaManager.cpp b/media/mediaManager.cpp
index 530dbe3..56c206a 100644
--- a/media/mediaManager.cpp
+++ b/media/mediaManager.cpp
@@ -98,55 +98,97 @@ StringList cMediaManager::GetSupportedProtocolInfos() const {
return list;
}
-int cMediaManager::Browse(BrowseRequest& request){
+void cMediaManager::CreateResponse(MediaRequest& request, const string& select){
+ stringstream resources, details;
+
+ resources << "SELECT * FROM resources WHERE "
+ << "`" << property::object::KEY_OBJECTID << "` = "
+ << "':objectID'";
+
+ tntdb::Statement select1 = mConnection.prepare(select);
+ tntdb::Statement select2 = mConnection.prepare(resources.str());
+
+ StringList filterList = cFilterCriteria::parse(request.filter);
+
request.numberReturned = 0;
- request.totalMatches = 0;
request.updateID = 0;
- stringstream sql;
+ // Using cursors, cannot calculate totalMatches as this would require another SQL request.
+ request.totalMatches = 0;
+
+ string didl = "<DIDL-Lite "
+ "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" "
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" "
+ "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" "
+ "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\"></DIDL-Lite>";
+
+
+
+ for(tntdb::Statement::const_iterator it = select1.begin(); it != select1.end(); ++it){
+ tntdb::Row row = (*it);
+
+
+ select2.setString("objectID", row.getString(property::object::KEY_OBJECTID));
+
+ for(tntdb::Statement::const_iterator it2 = select.begin(); it2 != select.end(); ++it2){
+ tntdb::Row row2 = (*it2);
- sql << "SELECT * FROM metadata LEFT JOIN resources USING "
- << "(`" << property::object::KEY_OBJECTID << "`)"
- << " WHERE ";
+ cMetadata::Resource resource;
+
+ resource.SetBitrate(row2.getInt(property::resource::KEY_BITRATE));
+ resource.SetBitsPerSample(row2.getInt(property::resource::KEY_BITS_PER_SAMPLE));
+
+ }
+
+ ++request.numberReturned;
+ }
+
+ request.result;
+}
+
+int cMediaManager::Browse(BrowseRequest& request){
+ stringstream metadata;
+
+ metadata << "SELECT *,(SELECT COUNT(1) FROM metadata m WHERE "
+ << "m.`" << property::object::KEY_PARENTID << "` = "
+ << "p.`" << property::object::KEY_OBJECTID << "`) as "
+ << "`" << property::object::KEY_CHILD_COUNT << "` FROM metadata p WHERE ";
switch (request.browseMetadata){
case CD_BROWSE_METADATA:
- sql << "`" << property::object::KEY_OBJECTID << "`";
+ metadata << "`" << property::object::KEY_OBJECTID << "`";
+
+ // Set the offset and count to 0,1 as this is the only allowed option here.
+ request.requestCount = 1;
+ request.startIndex = 0;
break;
case CD_BROWSE_DIRECT_CHILDREN:
- sql << "`" << property::object::KEY_PARENTID << "`";
+ metadata << "`" << property::object::KEY_PARENTID << "`";
break;
default:
esyslog("UPnP\tInvalid arguments. Browse flag invalid");
return UPNP_SOAP_E_INVALID_ARGS;
}
- sql << " = '" << request.objectID << "'";
+ metadata << " = '" << request.objectID << "'";
cSortCriteria::SortCriteriaList list = cSortCriteria::parse(request.sortCriteria);
if(!list.empty()){
- sql << " ORDER BY ";
+ metadata << " ORDER BY ";
upnp::cSortCriteria::SortCriteriaList::iterator it = list.begin();
- sql << (*it).property << " " << ((*it).sortDescending ? "DESC" : "ASC");
+ metadata << (*it).property << " " << ((*it).sortDescending ? "DESC" : "ASC");
for(++it; it != list.end(); ++it){
- sql << ", " << (*it).property << " " << ((*it).sortDescending ? "DESC" : "ASC");
+ metadata << ", " << (*it).property << " " << ((*it).sortDescending ? "DESC" : "ASC");
}
}
if(request.requestCount){
- sql << " LIMIT " << request.startIndex << ", " << request.requestCount;
+ metadata << " LIMIT " << request.startIndex << ", " << request.requestCount;
}
- cout << sql.str() << endl;
- tntdb::Statement select = mConnection.prepare(sql.str());
- for(tntdb::Statement::const_iterator it = select.begin(); it != select.end(); ++it){
- tntdb::Row row = (*it);
- cout << row.getString(property::object::KEY_TITLE) << endl;
- }
-
- return UPNP_E_SUCCESS;
+ return (request.totalMatches == 0 && request.numberReturned == 0) ? UPNP_CDS_E_CANT_PROCESS_REQUEST : UPNP_E_SUCCESS;
}
int cMediaManager::Search(SearchRequest& request){
@@ -197,6 +239,7 @@ bool cMediaManager::Initialise(){
<< "`" << property::object::KEY_CHANNEL_NAME << "` TEXT,"
<< "`" << property::object::KEY_SCHEDULED_START << "` TEXT,"
<< "`" << property::object::KEY_SCHEDULED_END << "` TEXT"
+ << "`" << property::object::KEY_OBJECT_UPDATE_ID << "` INTEGER"
<< ")";
tntdb::Statement objectTable = mConnection.prepare(ss.str());
diff --git a/media/pluginManager.cpp b/media/pluginManager.cpp
index 5b397b7..a9bfd73 100644
--- a/media/pluginManager.cpp
+++ b/media/pluginManager.cpp
@@ -24,7 +24,7 @@ public:
}
virtual ~PropertyValidator(){}
virtual string GetPropertyKey() const { return key; };
- virtual bool Validate(cMetadata::Property property) = 0;
+ virtual bool Validate(const cMetadata::Property& property) = 0;
};
void cMetadata::RegisterPropertyValidator(PropertyValidator* validator){
@@ -33,31 +33,15 @@ void cMetadata::RegisterPropertyValidator(PropertyValidator* validator){
validators[key] = validator;
}
-bool cMetadata::SetObjectIDByUri(string uri){
- return SetObjectID(tools::GenerateUUIDFromURL(uri));
+bool cMetadata::SetObjectIDByUri(const string& uri){
+ return SetProperty(Property(property::object::KEY_OBJECTID, tools::GenerateUUIDFromURL(uri)));
}
-bool cMetadata::SetParentIDByUri(string uri){
- return SetParentID(tools::GenerateUUIDFromURL(uri));
+bool cMetadata::SetParentIDByUri(const string& uri){
+ return SetProperty(Property(property::object::KEY_PARENTID, tools::GenerateUUIDFromURL(uri)));
}
-bool cMetadata::SetObjectID(string objectID){
- if(objectID.empty() || objectID.compare("0") == 0) return false;
-
- SetProperty(Property(property::object::KEY_OBJECTID, objectID));
-
- return true;
-};
-
-bool cMetadata::SetParentID(string parentID){
- if(parentID.compare("-1") == 0) return false;
-
- SetProperty(Property(property::object::KEY_PARENTID, parentID));
-
- return true;
-};
-
-bool cMetadata::AddProperty(Property property){
+bool cMetadata::AddProperty(const Property& property){
string key = property.GetKey();
// Try to find a validator
@@ -91,7 +75,7 @@ bool cMetadata::AddProperty(Property property){
return true;
}
-bool cMetadata::SetProperty(Property property, int index){
+bool cMetadata::SetProperty(const Property& property, int index){
// Try to find a validator
PropertyValidator* validator = validators[property.GetKey()];
// If there is one and it fails to validate the property, return false.
@@ -116,7 +100,7 @@ bool cMetadata::SetProperty(Property property, int index){
}
-cMetadata::PropertyRange cMetadata::GetPropertiesByKey(string property) {
+cMetadata::PropertyRange cMetadata::GetPropertiesByKey(const string& property) {
return properties.equal_range(property);
}
@@ -125,7 +109,7 @@ cMetadata::PropertyRange cMetadata::GetAllProperties() {
return range;
}
-cMetadata::Property& cMetadata::GetPropertyByKey(string property) {
+cMetadata::Property& cMetadata::GetPropertyByKey(const string& property) {
return (*properties.find(property)).second;
}
@@ -216,7 +200,7 @@ bool cMetadata::Resource::SetColorDepth(uint32_t colorDepth){
class ClassValidator : public PropertyValidator {
public:
ClassValidator() : PropertyValidator(property::object::KEY_CLASS) {}
- virtual bool Validate(cMetadata::Property property){
+ virtual bool Validate(const cMetadata::Property& property){
string value = property.GetString();
if(value.find("object.container", 0) == 0 ||
@@ -231,15 +215,15 @@ public:
}
} ClassValidatorInst;
-cMetadata* cUPnPResourceProvider::GetMetadata(string uri){
+cMetadata cUPnPResourceProvider::GetMetadata(string uri){
- cMetadata* metadata = new cMetadata;
+ cMetadata metadata;
- metadata->SetObjectIDByUri(uri);
- metadata->SetParentIDByUri(uri.substr(0,uri.find_last_of("/")));
- metadata->SetProperty(cMetadata::Property(property::object::KEY_TITLE, uri.substr(uri.find_last_of("/")+1)));
- metadata->SetProperty(cMetadata::Property(property::object::KEY_CLASS, "object.container"));
- metadata->SetProperty(cMetadata::Property(property::object::KEY_RESTRICTED, true));
+ metadata.SetObjectIDByUri(uri);
+ metadata.SetParentIDByUri(uri.substr(0,uri.find_last_of("/")));
+ metadata.SetProperty(cMetadata::Property(property::object::KEY_TITLE, uri.substr(uri.find_last_of("/")+1)));
+ metadata.SetProperty(cMetadata::Property(property::object::KEY_CLASS, "object.container"));
+ metadata.SetProperty(cMetadata::Property(property::object::KEY_RESTRICTED, true));
return metadata;