XMLWriter.cc

Go to the documentation of this file.
00001 // Copyright FreeHEP, 2005.
00002 
00003 #include "cheprep/config.h"
00004 
00005 #include <cstdio>
00006 
00007 #include "cheprep/DefaultHepRepAttValue.h"
00008 #include "cheprep/XMLWriter.h"
00009 
00010 using namespace std;
00011 
00016 namespace cheprep {
00017 
00018 XMLWriter::XMLWriter(ostream* out, string indentString, string aDefaultNameSpace)
00019     : AbstractXMLWriter(aDefaultNameSpace) {
00020     writer = new IndentPrintWriter(out);
00021     writer->setIndentString(indentString);
00022     closed = false;
00023     dtdName = "";
00024 }
00025 
00026 XMLWriter::~XMLWriter() {
00027     writer->close();
00028     delete writer;
00029 }
00030 
00031 void XMLWriter::close() {
00032     closeDoc();
00033     writer->close();
00034 }
00035 
00036 void XMLWriter::openDoc(string version, string encoding, bool standalone) {
00037     string indentString = writer->getIndentString();
00038     writer->setIndentString(indentString);
00039 
00040 //    if (!XMLCharacterProperties.validVersionNum(version)) throw new RuntimeException("Invalid version number: "+version);
00041     *writer << "<?xml version=\"" << version.c_str() << "\" ";
00042     if (encoding.compare("") != 0) {
00043 //        if (!XMLCharacterProperties.validEncName(encoding)) throw new RuntimeException("Invalid encoding name: "+encoding);
00044         *writer << "encoding=\"" << encoding.c_str() << "\" ";
00045     }
00046     if (standalone) {
00047         *writer << "standalone=\"yes\" ";
00048     }
00049     *writer << "?>";
00050     *writer << endl;
00051     writer->setIndentString(indentString);
00052 }
00053 
00054 void XMLWriter::referToDTD(string name, string pid, string ref) {
00055     if (dtdName != "") {
00056         cerr << "XMLWriter::ReferToDTD cannot be called twice" << endl;
00057     }
00058     dtdName = name;
00059     *writer << "<!DOCTYPE " << name.c_str() << " PUBLIC \"" << pid.c_str() << "\" \"" << ref.c_str() << "\">" << endl;
00060 }
00061 
00062 void XMLWriter::referToDTD(string name, string system) {
00063     if (dtdName != "") {
00064         cerr << "XMLWriter::ReferToDTD cannot be called twice";
00065     }
00066     dtdName = name;
00067     *writer << "<!DOCTYPE " << name.c_str() << " SYSTEM \"" << system.c_str() << "\">" << endl;
00068 }
00069 
00070 void XMLWriter::closeDoc(bool force) {
00071     if (!closed) {
00072         if (!openTags.empty()) {
00073             if (!force) cerr << "Not all tags were closed before closing XML document:" << endl;
00074             while (!openTags.empty()) {
00075                 if (force) {
00076                     closeTag();
00077                 } else {
00078                     cerr << "   </" << openTags.top().c_str() << ">" << endl;
00079                     openTags.pop();
00080                 }
00081             }
00082         }
00083         closed = true;
00084     }
00085 }
00086 
00087 void XMLWriter::printComment(string comment) {
00088     if (comment.find("--") != string::npos) {
00089         cerr << "XMLWriter::printComment '--' sequence not allowed in comment" << endl;
00090     }
00091     *writer << "<!--" << normalizeText(comment).c_str() << "-->" << endl;
00092 }
00093 
00094 void XMLWriter::printPlain(string text) {
00095     *writer << text.c_str();
00096 }
00097 
00098 void XMLWriter::print(string text) {
00099     *writer << normalizeText(text).c_str();
00100 }
00101 
00102 void XMLWriter::println(string text) {
00103     print(text);
00104     *writer << endl;
00105 }
00106 
00107 void XMLWriter::openTag(string name) {
00108     checkNameValid(name);
00109     if (openTags.empty() && dtdName.compare("") && dtdName.compare(name)) {
00110         cerr << "XMLWriter::openTag(), First tag: '" << name << "' not equal to DTD id: '" << dtdName << "'" << endl;
00111     }
00112     *writer << "<" << name.c_str();
00113     printAttributes(name.length());
00114     *writer << ">" << endl;
00115     writer->indent();
00116     openTags.push(name);
00117 }
00118 
00119 void XMLWriter::closeTag() {
00120     if (openTags.empty()) {
00121         writer->close();
00122         cerr << "XMLWriter::closeTag(), No open tags" << endl;
00123     }
00124     string name = openTags.top();
00125     openTags.pop();
00126     writer->outdent();
00127     *writer << "</" << name.c_str() << ">" << endl;
00128 }
00129 
00130 void XMLWriter::printTag(string name) {
00131     checkNameValid(name);
00132     *writer << "<" << name.c_str();
00133     printAttributes(name.length());
00134     *writer << "/>" << endl;
00135 }
00136 
00137 void XMLWriter::setAttribute(string name, char* value) {
00138     setAttribute(name, (string)value);
00139 }
00140 
00141 void XMLWriter::setAttribute(string name, string value) {
00142     attributes[name] = value;
00143     // NOTE: never set type here
00144 }
00145 
00146 void XMLWriter::setAttribute(std::string name, std::vector<double> value) {
00147     if (name == "value") setAttribute("type", (std::string)"Color");
00148     setAttribute(name, DefaultHepRepAttValue::getAsString(value));
00149 }
00150 
00151 void XMLWriter::setAttribute(std::string name, int64 value) {
00152     if (name == "value") setAttribute("type", (std::string)"long");
00153     setAttribute(name, DefaultHepRepAttValue::getAsString(value));
00154 }
00155 
00156 void XMLWriter::setAttribute(std::string name, int value) {
00157     if (name == "showlabel") {
00158         string label = DefaultHepRepAttValue::toShowLabel(value);
00159         setAttribute("showlabel", label);
00160     } else {
00161         if (name == "value") setAttribute("type", (std::string)"int");
00162         setAttribute(name, DefaultHepRepAttValue::getAsString(value));
00163     }
00164 }
00165 
00166 void XMLWriter::setAttribute(std::string name, bool value) {
00167     if (name == "value") setAttribute("type", (std::string)"boolean");
00168     setAttribute(name, DefaultHepRepAttValue::getAsString(value));
00169 }
00170 
00171 void XMLWriter::setAttribute(string name, double value) {
00172     if (name == "value") setAttribute("type", (std::string)"double");
00173     setAttribute(name, DefaultHepRepAttValue::getAsString(value));
00174 }
00175 
00176 void XMLWriter::printAttributes(int tagLength) {
00177         int width = tagLength + 1;
00178         bool extraIndent = false;
00179         for (map<string,string>::iterator i = attributes.begin(); i != attributes.end(); i++) {
00180                 string key = i->first;
00181                 checkNameValid(key);
00182                 string value = normalize(i->second);
00183                 int length = key.length() + value.length() + 3;
00184                 if (width > 0 && width + length + 2*writer->getIndent() > 60) {
00185                         width = 0;
00186                         *writer << endl;
00187                         if (!extraIndent) {
00188                                 writer->indent();
00189                                 extraIndent = true;
00190                         }
00191                 } else {
00192                         width += length;
00193                         *writer << " ";
00194                 }
00195                 *writer << key.c_str() << "=\"" << value.c_str() << "\"";
00196         }
00197         attributes.clear();
00198         if (extraIndent) writer->outdent();
00199 }
00200 
00201 string XMLWriter::normalize(string s) {
00202     string str = "";
00203     char buffer[20];
00204 
00205     int len = s.length();
00206     for (int i = 0; i < len; i++) {
00207         char ch = s[i];
00208         switch (ch) {
00209             case '<': {
00210                 str.append("&lt;");
00211                 break;
00212             }
00213             case '>': {
00214                 str.append("&gt;");
00215                 break;
00216             }
00217             case '&': {
00218                 str.append("&amp;");
00219                 break;
00220             }
00221             case '"': {
00222                 str.append("&quot;");
00223                 break;
00224             }
00225             case '\r':
00226             case '\n': {
00227                 sprintf(buffer, "&#%ud", ch);
00228                 str.append(buffer);
00229                 str.append(";");
00230                 break;
00231             }
00232             default: {
00233 //                if (ch > 0x00FF) {
00234 //                    sprintf(buffer, "&#x%4.4x", ch);
00235 //                    str.append(buffer);
00236 //                    str.append(";");
00237 //                } else {
00238                     str.append(&ch, 1);
00239 //                }
00240             }
00241         }
00242     }
00243 
00244     return str;
00245 }
00246 
00247 string XMLWriter::normalizeText(string s) {
00248     string str = "";
00249 
00250     int len = s.length();
00251     for (int i = 0; i < len; i++) {
00252         char ch = s[i];
00253         switch (ch) {
00254             case '<': {
00255                 str.append("&lt;");
00256                 break;
00257             }
00258             case '>': {
00259                 str.append("&gt;");
00260                 break;
00261             }
00262             case '&': {
00263                 str.append("&amp;");
00264                 break;
00265             }
00266             default: {
00267 //                if (ch > 0x00FF) {
00268 //                    sprintf(buffer, "&#x%4.4x", ch);
00269 //                    str.append(buffer);
00270 //                    str.append(";");
00271 //                } else {
00272                     str.append(&ch, 1);
00273 //                }
00274             }
00275         }
00276     }
00277     return str;
00278 }
00279 
00280 void XMLWriter::checkNameValid(string) {
00281 // Could be added.
00282 //    if (!XMLCharacterProperties.validName(s)) throw new RuntimeException("Invalid name: "+s);
00283 }
00284 
00285 
00286 } // cheprep

Generated on Mon May 27 17:50:36 2013 for Geant4 by  doxygen 1.4.7