TSP: The Transport Sample Protocol



Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

tsp_ascii_writer.c

Go to the documentation of this file.
00001 
00037 #include "tsp_ascii_writer.h"
00038 #include "tsp_consumer.h"
00039 #include "tsp_simple_trace.h"
00040 #include "tsp_const_def.h"
00041 #include "tsp_time.h"
00042 
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <fcntl.h>
00046 #include <unistd.h>
00047 #include <string.h>
00048 #include <strings.h>
00049 #include <assert.h>
00050 #include <errno.h>
00051 
00052 int yyrestart(FILE*);
00053 int yyparse (void);
00054 extern FILE *yyin, *yyout;
00055 
00056 static TSP_provider_t* myproviders = NULL;
00057 #define OUTPUT_STREAM_BUFFER_SIZE 1024*10
00058 #define MAX_VAR_NAME_SIZE 256
00059 static char tc_output_buffer[OUTPUT_STREAM_BUFFER_SIZE];
00060 static int stop_it = 0;
00061 
00062 int tsp_ascii_writer_parse_error    =  0;
00063 int tsp_ascii_writer_lineno         =  0;
00064 int tsp_ascii_writer_colno          =  0;
00065 int tsp_ascii_writer_nb_var         =  0;
00066 int tsp_ascii_writer_current_var    = -1;
00067 int tsp_ascii_writer_header_style   =  0;
00068 int tsp_ascii_writer_sample_running =  0;
00069 TSP_consumer_symbol_requested_t*  g_tsp_symbols = NULL; 
00070 
00071 int32_t 
00072 tsp_ascii_writer_initialise(int* argc, char** argv[]) {
00073   
00074   int32_t retcode;
00075 
00076   if (!TSP_consumer_init(argc, argv)) {
00077     STRACE_ERROR(("TSP init failed"));    
00078     retcode = -1;
00079   } else {
00080     retcode = 0;
00081   }
00082   return retcode;
00083 }  /* end of tsp_ascii_writer_initialise */
00084 
00085 int32_t
00086 tsp_ascii_writer_add_var(char* symbol_name) {
00087 
00088   int32_t retcode;
00089   
00090   /* 
00091    * if the tsp symbols is not allocated
00092    * we only do counting
00093    */
00094   if (NULL == g_tsp_symbols) {
00095     ++tsp_ascii_writer_nb_var;
00096     ++tsp_ascii_writer_current_var;
00097     retcode =0;
00098   } else {
00099     /* increment first since initialised to -1 */
00100     ++tsp_ascii_writer_current_var;
00101     g_tsp_symbols[tsp_ascii_writer_current_var].name = strdup(symbol_name);
00102     STRACE_INFO(("Added var <%s>",symbol_name));
00103     retcode =0;
00104   }
00105   return retcode;
00106 } /* tsp_ascii_writer_add_var */
00107 
00108 int32_t 
00109 tsp_ascii_writer_add_var_period(int32_t period) {
00110   if (NULL != g_tsp_symbols) {
00111     g_tsp_symbols[tsp_ascii_writer_current_var].period = period;
00112     STRACE_INFO(("Period <%d>",period));
00113   }
00114   return 0;
00115 } /* tsp_ascii_writer_add_var_period */
00116 
00117 int32_t 
00118 tsp_ascii_writer_add_comment(char* comment) {
00119   /* FIXME add dictionnary reconstruction facility */
00120   return 0;
00121 } /* tsp_ascii_writer_add_var_period */
00122 
00123 
00124 /*
00125  * This is an internal TSP ascii writer function which validate
00126  * a symbol against a tsp symbols list obtained from a TSP 
00127  * request info.
00128  * This is a brute force linear search
00129  * FIXME should be done another way on a hashed version of the tsp_symbols array.
00130  */
00131 int32_t
00132 tsp_ascii_writer_validate_symbol_info(char* symbol_name, 
00133                                       const TSP_consumer_symbol_info_list_t* tsp_symbols) {
00134   int     i;
00135   int32_t retval;
00136   char*   searched_array_symbol;
00137 
00138   assert(tsp_symbols);
00139   retval = 0;
00140   i = strlen(symbol_name);
00141   searched_array_symbol = malloc(i+2);
00142   strncpy(searched_array_symbol,symbol_name,i);
00143   searched_array_symbol[i] = '[';
00144   searched_array_symbol[i+1] = '\0';
00145 
00146   for (i=0; i< tsp_symbols->len; ++i) {
00147     /* scalar symbol match */
00148     if (0==strcmp(tsp_symbols->val[i].name,symbol_name)) {
00149       STRACE_DEBUG(("Scalar symbol match <%s>",symbol_name));
00150       retval =1;
00151       break;
00152     }
00153     /* 
00154      * consider arrays 
00155      * symbols whose name is found in several symbol 
00156      * and found symbol == searched symbol + '['
00157      * "toto" is an array iff we found "toto["
00158      */
00159     if (NULL != strstr(tsp_symbols->val[i].name,searched_array_symbol)) {
00160       ++retval;
00161     }
00162   }
00163   return retval;
00164 } /* end of tsp_ascii_writer_validatesymbol_info */
00165 
00166 int32_t
00167 tsp_ascii_writer_validate_symbol_requested(char* symbol_name,
00168                                            const TSP_consumer_symbol_requested_list_t* tsp_symbols) {
00169   int i;
00170   int32_t retval;
00171 
00172   assert(tsp_symbols);
00173   retval = 0;
00174   for (i=0; i< tsp_symbols->len; ++i) {
00175     if (NULL != strstr(tsp_symbols->val[i].name,symbol_name)) {
00176       ++retval;
00177     }
00178   }
00179   return retval;
00180 } /* end of tsp_ascii_writer_validatesymbol */
00181 
00182 int32_t 
00183 tsp_ascii_writer_load_config(const char* conffilename, 
00184                              TSP_consumer_symbol_requested_t**  tsp_symbols,
00185                              int32_t* nb_symbols) {
00186   
00187   int32_t retcode;
00188   char   syserr[TSP_MAX_SYSMSG_SIZE];
00189     
00190   retcode = 0;  
00191   
00192   yyin = fopen(conffilename,"r");
00193   if (((FILE*)(NULL)) == yyin) {    
00194     strncpy(syserr,strerror(errno),TSP_MAX_SYSMSG_SIZE);
00195     STRACE_ERROR(("Cannot open config file <%s> (%s)",conffilename,syserr));
00196     retcode = -1;
00197   }
00198   /* Lets parse the config file */
00199   if (0 == retcode) {    
00200     STRACE_INFO(("Parsing config file..."));
00201     /* First read Count */
00202     yyparse();
00203     retcode = tsp_ascii_writer_parse_error;
00204     STRACE_INFO(("<%d> variables requested...",tsp_ascii_writer_nb_var));
00205     /*
00206      * Allocate the global tsp symbol array then
00207      * rewind the file for second parsing.
00208      */
00209     if (0==retcode) {
00210       g_tsp_symbols = (TSP_consumer_symbol_requested_t*) calloc(tsp_ascii_writer_nb_var,sizeof(TSP_consumer_symbol_requested_t));
00211       
00212       /* restart parsing */
00213       rewind(yyin);
00214       tsp_ascii_writer_current_var = -1;
00215       
00216       yyrestart(yyin);
00217       /* parse again */
00218       yyparse(); 
00219       fclose(yyin);
00220       *nb_symbols  = tsp_ascii_writer_nb_var;
00221       *tsp_symbols = g_tsp_symbols;
00222     } /* proceed second parse if first parse was OK */
00223   }  
00224   return retcode;
00225 } /* tsp_ascii_writer_load_config */
00226 
00227 int32_t 
00228 tsp_ascii_writer_validate_symbols(TSP_consumer_symbol_requested_t*  tsp_symbols,
00229                                   int32_t nb_symbols,
00230                                   const char* tsp_provider_url,
00231                                   TSP_consumer_symbol_requested_list_t* tsp_symbol_list) {
00232   int32_t retcode;
00233   const TSP_consumer_information_t* tsp_info=NULL;
00234   int32_t symbol_dim;
00235   int32_t nb_scalar_symbol; 
00236   int32_t i;
00237   int32_t j;
00238   int32_t var_index;
00239   int32_t forced_period;
00240   
00241   retcode = 0;
00242   /* 
00243    * Connect to the provider.
00244    */
00245   if (NULL == myproviders) {
00246     myproviders = calloc(1,sizeof(TSP_provider_t));
00247     myproviders[0] = TSP_consumer_connect_url(tsp_provider_url);
00248     /* Verify if there is at least one provider */
00249     if (0==myproviders[0]) {
00250       STRACE_ERROR(("No provider found?!?"));
00251       retcode = -1;
00252     } else if (!TSP_consumer_request_open(myproviders[0], 0, 0 )) {
00253       STRACE_ERROR(("Cannot connect to provider <%s> (TSP_request_open failed.)",TSP_consumer_get_connected_name(myproviders[0])));
00254       retcode = -1;
00255     }
00256   }
00257   if (0==retcode) {
00258     /* send request info for getting symbols list */
00259     if(!TSP_consumer_request_information(myproviders[0])) {
00260       STRACE_ERROR(("TSP_request_information failed"));
00261       retcode = -1;
00262     }
00263   }
00264 
00265   if (0==retcode) {
00266     tsp_info = TSP_consumer_get_information(myproviders[0]);    
00267     /* We now validate symbols from config file against
00268      * the list provided by the TSP provider
00269      * (we discover array var too)
00270      */
00271     nb_scalar_symbol = 0;
00272     forced_period    = -1;
00273     for (i=0;i<nb_symbols;++i) {
00274       symbol_dim = tsp_ascii_writer_validate_symbol_info(tsp_symbols[i].name,&(tsp_info->symbols));
00275       /* symbol not found */
00276       if (0==symbol_dim) {
00277         fprintf(stderr,"Symbol <%s> not found on provider side.\n",tsp_symbols[i].name);
00278         /* hack for ignoring unfound symbols */
00279         tsp_symbols[i].phase  = -1;
00280       } else { /* symbol found */
00281         fprintf(stdout,"Asking for symbol <%s> with period <%d>",
00282                 tsp_symbols[i].name,
00283                 tsp_symbols[i].period);
00284         /* 
00285          * FIXME force period to be the same 
00286          * as the first valid symbol
00287          */
00288         if (-1 == forced_period) {
00289           forced_period = tsp_symbols[i].period;
00290         } else {
00291           if (tsp_symbols[i].period != forced_period) {
00292             tsp_symbols[i].period = forced_period;
00293             fprintf(stdout,"[period forced to <%d>]",tsp_symbols[i].period);
00294           }
00295         }
00296         if (symbol_dim>1) {
00297           fprintf(stdout," [array of size <%d>]\n",symbol_dim);
00298         } else {
00299           fprintf(stdout,"\n");
00300         }
00301         /* 
00302          * It's not so nice 
00303          * but we use the phase to store symbol dim
00304          * FXIME waiting for tsp to handle arrays !!!
00305          */
00306         tsp_symbols[i].phase  = symbol_dim;
00307         nb_scalar_symbol     += symbol_dim;
00308       } /* else symbol found */
00309     } /* loop over symbols coming from config file */
00310   } /* retcode is OK */
00311   
00312   /* Now build request sample */
00313   if (0==retcode) {
00314     tsp_symbol_list->val = (TSP_consumer_symbol_requested_t*)calloc(nb_scalar_symbol, sizeof(TSP_consumer_symbol_requested_t));
00315     tsp_symbol_list->len = nb_scalar_symbol;
00316     var_index = 0;
00317     for (i=0;i<nb_symbols; ++i) {
00318       /* 
00319        * Generate symbol name for array var specified without index.
00320        */
00321       if (tsp_symbols[i].phase > 1) {
00322         for (j=0;j<tsp_symbols[i].phase;++j) {      
00323           tsp_symbol_list->val[var_index].name = malloc(MAX_VAR_NAME_SIZE*sizeof(char));
00324           snprintf(tsp_symbol_list->val[var_index].name,
00325                    MAX_VAR_NAME_SIZE,                
00326                    "%s[%0d]",
00327                    tsp_symbols[i].name,
00328                    j);
00329           STRACE_DEBUG(("Asking for TSP var = <%s>",tsp_symbol_list->val[var_index].name));
00330           tsp_symbol_list->val[var_index].period = tsp_symbols[i].period;
00331           tsp_symbol_list->val[var_index].phase  = 0;
00332           ++var_index;
00333         } /* loop over array var index */
00334       } else {
00335         /* ignore symbols with negative phase */
00336         if (tsp_symbols[i].phase >0) {
00337           tsp_symbol_list->val[var_index].name   = strdup(tsp_symbols[i].name);
00338           STRACE_DEBUG(("Asking for TSP var = <%s>",tsp_symbol_list->val[var_index].name));
00339           tsp_symbol_list->val[var_index].period = tsp_symbols[i].period;
00340           tsp_symbol_list->val[var_index].phase  = 0;
00341           ++var_index;
00342         }
00343       } /* end if tsp_symbols[i].phase > 1 */
00344     } /* loop over nb_symbols */
00345   } /* end of build request_sample */
00346   
00347   /* Now send request sample */
00348   if (0==retcode) {
00349     if (!TSP_consumer_request_sample(myproviders[0],tsp_symbol_list)) {
00350       STRACE_ERROR(("TSP request sample refused by the provider?huh?..."));
00351       retcode = -1;
00352     }
00353   }
00354   
00355   return retcode;
00356 } /* tsp_ascii_writer_validate_symbols */
00357 
00358 int32_t 
00359 tsp_ascii_writer_start(FILE* sfile, int32_t nb_sample_max_infile) {
00360   
00361   int32_t retcode;
00362   int             new_sample;
00363   int             symbol_index;
00364   TSP_sample_t    sample;
00365   const TSP_consumer_symbol_requested_list_t*  symbols;
00366   int             complete_line;
00367   char            charbuf[MAX_VAR_NAME_SIZE];
00368   int             symbol_dim;
00369   int             nb_sample;
00370 
00371   retcode = 0;
00372 
00373   /* buf RAZ  */
00374   memset(tc_output_buffer,'\0',OUTPUT_STREAM_BUFFER_SIZE);
00375   /* tailored output stream buffer (if not stdout) */
00376   /* if (stdout != sfile) { */
00377 /*     setvbuf(sfile,tc_output_buffer,_IOFBF,OUTPUT_STREAM_BUFFER_SIZE);   */
00378 /*   } */
00379 
00380   /* Get previously configured symbols */
00381   symbols = TSP_consumer_get_requested_sample(myproviders[0]);
00382   /* Write header if necessary */
00383   switch  (tsp_ascii_writer_header_style) {
00384     case 0:
00385     /* no header */
00386     break;
00387     /* xxx style header */
00388     case 1: 
00389       for (symbol_index=0;symbol_index<symbols->len;++symbol_index) {
00390         /* 
00391          * Si la variable est un tableau on compte calcul
00392          * la taille de ce tableau
00393          */
00394         strncpy(charbuf,symbols->val[symbol_index].name,MAX_VAR_NAME_SIZE);
00395         if (NULL != index(charbuf,'[')) {
00396           *(index(charbuf,'[')) = '\0';
00397           symbol_dim   = tsp_ascii_writer_validate_symbol_requested(charbuf,symbols);
00398           symbol_index += symbol_dim - 1;
00399         } else {
00400           symbol_dim = 1;
00401         }
00402         fprintf(sfile,"%s : %d\n", charbuf, symbol_dim);    
00403       }
00404       fprintf(sfile," ==========================================\n");
00405       fflush(sfile);
00406     break;
00407   default:
00408     /* no header */
00409     break;
00410   }
00411  
00412   /* Demarrage des sample au niveau provider */
00413   if(!TSP_consumer_request_sample_init(myproviders[0],0,0)) {
00414     STRACE_ERROR(("Sample init refused by the provider??..."));
00415     retcode = -1;
00416   }
00417 
00418   tsp_ascii_writer_sample_running = 1;
00419   STRACE_DEBUG(("Begin sample read...\n"));
00420   if (0 == retcode) {
00421     complete_line = 0;
00422     nb_sample     = 0;
00423     /* write loop */
00424     while (TSP_consumer_read_sample(myproviders[0],&sample, &new_sample) && !stop_it) {
00425       if (new_sample) {
00426         fprintf(sfile,"%16.9E ",sample.user_value);
00427         ++complete_line;
00428         /* We write the endl if we receive a whole sample line */
00429         if (symbols->len==complete_line) {
00430           fprintf(sfile,"\n");
00431           complete_line = 0;
00432           ++nb_sample;
00433           if ((0 != nb_sample_max_infile) && 
00434               (0 == (nb_sample % nb_sample_max_infile ))
00435               ) {
00436             rewind(sfile);
00437           }
00438         }
00439       } else {
00440         tsp_usleep(1000);
00441       }
00442     } /* end of while ecriture */
00443   } /* end of if 0 */
00444   return retcode;
00445 }
00446 
00447 void* 
00448 tsp_ascii_writer_thread(void* sfile) {
00449 
00450   static int retcode;
00451   retcode = tsp_ascii_writer_start((FILE* )sfile,0);  
00452   return &retcode;
00453 } 
00454 
00455 
00456 int32_t 
00457 tsp_ascii_writer_stop() {
00458   
00459   int32_t retcode;
00460 
00461   STRACE_IO(("-->IN"));    
00462   retcode = 0;
00463   stop_it = 1;
00464   STRACE_IO(("-->OUT"));   
00465   return retcode;
00466 }
00467 
00468 
00469 int32_t 
00470 tsp_ascii_writer_finalise() {
00471   
00472   int32_t retcode;
00473 
00474   STRACE_IO(("-->IN"));  
00475   if (NULL != myproviders) {
00476     if (tsp_ascii_writer_sample_running) {
00477       if (!TSP_consumer_request_sample_destroy(myproviders[0])) {
00478         STRACE_ERROR(("TSP_request_sample_destroy en erreur??..."));
00479       }  
00480     }
00481   }
00482   TSP_consumer_end();
00483   retcode = 0;    
00484   STRACE_IO(("-->OUT"));   
00485   return retcode;
00486 } /* end of tsp_ascii_writer_finalise */
Framework Home Page.

Beware !! TSP wave is coming...