/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/utils/eh_dlm_file.c

Go to the documentation of this file.
00001 #include <eh_utils.h>
00002 
00003 /* Local function declarations */
00004 gchar*     eh_dlm_prepare                ( const gchar* file ,
00005                                            GError** err );
00006 double**   eh_dlm_read_data              ( gchar* str        ,
00007                                            gchar* delims     ,
00008                                            gint* n_rows      ,
00009                                            gint* n_cols      ,
00010                                            GError** err );
00011 
00012 gint       eh_dlm_find_n_cols            ( gchar* content , gchar* delims );
00013 gint       eh_dlm_find_n_rows            ( gchar* content , gint delim );
00014 
00015 gchar**    eh_dlm_split_records          ( gchar* str             ,
00016                                            const gchar* start_str ,
00017                                            const gchar* end_str   ,
00018                                            gchar*** rec_data );
00019 
00020 gchar*
00021 eh_dlm_prepare( const gchar* file , GError** err )
00022 {
00023    gchar* str = NULL;
00024 
00025    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00026 
00027    if ( file )
00028    {
00029       GError* tmp_error = NULL;
00030 
00031       g_file_get_contents( file , &str , NULL , &tmp_error );
00032 
00033       if ( !tmp_error )
00034       {
00035          /* Remove comments and empty lines */
00036          eh_str_remove_c_style_comments( str );
00037          eh_str_remove_to_eol_comments ( str , "#"  );
00038          eh_str_remove_to_eol_comments ( str , "//" );
00039          eh_str_replace                ( str , '\r' , '\n' );
00040          eh_dlm_remove_empty_lines     ( str );
00041       }
00042       else
00043          g_propagate_error( err , tmp_error );
00044    }
00045 
00046    return str;
00047 }
00048 
00066 double**
00067 eh_dlm_read( const gchar* file , 
00068              gchar* delims     ,
00069              gint* n_rows      ,
00070              gint* n_cols      ,
00071              GError** err )
00072 {
00073    double** data = NULL;
00074 
00075    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00076 
00077    if ( file )
00078    {
00079       double*** data_3;
00080       gint* n_x = NULL;
00081       gint* n_y = NULL;
00082       GError* tmp_err = NULL;
00083 
00084       data_3 = eh_dlm_read_full( file , delims , &n_x , &n_y , NULL , 1 , &tmp_err );
00085 
00086       if ( data_3 )
00087       {
00088          data    = data_3[0];
00089          *n_rows = n_x[0];
00090          *n_cols = n_y[0];
00091 
00092          eh_free( data_3 );
00093          eh_free( n_x    );
00094          eh_free( n_y    );
00095       }
00096       else
00097          g_propagate_error( err , tmp_err );
00098    }
00099 
00100    return data;
00101 }
00102 
00119 double** eh_dlm_read_swap( const gchar* file ,
00120                            gchar* delims     ,
00121                            gint* n_rows      ,
00122                            gint* n_cols      ,
00123                            GError** err )
00124 {
00125    double** data = NULL;
00126 
00127    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00128 
00129    if ( file )
00130    {
00131       gint tmp_rows, tmp_cols;
00132       double** tmp;
00133       GError* tmp_err = NULL;
00134 
00135       tmp  = eh_dlm_read( file , delims , &tmp_rows , &tmp_cols , &tmp_err );
00136 
00137       if ( tmp )
00138       {
00139          gint i, j;
00140 
00141          data = eh_new_2( double , tmp_cols , tmp_rows );
00142 
00143          for ( i=0 ; i<tmp_rows ; i++ )
00144             for ( j=0 ; j<tmp_cols ; j++ )
00145                data[j][i] = tmp[i][j];
00146 
00147          *n_rows = tmp_cols;
00148          *n_cols = tmp_rows;
00149 
00150       }
00151       else
00152          g_propagate_error( err , tmp_err );
00153 
00154       eh_free_2( tmp );
00155    }
00156 
00157    return data;
00158 }
00159 
00180 double***
00181 eh_dlm_read_full( const gchar* file ,
00182                   gchar* delims     ,
00183                   gint** n_rows     ,
00184                   gint** n_cols     ,
00185                   gchar*** rec_data ,
00186                   gint max_records  ,
00187                   GError** err )
00188 {
00189    double*** data = NULL;
00190 
00191    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00192 
00193    if ( file )
00194    {
00195       gchar* str;
00196       GError* tmp_error = NULL;
00197 
00198       str = eh_dlm_prepare( file , &tmp_error );
00199 
00200       if ( !tmp_error )
00201       {
00202          gchar** rec;
00203          gint i, n_recs;
00204          rec = eh_dlm_split_records( str , "[" , "]" , rec_data );
00205 
00206          n_recs  = g_strv_length( rec );
00207 
00208          if ( max_records>0 )
00209             n_recs = MAX( max_records , n_recs );
00210 
00211          data    = eh_new( double** , n_recs+1 );
00212          *n_rows = eh_new( gint     , n_recs );
00213          *n_cols = eh_new( gint     , n_recs );
00214 
00215          for ( i=0 ; i<n_recs ; i++ )
00216          {
00217             data[i] = eh_dlm_read_data( rec[i]    ,
00218                                         delims    ,
00219                                         *n_rows+i ,
00220                                         *n_cols+i ,
00221                                         NULL );
00222          }
00223          data[i] = NULL;
00224 
00225          g_strfreev( rec );
00226       }
00227       else
00228          g_propagate_error( err , tmp_error );
00229 
00230       eh_free( str );
00231    }
00232 
00233    return data;
00234 }
00235 
00254 double***
00255 eh_dlm_read_full_swap( const gchar* file ,
00256                        gchar* delims     ,
00257                        gint** n_rows     ,
00258                        gint** n_cols     ,
00259                        gchar*** rec_data ,
00260                        gint max_records  ,
00261                        GError** err )
00262 {
00263    double*** data = NULL;
00264 
00265    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00266 
00267    if ( file )
00268    {
00269       gint i, j;
00270       gint n, n_recs;
00271       double*** tmp;
00272       GError* tmp_err = NULL;
00273 
00274       tmp  = eh_dlm_read_full( file , delims , n_rows , n_cols , rec_data , max_records , &tmp_err );
00275 
00276       n_recs = g_strv_length( (gchar**)tmp );
00277 
00278       data = eh_new( double** , n_recs+1 );
00279 
00280       for ( n=0 ; n<n_recs ; n++ )
00281       {
00282          data[n] = eh_new_2( double , (*n_cols)[n] , (*n_rows)[n] );
00283 
00284          for ( i=0 ; i<(*n_rows)[n] ; i++ )
00285             for ( j=0 ; j<(*n_cols)[n] ; j++ )
00286                data[n][j][i] = tmp[n][i][j];
00287 
00288          eh_free_2( tmp[n] );
00289       }
00290       data[n_recs] = 0;
00291 
00292       EH_SWAP_PTR( *n_rows , *n_cols );
00293 
00294       eh_free( tmp );
00295    }
00296 
00297    return data;
00298 }
00299 
00300 double**
00301 eh_dlm_read_data( gchar* str        ,
00302                   gchar* delims     ,
00303                   gint* n_rows      ,
00304                   gint* n_cols      ,
00305                   GError** err )
00306 {
00307    double** data;
00308 
00309    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00310 
00311    if ( !delims )
00312       delims = ";,";
00313 
00314    if ( str )
00315    {
00316       *n_rows = eh_dlm_find_n_rows( str , '\n' );
00317       *n_cols = eh_dlm_find_n_cols( str , delims );
00318 
00319       /* Parse the data */
00320       {
00321          gint i, j;
00322          gchar* pos_0;
00323          gchar* pos_1;
00324          gchar** values;
00325          gint n_vals;
00326          gchar* str_end = str+strlen(str);
00327 
00328          data = eh_new_2( double , *n_rows , *n_cols );
00329 
00330          pos_0 = str;
00331          for ( i=0 ; pos_0<str_end ; i++ )
00332          {
00333             pos_1 = strchr( pos_0 , '\n' );
00334             if ( !pos_1 )
00335                pos_1 = str_end;
00336             pos_1[0] = '\0';
00337 
00338             values = g_strsplit_set( pos_0 , delims , -1 );
00339 
00340             n_vals = g_strv_length( values );
00341 
00342             for ( j=0 ; j<n_vals ; j++ )
00343                data[i][j] = g_ascii_strtod( values[j] , NULL );
00344             for (     ; j<*n_cols ; j++ )
00345                data[i][j] = 0.;
00346 
00347             pos_0 = pos_1+1;
00348 
00349             g_strfreev( values );
00350          }
00351       }
00352    }
00353 
00354    return data;
00355 }
00356 
00357 gint
00358 eh_dlm_find_n_rows( gchar* str , gint delim )
00359 {
00360    gint n = 0;
00361 
00362    if ( str )
00363    {
00364       n = eh_str_count_chr( str , str+strlen(str) , delim )+1;
00365    }
00366 
00367    return n;
00368 }
00369 
00370 gint
00371 eh_dlm_find_n_cols( gchar* str , gchar* delims )
00372 {
00373    gint n_cols = 0;
00374 
00375    if ( str )
00376    {
00377       gint i, n;
00378       gint n_delims  = strlen(delims);
00379       gchar* str_end = str + strlen(str);
00380       gchar* pos_0;
00381       gchar* pos_1;
00382 
00383       pos_0 = str;
00384       while ( pos_0<str_end )
00385       {
00386          pos_1 = strchr( pos_0 , '\n' );
00387          if ( !pos_1 )
00388             pos_1 = str_end;
00389 
00390          for ( i=0,n=0 ; i<n_delims ; i++ )
00391             n += eh_str_count_chr( pos_0 , pos_1 , delims[i] );
00392 
00393          if ( n>n_cols )
00394             n_cols = n;
00395 
00396          pos_0 = pos_1+1;
00397       }
00398    }
00399 
00400    return n_cols+1;
00401 }
00402 
00413 gchar*
00414 eh_dlm_remove_empty_lines( gchar* str )
00415 {
00416    if ( str && str[0]!='\0' )
00417    {
00418       gchar*  pos;
00419       gchar*  pos_0;
00420       gchar*  last_line;
00421       gint    len       = strlen(str);
00422       gchar*  str_end   = str+len;
00423       gchar** block     = eh_new0( gchar* , len );
00424       gchar** block_end = eh_new0( gchar* , len );
00425       gint    i=0;
00426 
00427       pos_0 = str;
00428       while ( pos_0>=str && pos_0<str_end )
00429       {
00430          last_line = NULL;
00431 
00432          for ( pos=pos_0 ; pos<str_end && g_ascii_isspace(*pos) ; pos++ )
00433          {
00434             if ( *pos == '\n' )
00435                last_line = pos;
00436          }
00437 
00438          if ( last_line )
00439          {
00440             block[i]     = pos_0;
00441             block_end[i] = last_line+1;
00442             i += 1;
00443          }
00444 
00445          pos_0 = strchr( pos , '\n' )+1;
00446       }
00447       eh_str_remove_blocks( str , block , block_end );
00448 
00449       eh_free( block_end );
00450       eh_free( block     );
00451 
00452       if ( str[strlen(str)-1]=='\n' )
00453          str[strlen(str)-1]='\0';
00454    }
00455    return str;
00456 }
00457 
00458 gchar**
00459 eh_dlm_split_records( gchar*       str       ,
00460                       const gchar* start_str ,
00461                       const gchar* end_str   ,
00462                       gchar***     rec_data )
00463 {
00464    gchar** split_str = NULL;
00465 
00466    eh_require( start_str );
00467    eh_require( end_str   );
00468 
00469    if ( rec_data )
00470       *rec_data = NULL;
00471 
00472    if ( str )
00473    {
00474       for ( ; g_ascii_isspace(*str) ; str++ );
00475 
00476       if ( strstr( str , start_str ) != str )
00477       {
00478          eh_strv_append( &split_str , g_strdup(str) );
00479       }
00480       else
00481       {
00482          gchar* pos_0;
00483          gchar* pos_1;
00484          gchar* str_end = str+strlen(str);
00485          gint start_len = strlen(start_str);
00486          gint end_len   = strlen(end_str  );
00487          gint len;
00488          gchar* new_line;
00489 
00490          pos_0 = str+start_len;
00491          for ( len=2 ; pos_0<str_end ; len++ )
00492          {
00493             /* Find the close of the header (or the end of the string) */
00494             pos_1 = strstr( pos_0 , end_str );
00495             if ( !pos_1 )
00496                pos_1 = str_end-end_len;
00497 
00498             /* Save the header info */
00499             if ( rec_data )
00500             {
00501                new_line = g_strndup( pos_0 , pos_1-pos_0 );
00502                eh_strv_append( rec_data , new_line );
00503                g_strstrip( new_line );
00504             }
00505 
00506             /* Go to the start of the data */
00507             pos_0 = pos_1 + end_len;
00508             for ( ; g_ascii_isspace(*pos_0) ; pos_0++ );
00509 
00510             /* Find the end of the data (the start of the next header) */
00511             pos_1 = strstr( pos_0 , start_str );
00512             if ( !pos_1 )
00513                pos_1 = str_end;
00514 
00515             new_line = g_strndup( pos_0 , pos_1-pos_0 );
00516             g_strstrip( new_line );
00517             
00518             eh_strv_append( &split_str , new_line );
00519 
00520             pos_0 = pos_1+start_len;
00521             for ( ; pos_0<str_end && g_ascii_isspace(*pos_0) ; pos_0++ );
00522          }
00523       }
00524    }
00525 
00526    return split_str;
00527 }
00528 
00529 gint
00530 eh_dlm_print( const gchar* file , const gchar* delim , const double** data , const gint n_rows , const gint n_cols , GError** error ) 
00531 {
00532    return eh_dlm_print_full( file , delim , data , n_rows , n_cols , FALSE , error );
00533 }
00534 
00535 gint
00536 eh_dlm_print_swap( const gchar* file , const gchar* delim , const double** data , const gint n_rows , const gint n_cols , GError** error ) 
00537 {
00538    return eh_dlm_print_full( file , delim , data , n_rows , n_cols , TRUE , error );
00539 }
00540 
00541 gint
00542 eh_dlm_print_full( const gchar* file , const gchar* delim , const double** data , const gint n_rows , const gint n_cols , gboolean swap , GError** error ) 
00543 {
00544    gint n = 0;
00545 
00546    eh_return_val_if_fail( error==NULL || *error==NULL , 0 );
00547    eh_require( data     );
00548    eh_require( n_rows>0 );
00549    eh_require( n_cols>0 );
00550 
00551    if ( data )
00552    {
00553       FILE* fp;
00554       GError* tmp_err = NULL;
00555 
00556       if ( file ) fp = eh_fopen_error( file , "w" , &tmp_err );
00557       else        fp = stdout;
00558 
00559       if ( fp )
00560       {
00561          gint i, j;
00562 
00563          if ( !delim ) delim = " ";
00564 
00565          if ( swap )
00566          {
00567             const gint top_row = n_rows-1;
00568             for ( j=0 ; j<n_cols ; j++ )
00569             {
00570                for ( i=0 ; i<top_row ; i++ )
00571                   n += fprintf( fp , "%f%s" , data[i][j] , delim );
00572                n += fprintf( fp , "%f" , data[i][j] );
00573                n += fprintf( fp , "\n" );
00574             }
00575          }
00576          else
00577          {
00578             const gint top_col = n_cols-1;
00579             for ( i=0 ; i<n_rows ; i++ )
00580             {
00581                for ( j=0 ; j<top_col ; j++ )
00582                   n += fprintf( fp , "%f%s" , data[i][j] , delim );
00583                n += fprintf( fp , "%f" , data[i][j] );
00584                n += fprintf( fp , "\n" );
00585             }
00586          }
00587       }
00588       else
00589          g_propagate_error( error , tmp_err );
00590    }
00591 
00592    return n;
00593 }
00594 
00595 gint
00596 eh_dlm_print_dbl_grid( const gchar* file , const gchar* delim , Eh_dbl_grid g , GError** error ) 
00597 {
00598    gint n = 0;
00599 
00600    eh_return_val_if_fail( error==NULL || *error==NULL , 0 );
00601    eh_require( g );
00602 
00603    if ( g )
00604    {
00605       GError* tmp_err = NULL;
00606 
00607       n = eh_dlm_print( file , delim , (double**)eh_dbl_grid_data(g) , eh_grid_n_x(g) , eh_grid_n_y(g) , &tmp_err );
00608 
00609       if ( tmp_err )
00610          g_propagate_error( error , tmp_err );
00611    }
00612 
00613    return n;
00614 }
00615 

Generated on Fri Jan 4 18:04:16 2008 for sedflux by  doxygen 1.5.2