kodi
PltUtilities.h
1 /*****************************************************************
2 |
3 | Platinum - Utilities
4 |
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
8 |
9 | This program is free software; you can redistribute it and/or
10 | modify it under the terms of the GNU General Public License
11 | as published by the Free Software Foundation; either version 2
12 | of the License, or (at your option) any later version.
13 |
14 | OEMs, ISVs, VARs and other distributors that combine and
15 | distribute commercially licensed software with Platinum software
16 | and do not wish to distribute the source code for the commercially
17 | licensed software under version 2, or (at your option) any later
18 | version, of the GNU General Public License (the "GPL") must enter
19 | into a commercial license agreement with Plutinosoft, LLC.
20 | licensing@plutinosoft.com
21 |
22 | This program is distributed in the hope that it will be useful,
23 | but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | GNU General Public License for more details.
26 |
27 | You should have received a copy of the GNU General Public License
28 | along with this program; see the file LICENSE.txt. If not, write to
29 | the Free Software Foundation, Inc.,
30 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 | http://www.gnu.org/licenses/gpl-2.0.html
32 |
33 ****************************************************************/
34 
35 #ifndef _PLT_UTILITIES_H_
36 #define _PLT_UTILITIES_H_
37 
38 /*----------------------------------------------------------------------
39 | includes
40 +---------------------------------------------------------------------*/
41 #include "Neptune.h"
42 
43 /*----------------------------------------------------------------------
44 | PLT_XmlAttributeFinder
45 +---------------------------------------------------------------------*/
51 {
52 public:
53  // if 'namespc' is NULL, we're looking for ANY namespace
54  // if 'namespc' is '\0', we're looking for NO namespace
55  // if 'namespc' is non-empty, look for that SPECIFIC namespace
57  const char* name,
58  const char* namespc) :
59  m_Element(element), m_Name(name), m_Namespace(namespc) {}
60 
61  bool operator()(const NPT_XmlAttribute* const & attribute) const {
62  if (attribute->GetName() == m_Name) {
63  if (m_Namespace) {
64  const NPT_String& prefix = attribute->GetPrefix();
65  if (m_Namespace[0] == '\0') {
66  // match if the attribute has NO namespace
67  return prefix.IsEmpty();
68  } else {
69  // match if the attribute has the SPECIFIC namespace
70  // we're looking for
71  const NPT_String* namespc = m_Element.GetNamespaceUri(prefix);
72  return namespc && *namespc == m_Namespace;
73  }
74  } else {
75  // ANY namespace will match
76  return true;
77  }
78  } else {
79  return false;
80  }
81  }
82 
83 private:
84  const NPT_XmlElementNode& m_Element;
85  const char* m_Name;
86  const char* m_Namespace;
87 };
88 
89 /*----------------------------------------------------------------------
90 | PLT_XmlHelper
91 +---------------------------------------------------------------------*/
97 {
98 public:
99 
100  // static methods
101 
102  static NPT_Result Parse(const NPT_String& xml, NPT_XmlElementNode*& tree) {
103  // reset tree
104  tree = NULL;
105 
106  // parse body
107  NPT_XmlParser parser;
108  NPT_XmlNode* node;
109  NPT_Result result = parser.Parse(xml, node);
110  if (NPT_FAILED(result)) {
111  //NPT_LOG_FINEST_1("Failed to parse %s", xml.IsEmpty()?"(empty string)":xml.GetChars());
112  NPT_CHECK(result);
113  }
114 
115  tree = node->AsElementNode();
116  if (!tree) {
117  delete node;
118  return NPT_FAILURE;
119  }
120 
121  return NPT_SUCCESS;
122  }
123 
124  static NPT_Result GetChildText(NPT_XmlElementNode* node,
125  const char* tag,
126  NPT_String& value,
127  const char* namespc = "",
128  NPT_Cardinal max_size = 1024) {
129  value = "";
130 
131  if (!node) return NPT_FAILURE;
132 
133  // special case "" means we look for the same namespace as the parent
134  if (namespc && namespc[0] == '\0') {
135  namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
136  }
137 
138  NPT_XmlElementNode* child = node->GetChild(tag, namespc);
139  if (!child) return NPT_FAILURE;
140 
141  const NPT_String* text = child->GetText();
142  // DLNA 7.3.17
143  if (text)
144  value = text->SubString(0, max_size);
145  return NPT_SUCCESS;
146  }
147 
148  static NPT_Result RemoveAttribute(NPT_XmlElementNode* node,
149  const char* name,
150  const char* namespc = "") {
151  if (!node) return NPT_FAILURE;
152 
153  // special case "" means we look for the same namespace as the parent
154  if (namespc && namespc[0] == '\0') {
155  namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
156  }
157 
159  attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc));
160  if (!attribute) return NPT_FAILURE;
161 
162  delete *attribute;
163  NPT_CHECK(node->GetAttributes().Erase(attribute));
164 
165  return NPT_SUCCESS;
166  }
167 
168  static NPT_Result GetAttribute(NPT_XmlElementNode* node,
169  const char* name,
170  NPT_XmlAttribute*& attr,
171  const char* namespc = "") {
172  attr = NULL;
173 
174  if (!node) return NPT_FAILURE;
175 
176  // special case "" means we look for the same namespace as the parent
177  if (namespc && namespc[0] == '\0') {
178  namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
179  }
180 
182  attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc));
183  if (!attribute) {
184  //NPT_Debug("Failed to find attribute [%s]:%s", namespc, name);
185  return NPT_FAILURE;
186  }
187 
188  attr = (*attribute);
189  return NPT_SUCCESS;
190  }
191 
192  static NPT_Result GetAttribute(NPT_XmlElementNode* node,
193  const char* name,
194  NPT_String& value,
195  const char* namespc = "",
196  NPT_Cardinal max_size = 1024) {
197  value = "";
198 
199  NPT_XmlAttribute* attribute = NULL;
200  NPT_Result result = GetAttribute(node, name, attribute, namespc);
201  if (NPT_FAILED(result)) return result;
202 
203  if (!attribute) return NPT_FAILURE;
204  // DLNA 7.3.17 truncate to 1024 bytes
205  value = attribute->GetValue().SubString(0, max_size);
206  return NPT_SUCCESS;
207  }
208 
209  static NPT_Result SetAttribute(NPT_XmlElementNode* node,
210  const char* name,
211  const char* value,
212  const char* namespc = "") {
213  NPT_XmlAttribute* attribute = NULL;
214  NPT_CHECK(GetAttribute(node, name, attribute, namespc));
215  if (!attribute) return NPT_FAILURE;
216 
217  attribute->SetValue(value);
218  return NPT_SUCCESS;
219  }
220 
221  static NPT_Result AddChildText(NPT_XmlElementNode* node,
222  const char* tag,
223  const char* text,
224  const char* prefix = NULL) {
225  if (!node) return NPT_FAILURE;
226  NPT_XmlElementNode* child = new NPT_XmlElementNode(prefix, tag);
227  child->AddText(text);
228  return node->AddChild(child);
229  }
230 
231  static bool IsMatch(const NPT_XmlNode* const & node, const char* tag, const char* namespc_mapped) {
232  // if m_Namespace is NULL, we're looking for ANY namespace
233  // if m_Namespace is '\0', we're looking for NO namespace
234  // if m_Namespace is non-empty, look for that SPECIFIC namespace
235 
236  const NPT_XmlElementNode* element = node->AsElementNode();
237  // is tag the same (case sensitive)?
238  if (element && element->GetTag() == tag) {
239  if (namespc_mapped) {
240  // look for a SPECIFIC namespace or NO namespace
241  const NPT_String* namespc = element->GetNamespace();
242  if (namespc) {
243  // the element has a namespace, match if it is equal to
244  // what we're looking for
245  return *namespc == namespc_mapped;
246  } else {
247  // the element does not have a namespace, match if we're
248  // looking for NO namespace
249  return namespc_mapped[0] == '\0';
250  }
251  } else {
252  // ANY namespace will match
253  return true;
254  }
255  }
256  return false;
257  }
258 
259  static NPT_Result GetChildren(NPT_XmlElementNode* node,
261  const char* tag,
262  const char* namespc = "") {
263  if (!node) return NPT_FAILURE;
264 
265  // special case "" means we look for the same namespace as the parent
266  if (namespc && namespc[0] == '\0') {
267  namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
268  }
269 
270  const char* namespc_mapped = (namespc==NULL)?"":(namespc[0]=='*' && namespc[1]=='\0')?NULL:namespc;
271 
272  // get all children first
273  NPT_List<NPT_XmlNode*>& allchildren = node->GetChildren();
274 
275  // iterate through children and add only elements with matching tag
276  NPT_List<NPT_XmlNode*>::Iterator child = allchildren.GetFirstItem();
277  while (child) {
278  if (IsMatch(*child, tag, namespc_mapped)) {
279  children.Add((*child)->AsElementNode());
280  }
281  ++child;
282  }
283  return NPT_SUCCESS;
284  }
285 
286  static NPT_XmlElementNode* GetChild(NPT_XmlElementNode* node,
287  const char* tag,
288  const char* namespc = "") {
289  if (!node) return NULL;
290 
291  // special case "" means we look for the same namespace as the parent
292  if (namespc && namespc[0] == '\0') {
293  namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
294  }
295 
296  return node->GetChild(tag, namespc);
297  }
298 
299  static NPT_Result GetChild(NPT_XmlElementNode* parent,
300  NPT_XmlElementNode*& child,
301  NPT_Ordinal n = 0) {
302  if (!parent) return NPT_FAILURE;
303 
304  // reset child
305  child = NULL;
306 
307  // get all children first
308  NPT_List<NPT_XmlNode*>::Iterator children = parent->GetChildren().GetFirstItem();
309  while (children) {
310  if ((*children)->AsElementNode() && n-- == 0) {
311  child = (*children)->AsElementNode();
312  return NPT_SUCCESS;
313  }
314  children++;
315  }
316 
317  return NPT_FAILURE;
318  }
319 
320  static NPT_Result Serialize(NPT_XmlNode& node, NPT_String& xml, bool add_header = true, NPT_Int8 indentation = 0) {
321  NPT_XmlWriter writer(indentation);
323  NPT_CHECK(writer.Serialize(node, *stream, add_header));
324  return NPT_SUCCESS;
325  }
326 
327  static NPT_String Serialize(NPT_XmlNode& node, bool add_header = true, NPT_Int8 indentation = 0) {
328  NPT_XmlWriter writer(indentation);
329  NPT_String xml;
331  if (NPT_FAILED(writer.Serialize(node, *stream, add_header))) {
332  NPT_Debug("Failed to serialize xml node");
333  return "";
334  }
335 
336  return xml;
337  }
338 private:
339  // members
340 };
341 
342 /*----------------------------------------------------------------------
343 | NPT_StringFinder
344 +---------------------------------------------------------------------*/
350 {
351 public:
352  // methods
353  explicit NPT_StringFinder(NPT_String& value, bool ignore_case = false) :
354  m_Value(value.GetChars()), m_IgnoreCase(ignore_case) {}
355 
356  explicit NPT_StringFinder(const char* value, bool ignore_case = false) :
357  m_Value(value), m_IgnoreCase(ignore_case) {}
358 
359  virtual ~NPT_StringFinder() {}
360 
361  bool operator()(const NPT_String* const & value) const {
362  return value->Compare(m_Value, m_IgnoreCase) ? false : true;
363  }
364  bool operator()(const NPT_String& value) const {
365  return value.Compare(m_Value, m_IgnoreCase) ? false : true;
366  }
367 
368 private:
369  // members
370  const char* m_Value;
371  bool m_IgnoreCase;
372 };
373 
374 /*----------------------------------------------------------------------
375 | NPT_IpAddressFinder
376 +---------------------------------------------------------------------*/
382 {
383 public:
384  // methods
385  NPT_IpAddressFinder(NPT_IpAddress ip) : m_Value(ip) {}
386  virtual ~NPT_IpAddressFinder() {}
387 
388  bool operator()(const NPT_IpAddress* const & value) const {
389  return *value == m_Value;
390  }
391  bool operator()(const NPT_IpAddress& value) const {
392  return value == m_Value;
393  }
394 
395 private:
396  // members
397  NPT_IpAddress m_Value;
398 };
399 
400 
401 /*----------------------------------------------------------------------
402 | PLT_UPnPMessageHelper class
403 +---------------------------------------------------------------------*/
409 {
410 public:
411  // methods
412  static const NPT_String* GetST(const NPT_HttpMessage& message) {
413  return message.GetHeaders().GetHeaderValue("ST");
414  }
415  static NPT_Result SetST(NPT_HttpMessage& message,
416  const char* st) {
417  return message.GetHeaders().SetHeader("ST", st);
418  }
419 
420  static const NPT_String* GetNT(const NPT_HttpMessage& message) {
421  return message.GetHeaders().GetHeaderValue("NT");
422  }
423  static NPT_Result SetNT(NPT_HttpMessage& message,
424  const char* nt) {
425  return message.GetHeaders().SetHeader("NT", nt);
426  }
427 
428  static const NPT_String* GetNTS(const NPT_HttpMessage& message) {
429  return message.GetHeaders().GetHeaderValue("NTS");
430  }
431  static NPT_Result SetNTS(NPT_HttpMessage& message,
432  const char* nts) {
433  return message.GetHeaders().SetHeader("NTS", nts);
434  }
435 
436  static const NPT_String* GetMAN(const NPT_HttpMessage& message) {
437  return message.GetHeaders().GetHeaderValue("MAN");
438  }
439  static NPT_Result SetMAN(NPT_HttpMessage& message,
440  const char* man) {
441  return message.GetHeaders().SetHeader("MAN", man);
442  }
443 
444  static const NPT_String* GetLocation(const NPT_HttpMessage& message) {
445  return message.GetHeaders().GetHeaderValue("Location");
446  }
447  static NPT_Result SetLocation(NPT_HttpMessage& message,
448  const char* location) {
449  return message.GetHeaders().SetHeader("Location", location);
450  }
451 
452  static const NPT_String* GetServer(const NPT_HttpMessage& message) {
453  return message.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_SERVER);
454  }
455  static NPT_Result SetServer(NPT_HttpMessage& message,
456  const char* server,
457  bool replace = true) {
458  return message.GetHeaders().SetHeader(
459  NPT_HTTP_HEADER_SERVER,
460  server,
461  replace);
462  }
463 
464  static const NPT_String* GetUSN(const NPT_HttpMessage& message) {
465  return message.GetHeaders().GetHeaderValue("USN");
466  }
467  static NPT_Result SetUSN(NPT_HttpMessage& message,
468  const char* usn) {
469  return message.GetHeaders().SetHeader("USN", usn);
470  }
471 
472  static const NPT_String* GetCallbacks(const NPT_HttpMessage& message) {
473  return message.GetHeaders().GetHeaderValue("CALLBACK");
474  }
475  static NPT_Result SetCallbacks(NPT_HttpMessage& message, const char* callbacks) {
476  return message.GetHeaders().SetHeader("CALLBACK", callbacks);
477  }
478 
479  static const NPT_String* GetSID(const NPT_HttpMessage& message) {
480  return message.GetHeaders().GetHeaderValue("SID");
481  }
482  static NPT_Result SetSID(NPT_HttpMessage& message,
483  const char* sid) {
484  return message.GetHeaders().SetHeader("SID", sid);
485  }
486 
487  static NPT_Result GetLeaseTime(const NPT_HttpMessage& message, NPT_TimeInterval& lease) {
488  const NPT_String* cc =
489  message.GetHeaders().GetHeaderValue("Cache-Control");
490  NPT_CHECK_POINTER(cc);
491  return ExtractLeaseTime(*cc, lease);
492  }
493  static NPT_Result SetLeaseTime(NPT_HttpMessage& message, const NPT_TimeInterval& lease) {
494  return message.GetHeaders().SetHeader("Cache-Control",
495  "max-age="+NPT_String::FromInteger(lease.ToSeconds()));
496  }
497 
498  static NPT_Result GetBootId(const NPT_HttpMessage& message, NPT_UInt32& bootId) {
499  bootId = 0;
500  const NPT_String* bid = message.GetHeaders().GetHeaderValue("BOOTID.UPNP.ORG");
501  NPT_CHECK_POINTER(bid);
502  return NPT_ParseInteger32(*bid, bootId, false);
503  }
504  static NPT_Result SetBootId(NPT_HttpMessage& message, const NPT_UInt32& bootId) {
505  return message.GetHeaders().SetHeader("BOOTID.UPNP.ORG",
506  NPT_String::FromInteger(bootId));
507  }
508 
509  static NPT_Result GetNextBootId(const NPT_HttpMessage& message, NPT_UInt32& nextBootId) {
510  nextBootId = 0;
511  const NPT_String* nbid = message.GetHeaders().GetHeaderValue("NEXTBOOTID.UPNP.ORG");
512  NPT_CHECK_POINTER(nbid);
513  return NPT_ParseInteger32(*nbid, nextBootId, false);
514  }
515  static NPT_Result SetNextBootId(NPT_HttpMessage& message, const NPT_UInt32& nextBootId) {
516  return message.GetHeaders().SetHeader("NEXTBOOTID.UPNP.ORG",
517  NPT_String::FromInteger(nextBootId));
518  }
519 
520  static NPT_Result GetConfigId(const NPT_HttpMessage& message, NPT_UInt32& configId) {
521  configId = 0;
522  const NPT_String* cid = message.GetHeaders().GetHeaderValue("CONFIGID.UPNP.ORG");
523  NPT_CHECK_POINTER(cid);
524  return NPT_ParseInteger32(*cid, configId, false);
525  }
526  static NPT_Result SetConfigId(NPT_HttpMessage& message, const NPT_UInt32& configId) {
527  return message.GetHeaders().SetHeader("CONFIGID.UPNP.ORG", NPT_String::FromInteger(configId));
528  }
529 
530  static NPT_Result GetTimeOut(const NPT_HttpMessage& message, NPT_Int32& seconds) {
531  seconds = 0;
532  const NPT_String* timeout =
533  message.GetHeaders().GetHeaderValue("TIMEOUT");
534  NPT_CHECK_POINTER(timeout);
535  return ExtractTimeOut(*timeout, seconds);
536  }
537  static NPT_Result SetTimeOut(NPT_HttpMessage& message, const NPT_Int32 seconds) {
538  if (seconds >= 0) {
539  return message.GetHeaders().SetHeader("TIMEOUT", "Second-"+NPT_String::FromInteger(seconds));
540  } else {
541  return message.GetHeaders().SetHeader("TIMEOUT", "Second-infinite");
542  }
543  }
544 
545  static NPT_Result SetDate(NPT_HttpMessage& message) {
546  NPT_TimeStamp now;
547  NPT_System::GetCurrentTimeStamp(now);
548  NPT_DateTime date(now);
549 
550  return message.GetHeaders().SetHeader("Date", date.ToString(NPT_DateTime::FORMAT_RFC_1123));
551  }
552 
553  static NPT_Result GetIfModifiedSince(const NPT_HttpMessage& message, NPT_DateTime& date) {
554  const NPT_String* value = message.GetHeaders().GetHeaderValue("If-Modified-Since");
555  if (!value) return NPT_FAILURE;
556 
557  // Try RFC 1123, RFC 1036, then ANSI
558  if (NPT_SUCCEEDED(date.FromString(*value, NPT_DateTime::FORMAT_RFC_1123)))
559  return NPT_SUCCESS;
560 
561  if (NPT_SUCCEEDED(date.FromString(*value, NPT_DateTime::FORMAT_RFC_1036)))
562  return NPT_SUCCESS;
563 
564  return date.FromString(*value, NPT_DateTime::FORMAT_ANSI);
565  }
566  static NPT_Result SetIfModifiedSince(NPT_HttpMessage& message, const NPT_DateTime& date) {
567  return message.GetHeaders().SetHeader("If-Modified-Since",
568  date.ToString(NPT_DateTime::FORMAT_RFC_1123));
569  }
570 
571  static NPT_Result GetMX(const NPT_HttpMessage& message, NPT_UInt32& value) {
572  value = 0;
573  const NPT_String* mx =
574  message.GetHeaders().GetHeaderValue("MX");
575  NPT_CHECK_POINTER(mx);
576  return NPT_ParseInteger32(*mx, value, false); // no relax to be UPnP compliant
577  }
578  static NPT_Result SetMX(NPT_HttpMessage& message, const NPT_UInt32 mx) {
579  return message.GetHeaders().SetHeader("MX",
580  NPT_String::FromInteger(mx));
581  }
582 
583  static NPT_Result GetSeq(const NPT_HttpMessage& message, NPT_UInt32& value) {
584  value = 0;
585  const NPT_String* seq =
586  message.GetHeaders().GetHeaderValue("SEQ");
587  NPT_CHECK_POINTER(seq);
588  return NPT_ParseInteger32(*seq, value);
589  }
590  static NPT_Result SetSeq(NPT_HttpMessage& message, const NPT_UInt32 seq) {
591  return message.GetHeaders().SetHeader("SEQ",
592  NPT_String::FromInteger(seq));
593  }
594 
595  static const char* GenerateUUID(int count, NPT_String& uuid) {
596  uuid = "";
597  for (int i=0;i<(count<100?count:100);i++) {
598  int random = NPT_System::GetRandomInteger();
599  uuid += (char)((random % 25) + 66);
600  }
601  return uuid;
602  }
603 
604  static const char* GenerateSerialNumber(NPT_String& sn, int count = 40) {
605  sn = "{";
606  for (int i=0;i<count;i++) {
607  char nibble = (char)(NPT_System::GetRandomInteger() % 16);
608  sn += (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10));
609  }
610  sn += "}";
611  return sn;
612  }
613 
614  static const char* GenerateGUID(NPT_String& guid) {
615  guid = "";
616  for (int i=0;i<32;i++) {
617  char nibble = (char)(NPT_System::GetRandomInteger() % 16);
618  guid += (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10));
619  if (i == 7 || i == 11 || i == 15 || i == 19) {
620  guid += '-';
621  }
622  }
623  return guid;
624  }
625 
626  static NPT_Result ExtractLeaseTime(const NPT_String& cache_control, NPT_TimeInterval& lease) {
627  NPT_Int32 value;
628  if (cache_control.StartsWith("max-age=", true) &&
629  NPT_SUCCEEDED(NPT_ParseInteger32(cache_control.GetChars()+8, value))) {
630  lease.SetSeconds(value);
631  return NPT_SUCCESS;
632  }
633  return NPT_FAILURE;
634  }
635 
636  static NPT_Result ExtractTimeOut(const char* timeout, NPT_Int32& len) {
637  NPT_String temp = timeout;
638  if (temp.CompareN("Second-", 7, true)) {
639  return NPT_ERROR_INVALID_FORMAT;
640  }
641 
642  if (temp.Compare("Second-infinite", true) == 0) {
643  len = NPT_TIMEOUT_INFINITE;
644  return NPT_SUCCESS;
645  }
646  return temp.SubString(7).ToInteger(len);
647  }
648 
649  static NPT_Result GetIPAddresses(NPT_List<NPT_IpAddress>& ips, bool with_localhost = false) {
651  NPT_CHECK(GetNetworkInterfaces(if_list, with_localhost));
652 
653  NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem();
654  while (iface) {
655  NPT_IpAddress ip = (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress();
656  if (ip.ToString().Compare("0.0.0.0") &&
657  (with_localhost || ip.ToString().Compare("127.0.0.1"))) {
658  ips.Add(ip);
659  }
660  ++iface;
661  }
662 
663  if (with_localhost && !ips.Find(NPT_IpAddressFinder(NPT_IpAddress(127, 0, 0, 1)))) {
664  NPT_IpAddress localhost;
665  localhost.Parse("127.0.0.1");
666  ips.Add(localhost);
667  }
668 
670  return NPT_SUCCESS;
671  }
672 
673  static NPT_Result GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list,
674  bool with_localhost = false) {
675  NPT_CHECK(_GetNetworkInterfaces(if_list, with_localhost, false));
676 
677  // if no valid interfaces or if requested, add localhost interface
678  if (if_list.GetItemCount() == 0) {
679  NPT_CHECK(_GetNetworkInterfaces(if_list, true, true));
680  }
681  return NPT_SUCCESS;
682  }
683 
684  static NPT_Result GetMACAddresses(NPT_List<NPT_String>& addresses) {
686  NPT_CHECK(GetNetworkInterfaces(if_list));
687 
688  NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem();
689  while (iface) {
690  NPT_String ip = (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress().ToString();
691  if (ip.Compare("0.0.0.0") && ip.Compare("127.0.0.1")) {
692  addresses.Add((*iface)->GetMacAddress().ToString());
693  }
694  ++iface;
695  }
696 
698  return NPT_SUCCESS;
699  }
700 
701 
702  static bool IsLocalNetworkAddress(const NPT_IpAddress& address) {
703  if (address.ToString() == "127.0.0.1") return true;
704 
706  NPT_NetworkInterface::GetNetworkInterfaces(if_list);
707 
708  NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem();
709  while (iface) {
710  if((*iface)->IsAddressInNetwork(address)) return true;
711  ++iface;
712  }
713 
715  return false;
716  }
717 
718 private:
719 
720  static NPT_Result _GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list,
721  bool include_localhost = false,
722  bool only_localhost = false) {
724  NPT_CHECK(NPT_NetworkInterface::GetNetworkInterfaces(_if_list));
725 
726  NPT_NetworkInterface* iface;
727  while (NPT_SUCCEEDED(_if_list.PopHead(iface))) {
728  // only interested in non PTP & multicast capable interfaces
729  if ((iface->GetAddresses().GetItemCount() == 0) ||
730  !(iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_MULTICAST) ||
731  (iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT)) {
732  delete iface;
733  continue;
734  }
735 
736  NPT_String ip = iface->GetAddresses().GetFirstItem()->GetPrimaryAddress().ToString();
737 
738  if (iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_LOOPBACK) {
739  if (include_localhost || only_localhost) {
740  if_list.Add(iface);
741  continue;
742  }
743  } else if (ip.Compare("0.0.0.0") && !only_localhost) {
744  if_list.Add(iface);
745  continue;
746  }
747 
748  delete iface;
749  }
750 
751  // cleanup any remaining items in list if we breaked early
752  _if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>());
753  return NPT_SUCCESS;
754  }
755 };
756 
757 #endif // _PLT_UTILITIES_H_
758 
759 
760 
761 
762 
763 
764 
765 
766 
Definition: NptNetwork.h:216
Definition: NptXml.h:172
Definition: NptArray.h:54
Definition: NptHttp.h:241
The PLT_XmlAttributeFinder class is used to determine if an attribute exists given an xml element nod...
Definition: PltUtilities.h:50
Definition: NptTime.h:50
Definition: NptNetwork.h:74
Definition: NptStreams.h:251
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:381
Definition: NptXml.h:363
Definition: NptXml.h:132
Definition: NptXml.h:279
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:349
Definition: NptList.h:63
The PLT_UPnPMessageHelper class is a set of utility functions for manipulating specific UPnP HTTP hea...
Definition: PltUtilities.h:408
Definition: NptXml.h:62
Definition: NptReferences.h:45
Definition: NptTime.h:116
Definition: NptStrings.h:57
Definition: NptList.h:54
Definition: NptCommon.h:45