/* ************************************************************************** Author: Achim Gaedke Created: June 2004 ****************************************************************************/ #include "states.h" #include "xml_states.h" #include #include #include #include #ifndef SIZETPRINTFLETTER # ifndef __LP64__ # define SIZETPRINTFLETTER "u" # else # define SIZETPRINTFLETTER "lu" # endif #endif void xml_state_reader_startelement_handler(xml_state_reader* self, const XML_Char *name, const XML_Char **atts ) { self->start_element(name,atts); } void xml_state_reader_endelement_handler(xml_state_reader* self, const XML_Char *name) { self->end_element(name); } const XML_Char* xml_state_reader::search_attribute(const XML_Char** atts,const XML_Char* attr_name) const { if (atts==NULL || atts[0]==NULL) return NULL; size_t attr_idx=0; while (strcmp(atts[attr_idx],attr_name)!=0) { attr_idx+=2; if (atts[attr_idx]==NULL) return NULL; } return atts[attr_idx+1]; } const XML_Char* xml_state_reader::search_attributes(const XML_Char** atts, ...) const { if (atts==NULL || atts[0]==NULL) return NULL; va_list names; va_start(names,atts); const XML_Char* attr_name=va_arg(names, const XML_Char*); while (attr_name!=NULL) { size_t attr_idx=0; while (atts[attr_idx]!=NULL && strcmp(atts[attr_idx],attr_name)!=0) attr_idx+=2; if (atts[attr_idx]!=NULL) { va_end(names); return atts[attr_idx+1]; } attr_name=va_arg(names, const XML_Char*); } va_end(names); return NULL; } state_atom* xml_state_reader::state_factory(const XML_Char *name, const XML_Char **atts) const { if (strcmp(name,"state")==0) { state* s=new state(1); const XML_Char* length=search_attributes(atts,"length","time",(XML_Char*)NULL); if (length!=NULL) s->length=strtod(length,NULL); return s; } if (strcmp(name,"sequent")==0) { state_sequent* s=new state_sequent(); const XML_Char* repeat=search_attribute(atts,"repeat"); if (repeat!=NULL) s->repeat=strtoul(repeat,0,0); else s->repeat=1; return s; } if (strcmp(name,"parallel")==0) { return new state_parallel(); } if (strcmp(name,"ttlout")==0) { ttlout* ttls=new ttlout(); const XML_Char* id=search_attributes(atts,"id","i",(XML_Char*)NULL); if (id!=NULL) ttls->id=strtol(id,NULL,0); const XML_Char* value=search_attribute(atts,"value"); if (value!=NULL) ttls->ttls=strtoul(value,NULL,0); const XML_Char* channel=search_attribute(atts,"channel"); if (channel!=NULL) { const XML_Char* state=search_attribute(atts,"state"); if (state!=NULL) { size_t number=strtoul(channel,0,0); char state_char=(state)[0]; if (state_char=='h' || state_char=='1') ttls->ttls.set(number,1); else ttls->ttls.set(number,0); } else { fprintf(stderr,"found invalid ttl state: ignoring\n"); delete ttls; ttls=NULL; } } return (state_atom*)ttls; } if (strcmp(name,"analogout")==0) { analogout* aout=new analogout(); const XML_Char* channel=search_attributes(atts,"channel","c","id","i",(XML_Char*)NULL); const XML_Char* frequency=search_attributes(atts,"frequency","f",(XML_Char*)NULL); const XML_Char* phase=search_attributes(atts,"phase","p",(XML_Char*)NULL); const XML_Char* amplitude=search_attributes(atts,"amplitude","a",(XML_Char*)NULL); const XML_Char* dac_value=search_attributes(atts,"dac_value","d",(XML_Char*)NULL); if (dac_value!=NULL) aout->dac_value=strtol(dac_value,NULL,0); if (channel!=NULL) aout->id=strtoul(channel,NULL,0); if (frequency!=NULL) aout->frequency=strtod(frequency,NULL); if (phase!=NULL) aout->phase=strtod(phase,NULL); if (amplitude!=NULL) aout->amplitude=strtod(amplitude,NULL); else aout->amplitude=1.0; return (state_atom*)aout; } if (strcmp(name,"analogin")==0) { analogin* ain=new analogin(); const XML_Char* id=search_attributes(atts,"id","i",(XML_Char*)NULL); const XML_Char* frequency=search_attributes(atts,"f","frequency",(XML_Char*)NULL); const XML_Char* samples=search_attributes(atts,"s","samples",(XML_Char*)NULL); const XML_Char* channels=search_attributes(atts,"c","channels",(XML_Char*)NULL); const XML_Char* resolution = search_attributes(atts,"r","res","resolution",(XML_Char*)NULL); if (resolution!=NULL) ain->resolution=strtoul(resolution,NULL,0); else ain->resolution=14; // was 12 if (frequency!=NULL) ain->sample_frequency=strtod(frequency,NULL); if (samples!=NULL) ain->samples=strtoul(samples,NULL,0); if (id!=NULL) ain->id=strtoul(id,NULL,0); if (channels!=NULL) { ain->channels = channel_array(strtoul(channels,NULL,0)); ain->nchannels = ain->channels.count(); } else { ain->channels = channel_array(3); ain->nchannels = ain->channels.count(); } // set parameters for each channel for (int i = 0; i < ain->nchannels; i++) { if (ain->channels[i] == true) { char buffer1[100]; char buffer2[100]; sprintf(buffer1, "sen%i", i); sprintf(buffer2, "sensitivity%i", i - 1); // read sensitivity const XML_Char* sensitivity = search_attributes(atts, buffer1, buffer2,(XML_Char*)NULL); if (sensitivity != NULL) { if (ain->sensitivity == NULL) { ain->sensitivity = new double[ain->nchannels]; } ain->sensitivity[i] = strtod(sensitivity, NULL); } else { ain->sensitivity[i] = ADC_M2I_DEFAULT_SENSITIVITY; } delete sensitivity; // read offset sprintf(buffer1, "offset%i", i); const XML_Char* offset = search_attributes(atts, buffer1, (XML_Char*)NULL); if (offset != NULL) { if (ain->offset == NULL) { ain->offset = new int[ain->nchannels]; } ain->offset[i] = strtol(offset, NULL, 0); } else { ain->offset[i] = ADC_M2I_DEFAULT_OFFSET; } delete offset; // read impedance sprintf(buffer1, "impedance%i", i); const XML_Char* impedance = search_attributes(atts, buffer1, (XML_Char*)NULL); if (impedance != NULL) { if (ain->impedance == NULL) { ain->impedance = new double[ain->nchannels]; } ain->impedance[i] = strtol(impedance, NULL, 0); } else { ain->impedance[i] = ADC_M2I_DEFAULT_IMPEDANCE; } delete impedance; } } return (state_atom*)ain; } fprintf(stderr,"unknown tag %s found\n",name); return NULL; } void xml_state_reader::start_element(const XML_Char *name, const XML_Char **atts) { state_atom* new_element=state_factory(name,atts); if (root==NULL) root=new_element; if (new_element!=NULL && !pending_elements.empty()) { state* container=dynamic_cast(pending_elements.back()); if (container!=NULL) container->push_back(new_element); else fprintf(stderr,"found invalid nested element %s\n",name); } pending_elements.push_back(new_element); } void xml_state_reader::end_element(const XML_Char *name) { pending_elements.pop_back(); } xml_state_reader::xml_state_reader() { fprintf(stderr, "xml_state_reader class is decrepated, please shift to xerces supporting classes.\n"); root=(state_atom*)NULL; parser=XML_ParserCreate((XML_Char*)NULL); XML_SetUserData(parser,(void*)this); XML_SetElementHandler(parser, (XML_StartElementHandler)xml_state_reader_startelement_handler, (XML_EndElementHandler)xml_state_reader_endelement_handler); } state_atom* xml_state_reader::read_from_string(const std::string& data) { if (!XML_Parse(parser,data.c_str(), data.size(),1)) { /* handle parse error */ fprintf(stderr,"error while parsing\n"); delete root; root=NULL; return NULL; } state_atom* return_value=root; root=NULL; return return_value; } state_atom* xml_state_reader::read_from_file(const std::string& filename) { int docfd=open(filename.c_str(),O_RDONLY); for (;;) { const size_t BUFF_SIZE=1<<12; int bytes_read; void *buff = XML_GetBuffer(parser, BUFF_SIZE); if (buff == NULL) { fprintf(stderr, "could not get the buffer from XML Parser\n"); close(docfd); return NULL; } bytes_read = read(docfd, buff, BUFF_SIZE); if (bytes_read < 0) { /* handle error */ fprintf(stderr,"error while reading\n"); if (root!=NULL) delete root; root=NULL; break; } if (! XML_ParseBuffer(parser, bytes_read, bytes_read == 0)) { /* handle parse error */ fprintf(stderr,"error while parsing\n"); if (root!=NULL) delete root; root=NULL; break; } // peaceful end if (bytes_read == 0) break; }; close(docfd); state_atom* return_value=root; root=NULL; return return_value; } xml_state_reader::~xml_state_reader(){ XML_ParserFree(parser); if (root!=NULL) delete root; } int xml_state_writer::write_states(FILE* output, const state_atom& states_to_write, int add_header, int indent_size) { if (add_header) { fprintf(output,"\n"); } std::string indent_string(indent_size,' '); const state_sequent* ss=dynamic_cast(&states_to_write); if (ss!=NULL) { if (ss->repeat==1) fprintf(output,"%s\n",indent_string.c_str()); else fprintf(output,"%s\n",indent_string.c_str(),ss->repeat); for (state::const_iterator i=ss->begin();i!=ss->end(); i++) { write_states(output,**i,0,indent_size+indent_increase); } fprintf(output,"%s\n",indent_string.c_str()); return 1; } const state_parallel* sp=dynamic_cast(&states_to_write); if (sp!=NULL){ fprintf(output,"%s\n",indent_string.c_str()); for (state::const_iterator i=sp->begin();i!=sp->end(); i++) { write_states(output,**i,0,indent_size+indent_increase); } fprintf(output,"%s\n",indent_string.c_str()); return 1; } const state* st=dynamic_cast(&states_to_write); if (st!=NULL) { fprintf(output,"%s\n",indent_string.c_str(),st->length); for (state::const_iterator i=st->begin();i!=st->end(); i++) { write_states(output,**i,0,indent_size+indent_increase); } fprintf(output,"%s\n",indent_string.c_str()); return 1; } const ttlout* ttlo=dynamic_cast(&states_to_write); if (ttlo!=NULL) { fprintf(output,"%s\n", indent_string.c_str(), ttlo->ttls.to_ulong()); return 1; } const analogout* ao=dynamic_cast(&states_to_write); if (ao!=NULL) { fprintf(output, "%s\n", indent_string.c_str(), ao->id, ao->frequency, ao->amplitude, ao->phase, ao->dac_value); return 1; } const analogin* ai=dynamic_cast(&states_to_write); if (ai!=NULL) { char args[2000]; char buffer[1000]; sprintf(args, "%sid, ai->samples, ai->sample_frequency, ai->channels.to_ulong(), ai->resolution); for (int i = 0; i < ai->nchannels; i++) { sprintf(buffer, "sensitivity%d=\"%g\" offset%d=\"%d\" impedance%d=\"%g\"", i, ai->sensitivity[i], i, ai->offset[i], i, ai->impedance[i]); strcat(args, buffer); } strcat(args, "/>\n"); // fix -Werror=format-security //fprintf(output, args); fputs(args,output); return 1; } fprintf(output,"%s\n",indent_string.c_str()); return 0; }