|
Teuchos - Trilinos Tools Package
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #include "Teuchos_XMLObject.hpp" 00043 #include "Teuchos_StrUtils.hpp" 00044 #include <cstring> 00045 00046 using namespace Teuchos; 00047 00048 00049 XMLObjectImplem::XMLObjectImplem(const std::string& tag) 00050 : tag_(tag), attributes_(), children_(0), content_(0) 00051 {;} 00052 00053 XMLObjectImplem* XMLObjectImplem::deepCopy() const 00054 { 00055 XMLObjectImplem* rtn = new XMLObjectImplem(tag_); 00056 TEUCHOS_TEST_FOR_EXCEPTION(rtn==0, std::runtime_error, "XMLObjectImplem::deepCopy()"); 00057 rtn->attributes_ = attributes_; 00058 rtn->content_ = content_; 00059 00060 for (int i=0; i<children_.length(); i++) 00061 { 00062 rtn->addChild(children_[i].deepCopy()); 00063 } 00064 00065 return rtn; 00066 } 00067 00068 int XMLObjectImplem::numChildren() const 00069 { 00070 return children_.length(); 00071 } 00072 00073 void XMLObjectImplem::addAttribute(const std::string& name, 00074 const std::string& value) 00075 { 00076 attributes_[name] = value; 00077 } 00078 00079 void XMLObjectImplem::addChild(const XMLObject& child) 00080 { 00081 children_.append(child); 00082 } 00083 00084 void XMLObjectImplem::addContent(const std::string& contentLine) 00085 { 00086 content_.append(contentLine); 00087 } 00088 00089 void XMLObjectImplem::removeContentLine(const size_t& i) 00090 { 00091 Array<std::string>::iterator pos = content_.begin()+i; 00092 // does bound checking within content_.erase if BoundaryChecks are enabled 00093 content_.erase(pos); 00094 } 00095 00096 const XMLObject& XMLObjectImplem::getChild(int i) const 00097 { 00098 return children_[i]; 00099 } 00100 00101 std::string XMLObjectImplem::header(bool strictXML) const 00102 { 00103 std::string rtn = "<" + tag_; 00104 for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i) 00105 { 00106 if (strictXML) 00107 { 00108 rtn += " " 00109 + (*i).first 00110 + "=" 00111 + XMLifyAttVal((*i).second); 00112 } 00113 else 00114 { 00115 rtn += " " + (*i).first + "=\"" + (*i).second + "\""; 00116 } 00117 } 00118 00119 rtn += ">"; 00120 return rtn; 00121 } 00122 00123 std::string XMLObjectImplem::XMLifyAttVal(const std::string &attval) { 00124 std::string ret; 00125 bool hasQuot, hasApos; 00126 char delim; 00127 00128 if (attval.find("\"") == std::string::npos) 00129 { 00130 hasQuot = false; 00131 } 00132 else 00133 { 00134 hasQuot = true; 00135 } 00136 00137 if (attval.find("\'") == std::string::npos) 00138 { 00139 hasApos = false; 00140 } 00141 else 00142 { 00143 hasApos = true; 00144 } 00145 00146 if (!hasQuot || hasApos) 00147 { 00148 delim = '\"'; // wrap the attribute value in " 00149 } 00150 else 00151 { 00152 delim = '\''; // wrap the attribute value in ' 00153 } 00154 00155 // Rules: 00156 // "-wrapped std::string cannot contain a literal " 00157 // '-wrapped std::string cannot contain a literal ' 00158 // attribute value cannot contain a literal < 00159 // attribute value cannot contain a literal & 00160 ret.push_back(delim); 00161 for (std::string::const_iterator i=attval.begin(); i != attval.end(); i++) 00162 { 00163 if (*i == delim) 00164 { 00165 if (delim == '\'') ret.append("'"); 00166 else if (delim == '\"') ret.append("""); 00167 } 00168 else if (*i == '&') 00169 { 00170 ret.append("&"); 00171 } 00172 else if (*i == '<') 00173 { 00174 ret.append("<"); 00175 } 00176 else 00177 { 00178 ret.push_back(*i); 00179 } 00180 } 00181 ret.push_back(delim); 00182 00183 return ret; 00184 } 00185 00186 std::string XMLObjectImplem::terminatedHeader(bool strictXML) const 00187 { 00188 std::string rtn = "<" + tag_; 00189 for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i) 00190 { 00191 if (strictXML) 00192 { 00193 rtn += " " 00194 + (*i).first 00195 + "=" 00196 + XMLifyAttVal((*i).second); 00197 } 00198 else 00199 { 00200 rtn += " " + (*i).first + "=\"" + (*i).second + "\""; 00201 } 00202 } 00203 00204 rtn += "/>"; 00205 return rtn; 00206 } 00207 00208 std::string XMLObjectImplem::toString() const 00209 { 00210 std::string rtn; 00211 if (content_.length()==0 && children_.length()==0) 00212 { 00213 rtn = terminatedHeader() + "\n"; 00214 } 00215 else 00216 { 00217 rtn = header() + "\n"; 00218 bool allBlankContent = true; 00219 for (int i=0; i<content_.length(); i++) 00220 { 00221 if (!StrUtils::isWhite(content_[i])) 00222 { 00223 allBlankContent=false; 00224 break; 00225 } 00226 } 00227 if (!allBlankContent) 00228 { 00229 for (int i=0; i<content_.length(); i++) 00230 { 00231 rtn += content_[i]; 00232 } 00233 rtn += "\n"; 00234 } 00235 for (int i=0; i<children_.length(); i++) 00236 { 00237 rtn += children_[i].toString(); 00238 } 00239 rtn += "</" + tag_ + ">\n"; 00240 } 00241 return rtn; 00242 } 00243 00244 void XMLObjectImplem::print(std::ostream& os, int indent) const 00245 { 00246 for (int i=0; i<indent; i++) os << " "; 00247 if (content_.length()==0 && children_.length()==0) 00248 { 00249 os << terminatedHeader(true) << std::endl; 00250 return; 00251 } 00252 else 00253 { 00254 os << header(true) << std::endl; 00255 printContent(os, indent+2); 00256 00257 for (int i=0; i<children_.length(); i++) 00258 { 00259 children_[i].print(os, indent+2); 00260 } 00261 for (int i=0; i<indent; i++) os << " "; 00262 os << "</" << tag_ << ">\n"; 00263 } 00264 } 00265 00266 void XMLObjectImplem::printContent(std::ostream& os, int indent) const 00267 { 00268 std::string space = ""; 00269 for (int i=0; i<indent; i++) space += " "; 00270 00271 bool allBlankContent = true; 00272 for (int i=0; i<content_.length(); i++) 00273 { 00274 if (!StrUtils::isWhite(content_[i])) 00275 { 00276 allBlankContent=false; 00277 break; 00278 } 00279 } 00280 00281 if (!allBlankContent) 00282 { 00283 00284 for (int i=0; i<content_.length(); i++) 00285 { 00286 // remove leading spaces, we will indent 00287 std::string s(content_[i]); 00288 s.erase(size_t(0), s.find_first_not_of(" \r\t")); 00289 if((s.length()>0) && (!StrUtils::isWhite(s))) 00290 os << space << s << '\n'; 00291 } 00292 } 00293 } 00294
1.7.6.1