15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2005, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmllite/xmlprinter.h" 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sstream> 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <string> 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <vector> 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmllite/xmlconstants.h" 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmllite/xmlelement.h" 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmllite/xmlnsstack.h" 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace buzz { 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass XmlPrinterImpl { 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgpublic: 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack); 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void PrintElement(const XmlElement* element); 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void PrintQuotedValue(const std::string& text); 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void PrintBodyText(const std::string& text); 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void PrintCDATAText(const std::string& text); 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgprivate: 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::ostream *pout_; 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlnsStack* ns_stack_; 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element) { 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlnsStack ns_stack; 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PrintXml(pout, element, &ns_stack); 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element, 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlnsStack* ns_stack) { 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlPrinterImpl printer(pout, ns_stack); 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org printer.PrintElement(element); 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmlPrinterImpl::XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack) 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org : pout_(pout), 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ns_stack_(ns_stack) { 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmlPrinterImpl::PrintElement(const XmlElement* element) { 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ns_stack_->PushFrame(); 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // first go through attrs of pel to add xmlns definitions 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlAttr* attr; 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) { 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (attr->Name() == QN_XMLNS) { 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ns_stack_->AddXmlns(STR_EMPTY, attr->Value()); 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (attr->Name().Namespace() == NS_XMLNS) { 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ns_stack_->AddXmlns(attr->Name().LocalPart(), 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org attr->Value()); 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // then go through qnames to make sure needed xmlns definitons are added 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::vector<std::string> new_ns; 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::pair<std::string, bool> prefix; 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org prefix = ns_stack_->AddNewPrefix(element->Name().Namespace(), false); 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (prefix.second) { 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org new_ns.push_back(prefix.first); 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org new_ns.push_back(element->Name().Namespace()); 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) { 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org prefix = ns_stack_->AddNewPrefix(attr->Name().Namespace(), true); 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (prefix.second) { 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org new_ns.push_back(prefix.first); 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org new_ns.push_back(attr->Name().Namespace()); 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // print the element name 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << '<' << ns_stack_->FormatQName(element->Name(), false); 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // and the attributes 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) { 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << ' ' << ns_stack_->FormatQName(attr->Name(), true) << "=\""; 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PrintQuotedValue(attr->Value()); 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << '"'; 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // and the extra xmlns declarations 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::vector<std::string>::iterator i(new_ns.begin()); 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (i < new_ns.end()) { 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (*i == STR_EMPTY) { 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << " xmlns=\"" << *(i + 1) << '"'; 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << " xmlns:" << *i << "=\"" << *(i + 1) << '"'; 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org i += 2; 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // now the children 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlChild* child = element->FirstChild(); 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (child == NULL) 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << "/>"; 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org else { 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << '>'; 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (child) { 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (child->IsText()) { 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->IsCDATA()) { 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PrintCDATAText(child->AsText()->Text()); 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PrintBodyText(child->AsText()->Text()); 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PrintElement(child->AsElement()); 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org child = child->NextChild(); 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << "</" << ns_stack_->FormatQName(element->Name(), false) << '>'; 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ns_stack_->PopFrame(); 1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmlPrinterImpl::PrintQuotedValue(const std::string& text) { 1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t safe = 0; 1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (;;) { 1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t unsafe = text.find_first_of("<>&\"", safe); 1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (unsafe == std::string::npos) 1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org unsafe = text.length(); 1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << text.substr(safe, unsafe - safe); 1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (unsafe == text.length()) 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (text[unsafe]) { 1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case '<': *pout_ << "<"; break; 1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case '>': *pout_ << ">"; break; 1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case '&': *pout_ << "&"; break; 1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case '"': *pout_ << """; break; 1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org safe = unsafe + 1; 1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (safe == text.length()) 1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmlPrinterImpl::PrintBodyText(const std::string& text) { 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t safe = 0; 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (;;) { 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t unsafe = text.find_first_of("<>&", safe); 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (unsafe == std::string::npos) 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org unsafe = text.length(); 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << text.substr(safe, unsafe - safe); 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (unsafe == text.length()) 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (text[unsafe]) { 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case '<': *pout_ << "<"; break; 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case '>': *pout_ << ">"; break; 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case '&': *pout_ << "&"; break; 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org safe = unsafe + 1; 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (safe == text.length()) 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmlPrinterImpl::PrintCDATAText(const std::string& text) { 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *pout_ << "<![CDATA[" << text << "]]>"; 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} // namespace buzz 192