00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <xercesc/util/PlatformUtils.hpp>
00042 #include <xercesc/dom/DOMNamedNodeMap.hpp>
00043
00044 #include "XParsers.hpp"
00045 #include "XString.hpp"
00046
00047 #include <assert.h>
00048 #include <stdlib.h>
00049 #include <stdio.h>
00050 #include <rpc/rpc.h>
00051 #include <unistd.h>
00052 #include <xstream/xdr.h>
00053
00054 #include <iostream>
00055 #include <fstream>
00056 #include <sstream>
00057
00058 #include "particleType.h"
00059
00060
00061 #define X(str) XString(str).unicode_str()
00062 #define S(str) str.c_str()
00063
00064 using namespace xercesc;
00065
00066 class XMLmaker
00067 {
00068 public:
00069 std::ofstream xout;
00070
00071 XMLmaker() {};
00072 ~XMLmaker() {};
00073
00074 void writeXML(const XString& s);
00075 void constructXML(xstream::xdr::istream& ifx, DOMElement* el, int depth);
00076 };
00077
00078 void usage()
00079 {
00080 std::cerr
00081 << "\nUsage:\n"
00082 << " hddm-xml [-o <filename>] [HDDM file]\n\n"
00083 << "Options:\n"
00084 << " -o <filename> write to <filename>.xml"
00085 << std::endl;
00086 }
00087
00088
00089 int main(int argC, char* argV[])
00090 {
00091 XString xFilename;
00092
00093 try
00094 {
00095 XMLPlatformUtils::Initialize();
00096 }
00097 catch (const XMLException* toCatch)
00098 {
00099 XString msg(toCatch->getMessage());
00100 std::cerr
00101 << "hddm-xml: Error during initialization! :\n"
00102 << S(msg) << std::endl;
00103 return 1;
00104 }
00105
00106 int reqcount=0;
00107 int argInd;
00108 for (argInd = 1; argInd < argC; argInd++)
00109 {
00110 if (argV[argInd][0] != '-')
00111 {
00112 break;
00113 }
00114 else if (strcmp(argV[argInd],"-o") == 0)
00115 {
00116 xFilename = argV[++argInd];
00117 }
00118 else if (sscanf(argV[argInd],"%d",&reqcount))
00119 {
00120 reqcount = 1-reqcount;
00121 }
00122 else
00123 {
00124 usage();
00125 return 1;
00126 }
00127 }
00128
00129 XString hddmFile;
00130 std::istream* ifs;
00131 if (argInd == argC)
00132 {
00133 ifs = &std::cin;
00134 }
00135 else if (argInd == argC - 1)
00136 {
00137 hddmFile = XString(argV[argInd]);
00138 ifs = new std::ifstream(hddmFile.c_str());
00139 }
00140 else
00141 {
00142 usage();
00143 return 1;
00144 }
00145 if (!ifs->good())
00146 {
00147 std::cerr
00148 << "hddm-xml: Error opening input stream " << hddmFile << std::endl;
00149 exit(1);
00150 }
00151 std::ostringstream tmpFileStr;
00152 tmpFileStr << "tmp" << getpid();
00153 std::ofstream ofs(tmpFileStr.str().c_str());
00154 if (! ofs.is_open())
00155 {
00156 std::cerr
00157 << "hddm-xml: Error opening temp file " << tmpFileStr << std::endl;
00158 exit(2);
00159 }
00160
00161 ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
00162 XString xmlHeader;
00163 XString line;
00164 if (getline(*ifs,line))
00165 {
00166 if (line.substr(0,5) == "<?xml")
00167 {
00168 std::cerr
00169 << "hddm-xml: Error reading input stream " << hddmFile
00170 << std::endl;
00171 std::cerr
00172 << "Input file appears to be an xml document!" << std::endl;
00173 exit(1);
00174 }
00175 else if (line.substr(0,5) == "<HDDM")
00176 {
00177 xmlHeader = line + "\n";
00178 ofs << line;
00179 }
00180 else
00181 {
00182 std::cerr
00183 << "hddm-xml: Input stream does not contain valid hddm header"
00184 << std::endl;
00185 exit(1);
00186 }
00187 }
00188 else
00189 {
00190 std::cerr
00191 << "hddm-xml: Error reading from input stream " << hddmFile
00192 << std::endl;
00193 exit(1);
00194 }
00195 while (getline(*ifs,line))
00196 {
00197 ofs << line;
00198 if (line == "</HDDM>")
00199 {
00200 break;
00201 }
00202 }
00203 ofs.close();
00204
00205 #if defined OLD_STYLE_XERCES_PARSER
00206 DOMDocument* document = parseInputDocument(tmpFileStr.str().c_str(),false);
00207 #else
00208 DOMDocument* document = buildDOMDocument(tmpFileStr.str().c_str(),false);
00209 #endif
00210 if (document == 0)
00211 {
00212 std::cerr
00213 << "hddm-xml : Error parsing HDDM document, "
00214 << "cannot continue" << std::endl;
00215 return 1;
00216 }
00217 unlink(tmpFileStr.str().c_str());
00218
00219 DOMElement* rootEl = document->getDocumentElement();
00220 XString rootS(rootEl->getTagName());
00221 if (rootS != "HDDM")
00222 {
00223 std::cerr
00224 << "hddm-xml error: root element of input document is "
00225 << "\"" << S(rootS) << "\", expected \"HDDM\""
00226 << std::endl;
00227 return 1;
00228 }
00229
00230 XMLmaker builder;
00231 if (xFilename.size())
00232 {
00233 XString fname(xFilename + ".xml");
00234 builder.xout.open(fname.c_str());
00235 }
00236
00237 builder.writeXML("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00238 builder.writeXML(xmlHeader);
00239
00240 xstream::xdr::istream ifx(*ifs);
00241 while (--reqcount && ifs->good())
00242 {
00243 DOMNodeList* contList = rootEl->getChildNodes();
00244 int contLength = contList->getLength();
00245 int size;
00246 ifx >> size;
00247 if (size < 0)
00248 {
00249 break;
00250 }
00251 for (int c = 0; c < contLength; c++)
00252 {
00253 DOMNode* cont = contList->item(c);
00254 short type = cont->getNodeType();
00255 if (type == DOMNode::ELEMENT_NODE)
00256 {
00257 DOMElement* contEl = (DOMElement*) cont;
00258 ifx >> size;
00259 if (size > 0)
00260 {
00261 builder.constructXML(ifx,contEl,1);
00262 }
00263 }
00264 }
00265 }
00266
00267 builder.writeXML("</HDDM>\n");
00268
00269 if (ifs != &std::cin)
00270 {
00271 ((std::ifstream*)ifs)->close();
00272 }
00273 XMLPlatformUtils::Terminate();
00274 return 0;
00275 }
00276
00277
00278
00279 void XMLmaker::writeXML(const XString& s)
00280 {
00281 if (xout.is_open())
00282 {
00283 xout << s;
00284 }
00285 else
00286 {
00287 std::cout << s;
00288 }
00289 }
00290
00291
00292
00293
00294
00295 void XMLmaker::constructXML(xstream::xdr::istream& ifx,
00296 DOMElement* el, int depth)
00297 {
00298 XString repS(el->getAttribute(X("maxOccurs")));
00299 int rep = (repS == "unbounded")? 9999 :
00300 (repS == "")? 1 :
00301 atoi(S(repS));
00302 if (rep > 1)
00303 {
00304 ifx >> rep;
00305 }
00306
00307 for (int r = 0; r < rep; r++)
00308 {
00309 XString tagS(el->getTagName());
00310 for (int d = 0; d < depth; d++)
00311 {
00312 writeXML(" ");
00313 }
00314 writeXML("<");
00315 writeXML(S(tagS));
00316 DOMNamedNodeMap* attrList = el->getAttributes();
00317 int listLength = attrList->getLength();
00318 for (int a = 0; a < listLength; a++)
00319 {
00320 XString nameS(attrList->item(a)->getNodeName());
00321 XString typeS(attrList->item(a)->getNodeValue());
00322 std::ostringstream attrStr;
00323 if (typeS == "int")
00324 {
00325 int32_t value;
00326 ifx >> value;
00327 attrStr << " " << nameS << "=\"" << value << "\"";
00328 }
00329 else if (typeS == "long")
00330 {
00331 int64_t value;
00332 ifx >> value;
00333 attrStr << " " << nameS << "=\"" << value << "\"";
00334 }
00335 else if (typeS == "float")
00336 {
00337 float value;
00338 ifx >> value;
00339 attrStr << " " << nameS << "=\"" << value << "\"";
00340 }
00341 else if (typeS == "double")
00342 {
00343 double value;
00344 ifx >> value;
00345 attrStr << " " << nameS << "=\"" << value << "\"";
00346 }
00347 else if (typeS == "boolean")
00348 {
00349 bool_t value;
00350 ifx >> value;
00351 attrStr << " " << nameS << "=\"" << value << "\"";
00352 }
00353 else if (typeS == "Particle_t")
00354 {
00355 int32_t value;
00356 ifx >> value;
00357 attrStr << " " << nameS << "=\"" << ParticleType((Particle_t)value) << "\"";
00358 }
00359 else if (typeS == "string" || typeS == "anyURI")
00360 {
00361 std::string value;
00362 ifx >> value;
00363 attrStr << " " << nameS << "=\"" << value << "\"";
00364 }
00365 else if (nameS == "minOccurs" || nameS == "maxOccurs")
00366 {
00367 ;
00368 }
00369 else
00370 {
00371 attrStr << " " << nameS << "=\"" << typeS << "\"";
00372 }
00373 writeXML(attrStr.str());
00374 }
00375
00376 DOMNodeList* contList = el->getChildNodes();
00377 int contLength = contList->getLength();
00378 if (contLength > 1)
00379 {
00380 writeXML(">\n");
00381 }
00382 else
00383 {
00384 writeXML(" />\n");
00385 }
00386
00387 for (int c = 0; c < contLength; c++)
00388 {
00389 DOMNode* cont = contList->item(c);
00390 short type = cont->getNodeType();
00391 if (type == DOMNode::ELEMENT_NODE)
00392 {
00393 DOMElement* contEl = (DOMElement*) cont;
00394 int size;
00395 ifx >> size;
00396 if (size > 0) {
00397 constructXML(ifx,contEl,depth +1);
00398 }
00399 }
00400 }
00401
00402 if (contLength > 1)
00403 {
00404 for (int d = 0; d < depth; d++)
00405 {
00406 writeXML(" ");
00407 }
00408 XString endTag("</"+tagS+">\n");
00409 writeXML(endTag);
00410 }
00411 }
00412 }