File indexing completed on 2026-04-09 07:49:04
0001 #include "GDXMLRead.hh"
0002
0003 #include <iostream>
0004 #include <iomanip>
0005 #include <sstream>
0006 #include <string>
0007 #include <csignal>
0008 #include <vector>
0009
0010 #include "SLOG.hh"
0011 #include "GDXMLErrorHandler.hh"
0012
0013 std::string Matrix::desc() const
0014 {
0015 std::stringstream ss ;
0016 ss
0017 << " repeat_index " << std::setw(5) << repeat_index
0018 << " matrixElement " << std::setw(10) << matrixElement
0019 << " name " << std::setw(25) << name
0020 << " values " << values
0021 ;
0022 std::string s = ss.str();
0023 return s ;
0024 }
0025
0026 double atod_( const char* a )
0027 {
0028 std::string s(a);
0029 std::istringstream iss(s);
0030 double d ;
0031 iss >> d ;
0032 return d ;
0033 }
0034
0035 std::string Transcode(const XMLCh* const toTranscode)
0036 {
0037 char* char_str = xercesc::XMLString::transcode(toTranscode);
0038 std::string my_str(char_str);
0039 xercesc::XMLString::release(&char_str);
0040 return my_str;
0041 }
0042
0043
0044 const plog::Severity GDXMLRead::LEVEL = SLOG::EnvLevel("GDXMLRead", "DEBUG") ;
0045
0046
0047 GDXMLRead::GDXMLRead( const char* path, bool kludge_truncated_matrix_)
0048 :
0049 validate(false),
0050 kludge_truncated_matrix(kludge_truncated_matrix_),
0051 handler(new GDXMLErrorHandler(!validate)),
0052 parser(new xercesc::XercesDOMParser),
0053 doc(nullptr),
0054 element(nullptr)
0055 {
0056 LOG(LEVEL) << "reading " << path ;
0057
0058 if (validate)
0059 {
0060 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
0061 }
0062 parser->setValidationSchemaFullChecking(validate);
0063 parser->setCreateEntityReferenceNodes(false);
0064
0065
0066 parser->setDoNamespaces(true);
0067 parser->setDoSchema(validate);
0068 parser->setErrorHandler(handler);
0069
0070 try
0071 {
0072 parser->parse(path);
0073 }
0074 catch (const xercesc::XMLException &e)
0075 {
0076 LOG(error) << "XMLException " << Transcode(e.getMessage()) ;
0077 }
0078 catch (const xercesc::DOMException &e)
0079 {
0080 LOG(error) << "DOMException " << Transcode(e.getMessage());
0081 }
0082
0083 doc = parser->getDocument();
0084
0085 if (!doc)
0086 {
0087 LOG(fatal) << "Unable to open document " << path ;
0088 return ;
0089 }
0090
0091 element = doc->getDocumentElement();
0092 LOG(LEVEL) << "documenElement " << element ;
0093 assert( element);
0094
0095 for(xercesc::DOMNode* iter = element->getFirstChild(); iter != 0; iter = iter->getNextSibling())
0096 {
0097 if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
0098
0099 const xercesc::DOMElement* const child = dynamic_cast<xercesc::DOMElement*>(iter);
0100
0101 assert( child );
0102
0103 const std::string tag = Transcode(child->getTagName());
0104
0105 if (tag=="define")
0106 {
0107 DefineRead(child);
0108 }
0109 else
0110 {
0111 LOG(LEVEL) << " tag " << tag ;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 }
0132 }
0133
0134
0135 void GDXMLRead::MatrixRead( const xercesc::DOMElement* const matrixElement, bool& truncated_values )
0136 {
0137 std::string name = "";
0138
0139 std::string values = "";
0140
0141 const xercesc::DOMNamedNodeMap* const attributes = matrixElement->getAttributes();
0142 XMLSize_t attributeCount = attributes->getLength();
0143
0144 for (XMLSize_t attribute_index=0; attribute_index<attributeCount; attribute_index++)
0145 {
0146 xercesc::DOMNode* node = attributes->item(attribute_index);
0147
0148 if (node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE) { continue; }
0149
0150 const xercesc::DOMAttr* const attribute = dynamic_cast<xercesc::DOMAttr*>(node);
0151
0152 assert( attribute );
0153
0154 const std::string attName = Transcode(attribute->getName());
0155 const std::string attValue = Transcode(attribute->getValue());
0156
0157 if (attName=="name") { name = attValue ; } else
0158
0159
0160 if (attName=="values") { values = attValue; }
0161 }
0162
0163
0164
0165
0166
0167 Matrix m = {} ;
0168 m.name = name ;
0169 m.values = values ;
0170 m.matrixElement = const_cast<xercesc::DOMElement*>(matrixElement) ;
0171 m.repeat_index = -1 ;
0172
0173 matrix.push_back(m) ;
0174
0175
0176 std::vector<double> valueList;
0177 std::stringstream ss;
0178 ss.str(values.c_str()) ;
0179 char delim = ' ' ;
0180 std::string s;
0181 while (std::getline(ss, s, delim)) valueList.push_back(atod_(s.c_str())) ;
0182
0183
0184 truncated_values = false ;
0185 if(values.length() >= 9999 || valueList.size() % 2 != 0) truncated_values = true ;
0186 if(truncated_values)
0187 {
0188 xercesc::DOMElement* me = const_cast<xercesc::DOMElement*>(matrixElement);
0189 truncated_matrixElement.push_back(me);
0190 if(kludge_truncated_matrix) KludgeTruncatedMatrix(me);
0191 }
0192
0193 LOG(LEVEL)
0194 << " " << ( truncated_values ? "**" : " " )
0195 << " values.lenth " << std::setw(7) << values.size()
0196 << " last50 " << std::setw(50) << values.substr(std::max(0,int(values.length())-50))
0197 << " valueList.size " << std::setw(10) << valueList.size()
0198 << " " << ( truncated_values ? "**" : " " )
0199 << " name " << name
0200 ;
0201 }
0202
0203
0204
0205
0206
0207
0208
0209 int GDXMLRead::checkDuplicatedMatrix()
0210 {
0211 unsigned num_matrix = matrix.size() ;
0212 LOG(LEVEL) << " num_matrix " << num_matrix ;
0213 int total_duplicated_matrix = 0 ;
0214
0215 for(unsigned i=0 ; i < num_matrix ; i++)
0216 {
0217 Matrix& im = matrix[i] ;
0218
0219 std::vector<unsigned> dupes ;
0220 for(unsigned j=0 ; j < num_matrix ; j++)
0221 {
0222 Matrix& jm = matrix[j] ;
0223 if( j > i && jm.repeat_index == -1 )
0224 {
0225 if( im == jm )
0226 {
0227 dupes.push_back(j) ;
0228 jm.repeat_index = dupes.size() ;
0229
0230 bool expect = im.values.compare(jm.values) == 0 ;
0231 assert(expect) ;
0232 if(!expect) std::raise(SIGINT);
0233 }
0234 }
0235 }
0236
0237 std::stringstream ss ;
0238
0239 if(dupes.size() > 0 )
0240 {
0241 ss << std::endl << " i " << std::setw(5) << i << " : " << matrix[i].desc() << std::endl ;
0242 for(unsigned k=0 ; k < dupes.size() ; k++)
0243 {
0244 unsigned j = dupes[k] ;
0245 ss << " j " << std::setw(5) << j << " : " << matrix[j].desc() << std::endl ;
0246 }
0247 }
0248 std::string s = ss.str();
0249 LOG(LEVEL) << s ;
0250
0251 total_duplicated_matrix += dupes.size() ;
0252 }
0253
0254 LOG(LEVEL)
0255 << " num_matrix " << num_matrix
0256 << " total_duplicated__matrix " << total_duplicated_matrix
0257 ;
0258
0259 return total_duplicated_matrix ;
0260 }
0261
0262
0263 int GDXMLRead::pruneDuplicatedMatrix()
0264 {
0265 assert(the_defineElement);
0266 unsigned num_matrix = matrix.size() ;
0267 LOG(LEVEL) << " num_matrix " << num_matrix ;
0268
0269 unsigned prune_count = 0 ;
0270 for(unsigned i=0 ; i < num_matrix ; i++)
0271 {
0272 Matrix& im = matrix[i] ;
0273 if( im.repeat_index > -1 )
0274 {
0275 LOG(LEVEL) << "pruning i " << std::setw(5) << i << " im.desc " << im.desc() ;
0276 the_defineElement->removeChild(im.matrixElement) ;
0277 prune_count += 1 ;
0278 }
0279 }
0280 LOG(LEVEL)
0281 << " prune_count " << prune_count
0282 ;
0283
0284 return prune_count ;
0285 }
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 std::string GDXMLRead::KludgeFix( const char* values )
0302 {
0303 std::stringstream ss;
0304 ss.str(values) ;
0305
0306 std::vector<std::string> elem ;
0307 char delim = ' ' ;
0308 std::string s ;
0309 while (std::getline(ss, s, delim)) elem.push_back(s) ;
0310
0311 unsigned num_trim = elem.size() % 2 == 1 ? 1 : 2 ;
0312 unsigned i0 = 0 ;
0313 unsigned i1 = elem.size() - num_trim ;
0314
0315 std::stringstream kk ;
0316 for(unsigned i=i0 ; i < i1 ; i++)
0317 {
0318 std::string k = elem[i];
0319 kk << k ;
0320 if(i < i1 - 1 ) kk << delim ;
0321 }
0322
0323 std::string kludged = kk.str();
0324 return kludged ;
0325 }
0326
0327
0328
0329
0330
0331
0332
0333 void GDXMLRead::KludgeTruncatedMatrix(xercesc::DOMElement* matrixElement )
0334 {
0335 xercesc::DOMNamedNodeMap* attributes = matrixElement->getAttributes();
0336 XMLSize_t attributeCount = attributes->getLength();
0337
0338 for (XMLSize_t attribute_index=0; attribute_index<attributeCount; attribute_index++)
0339 {
0340 xercesc::DOMNode* node = attributes->item(attribute_index);
0341 if (node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE) { continue; }
0342 xercesc::DOMAttr* attribute = dynamic_cast<xercesc::DOMAttr*>(node);
0343 const std::string attName = Transcode(attribute->getName());
0344
0345 if( attName == "values" )
0346 {
0347 const std::string attValueOri = Transcode(attribute->getValue());
0348 std::string attValueKlu = KludgeFix(attValueOri.c_str());
0349
0350
0351 LOG(LEVEL)
0352 << " attName " << attName
0353 << " attValueOri.length " << attValueOri.length()
0354 << " attValueKlu.length " << attValueKlu.length()
0355 ;
0356
0357 LOG(LEVEL)
0358 << std::endl
0359 << " attValueOri.length " << attValueOri.length() << std::endl
0360 << " attValueKlu.length " << attValueKlu.length() << std::endl
0361 << " attValueOri.last50 " << std::setw(50) << attValueOri.substr(std::max(0,int(attValueOri.length())-50)) << std::endl
0362 << " attValueKlu.last50 " << std::setw(50) << attValueKlu.substr(std::max(0,int(attValueKlu.length())-50))
0363 ;
0364
0365 xercesc::XMLString::transcode(attValueKlu.c_str() , tempStr, 9999);
0366 attribute->setValue(tempStr);
0367 }
0368 }
0369 }
0370
0371 Constant GDXMLRead::ConstantRead( const xercesc::DOMElement* const constantElement )
0372 {
0373 Constant c = {} ;
0374 c.name = "" ;
0375 c.value = 0.0 ;
0376 c.constantElement = const_cast<xercesc::DOMElement*>(constantElement) ;
0377
0378 const xercesc::DOMNamedNodeMap* const attributes = constantElement->getAttributes();
0379 XMLSize_t attributeCount = attributes->getLength();
0380
0381 for (XMLSize_t attribute_index=0; attribute_index<attributeCount; attribute_index++)
0382 {
0383 xercesc::DOMNode* node = attributes->item(attribute_index);
0384 if (node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE) { continue; }
0385 const xercesc::DOMAttr* const attribute = dynamic_cast<xercesc::DOMAttr*>(node);
0386 assert(attribute);
0387 const std::string attName = Transcode(attribute->getName());
0388 const std::string attValue = Transcode(attribute->getValue());
0389 if (attName=="name") { c.name = attValue; } else
0390 if (attName=="value") { c.value = atod_(attValue.c_str()); }
0391 }
0392 return c ;
0393 }
0394
0395 void GDXMLRead::DefineRead( const xercesc::DOMElement* const defineElement )
0396 {
0397 assert( the_defineElement == nullptr );
0398 the_defineElement = const_cast<xercesc::DOMElement*>(defineElement) ;
0399
0400 LOG(LEVEL) ;
0401
0402 xercesc::DOMElement* modifiableDefineElement = const_cast<xercesc::DOMElement*>(defineElement);
0403
0404
0405 for (xercesc::DOMNode* iter = defineElement->getFirstChild(); iter != 0; iter = iter->getNextSibling())
0406 {
0407 if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
0408
0409 const xercesc::DOMElement* const child = dynamic_cast<xercesc::DOMElement*>(iter);
0410 assert( child );
0411 const std::string tag = Transcode(child->getTagName());
0412
0413 bool truncated_matrix_values = false ;
0414
0415 if (tag=="constant")
0416 {
0417 Constant c = ConstantRead(child);
0418 constants.push_back(c);
0419 }
0420 else if (tag=="matrix")
0421 {
0422 MatrixRead(child, truncated_matrix_values);
0423 }
0424 else
0425
0426
0427
0428
0429
0430
0431
0432
0433 {
0434 std::cout << "Unknown tag in define " << tag << std::endl ;
0435 }
0436 }
0437
0438
0439 LOG(LEVEL) << "constants.size " << constants.size() ;
0440
0441 for(unsigned i=0 ; i < constants.size() ; i++)
0442 {
0443 const Constant& c = constants[i] ;
0444 LOG(LEVEL)
0445 << " c.name " << std::setw(20) << c.name
0446 << " c.value " << std::setw(10) << c.value
0447 << " c.constantElement " << c.constantElement
0448 ;
0449 modifiableDefineElement->removeChild(c.constantElement);
0450 }
0451
0452
0453 }
0454
0455
0456
0457
0458
0459 GDXMLRead::~GDXMLRead()
0460 {
0461 delete handler ;
0462 delete parser ;
0463 }
0464
0465
0466