XMLwrapper.cpp (12826B)
1 /* 2 XMLwrapper.C - XML wrapper 3 Copyright (C) 2003-2009 Nasca Octavian Paul 4 Author: Nasca Octavian Paul 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of version 2 of the GNU General Public License 8 as published by the Free Software Foundation. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License (version 2 or later) for more details. 14 15 You should have received a copy of the GNU General Public License (version 2) 16 along with this program; if not, write to the Free Software Foundation, 17 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 */ 20 21 #include "XMLwrapper.h" 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <zlib.h> 25 26 //#include "Util.h" 27 28 int xml_k=0; 29 char tabs[STACKSIZE+2]; 30 31 const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where){ 32 const char *name=node->value.element.name; 33 34 if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL); 35 if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL); 36 37 if ((where==MXML_WS_BEFORE_OPEN)||(where==MXML_WS_BEFORE_CLOSE)) { 38 /* const char *tmp=node->value.element.name; 39 if (tmp!=NULL) { 40 if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { 41 printf("%s ",tmp); 42 if (where==MXML_WS_BEFORE_OPEN) xml_k++; 43 if (where==MXML_WS_BEFORE_CLOSE) xml_k--; 44 if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; 45 if (xml_k<0) xml_k=0; 46 printf("%d\n",xml_k); 47 printf("\n"); 48 }; 49 50 }; 51 int i=0; 52 for (i=1;i<xml_k;i++) tabs[i]='\t'; 53 tabs[0]='\n';tabs[i+1]='\0'; 54 if (where==MXML_WS_BEFORE_OPEN) return(tabs); 55 else return("\n"); 56 */ 57 return("\n"); 58 }; 59 60 return(0); 61 }; 62 63 64 XMLwrapper::XMLwrapper(){ 65 ZERO(&parentstack,(int)sizeof(parentstack)); 66 ZERO(&values,(int)sizeof(values)); 67 68 minimal=true; 69 stackpos=0; 70 71 tree=mxmlNewElement(MXML_NO_PARENT,"?xml version=\"1.0\" encoding=\"UTF-8\"?"); 72 /* for mxml 2.1 (and older) 73 tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); 74 mxmlElementSetAttr(tree,"version","1.0"); 75 mxmlElementSetAttr(tree,"encoding","UTF-8"); 76 */ 77 78 mxml_node_t *doctype=mxmlNewElement(tree,"!DOCTYPE"); 79 mxmlElementSetAttr(doctype,"paulstretch-data",NULL); 80 81 node=root=mxmlNewElement(tree,"paulstretch-data"); 82 83 mxmlElementSetAttr(root,"version-major","1"); 84 mxmlElementSetAttr(root,"version-minor","0"); 85 mxmlElementSetAttr(root,"paulstretch-author","Nasca Octavian Paul"); 86 87 //make the empty branch that will contain the information parameters 88 info=addparams0("INFORMATION"); 89 90 //save specifications 91 beginbranch("BASE_PARAMETERS"); 92 endbranch(); 93 94 }; 95 96 XMLwrapper::~XMLwrapper(){ 97 if (tree!=NULL) mxmlDelete(tree); 98 }; 99 100 bool XMLwrapper::checkfileinformation(char *filename){ 101 stackpos=0; 102 ZERO(&parentstack,(int)sizeof(parentstack)); 103 104 if (tree!=NULL) mxmlDelete(tree);tree=NULL; 105 char *xmldata=doloadfile(filename); 106 if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed 107 108 109 char *start=strstr(xmldata,"<INFORMATION>"); 110 char *end=strstr(xmldata,"</INFORMATION>"); 111 112 if ((start==NULL)||(end==NULL)||(start>end)) { 113 delete []xmldata; 114 return(false); 115 }; 116 end+=strlen("</INFORMATION>"); 117 end[0]='\0'; 118 119 tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); 120 node=root=mxmlLoadString(tree,xmldata,MXML_OPAQUE_CALLBACK); 121 if (root==NULL) { 122 delete []xmldata; 123 mxmlDelete(tree); 124 node=root=tree=NULL; 125 return(false); 126 }; 127 128 root=mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND); 129 push(root); 130 131 if (root==NULL){ 132 delete []xmldata; 133 mxmlDelete(tree); 134 node=root=tree=NULL; 135 return(false); 136 }; 137 138 exitbranch(); 139 if (tree!=NULL) mxmlDelete(tree); 140 delete []xmldata; 141 node=root=tree=NULL; 142 143 return(true); 144 }; 145 146 147 /* SAVE XML members */ 148 149 int XMLwrapper::saveXMLfile(const char *filename){ 150 char *xmldata=getXMLdata(); 151 if (xmldata==NULL) return(-2); 152 153 int compression=3; 154 155 int fnsize=strlen(filename)+100; 156 char *filenamenew=new char [fnsize]; 157 snprintf(filenamenew,fnsize,"%s",filename); 158 159 int result=dosavefile(filenamenew,compression,xmldata); 160 161 delete []filenamenew; 162 delete []xmldata; 163 return(result); 164 }; 165 166 char *XMLwrapper::getXMLdata(){ 167 xml_k=0; 168 ZERO(tabs,STACKSIZE+2); 169 170 mxml_node_t *oldnode=node; 171 172 node=info; 173 //Info storing 174 175 node=oldnode; 176 char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback); 177 178 return(xmldata); 179 }; 180 181 182 int XMLwrapper::dosavefile(char *filename,int compression,char *xmldata){ 183 if (compression==0){ 184 FILE *file; 185 file=fopen(filename,"w"); 186 if (file==NULL) return(-1); 187 fputs(xmldata,file); 188 fclose(file); 189 } else { 190 if (compression>9) compression=9; 191 if (compression<1) compression=1; 192 char options[10]; 193 snprintf(options,10,"wb%d",compression); 194 195 gzFile gzfile; 196 gzfile=gzopen(filename,options); 197 if (gzfile==NULL) return(-1); 198 gzputs(gzfile,xmldata); 199 gzclose(gzfile); 200 }; 201 202 return(0); 203 }; 204 205 206 207 void XMLwrapper::addpar(const char *name,int val){ 208 addparams2("par","name",name,"value",int2str(val)); 209 }; 210 211 void XMLwrapper::addparreal(const char *name,REALTYPE val){ 212 addparams2("par_real","name",name,"value",real2str(val)); 213 }; 214 215 void XMLwrapper::addparbool(const char *name,int val){ 216 if (val!=0) addparams2("par_bool","name",name,"value","yes"); 217 else addparams2("par_bool","name",name,"value","no"); 218 }; 219 220 void XMLwrapper::addparstr(const char *name,const char *val){ 221 mxml_node_t *element=mxmlNewElement(node,"string"); 222 mxmlElementSetAttr(element,"name",name); 223 mxmlNewText(element,0,val); 224 }; 225 226 227 void XMLwrapper::beginbranch(const char *name){ 228 push(node); 229 node=addparams0(name); 230 }; 231 232 void XMLwrapper::beginbranch(const char *name,int id){ 233 push(node); 234 node=addparams1(name,"id",int2str(id)); 235 }; 236 237 void XMLwrapper::endbranch(){ 238 node=pop(); 239 }; 240 241 242 243 /* LOAD XML members */ 244 245 int XMLwrapper::loadXMLfile(const char *filename){ 246 if (tree!=NULL) mxmlDelete(tree); 247 tree=NULL; 248 249 ZERO(&parentstack,(int)sizeof(parentstack)); 250 ZERO(&values,(int)sizeof(values)); 251 252 stackpos=0; 253 254 char *xmldata=doloadfile(filename); 255 if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed 256 257 printf("%s\n",xmldata); 258 root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); 259 260 delete []xmldata; 261 262 if (tree==NULL) return(-2);//this is not XML 263 264 265 node=root=mxmlFindElement(tree,tree,"paulstretch-data",NULL,NULL,MXML_DESCEND); 266 if (root==NULL) return(-3);//the XML doesnt embbed required data 267 push(root); 268 269 values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major")); 270 values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor")); 271 272 return(0); 273 }; 274 275 276 char *XMLwrapper::doloadfile(const char *filename){ 277 char *xmldata=NULL; 278 int filesize=-1; 279 280 //try get filesize as gzip data (first) 281 gzFile gzfile=gzopen(filename,"rb"); 282 if (gzfile!=NULL){//this is a gzip file 283 // first check it's size 284 int bufsize=1024; 285 char* tmpbuf=new char[bufsize]; 286 filesize=0; 287 while(!gzeof(gzfile)) { 288 filesize+=gzread(gzfile,tmpbuf,bufsize); 289 }; 290 delete []tmpbuf; 291 292 //rewind the file and load the data 293 xmldata=new char[filesize+1]; 294 ZERO(xmldata,filesize+1); 295 296 gzrewind(gzfile); 297 gzread(gzfile,xmldata,filesize); 298 299 gzclose(gzfile); 300 return (xmldata); 301 } else {//this is not a gzip file 302 notgzip: 303 FILE *file=fopen(filename,"rb"); 304 if (file==NULL) return(NULL); 305 fseek(file,0,SEEK_END); 306 filesize=ftell(file); 307 308 xmldata=new char [filesize+1]; 309 ZERO(xmldata,filesize+1); 310 311 rewind(file); 312 int tmp=fread(xmldata,filesize,1,file); 313 314 fclose(file); 315 return(xmldata); 316 }; 317 }; 318 319 bool XMLwrapper::putXMLdata(char *xmldata){ 320 if (tree!=NULL) mxmlDelete(tree); 321 tree=NULL; 322 323 ZERO(&parentstack,(int)sizeof(parentstack)); 324 ZERO(&values,(int)sizeof(values)); 325 326 stackpos=0; 327 328 if (xmldata==NULL) return (false); 329 330 root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); 331 332 if (tree==NULL) return(false); 333 334 node=root=mxmlFindElement(tree,tree,"paulstretch-data",NULL,NULL,MXML_DESCEND); 335 if (root==NULL) return (false);; 336 push(root); 337 338 return(true); 339 }; 340 341 342 343 int XMLwrapper::enterbranch(const char *name){ 344 node=mxmlFindElement(peek(),peek(),name,NULL,NULL,MXML_DESCEND_FIRST); 345 if (node==NULL) return(0); 346 347 push(node); 348 return(1); 349 }; 350 351 int XMLwrapper::enterbranch(const char *name,int id){ 352 snprintf(tmpstr,TMPSTR_SIZE,"%d",id); 353 node=mxmlFindElement(peek(),peek(),name,"id",tmpstr,MXML_DESCEND_FIRST); 354 if (node==NULL) return(0); 355 356 push(node); 357 return(1); 358 }; 359 360 361 void XMLwrapper::exitbranch(){ 362 pop(); 363 }; 364 365 366 int XMLwrapper::getbranchid(int min, int max){ 367 int id=str2int(mxmlElementGetAttr(node,"id")); 368 if ((min==0)&&(max==0)) return(id); 369 370 if (id<min) id=min; 371 else if (id>max) id=max; 372 373 return(id); 374 }; 375 376 int XMLwrapper::getpar(const char *name,int defaultpar,int min,int max){ 377 node=mxmlFindElement(peek(),peek(),"par","name",name,MXML_DESCEND_FIRST); 378 if (node==NULL) return(defaultpar); 379 380 const char *strval=mxmlElementGetAttr(node,"value"); 381 if (strval==NULL) return(defaultpar); 382 383 int val=str2int(strval); 384 if (val<min) val=min; 385 else if (val>max) val=max; 386 387 return(val); 388 }; 389 390 int XMLwrapper::getpar127(const char *name,int defaultpar){ 391 return(getpar(name,defaultpar,0,127)); 392 }; 393 394 int XMLwrapper::getparbool(const char *name,int defaultpar){ 395 node=mxmlFindElement(peek(),peek(),"par_bool","name",name,MXML_DESCEND_FIRST); 396 if (node==NULL) return(defaultpar); 397 398 const char *strval=mxmlElementGetAttr(node,"value"); 399 if (strval==NULL) return(defaultpar); 400 401 if ((strval[0]=='Y')||(strval[0]=='y')) return(1); 402 else return(0); 403 }; 404 405 void XMLwrapper::getparstr(const char *name,char *par,int maxstrlen){ 406 ZERO(par,maxstrlen); 407 node=mxmlFindElement(peek(),peek(),"string","name",name,MXML_DESCEND_FIRST); 408 409 if (node==NULL) return; 410 if (node->child==NULL) return; 411 if (node->child->type!=MXML_OPAQUE) return; 412 413 snprintf(par,maxstrlen,"%s",node->child->value.element.name); 414 415 }; 416 417 REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar){ 418 node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST); 419 if (node==NULL) return(defaultpar); 420 421 const char *strval=mxmlElementGetAttr(node,"value"); 422 if (strval==NULL) return(defaultpar); 423 424 return(str2real(strval)); 425 }; 426 427 REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max){ 428 REALTYPE result=getparreal(name,defaultpar); 429 430 if (result<min) result=min; 431 else if (result>max) result=max; 432 return(result); 433 }; 434 435 436 /** Private members **/ 437 438 char *XMLwrapper::int2str(int x){ 439 snprintf(tmpstr,TMPSTR_SIZE,"%d",x); 440 return(tmpstr); 441 }; 442 443 char *XMLwrapper::real2str(REALTYPE x){ 444 snprintf(tmpstr,TMPSTR_SIZE,"%g",x); 445 return(tmpstr); 446 }; 447 448 int XMLwrapper::str2int(const char *str){ 449 if (str==NULL) return(0); 450 int result=strtol(str,NULL,10); 451 return(result); 452 }; 453 454 REALTYPE XMLwrapper::str2real(const char *str){ 455 if (str==NULL) return(0.0); 456 REALTYPE result=strtod(str,NULL); 457 return(result); 458 }; 459 460 461 mxml_node_t *XMLwrapper::addparams0(const char *name){ 462 mxml_node_t *element=mxmlNewElement(node,name); 463 return(element); 464 }; 465 466 mxml_node_t *XMLwrapper::addparams1(const char *name,const char *par1,const char *val1){ 467 mxml_node_t *element=mxmlNewElement(node,name); 468 mxmlElementSetAttr(element,par1,val1); 469 return(element); 470 }; 471 472 mxml_node_t *XMLwrapper::addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2){ 473 mxml_node_t *element=mxmlNewElement(node,name); 474 mxmlElementSetAttr(element,par1,val1); 475 mxmlElementSetAttr(element,par2,val2); 476 return(element); 477 }; 478 479 480 481 482 void XMLwrapper::push(mxml_node_t *node){ 483 if (stackpos>=STACKSIZE-1) { 484 printf("BUG!: XMLwrapper::push() - full parentstack\n"); 485 return; 486 }; 487 stackpos++; 488 parentstack[stackpos]=node; 489 490 // printf("push %d - %s\n",stackpos,node->value.element.name); 491 492 }; 493 mxml_node_t *XMLwrapper::pop(){ 494 if (stackpos<=0) { 495 printf("BUG!: XMLwrapper::pop() - empty parentstack\n"); 496 return (root); 497 }; 498 mxml_node_t *node=parentstack[stackpos]; 499 parentstack[stackpos]=NULL; 500 501 // printf("pop %d - %s\n",stackpos,node->value.element.name); 502 503 stackpos--; 504 return(node); 505 }; 506 507 mxml_node_t *XMLwrapper::peek(){ 508 if (stackpos<=0) { 509 printf("BUG!: XMLwrapper::peek() - empty parentstack\n"); 510 return (root); 511 }; 512 return(parentstack[stackpos]); 513 }; 514 515 516