summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/synti/zynaddsubfx/Misc/XMLwrapper.C
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/synti/zynaddsubfx/Misc/XMLwrapper.C')
-rw-r--r--muse_qt4_evolution/synti/zynaddsubfx/Misc/XMLwrapper.C533
1 files changed, 533 insertions, 0 deletions
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Misc/XMLwrapper.C b/muse_qt4_evolution/synti/zynaddsubfx/Misc/XMLwrapper.C
new file mode 100644
index 00000000..0f35faf2
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Misc/XMLwrapper.C
@@ -0,0 +1,533 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ XMLwrapper.C - XML wrapper
+ Copyright (C) 2003-2005 Nasca Octavian Paul
+ Author: Nasca Octavian Paul
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License (version 2) for more details.
+
+ You should have received a copy of the GNU General Public License (version 2)
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#include "XMLwrapper.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <zlib.h>
+
+#include "../globals.h"
+#include "Util.h"
+
+int xml_k=0;
+char tabs[STACKSIZE+2];
+
+const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where){
+ const char *name=node->value.element.name;
+
+ if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL);
+ if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL);
+
+ if ((where==MXML_WS_BEFORE_OPEN)||(where==MXML_WS_BEFORE_CLOSE)) {
+/* const char *tmp=node->value.element.name;
+ if (tmp!=NULL) {
+ if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) {
+ printf("%s ",tmp);
+ if (where==MXML_WS_BEFORE_OPEN) xml_k++;
+ if (where==MXML_WS_BEFORE_CLOSE) xml_k--;
+ if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1;
+ if (xml_k<0) xml_k=0;
+ printf("%d\n",xml_k);
+ printf("\n");
+ };
+
+ };
+ int i=0;
+ for (i=1;i<xml_k;i++) tabs[i]='\t';
+ tabs[0]='\n';tabs[i+1]='\0';
+ if (where==MXML_WS_BEFORE_OPEN) return(tabs);
+ else return("\n");
+*/
+ return("\n");
+ };
+
+ return(0);
+};
+
+
+XMLwrapper::XMLwrapper(){
+ ZERO(&parentstack,(int)sizeof(parentstack));
+ ZERO(&values,(int)sizeof(values));
+
+ minimal=true;
+ stackpos=0;
+
+ information.PADsynth_used=false;
+
+ tree=mxmlNewElement(MXML_NO_PARENT,"?xml version=\"1.0\" encoding=\"UTF-8\"?");
+/* for mxml 2.1 (and older)
+ tree=mxmlNewElement(MXML_NO_PARENT,"?xml");
+ mxmlElementSetAttr(tree,"version","1.0");
+ mxmlElementSetAttr(tree,"encoding","UTF-8");
+*/
+
+ mxml_node_t *doctype=mxmlNewElement(tree,"!DOCTYPE");
+ mxmlElementSetAttr(doctype,"ZynAddSubFX-data",NULL);
+
+ node=root=mxmlNewElement(tree,"ZynAddSubFX-data");
+
+ mxmlElementSetAttr(root,"version-major","1");
+ mxmlElementSetAttr(root,"version-minor","1");
+ mxmlElementSetAttr(root,"ZynAddSubFX-author","Nasca Octavian Paul");
+
+ //make the empty branch that will contain the information parameters
+ info=addparams0("INFORMATION");
+
+ //save zynaddsubfx specifications
+ beginbranch("BASE_PARAMETERS");
+ addpar("max_midi_parts",NUM_MIDI_PARTS);
+ addpar("max_kit_items_per_instrument",NUM_KIT_ITEMS);
+
+ addpar("max_system_effects",NUM_SYS_EFX);
+ addpar("max_insertion_effects",NUM_INS_EFX);
+ addpar("max_instrument_effects",NUM_PART_EFX);
+
+ addpar("max_addsynth_voices",NUM_VOICES);
+ endbranch();
+
+};
+
+XMLwrapper::~XMLwrapper(){
+ if (tree!=NULL) mxmlDelete(tree);
+};
+
+bool XMLwrapper::checkfileinformation(char *filename){
+ stackpos=0;
+ ZERO(&parentstack,(int)sizeof(parentstack));
+ information.PADsynth_used=false;
+
+ if (tree!=NULL) mxmlDelete(tree);tree=NULL;
+ char *xmldata=doloadfile(filename);
+ if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed
+
+
+ char *start=strstr(xmldata,"<INFORMATION>");
+ char *end=strstr(xmldata,"</INFORMATION>");
+
+ if ((start==NULL)||(end==NULL)||(start>end)) {
+ delete(xmldata);
+ return(false);
+ };
+ end+=strlen("</INFORMATION>");
+ end[0]='\0';
+
+ tree=mxmlNewElement(MXML_NO_PARENT,"?xml");
+ node=root=mxmlLoadString(tree,xmldata,MXML_OPAQUE_CALLBACK);
+ if (root==NULL) {
+ delete(xmldata);
+ mxmlDelete(tree);
+ node=root=tree=NULL;
+ return(false);
+ };
+
+ root=mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND);
+ push(root);
+
+ if (root==NULL){
+ delete(xmldata);
+ mxmlDelete(tree);
+ node=root=tree=NULL;
+ return(false);
+ };
+
+ information.PADsynth_used=getparbool("PADsynth_used",false);
+
+ exitbranch();
+ if (tree!=NULL) mxmlDelete(tree);
+ delete(xmldata);
+ node=root=tree=NULL;
+
+ return(true);
+};
+
+
+/* SAVE XML members */
+
+int XMLwrapper::saveXMLfile(char *filename){
+ char *xmldata=getXMLdata();
+ if (xmldata==NULL) return(-2);
+
+ int compression=config.cfg.GzipCompression;
+
+ int fnsize=strlen(filename)+100;
+ char *filenamenew=new char [fnsize];
+ snprintf(filenamenew,fnsize,"%s",filename);
+
+ int result=dosavefile(filenamenew,compression,xmldata);
+
+ delete(filenamenew);
+ delete(xmldata);
+ return(result);
+};
+
+char *XMLwrapper::getXMLdata(){
+ xml_k=0;
+ ZERO(tabs,STACKSIZE+2);
+
+ mxml_node_t *oldnode=node;
+
+ node=info;
+ //Info storing
+ addparbool("PADsynth_used",information.PADsynth_used);
+
+ node=oldnode;
+ char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback);
+
+ return(xmldata);
+};
+
+
+int XMLwrapper::dosavefile(char *filename,int compression,char *xmldata){
+ if (compression==0){
+ FILE *file;
+ file=fopen(filename,"w");
+ if (file==NULL) return(-1);
+ fputs(xmldata,file);
+ fclose(file);
+ } else {
+ if (compression>9) compression=9;
+ if (compression<1) compression=1;
+ char options[10];
+ snprintf(options,10,"wb%d",compression);
+
+ gzFile gzfile;
+ gzfile=gzopen(filename,options);
+ if (gzfile==NULL) return(-1);
+ gzputs(gzfile,xmldata);
+ gzclose(gzfile);
+ };
+
+ return(0);
+};
+
+
+
+void XMLwrapper::addpar(char *name,int val){
+ addparams2("par","name",name,"value",int2str(val));
+};
+
+void XMLwrapper::addparreal(char *name,REALTYPE val){
+ addparams2("par_real","name",name,"value",real2str(val));
+};
+
+void XMLwrapper::addparbool(char *name,int val){
+ if (val!=0) addparams2("par_bool","name",name,"value","yes");
+ else addparams2("par_bool","name",name,"value","no");
+};
+
+void XMLwrapper::addparstr(char *name,char *val){
+ mxml_node_t *element=mxmlNewElement(node,"string");
+ mxmlElementSetAttr(element,"name",name);
+ mxmlNewText(element,0,val);
+};
+
+
+void XMLwrapper::beginbranch(char *name){
+ push(node);
+ node=addparams0(name);
+};
+
+void XMLwrapper::beginbranch(char *name,int id){
+ push(node);
+ node=addparams1(name,"id",int2str(id));
+};
+
+void XMLwrapper::endbranch(){
+ node=pop();
+};
+
+
+
+/* LOAD XML members */
+
+int XMLwrapper::loadXMLfile(const char *filename){
+ if (tree!=NULL) mxmlDelete(tree);
+ tree=NULL;
+
+ ZERO(&parentstack,(int)sizeof(parentstack));
+ ZERO(&values,(int)sizeof(values));
+
+ stackpos=0;
+
+ char *xmldata=doloadfile(filename);
+ if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed
+
+ root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK);
+
+ delete(xmldata);
+
+ if (tree==NULL) return(-2);//this is not XML
+
+
+ node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND);
+ if (root==NULL) return(-3);//the XML doesnt embbed zynaddsubfx data
+ push(root);
+
+ values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major"));
+ values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor"));
+
+ return(0);
+};
+
+
+char *XMLwrapper::doloadfile(const char *filename){
+ char *xmldata=NULL;
+ int filesize=-1;
+
+ //try get filesize as gzip data (first)
+ gzFile gzfile=gzopen(filename,"rb");
+ if (gzfile!=NULL){//this is a gzip file
+ // first check it's size
+ while(!gzeof(gzfile)) {
+ gzseek (gzfile,1024*1024,SEEK_CUR);
+ if (gztell(gzfile)>10000000) {
+ gzclose(gzfile);
+ goto notgzip;//the file is too big
+ };
+ };
+ filesize=gztell(gzfile);
+
+ //rewind the file and load the data
+ xmldata=new char[filesize+1];
+ ZERO(xmldata,filesize+1);
+
+ gzrewind(gzfile);
+ gzread(gzfile,xmldata,filesize);
+
+ gzclose(gzfile);
+ return (xmldata);
+ } else {//this is not a gzip file
+ notgzip:
+ FILE *file=fopen(filename,"rb");
+ if (file==NULL) return(NULL);
+ fseek(file,0,SEEK_END);
+ filesize=ftell(file);
+
+ xmldata=new char [filesize+1];
+ ZERO(xmldata,filesize+1);
+
+ rewind(file);
+ fread(xmldata,filesize,1,file);
+
+ fclose(file);
+ return(xmldata);
+ };
+};
+
+bool XMLwrapper::putXMLdata(char *xmldata){
+ if (tree!=NULL) mxmlDelete(tree);
+ tree=NULL;
+
+ ZERO(&parentstack,(int)sizeof(parentstack));
+ ZERO(&values,(int)sizeof(values));
+
+ stackpos=0;
+
+ if (xmldata==NULL) return (false);
+
+ root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK);
+
+ if (tree==NULL) return(false);
+
+ node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND);
+ if (root==NULL) return (false);;
+ push(root);
+
+ return(true);
+};
+
+
+
+int XMLwrapper::enterbranch(char *name){
+ node=mxmlFindElement(peek(),peek(),name,NULL,NULL,MXML_DESCEND_FIRST);
+ if (node==NULL) return(0);
+
+ push(node);
+ return(1);
+};
+
+int XMLwrapper::enterbranch(char *name,int id){
+ snprintf(tmpstr,TMPSTR_SIZE,"%d",id);
+ node=mxmlFindElement(peek(),peek(),name,"id",tmpstr,MXML_DESCEND_FIRST);
+ if (node==NULL) return(0);
+
+ push(node);
+ return(1);
+};
+
+
+void XMLwrapper::exitbranch(){
+ pop();
+};
+
+
+int XMLwrapper::getbranchid(int min, int max){
+ int id=str2int(mxmlElementGetAttr(node,"id"));
+ if ((min==0)&&(max==0)) return(id);
+
+ if (id<min) id=min;
+ else if (id>max) id=max;
+
+ return(id);
+};
+
+int XMLwrapper::getpar(char *name,int defaultpar,int min,int max){
+ node=mxmlFindElement(peek(),peek(),"par","name",name,MXML_DESCEND_FIRST);
+ if (node==NULL) return(defaultpar);
+
+ const char *strval=mxmlElementGetAttr(node,"value");
+ if (strval==NULL) return(defaultpar);
+
+ int val=str2int(strval);
+ if (val<min) val=min;
+ else if (val>max) val=max;
+
+ return(val);
+};
+
+int XMLwrapper::getpar127(char *name,int defaultpar){
+ return(getpar(name,defaultpar,0,127));
+};
+
+int XMLwrapper::getparbool(char *name,int defaultpar){
+ node=mxmlFindElement(peek(),peek(),"par_bool","name",name,MXML_DESCEND_FIRST);
+ if (node==NULL) return(defaultpar);
+
+ const char *strval=mxmlElementGetAttr(node,"value");
+ if (strval==NULL) return(defaultpar);
+
+ if ((strval[0]=='Y')||(strval[0]=='y')) return(1);
+ else return(0);
+};
+
+void XMLwrapper::getparstr(char *name,char *par,int maxstrlen){
+ ZERO(par,maxstrlen);
+ node=mxmlFindElement(peek(),peek(),"string","name",name,MXML_DESCEND_FIRST);
+
+ if (node==NULL) return;
+ if (node->child==NULL) return;
+ if (node->child->type!=MXML_OPAQUE) return;
+
+ snprintf(par,maxstrlen,"%s",node->child->value.element.name);
+
+};
+
+REALTYPE XMLwrapper::getparreal(char *name,REALTYPE defaultpar){
+ node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST);
+ if (node==NULL) return(defaultpar);
+
+ const char *strval=mxmlElementGetAttr(node,"value");
+ if (strval==NULL) return(defaultpar);
+
+ return(str2real(strval));
+};
+
+REALTYPE XMLwrapper::getparreal(char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max){
+ REALTYPE result=getparreal(name,defaultpar);
+
+ if (result<min) result=min;
+ else if (result>max) result=max;
+ return(result);
+};
+
+
+/** Private members **/
+
+char *XMLwrapper::int2str(int x){
+ snprintf(tmpstr,TMPSTR_SIZE,"%d",x);
+ return(tmpstr);
+};
+
+char *XMLwrapper::real2str(REALTYPE x){
+ snprintf(tmpstr,TMPSTR_SIZE,"%g",x);
+ return(tmpstr);
+};
+
+int XMLwrapper::str2int(const char *str){
+ if (str==NULL) return(0);
+ int result=strtol(str,NULL,10);
+ return(result);
+};
+
+REALTYPE XMLwrapper::str2real(const char *str){
+ if (str==NULL) return(0.0);
+ REALTYPE result=strtod(str,NULL);
+ return(result);
+};
+
+
+mxml_node_t *XMLwrapper::addparams0(char *name){
+ mxml_node_t *element=mxmlNewElement(node,name);
+ return(element);
+};
+
+mxml_node_t *XMLwrapper::addparams1(char *name,char *par1,char *val1){
+ mxml_node_t *element=mxmlNewElement(node,name);
+ mxmlElementSetAttr(element,par1,val1);
+ return(element);
+};
+
+mxml_node_t *XMLwrapper::addparams2(char *name,char *par1,char *val1,char *par2, char *val2){
+ mxml_node_t *element=mxmlNewElement(node,name);
+ mxmlElementSetAttr(element,par1,val1);
+ mxmlElementSetAttr(element,par2,val2);
+ return(element);
+};
+
+
+
+
+void XMLwrapper::push(mxml_node_t *node){
+ if (stackpos>=STACKSIZE-1) {
+ printf("BUG!: XMLwrapper::push() - full parentstack\n");
+ return;
+ };
+ stackpos++;
+ parentstack[stackpos]=node;
+
+// printf("push %d - %s\n",stackpos,node->value.element.name);
+
+};
+mxml_node_t *XMLwrapper::pop(){
+ if (stackpos<=0) {
+ printf("BUG!: XMLwrapper::pop() - empty parentstack\n");
+ return (root);
+ };
+ mxml_node_t *node=parentstack[stackpos];
+ parentstack[stackpos]=NULL;
+
+// printf("pop %d - %s\n",stackpos,node->value.element.name);
+
+ stackpos--;
+ return(node);
+};
+
+mxml_node_t *XMLwrapper::peek(){
+ if (stackpos<=0) {
+ printf("BUG!: XMLwrapper::peek() - empty parentstack\n");
+ return (root);
+ };
+ return(parentstack[stackpos]);
+};
+
+
+