summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY5
-rw-r--r--common.h10
-rw-r--r--database/object.cpp148
-rw-r--r--database/resources.cpp2
-rw-r--r--inc/object.h8
-rw-r--r--inc/util.h9
-rw-r--r--misc/util.cpp76
7 files changed, 173 insertions, 85 deletions
diff --git a/HISTORY b/HISTORY
index e2a4c1c..05b1439 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,11 @@
VDR Plugin 'upnp' Revision History
----------------------------------
+2009-01-25: Version 0.0.2-alpha1
+
+ - Bug: A minor bug prevented the plugin from detecting the resources
+ correnctly
+
2009-01-24: Version 0.0.2-alpha0
- New: Added record streaming support for SDTV
diff --git a/common.h b/common.h
index 6b0d676..7a19aa1 100644
--- a/common.h
+++ b/common.h
@@ -376,10 +376,13 @@ enum UPNP_WEB_METHODS {
#define UPNP_PROP_WRITESTATUS "upnp:writeStatus"
#define UPNP_PROP_CLASS "upnp:class"
#define UPNP_PROP_CLASSNAME UPNP_PROP_CLASS "@name"
+#define UPNP_PROP_CREATECLASS "upnp:createClass"
#define UPNP_PROP_SEARCHCLASS "upnp:searchClass"
#define UPNP_PROP_SCLASSDERIVED UPNP_PROP_SEARCHCLASS "@includeDerived"
-#define UPNP_PROP_REFERENCEID UPNP_OBJECT_ITEM "@refID"
#define UPNP_PROP_SCLASSNAME UPNP_PROP_SEARCHCLASS "@name"
+#define UPNP_PROP_CCLASSDERIVED UPNP_PROP_CREATECLASS "@includeDerived"
+#define UPNP_PROP_CCLASSNAME UPNP_PROP_CREATECLASS "@name"
+#define UPNP_PROP_REFERENCEID UPNP_OBJECT_ITEM "@refID"
#define UPNP_PROP_SEARCHABLE UPNP_OBJECT_CONTAINER "@searchable"
#define UPNP_PROP_CHILDCOUNT UPNP_OBJECT_CONTAINER "@childcount"
#define UPNP_PROP_RESOURCE "res"
@@ -481,8 +484,9 @@ enum UPNP_WEB_METHODS {
UPNP_PROP_LONGDESCRIPTION ","\
UPNP_PROP_PUBLISHER
-#define UPNP_DURATION_FORMAT_STRING "%5d:%02d:%02d"
-#define UPNP_DURATION_FRAME_FORMAT ".%03d"
+#define UPNP_DURATION_FORMAT "%5d:%02d:%02d"
+#define UPNP_DURATION_FRAME_FORMAT "%5d:%02d:%02d.%03d"
+#define UPNP_MAX_METADATA_LENGTH 1024
#define AVDETECTOR_TIME_BASE 1000
/****************************************************
diff --git a/database/object.cpp b/database/object.cpp
index 71dfe63..b193567 100644
--- a/database/object.cpp
+++ b/database/object.cpp
@@ -334,30 +334,22 @@ IXML_Node* cUPnPClassItem::createDIDLFragment(IXML_Document* Document, cStringLi
MESSAGE(VERBOSE_DIDL, "ParentID: %s", *this->getParentID());
MESSAGE(VERBOSE_DIDL, "Restricted: %s", this->isRestricted()?"1":"0");
MESSAGE(VERBOSE_DIDL, "Class: %s", this->getClass());
+ MESSAGE(VERBOSE_DIDL, "Filter: %d", Filter?Filter->Size():-1);
IXML_Node* Didl = ixmlNode_getFirstChild((IXML_Node*) this->mDIDLFragment);
IXML_Element* eItem = ixmlDocument_createElement(this->mDIDLFragment, "item");
- ixmlElement_setAttribute(eItem, att(UPNP_PROP_OBJECTID), *this->getID());
- ixmlElement_setAttribute(eItem, att(UPNP_PROP_PARENTID), *this->getParentID());
- ixmlElement_setAttribute(eItem, att(UPNP_PROP_RESTRICTED), this->isRestricted()?"1":"0");
-
ixmlNode_appendChild(Didl, (IXML_Node*) eItem);
- IXML_Element* eTitle = ixmlDocument_createElement(this->mDIDLFragment, UPNP_PROP_TITLE);
- IXML_Node* Title = ixmlDocument_createTextNode(this->mDIDLFragment, this->getTitle());
-
- IXML_Element* eClass = ixmlDocument_createElement(this->mDIDLFragment, UPNP_PROP_CLASS);
- IXML_Node* Class = ixmlDocument_createTextNode(this->mDIDLFragment, this->getClass());
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_OBJECTID, *this->getID());
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_PARENTID, *this->getParentID());
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_RESTRICTED, this->isRestricted()?"1":"0");
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_TITLE, this->getTitle());
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_CLASS, this->getClass());
- ixmlNode_appendChild((IXML_Node*) eTitle, Title);
- ixmlNode_appendChild((IXML_Node*) eClass, Class);
- ixmlNode_appendChild((IXML_Node*) eItem, (IXML_Node*) eTitle);
- ixmlNode_appendChild((IXML_Node*) eItem, (IXML_Node*) eClass);
-
-// if(Filter==NULL || Filter->Find(UPNP_PROP_CREATOR)) ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_CREATOR, this->getCreator());
-// if(Filter==NULL || Filter->Find(UPNP_PROP_WRITESTATUS)) ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_WRITESTATUS, itoa(this->getWriteStatus()));
-// if(Filter==NULL || Filter->Find(UPNP_PROP_REFERENCEID)) ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_REFERENCEID, *this->getReferenceID());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CREATOR, this->getCreator());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_WRITESTATUS, itoa(this->getWriteStatus()));
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_REFERENCEID, ((int)(this->getReferenceID())<0)?"":*this->getReferenceID());
for(cUPnPResource* Resource = this->getResources()->First(); Resource; Resource = this->getResources()->Next(Resource)){
MESSAGE(VERBOSE_DIDL, "Resource: %s", Resource->getResource());
@@ -367,18 +359,17 @@ IXML_Node* cUPnPClassItem::createDIDLFragment(IXML_Document* Document, cStringLi
cString ResourceURL = cString::sprintf("%s%s/get?resId=%d", *URLBase, UPNP_DIR_SHARES, Resource->getID());
MESSAGE(VERBOSE_DIDL, "Resource-URI: %s", *ResourceURL);
+
+ IXML_Element* eRes = ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_RESOURCE, *ResourceURL);
+ if(eRes){
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_BITRATE, itoa(Resource->getBitrate()));
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_BITSPERSAMPLE, itoa(Resource->getBitsPerSample()));
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_COLORDEPTH, itoa(Resource->getColorDepth()));
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_DURATION, Resource->getDuration());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_PROTOCOLINFO, Resource->getProtocolInfo());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eRes, UPNP_PROP_SIZE, cString::sprintf("%lld", Resource->getFileSize()));
+ }
- IXML_Element* eRes = ixmlDocument_createElement(this->mDIDLFragment, UPNP_PROP_RESOURCE);
- IXML_Node* Res = ixmlDocument_createTextNode(this->mDIDLFragment, *ResourceURL);
- ixmlNode_appendChild((IXML_Node*) eRes, Res);
-
- if(Resource->getBitrate()) ixmlElement_setAttribute(eRes, att(UPNP_PROP_BITRATE), itoa(Resource->getBitrate()));
- if(Resource->getBitsPerSample()) ixmlElement_setAttribute(eRes, att(UPNP_PROP_BITSPERSAMPLE), itoa(Resource->getBitsPerSample()));
- if(Resource->getColorDepth()) ixmlElement_setAttribute(eRes, att(UPNP_PROP_COLORDEPTH), itoa(Resource->getColorDepth()));
- if(Resource->getDuration()) ixmlElement_setAttribute(eRes, att(UPNP_PROP_DURATION), Resource->getDuration());
- if(Resource->getProtocolInfo()) ixmlElement_setAttribute(eRes, att(UPNP_PROP_PROTOCOLINFO), Resource->getProtocolInfo());
-
- ixmlNode_appendChild((IXML_Node*) eItem, (IXML_Node*) eRes);
}
return (IXML_Node*)eItem;
@@ -411,25 +402,38 @@ IXML_Node* cUPnPClassContainer::createDIDLFragment(IXML_Document* Document, cStr
MESSAGE(VERBOSE_DIDL, "ParentID: %s", *this->getParentID());
MESSAGE(VERBOSE_DIDL, "Restricted: %s", this->isRestricted()?"1":"0");
MESSAGE(VERBOSE_DIDL, "Class: %s", this->getClass());
+ MESSAGE(VERBOSE_DIDL, "Filter: %d", Filter?Filter->Size():-1);
IXML_Node* Didl = ixmlNode_getFirstChild((IXML_Node*) this->mDIDLFragment);
IXML_Element* eItem = ixmlDocument_createElement(this->mDIDLFragment, "container");
- ixmlElement_setAttribute(eItem, att(UPNP_PROP_OBJECTID), *this->getID());
- ixmlElement_setAttribute(eItem, att(UPNP_PROP_PARENTID), *this->getParentID());
- ixmlElement_setAttribute(eItem, att(UPNP_PROP_RESTRICTED), this->isRestricted()?"1":"0");
ixmlNode_appendChild(Didl, (IXML_Node*) eItem);
- IXML_Element* eTitle = ixmlDocument_createElement(this->mDIDLFragment, UPNP_PROP_TITLE);
- IXML_Node* Title = ixmlDocument_createTextNode(this->mDIDLFragment, this->getTitle());
-
- IXML_Element* eClass = ixmlDocument_createElement(this->mDIDLFragment, UPNP_PROP_CLASS);
- IXML_Node* Class = ixmlDocument_createTextNode(this->mDIDLFragment, this->getClass());
-
- ixmlNode_appendChild((IXML_Node*) eTitle, Title);
- ixmlNode_appendChild((IXML_Node*) eClass, Class);
- ixmlNode_appendChild((IXML_Node*) eItem, (IXML_Node*) eTitle);
- ixmlNode_appendChild((IXML_Node*) eItem, (IXML_Node*) eClass);
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_OBJECTID, *this->getID());
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_PARENTID, *this->getParentID());
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_RESTRICTED, this->isRestricted()?"1":"0");
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_TITLE, this->getTitle());
+ ixmlAddProperty(this->mDIDLFragment, eItem, UPNP_PROP_CLASS, this->getClass());
+
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_DLNA_CONTAINERTYPE, this->getContainerType());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CHILDCOUNT, itoa(this->getChildCount()));
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_SEARCHABLE, this->isSearchable()?"1":"0");
+
+ const tClassVector* CreateClasses = this->getCreateClasses();
+ for(unsigned int i = 0; i < CreateClasses->size(); i++){
+ cClass CreateClass = CreateClasses->at(i);
+ IXML_Element* eCreateClasses = ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CREATECLASS, CreateClass.ID);
+ if(eCreateClasses)
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CCLASSDERIVED, CreateClass.includeDerived?"1":"0");
+ }
+ const tClassVector* SearchClasses = this->getSearchClasses();
+ for(unsigned int i = 0; i < SearchClasses->size(); i++){
+ cClass SearchClass = SearchClasses->at(i);
+ IXML_Element* eSearchClasses = ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_SEARCHCLASS, SearchClass.ID);
+ if(eSearchClasses)
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_SCLASSDERIVED, SearchClass.includeDerived?"1":"0");
+ }
+
return (IXML_Node*)eItem;
}
@@ -596,9 +600,52 @@ cUPnPClassVideoItem::cUPnPClassVideoItem(){
cUPnPClassVideoItem::~cUPnPClassVideoItem(){
}
-//cString cUPnPClassVideoItem::createDIDLFragment(cStringList* Filter){
-// return NULL;
-//}
+IXML_Node* cUPnPClassVideoItem::createDIDLFragment(IXML_Document* Document, cStringList* Filter){
+ IXML_Element* eItem = (IXML_Element*) cUPnPClassItem::createDIDLFragment(Document, Filter);
+
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_LONGDESCRIPTION, this->getLongDescription());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_DESCRIPTION, this->getDescription());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_LANGUAGE, this->getLanguage());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_RATING, this->getRating());
+
+ char* genre = strtok(strdup0(this->getGenre()), ",");
+ while(genre){
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_GENRE, genre);
+ genre = strtok(NULL, ",");
+ }
+
+ char* producer = strtok(strdup0(this->getProducers()), ",");
+ while(producer){
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_PRODUCER, producer);
+ producer = strtok(NULL, ",");
+ }
+
+ char* actor = strtok(strdup0(this->getActors()), ",");
+ while(actor){
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_ACTOR, actor);
+ actor = strtok(NULL, ",");
+ }
+
+ char* director = strtok(strdup0(this->getDirectors()), ",");
+ while(director){
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_DIRECTOR, director);
+ director = strtok(NULL, ",");
+ }
+
+ char* publisher = strtok(strdup0(this->getPublishers()), ",");
+ while(publisher){
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_PUBLISHER, publisher);
+ publisher = strtok(NULL, ",");
+ }
+
+ char* relation = strtok(strdup0(this->getRelations()), ",");
+ while(relation){
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_RELATION, relation);
+ relation = strtok(NULL, ",");
+ }
+
+ return (IXML_Node*) eItem;
+}
cStringList* cUPnPClassVideoItem::getPropertyList(){
cStringList* Properties = cUPnPClassItem::getPropertyList();
@@ -754,9 +801,16 @@ cUPnPClassVideoBroadcast::cUPnPClassVideoBroadcast(){
cUPnPClassVideoBroadcast::~cUPnPClassVideoBroadcast(){
}
-//cString cUPnPClassVideoBroadcast::createDIDLFragment(cStringList* Filter){
-// return NULL;
-//}
+IXML_Node* cUPnPClassVideoBroadcast::createDIDLFragment(IXML_Document* Document, cStringList* Filter){
+ IXML_Element* eItem = (IXML_Element*) cUPnPClassItem::createDIDLFragment(Document, Filter);
+
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CHANNELNAME, this->getChannelName());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_CHANNELNR, itoa(this->getChannelNr()));
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_ICON, this->getIcon());
+ ixmlAddFilteredProperty(Filter, this->mDIDLFragment, eItem, UPNP_PROP_REGION, this->getRegion());
+
+ return (IXML_Node*) eItem;
+}
cStringList* cUPnPClassVideoBroadcast::getPropertyList(){
cStringList* Properties = cUPnPClassVideoItem::getPropertyList();
diff --git a/database/resources.cpp b/database/resources.cpp
index 8ff478f..23403d5 100644
--- a/database/resources.cpp
+++ b/database/resources.cpp
@@ -156,7 +156,7 @@ int cUPnPResources::createFromRecording(cUPnPClassVideoItem* Object, cRecording*
cUPnPResource* Resource = this->mMediator->newResource(Object, UPNP_RESOURCE_RECORDING,ResourceFile, Detector->getDLNAProfile()->mime, ProtocolInfo);
Resource->mBitrate = Detector->getBitrate();
Resource->mBitsPerSample = Detector->getBitsPerSample();
- Resource->mDuration = duration(Detector->getDuration());
+ Resource->mDuration = duration(Detector->getDuration(), AVDETECTOR_TIME_BASE);
Resource->mResolution = (Detector->getWidth() && Detector->getHeight()) ? *cString::sprintf("%dx%d",Detector->getWidth(), Detector->getHeight()) : NULL;
Resource->mSampleFrequency = Detector->getSampleFrequency();
Resource->mSize = Detector->getFileSize();
diff --git a/inc/object.h b/inc/object.h
index bceb3f1..1031589 100644
--- a/inc/object.h
+++ b/inc/object.h
@@ -752,7 +752,7 @@ public:
*
* @return a vector with all search classes
*/
- const std::vector<cClass>* getSearchClasses() const { return &(this->mSearchClasses); }
+ const tClassVector* getSearchClasses() const { return &(this->mSearchClasses); }
/**
* Get the create classes
*
@@ -763,7 +763,7 @@ public:
*
* @return a vector with create classes
*/
- const std::vector<cClass>* getCreateClasses() const { return &(this->mCreateClasses); }
+ const tClassVector* getCreateClasses() const { return &(this->mCreateClasses); }
/**
* Is this container searchable
*
@@ -832,7 +832,7 @@ protected:
cUPnPClassVideoItem();
public:
virtual ~cUPnPClassVideoItem();
- //virtual cString createDIDLFragment(cStringList* Filter);
+ virtual IXML_Node* createDIDLFragment(IXML_Document* Document, cStringList* Filter);
virtual cStringList* getPropertyList();
virtual bool setProperty(const char* Property, const char* Value);
virtual bool getProperty(const char* Property, char** Value) const;
@@ -1141,7 +1141,7 @@ protected:
cUPnPClassVideoBroadcast();
public:
virtual ~cUPnPClassVideoBroadcast();
- //virtual cString createDIDLFragment(cStringList* Filter);
+ virtual IXML_Node* createDIDLFragment(IXML_Document* Document, cStringList* Filter);
virtual cStringList* getPropertyList();
virtual bool setProperty(const char* Property, const char* Value);
virtual bool getProperty(const char* Property, char** Value) const;
diff --git a/inc/util.h b/inc/util.h
index 5f6f4a3..f194186 100644
--- a/inc/util.h
+++ b/inc/util.h
@@ -88,14 +88,17 @@ char* ixmlGetFirstDocumentItem( IN IXML_Document * doc, IN const char *item, int
* The property must have the pattern "namespace:property@attribute".
*
* @return returns
- * - \bc <0, in case of an error
- * - \bc 0, otherwise
+ * - \bc NULL, in case of an error
+ * - \bc the newly created property node or the node at which the attribute was
+ * appended to
* @param document the \c IXML document to put the parameter in
* @param node the specific node where to put the parameter
* @param upnpproperty the upnp property
* @param value the value of the upnp property
*/
-int ixmlAddProperty(IN IXML_Document* document, IN IXML_Element* node, const char* upnpproperty, const char* value );
+IXML_Element* ixmlAddProperty(IN IXML_Document* document, IN IXML_Element* node, IN const char* upnpproperty, IN const char* value );
+
+IXML_Element* ixmlAddFilteredProperty(IN cStringList* Filter, IN IXML_Document* document, IN IXML_Element* node, IN const char* upnpproperty, IN const char* value );
/**
* creates a part of a string
*
diff --git a/misc/util.cpp b/misc/util.cpp
index d93d027..0781307 100644
--- a/misc/util.cpp
+++ b/misc/util.cpp
@@ -18,13 +18,15 @@
#include <iosfwd>
#include <time.h>
-#define DURATION_MAX_STRING_LENGTH 13 // DLNA: 1-5 DIGIT hours :
+#define DURATION_MAX_STRING_LENGTH 16 // DLNA: 1-5 DIGIT hours :
// 2 DIGIT minutes :
// 2 DIGIT seconds .
// 3 DIGIT fraction
char* duration(off64_t duration, unsigned int timeBase){
- if (timeBase == 0) timeBase = 1;
+ if(!timeBase){
+ timeBase = 1;
+ }
int seconds, minutes, hours, fraction;
@@ -37,28 +39,29 @@ char* duration(off64_t duration, unsigned int timeBase){
char* output = new char[DURATION_MAX_STRING_LENGTH];
- if(!snprintf(
- output,
- DURATION_MAX_STRING_LENGTH,
- UPNP_DURATION_FORMAT_STRING,
- hours, minutes, seconds)
- ){
- delete output;
- return NULL;
+ if(timeBase > 1){
+ if(!snprintf(
+ output,
+ DURATION_MAX_STRING_LENGTH,
+ UPNP_DURATION_FRAME_FORMAT,
+ hours, minutes, seconds, fraction) < 0
+ ){
+ delete [] output;
+ return NULL;
+ }
}
else {
- if(timeBase > 1 &&
- !snprintf(
+ if(snprintf(
output,
DURATION_MAX_STRING_LENGTH,
- "%s" UPNP_DURATION_FRAME_FORMAT,
- output, fraction)
+ UPNP_DURATION_FORMAT,
+ hours, minutes, seconds) < 0
){
- delete output;
+ delete [] output;
return NULL;
}
- else return output;
}
+ return output;
}
char* substr(const char* str, unsigned int offset, unsigned int length){
@@ -475,39 +478,58 @@ char* ixmlGetFirstDocumentItem( IN IXML_Document * doc, IN const char *item, int
return ret;
}
-int ixmlAddProperty(IXML_Document* document, IXML_Element* node, const char* upnpproperty, const char* value){
- if(!node) return -1;
+IXML_Element* ixmlAddProperty(IXML_Document* document, IXML_Element* node, const char* upnpproperty, const char* value){
+ if(!node) return NULL;
IXML_Element* PropertyNode = NULL;
+ char tvalue[UPNP_MAX_METADATA_LENGTH];
+ // trim the value to max metadata size
+ if(value){
+ strncpy(tvalue, value, UPNP_MAX_METADATA_LENGTH);
+ }
+
const char* attribute = att(upnpproperty);
const char* property = prop(upnpproperty);
if(attribute){
- if(strcasecmp(property,"")){
- ixmlElement_setAttribute(node, attribute, value);
+ if(!strcmp(property,"")){
+ ixmlElement_setAttribute(node, attribute, tvalue);
}
else {
IXML_NodeList* NodeList = ixmlElement_getElementsByTagName(node, property);
if(NodeList!=NULL){
- IXML_Node* Node = ixmlNodeList_item(NodeList, 0);
- PropertyNode = (IXML_Element*) ixmlNode_getFirstChild(Node);
+ PropertyNode = (IXML_Element*) ixmlNodeList_item(NodeList, 0);
if(PropertyNode){
- ixmlElement_setAttribute(PropertyNode, attribute, value);
+ if(ixmlElement_setAttribute(PropertyNode, attribute, tvalue)!=IXML_SUCCESS){
+ return NULL;
+ }
}
else {
ixmlNodeList_free(NodeList);
- return -1;
+ return NULL;
}
}
else {
- return -1;
+ return NULL;
}
}
}
else {
PropertyNode = ixmlDocument_createElement(document, property);
- IXML_Node* PropertyText = ixmlDocument_createTextNode(document, value);
+ IXML_Node* PropertyText = ixmlDocument_createTextNode(document, tvalue);
ixmlNode_appendChild((IXML_Node*) PropertyNode, PropertyText);
ixmlNode_appendChild((IXML_Node*) node, (IXML_Node*) PropertyNode);
}
- return 0;
+ return PropertyNode;
}
+
+IXML_Element* ixmlAddFilteredProperty(cStringList* Filter, IXML_Document* document, IXML_Element* node, const char* upnpproperty, const char* value){
+ // leave out empty values.
+ if(!value || !strcmp(value, "") || !strcmp(value, "0")){
+ return NULL;
+ }
+
+ if(!Filter || Filter->Find(upnpproperty))
+ return ixmlAddProperty(document, node, upnpproperty, value);
+ else
+ return NULL;
+} \ No newline at end of file