bgpstream_csvfile_datasource_t *
bgpstream_csvfile_datasource_create(bgpstream_filter_mgr_t *filter_mgr, 
                                    char *csvfile_file)
{
  bgpstream_debug("\t\tBSDS_CSVFILE: create csvfile_ds start");  
  bgpstream_csvfile_datasource_t *csvfile_ds = (bgpstream_csvfile_datasource_t*) malloc_zero(sizeof(bgpstream_csvfile_datasource_t));
  if(csvfile_ds == NULL) {
    bgpstream_log_err("\t\tBSDS_CSVFILE: create csvfile_ds can't allocate memory");    
    goto err;
  }  
  if(csvfile_file == NULL)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: create csvfile_ds no file provided");    
      goto err;
    }
  if((csvfile_ds->csvfile_file = strdup(csvfile_file)) == NULL)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: can't allocate memory for filename");    
      goto err;
    }
  
  /* cvs file parser options */
  unsigned char options = CSV_STRICT | CSV_REPALL_NL | CSV_STRICT_FINI |
                CSV_APPEND_NULL | CSV_EMPTY_IS_NULL;

  if(csv_init(&(csvfile_ds->parser), options) !=0)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: can't initialize csv parser");    
      goto err;
    }

  csvfile_ds->current_field = CSVFILE_PATH;
  
  csvfile_ds->filter_mgr = filter_mgr;
  csvfile_ds->input_mgr = NULL;

  csvfile_ds->num_results = 0;

  csvfile_ds->max_ts_infile = 0;
  csvfile_ds->last_processed_ts = 0;
  csvfile_ds->max_accepted_ts = 0;

  bgpstream_debug("\t\tBSDS_CSVFILE: create csvfile_ds end");
  return csvfile_ds;
  
 err:
  bgpstream_csvfile_datasource_destroy(csvfile_ds);
  return NULL;
}
void bgpstream_datasource_mgr_destroy(
  bgpstream_datasource_mgr_t *datasource_mgr)
{
  bgpstream_debug("\tBSDS_MGR: destroy start");
  if (datasource_mgr == NULL) {
    return; // no manager to destroy
  }
// destroy any active datasource (if they have not been destroyed before)
#ifdef WITH_DATA_INTERFACE_SINGLEFILE
  bgpstream_singlefile_datasource_destroy(datasource_mgr->singlefile_ds);
  datasource_mgr->singlefile_ds = NULL;
  free(datasource_mgr->singlefile_rib_mrtfile);
  free(datasource_mgr->singlefile_upd_mrtfile);
#endif

#ifdef WITH_DATA_INTERFACE_CSVFILE
  bgpstream_csvfile_datasource_destroy(datasource_mgr->csvfile_ds);
  datasource_mgr->csvfile_ds = NULL;
  free(datasource_mgr->csvfile_file);
#endif

#ifdef WITH_DATA_INTERFACE_SQLITE
  bgpstream_sqlite_datasource_destroy(datasource_mgr->sqlite_ds);
  datasource_mgr->sqlite_ds = NULL;
  free(datasource_mgr->sqlite_file);
#endif

#ifdef WITH_DATA_INTERFACE_BROKER
  bgpstream_broker_datasource_destroy(datasource_mgr->broker_ds);
  datasource_mgr->broker_ds = NULL;
  free(datasource_mgr->broker_url);
  int i;
  for (i = 0; i < datasource_mgr->broker_params_cnt; i++) {
    free(datasource_mgr->broker_params[i]);
    datasource_mgr->broker_params[i] = NULL;
  }
  free(datasource_mgr->broker_params);
  datasource_mgr->broker_params = NULL;
  datasource_mgr->broker_params_cnt = 0;
#endif

  free(datasource_mgr);
  bgpstream_debug("\tBSDS_MGR: destroy end");
}
void bgpstream_datasource_mgr_close(bgpstream_datasource_mgr_t *datasource_mgr)
{
  bgpstream_debug("\tBSDS_MGR: close start");
  if (datasource_mgr == NULL) {
    return; // no manager to destroy
  }
  switch (datasource_mgr->datasource) {
#ifdef WITH_DATA_INTERFACE_SINGLEFILE
  case BGPSTREAM_DATA_INTERFACE_SINGLEFILE:
    bgpstream_singlefile_datasource_destroy(datasource_mgr->singlefile_ds);
    datasource_mgr->singlefile_ds = NULL;
    break;
#endif

#ifdef WITH_DATA_INTERFACE_CSVFILE
  case BGPSTREAM_DATA_INTERFACE_CSVFILE:
    bgpstream_csvfile_datasource_destroy(datasource_mgr->csvfile_ds);
    datasource_mgr->csvfile_ds = NULL;
    break;
#endif

#ifdef WITH_DATA_INTERFACE_SQLITE
  case BGPSTREAM_DATA_INTERFACE_SQLITE:
    bgpstream_sqlite_datasource_destroy(datasource_mgr->sqlite_ds);
    datasource_mgr->sqlite_ds = NULL;
    break;
#endif

#ifdef WITH_DATA_INTERFACE_BROKER
  case BGPSTREAM_DATA_INTERFACE_BROKER:
    bgpstream_broker_datasource_destroy(datasource_mgr->broker_ds);
    datasource_mgr->broker_ds = NULL;
    break;
#endif

  default:
    assert(0);
    break;
  }
  datasource_mgr->status = BGPSTREAM_DATASOURCE_STATUS_OFF;
  bgpstream_debug("\tBSDS_MGR: close end");
}