QXmppElement.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright (C) 2008-2012 The QXmpp developers
  3. *
  4. * Author:
  5. * Jeremy Lainé
  6. *
  7. * Source:
  8. * http://code.google.com/p/qxmpp
  9. *
  10. * This file is a part of QXmpp library.
  11. *
  12. * This library is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * This library is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. */
  23. #include "QXmppElement.h"
  24. #include "QXmppUtils.h"
  25. #include <QDomElement>
  26. class QXmppElementPrivate
  27. {
  28. public:
  29. QXmppElementPrivate();
  30. QXmppElementPrivate(const QDomElement &element);
  31. ~QXmppElementPrivate();
  32. QAtomicInt counter;
  33. QXmppElementPrivate *parent;
  34. QMap<QString, QString> attributes;
  35. QList<QXmppElementPrivate*> children;
  36. QString name;
  37. QString value;
  38. };
  39. QXmppElementPrivate::QXmppElementPrivate()
  40. : counter(1), parent(NULL)
  41. {
  42. }
  43. QXmppElementPrivate::QXmppElementPrivate(const QDomElement &element)
  44. : counter(1), parent(NULL)
  45. {
  46. if (element.isNull())
  47. return;
  48. name = element.tagName();
  49. QString xmlns = element.namespaceURI();
  50. QString parentns = element.parentNode().namespaceURI();
  51. if (!xmlns.isEmpty() && xmlns != parentns)
  52. attributes.insert("xmlns", xmlns);
  53. QDomNamedNodeMap attrs = element.attributes();
  54. for (int i = 0; i < attrs.size(); i++)
  55. {
  56. QDomAttr attr = attrs.item(i).toAttr();
  57. attributes.insert(attr.name(), attr.value());
  58. }
  59. QDomNode childNode = element.firstChild();
  60. while (!childNode.isNull())
  61. {
  62. if (childNode.isElement())
  63. {
  64. QXmppElementPrivate *child = new QXmppElementPrivate(childNode.toElement());
  65. child->parent = this;
  66. children.append(child);
  67. } else if (childNode.isText()) {
  68. value += childNode.toText().data();
  69. }
  70. childNode = childNode.nextSibling();
  71. }
  72. }
  73. QXmppElementPrivate::~QXmppElementPrivate()
  74. {
  75. foreach (QXmppElementPrivate *child, children)
  76. if (!child->counter.deref())
  77. delete child;
  78. }
  79. QXmppElement::QXmppElement()
  80. {
  81. d = new QXmppElementPrivate();
  82. }
  83. QXmppElement::QXmppElement(const QXmppElement &other)
  84. {
  85. other.d->counter.ref();
  86. d = other.d;
  87. }
  88. QXmppElement::QXmppElement(QXmppElementPrivate *other)
  89. {
  90. other->counter.ref();
  91. d = other;
  92. }
  93. QXmppElement::QXmppElement(const QDomElement &element)
  94. {
  95. d = new QXmppElementPrivate(element);
  96. }
  97. QXmppElement::~QXmppElement()
  98. {
  99. if (!d->counter.deref())
  100. delete d;
  101. }
  102. QXmppElement &QXmppElement::operator=(const QXmppElement &other)
  103. {
  104. other.d->counter.ref();
  105. if (!d->counter.deref())
  106. delete d;
  107. d = other.d;
  108. return *this;
  109. }
  110. QStringList QXmppElement::attributeNames() const
  111. {
  112. return d->attributes.keys();
  113. }
  114. QString QXmppElement::attribute(const QString &name) const
  115. {
  116. return d->attributes.value(name);
  117. }
  118. void QXmppElement::setAttribute(const QString &name, const QString &value)
  119. {
  120. d->attributes.insert(name, value);
  121. }
  122. void QXmppElement::appendChild(const QXmppElement &child)
  123. {
  124. if (child.d->parent == d)
  125. return;
  126. if (child.d->parent)
  127. child.d->parent->children.removeAll(child.d);
  128. else
  129. child.d->counter.ref();
  130. child.d->parent = d;
  131. d->children.append(child.d);
  132. }
  133. QXmppElement QXmppElement::firstChildElement(const QString &name) const
  134. {
  135. foreach (QXmppElementPrivate *child_d, d->children)
  136. if (name.isEmpty() || child_d->name == name)
  137. return QXmppElement(child_d);
  138. return QXmppElement();
  139. }
  140. QXmppElement QXmppElement::nextSiblingElement(const QString &name) const
  141. {
  142. if (!d->parent)
  143. return QXmppElement();
  144. const QList<QXmppElementPrivate*> &siblings_d = d->parent->children;
  145. for (int i = siblings_d.indexOf(d) + 1; i < siblings_d.size(); i++)
  146. if (name.isEmpty() || siblings_d[i]->name == name)
  147. return QXmppElement(siblings_d[i]);
  148. return QXmppElement();
  149. }
  150. bool QXmppElement::isNull() const
  151. {
  152. return d->name.isEmpty();
  153. }
  154. void QXmppElement::removeChild(const QXmppElement &child)
  155. {
  156. if (child.d->parent != d)
  157. return;
  158. d->children.removeAll(child.d);
  159. child.d->counter.deref();
  160. child.d->parent = NULL;
  161. }
  162. QString QXmppElement::tagName() const
  163. {
  164. return d->name;
  165. }
  166. void QXmppElement::setTagName(const QString &tagName)
  167. {
  168. d->name = tagName;
  169. }
  170. QString QXmppElement::value() const
  171. {
  172. return d->value;
  173. }
  174. void QXmppElement::setValue(const QString &value)
  175. {
  176. d->value = value;
  177. }
  178. void QXmppElement::toXml(QXmlStreamWriter *writer) const
  179. {
  180. if (isNull())
  181. return;
  182. writer->writeStartElement(d->name);
  183. if (d->attributes.contains("xmlns"))
  184. writer->writeAttribute("xmlns", d->attributes.value("xmlns"));
  185. foreach (const QString &attr, d->attributes.keys())
  186. if (attr != "xmlns")
  187. helperToXmlAddAttribute(writer, attr, d->attributes.value(attr));
  188. if (!d->value.isEmpty())
  189. writer->writeCharacters(d->value);
  190. foreach (const QXmppElement &child, d->children)
  191. child.toXml(writer);
  192. writer->writeEndElement();
  193. }