1 /* 2 * libjingle 3 * Copyright 2010, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/p2p/base/parsing.h" 29 30 #include <algorithm> 31 #include <stdlib.h> 32 #include "talk/base/stringutils.h" 33 34 namespace { 35 std::string kTrue = "true"; 36 std::string kOne = "1"; 37 } 38 39 namespace cricket { 40 41 bool BadParse(const std::string& text, ParseError* err) { 42 if (err != NULL) { 43 err->text = text; 44 } 45 return false; 46 } 47 48 bool BadWrite(const std::string& text, WriteError* err) { 49 if (err != NULL) { 50 err->text = text; 51 } 52 return false; 53 } 54 55 std::string GetXmlAttr(const buzz::XmlElement* elem, 56 const buzz::QName& name, 57 const std::string& def) { 58 std::string val = elem->Attr(name); 59 return val.empty() ? def : val; 60 } 61 62 std::string GetXmlAttr(const buzz::XmlElement* elem, 63 const buzz::QName& name, 64 const char* def) { 65 return GetXmlAttr(elem, name, std::string(def)); 66 } 67 68 bool GetXmlAttr(const buzz::XmlElement* elem, 69 const buzz::QName& name, bool def) { 70 std::string val = elem->Attr(name); 71 std::transform(val.begin(), val.end(), val.begin(), tolower); 72 73 return val.empty() ? def : (val == kTrue || val == kOne); 74 } 75 76 int GetXmlAttr(const buzz::XmlElement* elem, 77 const buzz::QName& name, int def) { 78 std::string val = elem->Attr(name); 79 return val.empty() ? def : atoi(val.c_str()); 80 } 81 82 void AddXmlAttr(buzz::XmlElement* elem, 83 const buzz::QName& name, int n) { 84 char buf[32]; 85 talk_base::sprintfn(buf, sizeof(buf), "%d", n); 86 elem->AddAttr(name, buf); 87 } 88 89 void SetXmlBody(buzz::XmlElement* elem, uint32 u) { 90 char buf[16]; 91 talk_base::sprintfn(buf, sizeof(buf), "%u", u); 92 elem->SetBodyText(buf); 93 } 94 95 const buzz::XmlElement* GetXmlChild(const buzz::XmlElement* parent, 96 const std::string& name) { 97 for (const buzz::XmlElement* child = parent->FirstElement(); 98 child != NULL; 99 child = child->NextElement()) { 100 if (child->Name().LocalPart() == name) { 101 return child; 102 } 103 } 104 return NULL; 105 } 106 107 bool RequireXmlChild(const buzz::XmlElement* parent, 108 const std::string& name, 109 const buzz::XmlElement** child, 110 ParseError* error) { 111 *child = GetXmlChild(parent, name); 112 if (*child == NULL) { 113 return BadParse("element '" + parent->Name().Merged() + 114 "' missing required child '" + name, 115 error); 116 } else { 117 return true; 118 } 119 } 120 121 bool RequireXmlAttr(const buzz::XmlElement* elem, 122 const buzz::QName& name, 123 std::string* value, 124 ParseError* error) { 125 if (!elem->HasAttr(name)) { 126 return BadParse("element '" + elem->Name().Merged() + 127 "' missing required attribute '" 128 + name.Merged() + "'", 129 error); 130 } else { 131 *value = elem->Attr(name); 132 return true; 133 } 134 } 135 136 void AddXmlChildren(buzz::XmlElement* parent, 137 const std::vector<buzz::XmlElement*>& children) { 138 for (std::vector<buzz::XmlElement*>::const_iterator iter = children.begin(); 139 iter != children.end(); 140 iter++) { 141 parent->AddElement(*iter); 142 } 143 } 144 145 void CopyXmlChildren(const buzz::XmlElement* source, buzz::XmlElement* dest) { 146 for (const buzz::XmlElement* child = source->FirstElement(); 147 child != NULL; 148 child = child->NextElement()) { 149 dest->AddElement(new buzz::XmlElement(*child)); 150 } 151 } 152 153 std::vector<buzz::XmlElement*> CopyOfXmlChildren(const buzz::XmlElement* elem) { 154 std::vector<buzz::XmlElement*> children; 155 for (const buzz::XmlElement* child = elem->FirstElement(); 156 child != NULL; 157 child = child->NextElement()) { 158 children.push_back(new buzz::XmlElement(*child)); 159 } 160 return children; 161 } 162 163 } // namespace cricket 164