35 #ifndef _PLT_UTILITIES_H_
36 #define _PLT_UTILITIES_H_
58 const char* namespc) :
59 m_Element(element), m_Name(name), m_Namespace(namespc) {}
61 bool operator()(
const NPT_XmlAttribute*
const & attribute)
const {
62 if (attribute->GetName() == m_Name) {
64 const NPT_String& prefix = attribute->GetPrefix();
65 if (m_Namespace[0] ==
'\0') {
67 return prefix.IsEmpty();
71 const NPT_String* namespc = m_Element.GetNamespaceUri(prefix);
72 return namespc && *namespc == m_Namespace;
84 const NPT_XmlElementNode& m_Element;
86 const char* m_Namespace;
102 static NPT_Result Parse(
const NPT_String& xml, NPT_XmlElementNode*& tree) {
107 NPT_XmlParser parser;
109 NPT_Result result = parser.Parse(xml, node);
110 if (NPT_FAILED(result)) {
115 tree = node->AsElementNode();
124 static NPT_Result GetChildText(NPT_XmlElementNode* node,
127 const char* namespc =
"",
128 NPT_Cardinal max_size = 1024) {
131 if (!node)
return NPT_FAILURE;
134 if (namespc && namespc[0] ==
'\0') {
135 namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
138 NPT_XmlElementNode* child = node->GetChild(tag, namespc);
139 if (!child)
return NPT_FAILURE;
141 const NPT_String* text = child->GetText();
143 value = text?text->SubString(0, max_size):
"";
147 static NPT_Result RemoveAttribute(NPT_XmlElementNode* node,
149 const char* namespc =
"") {
150 if (!node)
return NPT_FAILURE;
153 if (namespc && namespc[0] ==
'\0') {
154 namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
157 NPT_List<NPT_XmlAttribute*>::Iterator attribute;
159 if (!attribute)
return NPT_FAILURE;
162 NPT_CHECK(node->GetAttributes().Erase(attribute));
167 static NPT_Result GetAttribute(NPT_XmlElementNode* node,
169 NPT_XmlAttribute*& attr,
170 const char* namespc =
"") {
173 if (!node)
return NPT_FAILURE;
176 if (namespc && namespc[0] ==
'\0') {
177 namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
180 NPT_List<NPT_XmlAttribute*>::Iterator attribute;
191 static NPT_Result GetAttribute(NPT_XmlElementNode* node,
194 const char* namespc =
"",
195 NPT_Cardinal max_size = 1024) {
198 NPT_XmlAttribute* attribute = NULL;
199 NPT_Result result = GetAttribute(node, name, attribute, namespc);
200 if (NPT_FAILED(result))
return result;
202 if (!attribute)
return NPT_FAILURE;
204 value = attribute->GetValue().SubString(0, max_size);
208 static NPT_Result SetAttribute(NPT_XmlElementNode* node,
211 const char* namespc =
"") {
212 NPT_XmlAttribute* attribute = NULL;
213 NPT_CHECK(GetAttribute(node, name, attribute, namespc));
214 if (!attribute)
return NPT_FAILURE;
216 attribute->SetValue(value);
220 static NPT_Result AddChildText(NPT_XmlElementNode* node,
223 const char* prefix = NULL) {
224 if (!node)
return NPT_FAILURE;
225 NPT_XmlElementNode* child =
new NPT_XmlElementNode(prefix, tag);
226 child->AddText(text);
227 return node->AddChild(child);
230 static bool IsMatch(
const NPT_XmlNode*
const & node,
const char* tag,
const char* namespc_mapped) {
235 const NPT_XmlElementNode* element = node->AsElementNode();
237 if (element && element->GetTag() == tag) {
238 if (namespc_mapped) {
240 const NPT_String* namespc = element->GetNamespace();
244 return *namespc == namespc_mapped;
248 return namespc_mapped[0] ==
'\0';
258 static NPT_Result GetChildren(NPT_XmlElementNode* node,
259 NPT_Array<NPT_XmlElementNode*>& children,
261 const char* namespc =
"") {
262 if (!node)
return NPT_FAILURE;
265 if (namespc && namespc[0] ==
'\0') {
266 namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
269 const char* namespc_mapped = (namespc==NULL)?
"":(namespc[0]==
'*' && namespc[1]==
'\0')?NULL:namespc;
272 NPT_List<NPT_XmlNode*>& allchildren = node->GetChildren();
275 NPT_List<NPT_XmlNode*>::Iterator child = allchildren.GetFirstItem();
277 if (IsMatch(*child, tag, namespc_mapped)) {
278 children.Add((*child)->AsElementNode());
285 static NPT_XmlElementNode* GetChild(NPT_XmlElementNode* node,
287 const char* namespc =
"") {
288 if (!node)
return NULL;
291 if (namespc && namespc[0] ==
'\0') {
292 namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
295 return node->GetChild(tag, namespc);
298 static NPT_Result GetChild(NPT_XmlElementNode* parent,
299 NPT_XmlElementNode*& child,
301 if (!parent)
return NPT_FAILURE;
307 NPT_List<NPT_XmlNode*>::Iterator children = parent->GetChildren().GetFirstItem();
309 if ((*children)->AsElementNode() && n-- == 0) {
310 child = (*children)->AsElementNode();
319 static NPT_Result Serialize(NPT_XmlNode& node, NPT_String& xml,
bool add_header =
true, NPT_Int8 indentation = 0) {
320 NPT_XmlWriter writer(indentation);
321 NPT_StringOutputStreamReference stream(
new NPT_StringOutputStream(&xml));
322 NPT_CHECK(writer.Serialize(node, *stream, add_header));
326 static NPT_String Serialize(NPT_XmlNode& node,
bool add_header =
true, NPT_Int8 indentation = 0) {
327 NPT_XmlWriter writer(indentation);
329 NPT_StringOutputStreamReference stream(
new NPT_StringOutputStream(&xml));
330 if (NPT_FAILED(writer.Serialize(node, *stream, add_header))) {
331 NPT_Debug(
"Failed to serialize xml node");
353 m_Value(value.GetChars()), m_IgnoreCase(ignore_case) {}
356 m_Value(value), m_IgnoreCase(ignore_case) {}
360 bool operator()(
const NPT_String*
const & value)
const {
361 return value->Compare(m_Value, m_IgnoreCase) ?
false :
true;
363 bool operator()(
const NPT_String& value)
const {
364 return value.Compare(m_Value, m_IgnoreCase) ?
false :
true;
387 bool operator()(
const NPT_IpAddress*
const & value)
const {
388 return *value == m_Value;
390 bool operator()(
const NPT_IpAddress& value)
const {
391 return value == m_Value;
396 NPT_IpAddress m_Value;
411 static const NPT_String* GetST(
const NPT_HttpMessage& message) {
412 return message.GetHeaders().GetHeaderValue(
"ST");
414 static NPT_Result SetST(NPT_HttpMessage& message,
416 return message.GetHeaders().SetHeader(
"ST", st);
419 static const NPT_String* GetNT(
const NPT_HttpMessage& message) {
420 return message.GetHeaders().GetHeaderValue(
"NT");
422 static NPT_Result SetNT(NPT_HttpMessage& message,
424 return message.GetHeaders().SetHeader(
"NT", nt);
427 static const NPT_String* GetNTS(
const NPT_HttpMessage& message) {
428 return message.GetHeaders().GetHeaderValue(
"NTS");
430 static NPT_Result SetNTS(NPT_HttpMessage& message,
432 return message.GetHeaders().SetHeader(
"NTS", nts);
435 static const NPT_String* GetMAN(
const NPT_HttpMessage& message) {
436 return message.GetHeaders().GetHeaderValue(
"MAN");
438 static NPT_Result SetMAN(NPT_HttpMessage& message,
440 return message.GetHeaders().SetHeader(
"MAN", man);
443 static const NPT_String* GetLocation(
const NPT_HttpMessage& message) {
444 return message.GetHeaders().GetHeaderValue(
"Location");
446 static NPT_Result SetLocation(NPT_HttpMessage& message,
447 const char* location) {
448 return message.GetHeaders().SetHeader(
"Location", location);
451 static const NPT_String* GetServer(
const NPT_HttpMessage& message) {
452 return message.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_SERVER);
454 static NPT_Result SetServer(NPT_HttpMessage& message,
456 bool replace =
true) {
457 return message.GetHeaders().SetHeader(
458 NPT_HTTP_HEADER_SERVER,
463 static const NPT_String* GetUSN(
const NPT_HttpMessage& message) {
464 return message.GetHeaders().GetHeaderValue(
"USN");
466 static NPT_Result SetUSN(NPT_HttpMessage& message,
468 return message.GetHeaders().SetHeader(
"USN", usn);
471 static const NPT_String* GetCallbacks(
const NPT_HttpMessage& message) {
472 return message.GetHeaders().GetHeaderValue(
"CALLBACK");
474 static NPT_Result SetCallbacks(NPT_HttpMessage& message,
const char* callbacks) {
475 return message.GetHeaders().SetHeader(
"CALLBACK", callbacks);
478 static const NPT_String* GetSID(
const NPT_HttpMessage& message) {
479 return message.GetHeaders().GetHeaderValue(
"SID");
481 static NPT_Result SetSID(NPT_HttpMessage& message,
483 return message.GetHeaders().SetHeader(
"SID", sid);
486 static NPT_Result GetLeaseTime(
const NPT_HttpMessage& message, NPT_TimeInterval& lease) {
487 const NPT_String* cc =
488 message.GetHeaders().GetHeaderValue(
"Cache-Control");
489 NPT_CHECK_POINTER(cc);
490 return ExtractLeaseTime(*cc, lease);
492 static NPT_Result SetLeaseTime(NPT_HttpMessage& message,
const NPT_TimeInterval& lease) {
493 return message.GetHeaders().SetHeader(
"Cache-Control",
494 "max-age="+NPT_String::FromInteger(lease.ToSeconds()));
497 static NPT_Result GetBootId(
const NPT_HttpMessage& message, NPT_UInt32& bootId) {
499 const NPT_String* bid = message.GetHeaders().GetHeaderValue(
"BOOTID.UPNP.ORG");
500 NPT_CHECK_POINTER(bid);
501 return NPT_ParseInteger32(*bid, bootId,
false);
503 static NPT_Result SetBootId(NPT_HttpMessage& message,
const NPT_UInt32& bootId) {
504 return message.GetHeaders().SetHeader(
"BOOTID.UPNP.ORG",
505 NPT_String::FromInteger(bootId));
508 static NPT_Result GetNextBootId(
const NPT_HttpMessage& message, NPT_UInt32& nextBootId) {
510 const NPT_String* nbid = message.GetHeaders().GetHeaderValue(
"NEXTBOOTID.UPNP.ORG");
511 NPT_CHECK_POINTER(nbid);
512 return NPT_ParseInteger32(*nbid, nextBootId,
false);
514 static NPT_Result SetNextBootId(NPT_HttpMessage& message,
const NPT_UInt32& nextBootId) {
515 return message.GetHeaders().SetHeader(
"NEXTBOOTID.UPNP.ORG",
516 NPT_String::FromInteger(nextBootId));
519 static NPT_Result GetConfigId(
const NPT_HttpMessage& message, NPT_UInt32& configId) {
521 const NPT_String* cid = message.GetHeaders().GetHeaderValue(
"CONFIGID.UPNP.ORG");
522 NPT_CHECK_POINTER(cid);
523 return NPT_ParseInteger32(*cid, configId,
false);
525 static NPT_Result SetConfigId(NPT_HttpMessage& message,
const NPT_UInt32& configId) {
526 return message.GetHeaders().SetHeader(
"CONFIGID.UPNP.ORG", NPT_String::FromInteger(configId));
529 static NPT_Result GetTimeOut(
const NPT_HttpMessage& message, NPT_Int32& seconds) {
531 const NPT_String* timeout =
532 message.GetHeaders().GetHeaderValue(
"TIMEOUT");
533 NPT_CHECK_POINTER(timeout);
534 return ExtractTimeOut(*timeout, seconds);
536 static NPT_Result SetTimeOut(NPT_HttpMessage& message,
const NPT_Int32 seconds) {
538 return message.GetHeaders().SetHeader(
"TIMEOUT",
"Second-"+NPT_String::FromInteger(seconds));
540 return message.GetHeaders().SetHeader(
"TIMEOUT",
"Second-infinite");
544 static NPT_Result SetDate(NPT_HttpMessage& message) {
546 NPT_System::GetCurrentTimeStamp(now);
547 NPT_DateTime date(now);
549 return message.GetHeaders().SetHeader(
"Date", date.ToString(NPT_DateTime::FORMAT_RFC_1123));
552 static NPT_Result GetIfModifiedSince(
const NPT_HttpMessage& message, NPT_DateTime& date) {
553 const NPT_String* value = message.GetHeaders().GetHeaderValue(
"If-Modified-Since");
554 if (!value)
return NPT_FAILURE;
557 if (NPT_SUCCEEDED(date.FromString(*value, NPT_DateTime::FORMAT_RFC_1123)))
560 if (NPT_SUCCEEDED(date.FromString(*value, NPT_DateTime::FORMAT_RFC_1036)))
563 return date.FromString(*value, NPT_DateTime::FORMAT_ANSI);
565 static NPT_Result SetIfModifiedSince(NPT_HttpMessage& message,
const NPT_DateTime& date) {
566 return message.GetHeaders().SetHeader(
"If-Modified-Since",
567 date.ToString(NPT_DateTime::FORMAT_RFC_1123));
570 static NPT_Result GetMX(
const NPT_HttpMessage& message, NPT_UInt32& value) {
572 const NPT_String* mx =
573 message.GetHeaders().GetHeaderValue(
"MX");
574 NPT_CHECK_POINTER(mx);
575 return NPT_ParseInteger32(*mx, value,
false);
577 static NPT_Result SetMX(NPT_HttpMessage& message,
const NPT_UInt32 mx) {
578 return message.GetHeaders().SetHeader(
"MX",
579 NPT_String::FromInteger(mx));
582 static NPT_Result GetSeq(
const NPT_HttpMessage& message, NPT_UInt32& value) {
584 const NPT_String* seq =
585 message.GetHeaders().GetHeaderValue(
"SEQ");
586 NPT_CHECK_POINTER(seq);
587 return NPT_ParseInteger32(*seq, value);
589 static NPT_Result SetSeq(NPT_HttpMessage& message,
const NPT_UInt32 seq) {
590 return message.GetHeaders().SetHeader(
"SEQ",
591 NPT_String::FromInteger(seq));
594 static const char* GenerateUUID(
int count, NPT_String& uuid) {
596 for (
int i=0;i<(count<100?count:100);i++) {
597 int random = NPT_System::GetRandomInteger();
598 uuid += (char)((random % 25) + 66);
603 static const char* GenerateSerialNumber(NPT_String& sn,
int count = 40) {
605 for (
int i=0;i<count;i++) {
606 char nibble = (char)(NPT_System::GetRandomInteger() % 16);
607 sn += (nibble < 10) ? (
'0' + nibble) : (
'a' + (nibble-10));
613 static const char* GenerateGUID(NPT_String& guid) {
615 for (
int i=0;i<32;i++) {
616 char nibble = (char)(NPT_System::GetRandomInteger() % 16);
617 guid += (nibble < 10) ? (
'0' + nibble) : (
'a' + (nibble-10));
618 if (i == 7 || i == 11 || i == 15 || i == 19) {
625 static NPT_Result ExtractLeaseTime(
const NPT_String& cache_control, NPT_TimeInterval& lease) {
627 if (cache_control.StartsWith(
"max-age=",
true) &&
628 NPT_SUCCEEDED(NPT_ParseInteger32(cache_control.GetChars()+8, value))) {
629 lease.SetSeconds(value);
635 static NPT_Result ExtractTimeOut(
const char* timeout, NPT_Int32& len) {
636 NPT_String temp = timeout;
637 if (temp.CompareN(
"Second-", 7,
true)) {
638 return NPT_ERROR_INVALID_FORMAT;
641 if (temp.Compare(
"Second-infinite",
true) == 0) {
642 len = NPT_TIMEOUT_INFINITE;
645 return temp.SubString(7).ToInteger(len);
648 static NPT_Result GetIPAddresses(NPT_List<NPT_IpAddress>& ips,
bool with_localhost =
false) {
649 NPT_List<NPT_NetworkInterface*> if_list;
650 NPT_CHECK(GetNetworkInterfaces(if_list, with_localhost));
652 NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem();
654 NPT_IpAddress ip = (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress();
655 if (ip.ToString().Compare(
"0.0.0.0") &&
656 (with_localhost || ip.ToString().Compare(
"127.0.0.1"))) {
663 NPT_IpAddress localhost;
664 localhost.Parse(
"127.0.0.1");
668 if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>());
672 static NPT_Result GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list,
673 bool with_localhost =
false) {
674 NPT_CHECK(_GetNetworkInterfaces(if_list, with_localhost,
false));
677 if (if_list.GetItemCount() == 0) {
678 NPT_CHECK(_GetNetworkInterfaces(if_list,
true,
true));
683 static NPT_Result GetMACAddresses(NPT_List<NPT_String>& addresses) {
684 NPT_List<NPT_NetworkInterface*> if_list;
685 NPT_CHECK(GetNetworkInterfaces(if_list));
687 NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem();
689 NPT_String ip = (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress().ToString();
690 if (ip.Compare(
"0.0.0.0") && ip.Compare(
"127.0.0.1")) {
691 addresses.Add((*iface)->GetMacAddress().ToString());
696 if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>());
701 static bool IsLocalNetworkAddress(
const NPT_IpAddress& address) {
702 if (address.ToString() ==
"127.0.0.1")
return true;
704 NPT_List<NPT_NetworkInterface*> if_list;
705 NPT_NetworkInterface::GetNetworkInterfaces(if_list);
707 NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem();
709 if((*iface)->IsAddressInNetwork(address))
return true;
713 if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>());
719 static NPT_Result _GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list,
720 bool include_localhost =
false,
721 bool only_localhost =
false) {
722 NPT_List<NPT_NetworkInterface*> _if_list;
723 NPT_CHECK(NPT_NetworkInterface::GetNetworkInterfaces(_if_list));
725 NPT_NetworkInterface* iface;
726 while (NPT_SUCCEEDED(_if_list.PopHead(iface))) {
728 if ((iface->GetAddresses().GetItemCount() == 0) ||
729 !(iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_MULTICAST) ||
730 (iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT)) {
735 NPT_String ip = iface->GetAddresses().GetFirstItem()->GetPrimaryAddress().ToString();
737 if (iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_LOOPBACK) {
738 if (include_localhost || only_localhost) {
742 }
else if (ip.Compare(
"0.0.0.0") && !only_localhost) {
751 _if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>());
756 #endif // _PLT_UTILITIES_H_
The PLT_XmlAttributeFinder class is used to determine if an attribute exists given an xml element nod...
Definition: PltUtilities.h:50
The NPT_IpAddressFinder class is used to determine if a IP Address is found as part of a list of IP A...
Definition: PltUtilities.h:380
The PLT_XmlHelper class is a set of utility functions for manipulating xml documents and DOM trees...
Definition: PltUtilities.h:96
The NPT_StringFinder class is used to determine if a string is found as part of a list of strings...
Definition: PltUtilities.h:348
The PLT_UPnPMessageHelper class is a set of utility functions for manipulating specific UPnP HTTP hea...
Definition: PltUtilities.h:407