paulstretch_cpp

PaulStretch
Log | Files | Refs | LICENSE

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