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 static const char kTrue[] = "true"; 36 static const char 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 const buzz::XmlElement* GetXmlChild(const buzz::XmlElement* parent, 83 const std::string& name) { 84 for (const buzz::XmlElement* child = parent->FirstElement(); 85 child != NULL; 86 child = child->NextElement()) { 87 if (child->Name().LocalPart() == name) { 88 return child; 89 } 90 } 91 return NULL; 92 } 93 94 bool RequireXmlChild(const buzz::XmlElement* parent, 95 const std::string& name, 96 const buzz::XmlElement** child, 97 ParseError* error) { 98 *child = GetXmlChild(parent, name); 99 if (*child == NULL) { 100 return BadParse("element '" + parent->Name().Merged() + 101 "' missing required child '" + name, 102 error); 103 } else { 104 return true; 105 } 106 } 107 108 bool RequireXmlAttr(const buzz::XmlElement* elem, 109 const buzz::QName& name, 110 std::string* value, 111 ParseError* error) { 112 if (!elem->HasAttr(name)) { 113 return BadParse("element '" + elem->Name().Merged() + 114 "' missing required attribute '" 115 + name.Merged() + "'", 116 error); 117 } else { 118 *value = elem->Attr(name); 119 return true; 120 } 121 } 122 123 void AddXmlAttrIfNonEmpty(buzz::XmlElement* elem, 124 const buzz::QName name, 125 const std::string& value) { 126 if (!value.empty()) { 127 elem->AddAttr(name, value); 128 } 129 } 130 131 void AddXmlChildren(buzz::XmlElement* parent, 132 const std::vector<buzz::XmlElement*>& children) { 133 for (std::vector<buzz::XmlElement*>::const_iterator iter = children.begin(); 134 iter != children.end(); 135 iter++) { 136 parent->AddElement(*iter); 137 } 138 } 139 140 void CopyXmlChildren(const buzz::XmlElement* source, buzz::XmlElement* dest) { 141 for (const buzz::XmlElement* child = source->FirstElement(); 142 child != NULL; 143 child = child->NextElement()) { 144 dest->AddElement(new buzz::XmlElement(*child)); 145 } 146 } 147 148 std::vector<buzz::XmlElement*> CopyOfXmlChildren(const buzz::XmlElement* elem) { 149 std::vector<buzz::XmlElement*> children; 150 for (const buzz::XmlElement* child = elem->FirstElement(); 151 child != NULL; 152 child = child->NextElement()) { 153 children.push_back(new buzz::XmlElement(*child)); 154 } 155 return children; 156 } 157 158 } // namespace cricket 159