2022-09-24 17:47:18 -04:00
|
|
|
/*
|
|
|
|
* spicestream.c - spicestream interface functions
|
|
|
|
*
|
|
|
|
* include LICENSE
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <spicestream.h>
|
|
|
|
#include <fileformat.h>
|
|
|
|
|
|
|
|
#ifdef TRACE_MEM
|
|
|
|
#include <tracemem.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*** \brief Allocates memory for a new SpiceStream object.
|
|
|
|
*/
|
|
|
|
|
|
|
|
SpiceStream *spicestream_new( char *filename, char *format, WaveTable *wt )
|
|
|
|
{
|
|
|
|
SpiceStream *ss;
|
|
|
|
|
|
|
|
ss = app_new0(SpiceStream, 1);
|
|
|
|
spicestream_construct( ss, filename, format, wt );
|
|
|
|
app_class_overload_destroy( (AppClass *) ss, spicestream_destroy );
|
|
|
|
return ss;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Constructor for the SpiceStream object. */
|
|
|
|
|
|
|
|
void spicestream_construct( SpiceStream *ss, char *filename, char *format, WaveTable *wt)
|
|
|
|
{
|
|
|
|
app_class_construct( (AppClass *) ss );
|
|
|
|
|
|
|
|
ss->wt = wt;
|
|
|
|
wavetable_set_funcs( wt, (AppClass *) ss, spicestream_read_hdr,
|
|
|
|
spicestream_read_rows, spicestream_destroy );
|
|
|
|
ss->filename = filename;
|
|
|
|
ss->format = format;
|
2024-06-15 12:49:25 -04:00
|
|
|
ss->idxcol = -1;
|
2022-09-24 17:47:18 -04:00
|
|
|
|
|
|
|
/* open file */
|
|
|
|
ss->linebuf = fdbuf_new ( filename, "r", 0);
|
|
|
|
if ( ss->linebuf->status ) {
|
|
|
|
ss->status = ss->linebuf->status;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* fdbuf_set_flags(ss->linebuf, FDB_STRIP_CR); set by default */
|
|
|
|
ss->dbuf = dbuf_new( 0, 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Destructor for the SpiceStream object. */
|
|
|
|
|
|
|
|
void spicestream_destroy(void *ss)
|
|
|
|
{
|
|
|
|
SpiceStream *this = (SpiceStream *) ss;
|
|
|
|
|
|
|
|
if (ss == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fdbuf_destroy( this->linebuf);
|
|
|
|
g_free (this->rowData);
|
|
|
|
dbuf_destroy(this->dbuf);
|
|
|
|
if ( this->datrow ) {
|
|
|
|
g_free (this->datrow);
|
|
|
|
}
|
|
|
|
if ( this->nsindexes ) {
|
|
|
|
g_free (this->nsindexes);
|
|
|
|
}
|
|
|
|
|
|
|
|
app_class_destroy( ss );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sequential add of values
|
|
|
|
*/
|
|
|
|
void spicestream_val_add( SpiceStream *ss, double val)
|
|
|
|
{
|
|
|
|
ss->rowData[ss->curcol] = val;
|
|
|
|
if ( ++ss->curcol >= ss->ncols ){
|
|
|
|
ss->curcol = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void spicestream_var_add( SpiceStream *ss, char *varName, int type, int ncols)
|
|
|
|
{
|
|
|
|
dataset_var_add( ss->wds, varName, type, ncols);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Warning : fileformat_read_header do not return the same code as
|
|
|
|
* (ss->readHdrFunc)
|
|
|
|
* fileformat_read_header: >= 0 index of format, < 0 error or EOF
|
|
|
|
* (ss->readHdrFunc) : -1 error, 0 EOF, 1 succes
|
|
|
|
*/
|
|
|
|
|
|
|
|
int spicestream_read_hdr( AppClass *sss )
|
|
|
|
{
|
|
|
|
SpiceStream *ss = (SpiceStream *) sss;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ss->wds = wavetable_get_cur_dataset(ss->wt); /* curent wds */
|
|
|
|
if ( ss->flags & SSF_NORDHDR ) {
|
|
|
|
/* no read to read header again */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if ( ss->readHdrFunc ) {
|
|
|
|
ret = (ss->readHdrFunc) ( ss );
|
|
|
|
} else {
|
|
|
|
ret = fileformat_read_header( ss);
|
|
|
|
if ( ret >= 0 ) {
|
|
|
|
if ( ! ss->readHdrFunc ) {
|
|
|
|
ss->readHdrFunc = fileformat_get_readhdr_func(ret);
|
|
|
|
}
|
|
|
|
ss->readRowFunc = fileformat_get_read_func(ret);
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dbuf_clear( ss->dbuf );
|
|
|
|
if ( ret > 0 ) {
|
|
|
|
ss->ncols = ss->wds->ncols;
|
|
|
|
ss->curcol = 0;
|
|
|
|
ss->read_vals = ss->read_rows = 0;
|
|
|
|
if ( ss->rowData ) {
|
|
|
|
g_free(ss->rowData );
|
|
|
|
}
|
|
|
|
ss->rowData = g_new0 (double, ss->ncols );
|
|
|
|
return 1;
|
|
|
|
} else if ( ret < -1 ) {
|
|
|
|
/* clear garbage in vars */
|
|
|
|
dataset_remove_all_vars(ss->wds);
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
dbuf_clear( (DBuf *) ss->linebuf );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void spicestream_create_new_vars (SpiceStream *ss )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
WDataSet *owds = wavetable_get_dataset(ss->wt, 0 ) ;
|
|
|
|
|
|
|
|
ss->wds = wavetable_get_cur_dataset(ss->wt);
|
|
|
|
for ( i = 0 ; i < owds->numVars ; i++ ) {
|
|
|
|
WaveVar *var = g_ptr_array_index( owds->vars, i );
|
|
|
|
|
|
|
|
dataset_var_add(ss->wds, var->varName, var->type, var->ncols);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void spicestream_store_data_row(SpiceStream *ss)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
double *rowData = ss->rowData;
|
|
|
|
int ncols = ss->ncols;
|
|
|
|
|
|
|
|
for ( i = 0 ; i < ncols ; i++ ){
|
|
|
|
dataset_val_add (ss->wds, rowData[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* row is read in temp storage ss->rowData because
|
|
|
|
* we do not known if we have multiple set in the file
|
|
|
|
* indicated by a decreseing order of iv
|
|
|
|
*/
|
|
|
|
int spicestream_read_rows( AppClass *sss )
|
|
|
|
{
|
|
|
|
SpiceStream *ss = (SpiceStream *) sss;
|
|
|
|
int ret;
|
|
|
|
int row = 0;
|
|
|
|
double last_ival= -1.0e29;
|
|
|
|
double ival;
|
|
|
|
|
|
|
|
if ( ss->need_update ) {
|
|
|
|
if ( ss->flags & SSF_NORDHDR ) {
|
|
|
|
/* create new vars from wds 0 */
|
|
|
|
spicestream_create_new_vars ( ss );
|
|
|
|
}
|
|
|
|
if ( ss->need_update == 2 ) {
|
|
|
|
spicestream_store_data_row (ss);
|
|
|
|
}
|
|
|
|
ss->need_update = 0;
|
|
|
|
}
|
|
|
|
if (ss->nsweepparam && ss->rdSweepFunc ) {
|
|
|
|
ret = ss->rdSweepFunc(ss);
|
|
|
|
if ( ret != 1 ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while ((ret = ss->readRowFunc(ss)) > 0) {
|
|
|
|
if ( ss->flags & SSF_PUSHBACK ) {
|
|
|
|
ival = ss->rowData[0];
|
|
|
|
if (row > 0 && ival < last_ival) {
|
|
|
|
if (row == 1) {
|
|
|
|
msg_error(_("independent variable is not nondecreasing at row %d; ival=%g last_ival=%g - line %d"),
|
|
|
|
row, ival, last_ival, fdbuf_get_lineno(ss->linebuf) );
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
ss->need_update = 2;
|
|
|
|
return 2; /* finish the dataset and create a new one */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
spicestream_store_data_row( ss );
|
|
|
|
last_ival = ival;
|
|
|
|
}
|
|
|
|
if ( ret == 2 ) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
ss->need_update = 1;
|
|
|
|
if ( ret == -2 ) {
|
|
|
|
ret = 2 ; /* we have new tables, without need update */
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|