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 34namespace { 35std::string kTrue = "true"; 36std::string kOne = "1"; 37} 38 39namespace cricket { 40 41bool BadParse(const std::string& text, ParseError* err) { 42 if (err != NULL) { 43 err->text = text; 44 } 45 return false; 46} 47 48bool BadWrite(const std::string& text, WriteError* err) { 49 if (err != NULL) { 50 err->text = text; 51 } 52 return false; 53} 54 55std::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 62std::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 68bool 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 76int 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 82void 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 89void 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 95const 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 107bool 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 121bool 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 136void 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 145void 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 153std::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