LTP GCOV extension - code coverage report
Current view: directory - frmts/envisat - EnvisatFile.c
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 442
Code covered: 0.0 % Executed lines: 0

       1                 : /******************************************************************************
       2                 :  * $Id: EnvisatFile.c 11332 2007-04-21 20:48:53Z warmerdam $
       3                 :  *
       4                 :  * Project:  APP ENVISAT Support
       5                 :  * Purpose:  Low Level Envisat file access (read/write) API.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2001, Atlantis Scientific, Inc.
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #ifndef APP_BUILD
      31                 : #  define GDAL_BUILD
      32                 : #  include "cpl_conv.h"
      33                 : #  include "EnvisatFile.h"
      34                 : 
      35                 : CPL_CVSID("$Id: EnvisatFile.c 11332 2007-04-21 20:48:53Z warmerdam $");
      36                 : 
      37                 : #else
      38                 : #  include "APP/app.h"
      39                 : #  include "util/Files/EnvisatFile.h"
      40                 : #endif
      41                 : 
      42                 : typedef struct 
      43                 : {
      44                 :     char  *ds_name;
      45                 :     char  *ds_type;
      46                 :     char  *filename;
      47                 :     int   ds_offset;
      48                 :     int   ds_size;
      49                 :     int   num_dsr;
      50                 :     int   dsr_size;
      51                 : } EnvisatDatasetInfo;
      52                 : 
      53                 : typedef struct
      54                 : {
      55                 :     char  *key;
      56                 :     char  *value;
      57                 :     char  *units;
      58                 :     char  *literal_line;
      59                 :     int         value_offset;
      60                 : } EnvisatNameValue;
      61                 : 
      62                 : struct EnvisatFile_tag
      63                 : {
      64                 :     FILE  *fp;
      65                 :     char        *filename;
      66                 :     int   updatable;
      67                 :     int         header_dirty;
      68                 :     int   dsd_offset;
      69                 : 
      70                 :     int   mph_count;
      71                 :     EnvisatNameValue **mph_entries;
      72                 : 
      73                 :     int   sph_count;
      74                 :     EnvisatNameValue **sph_entries;
      75                 : 
      76                 :     int   ds_count;
      77                 :     EnvisatDatasetInfo **ds_info;
      78                 :     
      79                 : };
      80                 : 
      81                 : #ifdef GDAL_BUILD
      82                 : #  define SUCCESS 0
      83                 : #  define FAILURE 1
      84                 : #  define SendError( text )   CPLError( CE_Failure, CPLE_AppDefined, "%s", text )
      85                 : #endif
      86                 : 
      87                 : #define MPH_SIZE 1247
      88                 : 
      89                 : /*
      90                 :  * API For handling name/value lists.
      91                 :  */
      92                 : int S_NameValueList_Parse( const char *text, int text_offset, 
      93                 :                            int *entry_count, 
      94                 :                            EnvisatNameValue ***entries );
      95                 : void S_NameValueList_Destroy( int *entry_count, 
      96                 :                              EnvisatNameValue ***entries );
      97                 : int S_NameValueList_FindKey( const char *key,
      98                 :                              int entry_count, 
      99                 :                              EnvisatNameValue **entries );
     100                 : const char *S_NameValueList_FindValue( const char *key,
     101                 :                                        int entry_count, 
     102                 :                                        EnvisatNameValue **entries,
     103                 :                                        const char * default_value );
     104                 : 
     105                 : int S_NameValueList_Rewrite( FILE *fp, int entry_count, 
     106                 :                              EnvisatNameValue **entries );
     107                 : 
     108                 : EnvisatNameValue *
     109                 :     S_EnivsatFile_FindNameValue( EnvisatFile *self,
     110                 :                                  EnvisatFile_HeaderFlag mph_or_sph,
     111                 :                                  const char * key );
     112                 : 
     113                 : 
     114                 : 
     115                 : 
     116                 : /*-----------------------------------------------------------------------------
     117                 : 
     118                 : Name:
     119                 :     Envisat_SetupLevel0
     120                 : 
     121                 : Purpose:
     122                 :     Patch up missing information about SPH, and datasets for incomplete 
     123                 :     level 0 signal datasets.
     124                 : 
     125                 : Description:
     126                 : 
     127                 : Inputs:
     128                 :     self -- Envisat file handle.
     129                 : 
     130                 : Outputs:
     131                 : 
     132                 : Returns:
     133                 :     SUCCESS or FAILURE
     134                 : 
     135                 : -----------------------------------------------------------------------------*/
     136                 : 
     137                 : static int EnvisatFile_SetupLevel0( EnvisatFile *self )
     138                 : 
     139               0 : {
     140                 :     int file_length;
     141                 :     unsigned char header[68];
     142                 :     EnvisatDatasetInfo *ds_info;
     143                 : 
     144               0 :     self->dsd_offset = 0;
     145               0 :     self->ds_count = 1;
     146               0 :     self->ds_info = (EnvisatDatasetInfo **) 
     147                 :         calloc(sizeof(EnvisatDatasetInfo*),self->ds_count);
     148                 : 
     149               0 :     if( self->ds_info == NULL )
     150               0 :         return FAILURE;
     151                 : 
     152                 :     /*
     153                 :      * Figure out how long the file is. 
     154                 :      */
     155                 : 
     156               0 :     fseek( self->fp, 0, SEEK_END );
     157               0 :     file_length = (int) ftell( self->fp );
     158                 :     
     159                 :     /* 
     160                 :      * Read the first record header, and verify the well known values.
     161                 :      */
     162               0 :     fseek( self->fp, 3203, SEEK_SET );
     163               0 :     fread( header, 68, 1, self->fp );
     164                 : 
     165               0 :     if( header[38] != 0 || header[39] != 0x1d
     166                 :         || header[40] != 0 || header[41] != 0x54 )
     167                 :     {
     168               0 :         SendError( "Didn't get expected Data Field Header Length, or Mode ID\n"
     169                 :                    "values for the first data record." );
     170               0 :         return FAILURE;
     171                 :     }
     172                 : 
     173                 :     /* 
     174                 :      * Then build the dataset into structure from that. 
     175                 :      */
     176               0 :     ds_info = (EnvisatDatasetInfo *) calloc(sizeof(EnvisatDatasetInfo),1);
     177                 :     
     178               0 :     ds_info->ds_name = strdup( "ASAR SOURCE PACKETS         " );
     179               0 :     ds_info->ds_type = strdup( "M" );
     180               0 :     ds_info->filename = strdup( "                                                              " );
     181               0 :     ds_info->ds_offset = 3203;
     182               0 :     ds_info->dsr_size = -1;
     183               0 :     ds_info->num_dsr = 0;
     184               0 :     ds_info->ds_size = file_length - ds_info->ds_offset;
     185                 :     
     186               0 :     self->ds_info[0] = ds_info;
     187                 : 
     188               0 :     return SUCCESS;
     189                 : }
     190                 : 
     191                 : /*-----------------------------------------------------------------------------
     192                 : 
     193                 : Name:
     194                 :     Envisat_Open
     195                 : 
     196                 : Purpose:
     197                 :     Open an ENVISAT formatted file, and read all headers.
     198                 : 
     199                 : Description:
     200                 : 
     201                 : Inputs:
     202                 :     filename -- name of Envisat file.
     203                 :     mode -- either "r" for read access, or "r+" for read/write access.
     204                 : 
     205                 : Outputs:
     206                 :     self -- file handle, NULL on FAILURE.
     207                 : 
     208                 : Returns:
     209                 :     SUCCESS or FAILURE
     210                 : 
     211                 : -----------------------------------------------------------------------------*/
     212                 : 
     213                 : int EnvisatFile_Open( EnvisatFile **self_ptr, 
     214                 :                       const char *filename, 
     215                 :                       const char *mode )
     216                 : 
     217               0 : {
     218                 :     FILE  *fp;
     219                 :     EnvisatFile *self;
     220                 :     char  mph_data[1248];
     221                 :     char  *sph_data, *ds_data;
     222                 :     int   sph_size, num_dsd, dsd_size, i;
     223                 : 
     224               0 :     *self_ptr = NULL;
     225                 : 
     226                 :     /*
     227                 :      * Check for legal mode argument.  Force to be binary for correct
     228                 :      * operation on DOS file systems.
     229                 :      */
     230               0 :     if( strcmp(mode,"r") == 0 )
     231               0 :         mode = "rb";
     232               0 :     else if( strcmp(mode,"r+") == 0 )
     233               0 :         mode = "rb+";
     234                 :     else
     235                 :     {
     236               0 :         SendError( "Illegal mode value used in EnvisatFile_Open(), only "
     237                 :                    "\"r\" and \"r+\" are supported." );
     238               0 :         return FAILURE;
     239                 :     }
     240                 : 
     241                 :     /*
     242                 :      * Try to open the file, and report failure. 
     243                 :      */
     244                 : 
     245               0 :     fp = fopen( filename, mode );
     246                 : 
     247               0 :     if( fp == NULL )
     248                 :     {
     249                 :         char  error_buf[2048];
     250                 : 
     251               0 :         sprintf( error_buf, 
     252                 :                  "Unable to open file \"%s\" in EnvisatFile_Open().", 
     253                 :                  filename );
     254                 : 
     255               0 :         SendError( error_buf );
     256               0 :         return FAILURE;
     257                 :     }
     258                 : 
     259                 :     /*
     260                 :      * Create, and initialize the EnvisatFile structure. 
     261                 :      */
     262               0 :     self = (EnvisatFile *) calloc(sizeof(EnvisatFile),1);
     263               0 :     if( self == NULL )
     264               0 :         return FAILURE;
     265                 : 
     266               0 :     self->fp = fp;
     267               0 :     self->filename = strdup( filename );
     268               0 :     self->header_dirty = 0;
     269               0 :     self->updatable = (strcmp(mode,"rb+") == 0);
     270                 : 
     271                 :     /*
     272                 :      * Read the MPH, and process it as a group of name/value pairs. 
     273                 :      */
     274                 : 
     275               0 :     if( fread( mph_data, 1, MPH_SIZE, fp ) != MPH_SIZE )
     276                 :     {
     277               0 :         free( self );
     278               0 :         SendError( "fread() for mph failed." );
     279               0 :         return FAILURE;
     280                 :     }
     281                 : 
     282               0 :     mph_data[MPH_SIZE] = '\0';
     283               0 :     if( S_NameValueList_Parse( mph_data, 0, 
     284                 :                                &(self->mph_count), 
     285                 :                                &(self->mph_entries) ) == FAILURE )
     286               0 :         return FAILURE;
     287                 : 
     288                 :     /*
     289                 :      * Is this an incomplete level 0 file?
     290                 :      */
     291               0 :     if( EnvisatFile_GetKeyValueAsInt( self, MPH, "SPH_SIZE", -1 ) == 0 
     292                 :         && strncmp(EnvisatFile_GetKeyValueAsString( self, MPH, "PRODUCT", ""),
     293                 :                    "ASA_IM__0P", 10) == 0 )
     294                 :     {
     295                 : 
     296               0 :         if( EnvisatFile_SetupLevel0( self ) == FAILURE )
     297                 :         {
     298               0 :             EnvisatFile_Close( self );
     299               0 :             return FAILURE;
     300                 :         }
     301                 :         else
     302                 :         {
     303               0 :             *self_ptr = self;
     304               0 :             return SUCCESS;
     305                 :         }
     306                 :     }
     307                 : 
     308                 :     /*
     309                 :      * Read the SPH, and process it as a group of name/value pairs.  
     310                 :      */
     311               0 :     sph_size = EnvisatFile_GetKeyValueAsInt( self, MPH, "SPH_SIZE", 0 );
     312                 : 
     313               0 :     if( sph_size == 0 )             
     314                 :     {
     315               0 :         SendError( "File does not appear to have SPH,"
     316                 :                    " SPH_SIZE not set, or zero." );
     317               0 :         return FAILURE;
     318                 :     }
     319                 : 
     320               0 :     sph_data = (char *) malloc(sph_size + 1 );
     321               0 :     if( sph_data == NULL )
     322               0 :         return FAILURE;
     323                 : 
     324               0 :     if( (int) fread( sph_data, 1, sph_size, fp ) != sph_size )
     325                 :     {
     326               0 :         free( self );
     327               0 :         SendError( "fread() for sph failed." );
     328               0 :         return FAILURE;
     329                 :     }
     330                 : 
     331               0 :     sph_data[sph_size] = '\0';
     332               0 :     ds_data = strstr(sph_data,"DS_NAME");
     333               0 :     if( ds_data != NULL )
     334                 :     {
     335               0 :         self->dsd_offset = (int) (ds_data - sph_data) + MPH_SIZE;
     336               0 :         *(ds_data-1) = '\0';
     337                 :     }
     338                 : 
     339               0 :     if( S_NameValueList_Parse( sph_data, MPH_SIZE,
     340                 :                                &(self->sph_count), 
     341                 :                                &(self->sph_entries) ) == FAILURE )
     342               0 :         return FAILURE;
     343                 : 
     344                 :     /*
     345                 :      * Parse the Dataset Definitions.
     346                 :      */
     347               0 :     num_dsd = EnvisatFile_GetKeyValueAsInt( self, MPH, "NUM_DSD", 0 );
     348               0 :     dsd_size = EnvisatFile_GetKeyValueAsInt( self, MPH, "DSD_SIZE", 0 );
     349                 :     
     350               0 :     if( num_dsd > 0 && ds_data == NULL )
     351                 :     {
     352               0 :         SendError( "DSDs indicated in MPH, but not found in SPH." );
     353               0 :         return FAILURE;
     354                 :     }
     355                 : 
     356               0 :     self->ds_info = (EnvisatDatasetInfo **) 
     357                 :         calloc(sizeof(EnvisatDatasetInfo*),num_dsd);
     358               0 :     if( self->ds_info == NULL )
     359               0 :         return FAILURE;
     360                 : 
     361               0 :     for( i = 0; i < num_dsd; i++ )
     362                 :     {
     363               0 :         int dsdh_count = 0;
     364               0 :         EnvisatNameValue **dsdh_entries = NULL;
     365                 :         char  *dsd_data;
     366                 :         EnvisatDatasetInfo *ds_info;
     367                 : 
     368                 :         /*
     369                 :          * We parse each DSD grouping into a name/value list. 
     370                 :          */
     371               0 :         dsd_data = ds_data + i * dsd_size;
     372               0 :         dsd_data[dsd_size-1] = '\0';
     373                 :         
     374               0 :         if( S_NameValueList_Parse( dsd_data, 0, 
     375                 :                                    &dsdh_count, &dsdh_entries ) == FAILURE )
     376               0 :             return FAILURE;
     377                 : 
     378                 :         /* 
     379                 :          * Then build the dataset into structure from that. 
     380                 :          */
     381               0 :         ds_info = (EnvisatDatasetInfo *) calloc(sizeof(EnvisatDatasetInfo),1);
     382                 : 
     383               0 :         ds_info->ds_name = strdup( 
     384                 :             S_NameValueList_FindValue( "DS_NAME", 
     385                 :                                        dsdh_count, dsdh_entries, "" ));
     386               0 :         ds_info->ds_type = strdup( 
     387                 :             S_NameValueList_FindValue( "DS_TYPE", 
     388                 :                                        dsdh_count, dsdh_entries, "" ));
     389               0 :         ds_info->filename = strdup( 
     390                 :             S_NameValueList_FindValue( "FILENAME", 
     391                 :                                        dsdh_count, dsdh_entries, "" ));
     392               0 :         ds_info->ds_offset = atoi(
     393                 :             S_NameValueList_FindValue( "DS_OFFSET", 
     394                 :                                        dsdh_count, dsdh_entries, "0" ));
     395               0 :         ds_info->ds_size = atoi(
     396                 :             S_NameValueList_FindValue( "DS_SIZE", 
     397                 :                                        dsdh_count, dsdh_entries, "0" ));
     398               0 :         ds_info->num_dsr = atoi(
     399                 :             S_NameValueList_FindValue( "NUM_DSR", 
     400                 :                                        dsdh_count, dsdh_entries, "0" ));
     401               0 :         ds_info->dsr_size = atoi(
     402                 :             S_NameValueList_FindValue( "DSR_SIZE", 
     403                 :                                        dsdh_count, dsdh_entries, "0" ));
     404                 : 
     405               0 :         S_NameValueList_Destroy( &dsdh_count, &dsdh_entries );
     406                 : 
     407               0 :         self->ds_info[i] = ds_info;
     408               0 :         self->ds_count++;
     409                 :     }
     410                 :     
     411               0 :     free( sph_data );
     412                 : 
     413                 :     /*
     414                 :      * Return successfully.
     415                 :      */
     416               0 :     *self_ptr = self;
     417                 : 
     418               0 :     return SUCCESS;
     419                 : }
     420                 : 
     421                 : /*-----------------------------------------------------------------------------
     422                 : 
     423                 : Name:
     424                 :     EnvisatFile_Create
     425                 : 
     426                 : Purpose:
     427                 :     Create a new ENVISAT formatted file based on a template file.
     428                 : 
     429                 : Description:
     430                 : 
     431                 : Inputs:
     432                 :     filename -- name of Envisat file.
     433                 :     template_file -- name of envisat file header to utilize as template. 
     434                 : 
     435                 : Outputs:
     436                 :     self -- file handle, NULL on FAILURE.
     437                 : 
     438                 : Returns:
     439                 :     SUCCESS or FAILURE
     440                 : 
     441                 : -----------------------------------------------------------------------------*/
     442                 : 
     443                 : int EnvisatFile_Create( EnvisatFile **self_ptr, 
     444                 :                         const char *filename, 
     445                 :                         const char *template_file )
     446                 : 
     447               0 : {
     448                 :     int   template_size;
     449                 :     char  *template_data;
     450                 :     FILE  *fp;
     451                 : 
     452                 :     /*
     453                 :      * Try to open the template file, and read it into memory.
     454                 :      */
     455                 : 
     456               0 :     fp = fopen( template_file, "rb" );
     457                 : 
     458               0 :     if( fp == NULL )
     459                 :     {
     460                 :         char  error_buf[2048];
     461                 : 
     462               0 :         sprintf( error_buf, 
     463                 :                  "Unable to open file \"%s\" in EnvisatFile_Create().", 
     464                 :                  template_file );
     465                 : 
     466               0 :         SendError( error_buf );
     467               0 :         return FAILURE;
     468                 :     }
     469                 : 
     470               0 :     fseek( fp, 0, SEEK_END );
     471               0 :     template_size = (int) ftell( fp );
     472                 : 
     473               0 :     template_data = (char *) malloc(template_size);
     474                 :     
     475               0 :     fseek( fp, 0, SEEK_SET );
     476               0 :     fread( template_data, template_size, 1, fp );
     477               0 :     fclose( fp );
     478                 : 
     479                 :     /*
     480                 :      * Try to write the template out to the new filename. 
     481                 :      */
     482                 :     
     483               0 :     fp = fopen( filename, "wb" );
     484               0 :     if( fp == NULL )
     485                 :     {
     486                 :         char  error_buf[2048];
     487                 : 
     488               0 :         sprintf( error_buf, 
     489                 :                  "Unable to open file \"%s\" in EnvisatFile_Create().", 
     490                 :                  filename );
     491                 : 
     492               0 :         SendError( error_buf );
     493               0 :         return FAILURE;
     494                 :     }
     495                 : 
     496               0 :     fwrite( template_data, template_size, 1, fp );
     497               0 :     fclose( fp );
     498                 : 
     499               0 :     free( template_data );
     500                 : 
     501                 :     /*
     502                 :      * Now just open the file normally. 
     503                 :      */
     504                 :     
     505               0 :     return EnvisatFile_Open( self_ptr, filename, "r+" );
     506                 : }
     507                 : 
     508                 : /*-----------------------------------------------------------------------------
     509                 : 
     510                 : Name:
     511                 :     EnvisatFile_GetCurrentLength
     512                 : 
     513                 : Purpose:
     514                 :     Fetch the current file length.
     515                 : 
     516                 : Description:
     517                 :     The length is computed by scanning the dataset definitions, not the
     518                 :     physical file length.  
     519                 : 
     520                 : Inputs:
     521                 :     self -- the file to operate on. 
     522                 : 
     523                 : Outputs:
     524                 : 
     525                 : Returns:
     526                 :     Returns length or -1 on failure.
     527                 : 
     528                 : -----------------------------------------------------------------------------*/
     529                 : 
     530                 : int EnvisatFile_GetCurrentLength( EnvisatFile *self )
     531                 : 
     532               0 : {
     533                 :     int   length;
     534                 :     int   ds;
     535                 :     int   ds_offset;
     536                 :     int         ds_size;
     537                 : 
     538               0 :     length = MPH_SIZE 
     539                 :         + EnvisatFile_GetKeyValueAsInt( self, MPH, "SPH_SIZE", 0 );
     540                 : 
     541               0 :     for( ds = 0; 
     542               0 :          EnvisatFile_GetDatasetInfo( self, ds, NULL, NULL, NULL, 
     543                 :                                      &ds_offset, &ds_size, NULL, NULL )
     544                 :              != FAILURE; 
     545               0 :          ds++ )
     546                 :     {
     547               0 :         if( ds_offset != 0 && (ds_offset+ds_size) > length )
     548               0 :             length = ds_offset + ds_size;
     549                 :     }
     550                 : 
     551               0 :     return length;
     552                 : }
     553                 : 
     554                 : /*-----------------------------------------------------------------------------
     555                 : 
     556                 : Name:
     557                 :     EnvisatFile_RewriteHeader
     558                 : 
     559                 : Purpose:
     560                 :     Update the envisat file header on disk to match the in-memory image.
     561                 : 
     562                 : Description:
     563                 : 
     564                 : Inputs:
     565                 :     self -- handle for file to close.
     566                 : 
     567                 : Outputs:
     568                 : 
     569                 : Returns:
     570                 :     SUCCESS or FAILURE.
     571                 : 
     572                 : -----------------------------------------------------------------------------*/
     573                 : 
     574                 : static int EnvisatFile_RewriteHeader( EnvisatFile *self )
     575                 : 
     576               0 : {
     577                 :     int   dsd, dsd_size;
     578                 : 
     579                 :     /* 
     580                 :      * Rewrite MPH and SPH headers.
     581                 :      */
     582               0 :     if( S_NameValueList_Rewrite( self->fp, 
     583                 :                         self->mph_count, self->mph_entries ) == FAILURE )
     584               0 :         return FAILURE;
     585                 : 
     586               0 :     if( S_NameValueList_Rewrite( self->fp, 
     587                 :                         self->sph_count, self->sph_entries ) == FAILURE )
     588               0 :         return FAILURE;
     589                 : 
     590                 :     /*
     591                 :      * Rewrite DSDs.  We actually have to read each, and reparse to set
     592                 :      * the individual parameters properly.
     593                 :      */
     594               0 :     dsd_size = EnvisatFile_GetKeyValueAsInt( self, MPH, "DSD_SIZE", 0 );
     595               0 :     if( dsd_size == 0 )
     596               0 :         return FAILURE;
     597                 : 
     598               0 :     for( dsd = 0; dsd < self->ds_count; dsd++ )
     599                 :     {
     600                 :         char  *dsd_text;
     601               0 :         int dsdh_count = 0, key_index;
     602               0 :         EnvisatNameValue **dsdh_entries = NULL;
     603                 : 
     604               0 :         dsd_text = (char *) calloc(1,dsd_size+1);
     605               0 :         if( fseek( self->fp, self->dsd_offset + dsd * dsd_size, 
     606                 :                    SEEK_SET ) != 0 )
     607                 :         {
     608               0 :             SendError( "fseek() failed in EnvisatFile_RewriteHeader()" );
     609               0 :             return FAILURE;
     610                 :         }
     611                 :         
     612               0 :         if( (int) fread( dsd_text, 1, dsd_size, self->fp ) != dsd_size )
     613                 :         {
     614               0 :             SendError( "fread() failed in EnvisatFile_RewriteHeader()" );
     615               0 :             return FAILURE;
     616                 :         }
     617                 : 
     618               0 :         if( S_NameValueList_Parse( dsd_text, self->dsd_offset + dsd*dsd_size, 
     619                 :                                    &dsdh_count, &dsdh_entries ) == FAILURE )
     620               0 :             return FAILURE;
     621                 : 
     622               0 :         free( dsd_text );
     623                 : 
     624               0 :         key_index = S_NameValueList_FindKey( "DS_OFFSET", 
     625                 :                                              dsdh_count, dsdh_entries );
     626               0 :         if( key_index == -1 )
     627               0 :             continue;
     628                 : 
     629               0 :         sprintf( dsdh_entries[key_index]->value, "%+021d", 
     630                 :                  self->ds_info[dsd]->ds_offset );
     631                 : 
     632               0 :         key_index = S_NameValueList_FindKey( "DS_SIZE", 
     633                 :                                              dsdh_count, dsdh_entries );
     634               0 :         sprintf( dsdh_entries[key_index]->value, "%+021d", 
     635                 :                  self->ds_info[dsd]->ds_size );
     636                 : 
     637               0 :         key_index = S_NameValueList_FindKey( "NUM_DSR", 
     638                 :                                              dsdh_count, dsdh_entries );
     639               0 :         sprintf( dsdh_entries[key_index]->value, "%+011d", 
     640                 :                  self->ds_info[dsd]->num_dsr );
     641                 : 
     642               0 :         key_index = S_NameValueList_FindKey( "DSR_SIZE", 
     643                 :                                              dsdh_count, dsdh_entries );
     644               0 :         sprintf( dsdh_entries[key_index]->value, "%+011d", 
     645                 :                  self->ds_info[dsd]->dsr_size );
     646                 : 
     647               0 :         if( S_NameValueList_Rewrite( self->fp, dsdh_count, dsdh_entries )
     648                 :             == FAILURE )
     649               0 :             return FAILURE;
     650                 : 
     651               0 :         S_NameValueList_Destroy( &dsdh_count, &dsdh_entries );
     652                 :     }
     653                 : 
     654               0 :     self->header_dirty = 0;
     655                 : 
     656               0 :     return SUCCESS;
     657                 : }
     658                 : 
     659                 : /*-----------------------------------------------------------------------------
     660                 : 
     661                 : Name:
     662                 :     EnvisatFile_Close
     663                 : 
     664                 : Purpose:
     665                 :     Close an ENVISAT formatted file, releasing all associated resources.
     666                 : 
     667                 : Description:
     668                 : 
     669                 : Inputs:
     670                 :     self -- handle for file to close.
     671                 : 
     672                 : Outputs:
     673                 : 
     674                 : Returns:
     675                 : 
     676                 : 
     677                 : -----------------------------------------------------------------------------*/
     678                 : 
     679                 : void EnvisatFile_Close( EnvisatFile *self )
     680                 : 
     681               0 : {
     682                 :     int   i;
     683                 : 
     684                 :     /*
     685                 :      * Do we need to write out the header information?
     686                 :      */
     687               0 :     if( self->header_dirty )
     688               0 :         EnvisatFile_RewriteHeader( self );
     689                 : 
     690                 :     /*
     691                 :      * Close file. 
     692                 :      */
     693               0 :     if( self->fp != NULL )
     694               0 :         fclose( self->fp );
     695                 : 
     696                 :     /*
     697                 :      * Clean up data structures. 
     698                 :      */
     699               0 :     S_NameValueList_Destroy( &(self->mph_count), &(self->mph_entries) );
     700               0 :     S_NameValueList_Destroy( &(self->sph_count), &(self->sph_entries) );
     701                 : 
     702               0 :     for( i = 0; i < self->ds_count; i++ )
     703                 :     {
     704               0 :         if( self->ds_info != NULL && self->ds_info[i] != NULL )
     705                 :         {
     706               0 :             free( self->ds_info[i]->ds_name );
     707               0 :             free( self->ds_info[i]->ds_type );
     708               0 :             free( self->ds_info[i]->filename );
     709               0 :             free( self->ds_info[i] );
     710                 :         }
     711                 :     }
     712               0 :     if( self->ds_info != NULL )
     713               0 :         free( self->ds_info );
     714               0 :     if( self->filename != NULL )
     715               0 :         free( self->filename );
     716                 : 
     717               0 :     free( self );
     718               0 : }
     719                 : 
     720                 : /*-----------------------------------------------------------------------------
     721                 : 
     722                 : Name:
     723                 :     EnvisatFile_GetFilename
     724                 : 
     725                 : Purpose:
     726                 :     Fetch name of this Envisat file.
     727                 : 
     728                 : Description:
     729                 : 
     730                 : Inputs:
     731                 :     self -- handle for file to get name of.
     732                 : 
     733                 : Outputs:
     734                 : 
     735                 : Returns:
     736                 :     const pointer to internal copy of the filename.  Do not alter or free.
     737                 : 
     738                 : 
     739                 : -----------------------------------------------------------------------------*/
     740                 : 
     741                 : const char *EnvisatFile_GetFilename( EnvisatFile *self )
     742                 : 
     743               0 : {
     744               0 :     return self->filename;
     745                 : }
     746                 : 
     747                 : /*-----------------------------------------------------------------------------
     748                 : 
     749                 : Name:
     750                 :     EnvisatFile_GetKeyByIndex()
     751                 : 
     752                 : Purpose:
     753                 :     Fetch the key with the indicated index.
     754                 : 
     755                 : Description:
     756                 :     This function can be used to "discover" the set of available keys by
     757                 :     by scanning with index values starting at zero and ending when a NULL
     758                 :     is returned.
     759                 : 
     760                 : Inputs:
     761                 :     self -- the file to be searched.
     762                 :     mph_or_sph -- Either MPH or SPH depending on the header to be searched.
     763                 :     key_index -- key index, from zero to number of keys-1.
     764                 : 
     765                 : Outputs:
     766                 : 
     767                 : Returns:
     768                 :     pointer to key name or NULL on failure.
     769                 : 
     770                 : -----------------------------------------------------------------------------*/
     771                 : 
     772                 : const char *EnvisatFile_GetKeyByIndex( EnvisatFile *self, 
     773                 :                                        EnvisatFile_HeaderFlag mph_or_sph,
     774                 :                                        int key_index )
     775                 : 
     776               0 : {
     777                 :     int entry_count;
     778                 :     EnvisatNameValue **entries;
     779                 : 
     780                 :     /*
     781                 :      * Select source list. 
     782                 :      */
     783               0 :     if( mph_or_sph == MPH )
     784                 :     {
     785               0 :         entry_count = self->mph_count;
     786               0 :         entries = self->mph_entries;
     787                 :     }
     788                 :     else
     789                 :     {
     790               0 :         entry_count = self->sph_count;
     791               0 :         entries = self->sph_entries;
     792                 :     }
     793                 : 
     794               0 :     if( key_index < 0 || key_index >= entry_count )
     795               0 :         return NULL;
     796                 :     else
     797               0 :         return entries[key_index]->key;
     798                 : }
     799                 : 
     800                 : /*-----------------------------------------------------------------------------
     801                 : 
     802                 : Name:
     803                 :     EnvisatFile_GetKeyValueAsString()
     804                 : 
     805                 : Purpose:
     806                 :     Fetch the value associated with the indicated key as a string.
     807                 : 
     808                 : Description:
     809                 : 
     810                 : Inputs:
     811                 :     self -- the file to be searched.
     812                 :     mph_or_sph -- Either MPH or SPH depending on the header to be searched.
     813                 :     key -- the key (name) to be searched for.
     814                 :     default_value -- the value to return if the key is not found.
     815                 : 
     816                 : Outputs:
     817                 : 
     818                 : Returns:
     819                 :     pointer to value string, or default_value if not found.
     820                 : 
     821                 : -----------------------------------------------------------------------------*/
     822                 : 
     823                 : const char *EnvisatFile_GetKeyValueAsString( EnvisatFile *self, 
     824                 :                                              EnvisatFile_HeaderFlag mph_or_sph,
     825                 :                                              const char *key,
     826                 :                                              const char *default_value )
     827                 : 
     828               0 : {
     829                 :     int entry_count, key_index;
     830                 :     EnvisatNameValue **entries;
     831                 : 
     832                 :     /*
     833                 :      * Select source list. 
     834                 :      */
     835               0 :     if( mph_or_sph == MPH )
     836                 :     {
     837               0 :         entry_count = self->mph_count;
     838               0 :         entries = self->mph_entries;
     839                 :     }
     840                 :     else
     841                 :     {
     842               0 :         entry_count = self->sph_count;
     843               0 :         entries = self->sph_entries;
     844                 :     }
     845                 : 
     846                 :     /*
     847                 :      * Find and return the value.
     848                 :      */
     849               0 :     key_index = S_NameValueList_FindKey( key, entry_count, entries );
     850               0 :     if( key_index == -1 )
     851               0 :         return default_value;
     852                 :     else
     853               0 :         return entries[key_index]->value;
     854                 : }
     855                 : 
     856                 : /*-----------------------------------------------------------------------------
     857                 : 
     858                 : Name:
     859                 :     EnvisatFile_SetKeyValueAsString()
     860                 : 
     861                 : Purpose:
     862                 :     Set the value associated with the indicated key as a string.
     863                 : 
     864                 : Description:
     865                 : 
     866                 : Inputs:
     867                 :     self -- the file to be searched.
     868                 :     mph_or_sph -- Either MPH or SPH depending on the header to be searched.
     869                 :     key -- the key (name) to be searched for.
     870                 :     value -- the value to assign.
     871                 : 
     872                 : Outputs:
     873                 : 
     874                 : Returns:
     875                 :     SUCCESS or FAILURE.
     876                 : 
     877                 : -----------------------------------------------------------------------------*/
     878                 : 
     879                 : int EnvisatFile_SetKeyValueAsString( EnvisatFile *self, 
     880                 :                                      EnvisatFile_HeaderFlag mph_or_sph,
     881                 :                                      const char *key,
     882                 :                                      const char *value )
     883                 : 
     884               0 : {
     885                 :     int entry_count, key_index;
     886                 :     EnvisatNameValue **entries;
     887                 : 
     888               0 :     if( !self->updatable )
     889                 :     {
     890               0 :         SendError( "File not opened for update access." );
     891               0 :         return FAILURE;
     892                 :     }
     893                 : 
     894                 :     /*
     895                 :      * Select source list. 
     896                 :      */
     897               0 :     if( mph_or_sph == MPH )
     898                 :     {
     899               0 :         entry_count = self->mph_count;
     900               0 :         entries = self->mph_entries;
     901                 :     }
     902                 :     else
     903                 :     {
     904               0 :         entry_count = self->sph_count;
     905               0 :         entries = self->sph_entries;
     906                 :     }
     907                 : 
     908                 :     /*
     909                 :      * Find and return the value.
     910                 :      */
     911               0 :     key_index = S_NameValueList_FindKey( key, entry_count, entries );
     912               0 :     if( key_index == -1 )
     913                 :     {
     914                 :         char  error_buf[2048];
     915                 : 
     916               0 :         sprintf( error_buf, 
     917                 :                  "Unable to set header field \"%s\", field not found.", 
     918                 :                  key );
     919                 : 
     920               0 :         SendError( error_buf );
     921               0 :         return FAILURE;
     922                 :     }
     923                 : 
     924               0 :     self->header_dirty = 1;
     925               0 :     if( strlen(value) > strlen(entries[key_index]->value) )
     926                 :     {
     927               0 :         strncpy( entries[key_index]->value, value, 
     928                 :                  strlen(entries[key_index]->value) );
     929                 :     }
     930                 :     else
     931                 :     {
     932               0 :         memset( entries[key_index]->value, ' ', 
     933                 :                 strlen(entries[key_index]->value) );
     934               0 :         strncpy( entries[key_index]->value, value, strlen(value) );
     935                 :     }
     936                 : 
     937               0 :     return SUCCESS;
     938                 : }
     939                 : 
     940                 : /*-----------------------------------------------------------------------------
     941                 : 
     942                 : Name:
     943                 :     EnvisatFile_GetKeyValueAsInt()
     944                 : 
     945                 : Purpose:
     946                 :     Fetch the value associated with the indicated key as an integer.
     947                 : 
     948                 : Description:
     949                 : 
     950                 : Inputs:
     951                 :     self -- the file to be searched.
     952                 :     mph_or_sph -- Either MPH or SPH depending on the header to be searched.
     953                 :     key -- the key (name) to be searched for.
     954                 :     default_value -- the value to return if the key is not found.
     955                 : 
     956                 : Outputs:
     957                 : 
     958                 : Returns:
     959                 :     key value, or default_value if key not found.
     960                 : 
     961                 : -----------------------------------------------------------------------------*/
     962                 : 
     963                 : int EnvisatFile_GetKeyValueAsInt( EnvisatFile *self, 
     964                 :                                   EnvisatFile_HeaderFlag mph_or_sph,
     965                 :                                   const char *key,
     966                 :                                   int default_value )
     967                 : 
     968               0 : {
     969                 :     int entry_count, key_index;
     970                 :     EnvisatNameValue **entries;
     971                 : 
     972                 :     /*
     973                 :      * Select source list. 
     974                 :      */
     975               0 :     if( mph_or_sph == MPH )
     976                 :     {
     977               0 :         entry_count = self->mph_count;
     978               0 :         entries = self->mph_entries;
     979                 :     }
     980                 :     else
     981                 :     {
     982               0 :         entry_count = self->sph_count;
     983               0 :         entries = self->sph_entries;
     984                 :     }
     985                 : 
     986                 :     /*
     987                 :      * Find and return the value.
     988                 :      */
     989               0 :     key_index = S_NameValueList_FindKey( key, entry_count, entries );
     990               0 :     if( key_index == -1 )
     991               0 :         return default_value;
     992                 :     else
     993               0 :         return atoi(entries[key_index]->value);
     994                 : }
     995                 : 
     996                 : /*-----------------------------------------------------------------------------
     997                 : 
     998                 : Name:
     999                 :     EnvisatFile_SetKeyValueAsInt()
    1000                 : 
    1001                 : Purpose:
    1002                 :     Set the value associated with the indicated key as an integer.
    1003                 : 
    1004                 : Description:
    1005                 : 
    1006                 : Inputs:
    1007                 :     self -- the file to be searched.
    1008                 :     mph_or_sph -- Either MPH or SPH depending on the header to be searched.
    1009                 :     key -- the key (name) to be searched for.
    1010                 :     value -- the value to assign.
    1011                 : 
    1012                 : Outputs:
    1013                 : 
    1014                 : Returns:
    1015                 :     SUCCESS or FAILURE.
    1016                 : 
    1017                 : -----------------------------------------------------------------------------*/
    1018                 : 
    1019                 : int EnvisatFile_SetKeyValueAsInt( EnvisatFile *self, 
    1020                 :                                   EnvisatFile_HeaderFlag mph_or_sph,
    1021                 :                                   const char *key,
    1022                 :                                   int value )
    1023                 : 
    1024               0 : {
    1025                 :     char format[32], string_value[128];
    1026                 :     const char *prototype_value;
    1027                 : 
    1028                 : 
    1029               0 :     prototype_value = EnvisatFile_GetKeyValueAsString( self, mph_or_sph, key, NULL);
    1030               0 :     if( prototype_value == NULL )
    1031                 :     {
    1032                 :         char  error_buf[2048];
    1033                 : 
    1034               0 :         sprintf( error_buf, 
    1035                 :                  "Unable to set header field \"%s\", field not found.", 
    1036                 :                  key );
    1037                 : 
    1038               0 :         SendError( error_buf );
    1039               0 :         return FAILURE;
    1040                 :     }
    1041                 : 
    1042               0 :     sprintf( format, "%%+0%dd", (int) strlen(prototype_value) );
    1043               0 :     sprintf( string_value, format, value );
    1044                 : 
    1045               0 :     return EnvisatFile_SetKeyValueAsString( self, mph_or_sph, key, string_value );
    1046                 : }
    1047                 : 
    1048                 : /*-----------------------------------------------------------------------------
    1049                 : 
    1050                 : Name:
    1051                 :     EnvisatFile_GetKeyValueAsDouble()
    1052                 : 
    1053                 : Purpose:
    1054                 :     Fetch the value associated with the indicated key as a double.
    1055                 : 
    1056                 : Description:
    1057                 : 
    1058                 : Inputs:
    1059                 :     self -- the file to be searched.
    1060                 :     mph_or_sph -- Either MPH or SPH depending on the header to be searched.
    1061                 :     key -- the key (name) to be searched for.
    1062                 :     default_value -- the value to return if the key is not found.
    1063                 : 
    1064                 : Outputs:
    1065                 : 
    1066                 : Returns:
    1067                 :     key value, or default_value if key not found.
    1068                 : 
    1069                 : -----------------------------------------------------------------------------*/
    1070                 : 
    1071                 : double EnvisatFile_GetKeyValueAsDouble( EnvisatFile *self, 
    1072                 :                                         EnvisatFile_HeaderFlag mph_or_sph,
    1073                 :                                         const char *key,
    1074                 :                                         double default_value )
    1075                 : 
    1076               0 : {
    1077                 :     int entry_count, key_index;
    1078                 :     EnvisatNameValue **entries;
    1079                 : 
    1080                 :     /*
    1081                 :      * Select source list. 
    1082                 :      */
    1083               0 :     if( mph_or_sph == MPH )
    1084                 :     {
    1085               0 :         entry_count = self->mph_count;
    1086               0 :         entries = self->mph_entries;
    1087                 :     }
    1088                 :     else
    1089                 :     {
    1090               0 :         entry_count = self->sph_count;
    1091               0 :         entries = self->sph_entries;
    1092                 :     }
    1093                 : 
    1094                 :     /*
    1095                 :      * Find and return the value.
    1096                 :      */
    1097               0 :     key_index = S_NameValueList_FindKey( key, entry_count, entries );
    1098               0 :     if( key_index == -1 )
    1099               0 :         return default_value;
    1100                 :     else
    1101               0 :         return atof(entries[key_index]->value);
    1102                 : }
    1103                 : 
    1104                 : /*-----------------------------------------------------------------------------
    1105                 : 
    1106                 : Name:
    1107                 :     EnvisatFile_SetKeyValueAsDouble()
    1108                 : 
    1109                 : Purpose:
    1110                 :     Set the value associated with the indicated key as a double.
    1111                 : 
    1112                 : Description:
    1113                 :     Note that this function attempts to format the new value similarly to
    1114                 :     the previous value.  In some cases (expecially exponential values) this 
    1115                 :     may not work out well.  In case of problems the caller is encourage to
    1116                 :     format the value themselves, and use the EnvisatFile_SetKeyValueAsString
    1117                 :     function, but taking extreme care about the string length.
    1118                 : 
    1119                 : Inputs:
    1120                 :     self -- the file to be searched.
    1121                 :     mph_or_sph -- Either MPH or SPH depending on the header to be searched.
    1122                 :     key -- the key (name) to be searched for.
    1123                 :     value -- the value to assign.
    1124                 : 
    1125                 : Outputs:
    1126                 : 
    1127                 : Returns:
    1128                 :     SUCCESS or FAILURE.
    1129                 : 
    1130                 : -----------------------------------------------------------------------------*/
    1131                 : 
    1132                 : int EnvisatFile_SetKeyValueAsDouble( EnvisatFile *self, 
    1133                 :                                      EnvisatFile_HeaderFlag mph_or_sph,
    1134                 :                                      const char *key,
    1135                 :                                      double value )
    1136                 : 
    1137               0 : {
    1138                 :     char format[32], string_value[128];
    1139                 :     const char *prototype_value;
    1140                 :     int   length;
    1141                 : 
    1142               0 :     prototype_value = EnvisatFile_GetKeyValueAsString( self, mph_or_sph, key, NULL);
    1143               0 :     if( prototype_value == NULL )
    1144                 :     {
    1145                 :         char  error_buf[2048];
    1146                 : 
    1147               0 :         sprintf( error_buf, 
    1148                 :                  "Unable to set header field \"%s\", field not found.", 
    1149                 :                  key );
    1150                 : 
    1151               0 :         SendError( error_buf );
    1152               0 :         return FAILURE;
    1153                 :     }
    1154                 : 
    1155               0 :     length = strlen(prototype_value);
    1156               0 :     if( prototype_value[length-4] == 'E' )
    1157                 :     {
    1158               0 :         sprintf( format, "%%+%dE", length-4 );
    1159               0 :         sprintf( string_value, format, value );
    1160                 :     }
    1161                 :     else
    1162                 :     {
    1163               0 :         int decimals = 0, i;
    1164               0 :         for( i = length-1; i > 0; i-- )
    1165                 :         {
    1166               0 :             if( prototype_value[i] == '.' )
    1167               0 :                 break;
    1168                 :             
    1169               0 :             decimals++;
    1170                 :         }
    1171                 : 
    1172               0 :         sprintf( format, "%%+0%d.%df", length, decimals );
    1173               0 :         sprintf( string_value, format, value );
    1174                 : 
    1175               0 :         if( (int)strlen(string_value) > length )
    1176               0 :             string_value[length] = '\0';
    1177                 :     }
    1178                 : 
    1179               0 :     return EnvisatFile_SetKeyValueAsString( self, mph_or_sph, key, string_value );
    1180                 : }
    1181                 : 
    1182                 : /*-----------------------------------------------------------------------------
    1183                 : 
    1184                 : Name:
    1185                 :     EnvisatFile_GetDatasetIndex()
    1186                 : 
    1187                 : Purpose:
    1188                 :     Fetch the datasat index give a dataset name.
    1189                 : 
    1190                 : Description:
    1191                 :     The provided name is extended with spaces, so it isn't necessary for the
    1192                 :     application to pass all the passing spaces.
    1193                 : 
    1194                 : Inputs:
    1195                 :     self -- the file to be searched.
    1196                 :     ds_name -- the name (DS_NAME) of the dataset to find.
    1197                 : 
    1198                 : Outputs:
    1199                 : 
    1200                 : Returns:
    1201                 :     Dataset index that matches, or -1 if none found.
    1202                 : 
    1203                 : -----------------------------------------------------------------------------*/
    1204                 : 
    1205                 : int EnvisatFile_GetDatasetIndex( EnvisatFile *self, const char *ds_name )
    1206                 : 
    1207               0 : {
    1208                 :     int   i;
    1209                 :     char  padded_ds_name[100];
    1210                 : 
    1211                 :     /* 
    1212                 :      * Padd the name.  While the normal product spec says the DS_NAME will
    1213                 :      * be 28 characters, I try to pad more than this incase the specification
    1214                 :      * is changed. 
    1215                 :      */
    1216               0 :     strcpy( padded_ds_name, ds_name );
    1217               0 :     for( i = strlen(padded_ds_name); i < sizeof(padded_ds_name)-1; i++ )
    1218                 :     {
    1219               0 :         padded_ds_name[i] = ' ';
    1220                 :     }
    1221               0 :     padded_ds_name[i] = '\0';
    1222                 : 
    1223                 :     /* 
    1224                 :      * Compare only for the full length of DS_NAME we have saved.
    1225                 :      */
    1226               0 :     for( i = 0; i < self->ds_count; i++ )
    1227                 :     {
    1228               0 :         if( strncmp( padded_ds_name, self->ds_info[i]->ds_name, 
    1229                 :                      strlen(self->ds_info[i]->ds_name) ) == 0 )
    1230                 :         {
    1231               0 :             return i;
    1232                 :         }
    1233                 :     }
    1234                 : 
    1235               0 :     return -1;
    1236                 : }
    1237                 : 
    1238                 : /*-----------------------------------------------------------------------------
    1239                 : 
    1240                 : Name:
    1241                 :     EnvisatFile_GetDatasetInfo()
    1242                 : 
    1243                 : Purpose:
    1244                 :     Fetch the information associated with a dataset definition.
    1245                 : 
    1246                 : Description:
    1247                 :     The returned strings are pointers to internal copies, and should not be
    1248                 :     modified, or freed.  Note, any of the "output" parameters can safely be
    1249                 :     NULL if it is not needed.
    1250                 : 
    1251                 : Inputs:
    1252                 :     self -- the file to be searched.
    1253                 :     ds_index -- the dataset index to fetch
    1254                 : 
    1255                 : Outputs:
    1256                 :     ds_name -- the dataset symbolic name, ie 'MDS1 SQ ADS              '.
    1257                 :     ds_type -- the dataset type, ie. 'A', not sure of valid values.
    1258                 :     filename -- dataset filename, normally spaces, or 'NOT USED          '.
    1259                 :     ds_offset -- the byte offset in the whole file to the first byte of 
    1260                 :                  dataset data.  This is 0 for unused datasets.
    1261                 :     ds_size -- the size, in bytes, of the whole dataset.
    1262                 :     num_dsr -- the number of records in the dataset.
    1263                 :     dsr_size -- the size of one record in the dataset in bytes, -1 if
    1264                 :                 records are variable sized.
    1265                 : 
    1266                 : Returns:
    1267                 :     SUCCESS if dataset exists, or FAILURE if ds_index is out of range.
    1268                 : 
    1269                 : -----------------------------------------------------------------------------*/
    1270                 : 
    1271                 : int EnvisatFile_GetDatasetInfo( EnvisatFile *self, 
    1272                 :                                 int ds_index, 
    1273                 :                                 char **ds_name, 
    1274                 :                                 char **ds_type,
    1275                 :                                 char **filename,
    1276                 :                                 int  *ds_offset,
    1277                 :                                 int  *ds_size,
    1278                 :                                 int  *num_dsr,
    1279                 :                                 int  *dsr_size )
    1280                 : 
    1281               0 : {
    1282               0 :     if( ds_index < 0 || ds_index >= self->ds_count )
    1283               0 :         return FAILURE;
    1284                 : 
    1285               0 :     if( ds_name != NULL )
    1286               0 :         *ds_name = self->ds_info[ds_index]->ds_name;
    1287               0 :     if( ds_type != NULL )
    1288               0 :         *ds_type = self->ds_info[ds_index]->ds_type;
    1289               0 :     if( filename != NULL )
    1290               0 :         *filename = self->ds_info[ds_index]->filename;
    1291               0 :     if( ds_offset != NULL )
    1292               0 :         *ds_offset = self->ds_info[ds_index]->ds_offset;
    1293               0 :     if( ds_size != NULL )
    1294               0 :         *ds_size = self->ds_info[ds_index]->ds_size;
    1295               0 :     if( num_dsr != NULL )
    1296               0 :         *num_dsr = self->ds_info[ds_index]->num_dsr;
    1297               0 :     if( dsr_size != NULL )
    1298               0 :         *dsr_size = self->ds_info[ds_index]->dsr_size;
    1299                 : 
    1300               0 :     return SUCCESS;
    1301                 : }
    1302                 : 
    1303                 : /*-----------------------------------------------------------------------------
    1304                 : 
    1305                 : Name:
    1306                 :     EnvisatFile_SetDatasetInfo()
    1307                 : 
    1308                 : Purpose:
    1309                 :     Update the information associated with a dataset definition.
    1310                 : 
    1311                 : Description:
    1312                 : 
    1313                 : Inputs:
    1314                 :     self -- the file to be searched.
    1315                 :     ds_index -- the dataset index to fetch
    1316                 :     ds_offset -- the byte offset in the whole file to the first byte of 
    1317                 :                  dataset data.  This is 0 for unused datasets.
    1318                 :     ds_size -- the size, in bytes, of the whole dataset.
    1319                 :     num_dsr -- the number of records in the dataset.
    1320                 :     dsr_size -- the size of one record in the dataset in bytes, -1 if
    1321                 :                 records are variable sized.
    1322                 : 
    1323                 : Outputs:
    1324                 : 
    1325                 : Returns:
    1326                 :     SUCCESS or FAILURE.
    1327                 : 
    1328                 : -----------------------------------------------------------------------------*/
    1329                 : 
    1330                 : int EnvisatFile_SetDatasetInfo( EnvisatFile *self, 
    1331                 :                                 int ds_index, 
    1332                 :                                 int ds_offset,
    1333                 :                                 int ds_size,
    1334                 :                                 int num_dsr,
    1335                 :                                 int dsr_size )
    1336                 : 
    1337               0 : {
    1338               0 :     if( ds_index < 0 || ds_index >= self->ds_count )
    1339               0 :         return FAILURE;
    1340                 : 
    1341               0 :     self->ds_info[ds_index]->ds_offset = ds_offset;
    1342               0 :     self->ds_info[ds_index]->ds_size = ds_size;
    1343               0 :     self->ds_info[ds_index]->num_dsr = num_dsr;
    1344               0 :     self->ds_info[ds_index]->dsr_size = dsr_size;
    1345               0 :     self->header_dirty = 1;
    1346                 : 
    1347               0 :     return SUCCESS;
    1348                 : }
    1349                 : 
    1350                 : 
    1351                 : /*-----------------------------------------------------------------------------
    1352                 : 
    1353                 : Name:
    1354                 :     EnvisatFile_ReadDatasetChunk()
    1355                 : 
    1356                 : Purpose:
    1357                 :     Read an arbitrary chunk of a dataset.
    1358                 : 
    1359                 : Description:
    1360                 :     Note that no range checking is made on offset and size, and data may be
    1361                 :     read from outside the dataset if they are inappropriate.
    1362                 : 
    1363                 : Inputs:
    1364                 :     self -- the file to be searched.
    1365                 :     ds_index -- the index of dataset to access.
    1366                 :     offset -- byte offset within database to read.
    1367                 :     size -- size of buffer to fill in bytes.
    1368                 :     buffer -- buffer to load data into
    1369                 : 
    1370                 : Outputs:
    1371                 :     buffer is updated on SUCCESS.
    1372                 : 
    1373                 : Returns:
    1374                 :     SUCCESS or FAILURE
    1375                 : 
    1376                 : -----------------------------------------------------------------------------*/
    1377                 : 
    1378                 : int EnvisatFile_ReadDatasetChunk( EnvisatFile *self, 
    1379                 :                                   int ds_index,
    1380                 :                                   int offset,
    1381                 :                                   int size,
    1382                 :                                   void * buffer )
    1383                 : 
    1384               0 : {
    1385               0 :     if( ds_index < 0 || ds_index >= self->ds_count )
    1386                 :     {
    1387               0 :         SendError( "Attempt to read non-existant dataset in "
    1388                 :                    "EnvisatFile_ReadDatasetChunk()" );
    1389               0 :         return FAILURE;
    1390                 :     }
    1391                 : 
    1392               0 :     if( offset < 0 
    1393                 :         || offset + size > self->ds_info[ds_index]->ds_size )
    1394                 :     {
    1395               0 :         SendError( "Attempt to read beyond end of dataset in "
    1396                 :                    "EnvisatFile_ReadDatasetChunk()" );
    1397               0 :         return FAILURE;
    1398                 :     }
    1399                 : 
    1400               0 :     if( fseek( self->fp, self->ds_info[ds_index]->ds_offset+offset, SEEK_SET )
    1401                 :         != 0 )
    1402                 :     {
    1403               0 :         SendError( "seek failed in EnvisatFile_ReadChunk()" );
    1404               0 :         return FAILURE;
    1405                 :     }
    1406                 : 
    1407               0 :     if( (int) fread( buffer, 1, size, self->fp ) != size )
    1408                 :     {
    1409               0 :         SendError( "read failed in EnvisatFile_ReadChunk()" );
    1410               0 :         return FAILURE;
    1411                 :     }
    1412                 : 
    1413               0 :     return SUCCESS;
    1414                 : }
    1415                 : 
    1416                 : /*-----------------------------------------------------------------------------
    1417                 : 
    1418                 : Name:
    1419                 :     EnvisatFile_WriteDatasetRecord()
    1420                 : 
    1421                 : Purpose:
    1422                 :     Write an arbitrary dataset record.
    1423                 : 
    1424                 : Description:
    1425                 :     Note that no range checking is made on offset and size, and data may be
    1426                 :     read from outside the dataset if they are inappropriate.
    1427                 : 
    1428                 : Inputs:
    1429                 :     self -- the file to be searched.
    1430                 :     ds_index -- the index of dataset to access.
    1431                 :     record_index -- the record to write.
    1432                 :     record_buffer -- buffer to load data into
    1433                 : 
    1434                 : Outputs:
    1435                 : 
    1436                 : Returns:
    1437                 :     SUCCESS or FAILURE
    1438                 : 
    1439                 : -----------------------------------------------------------------------------*/
    1440                 : 
    1441                 : int EnvisatFile_WriteDatasetRecord( EnvisatFile *self, 
    1442                 :                                     int ds_index,
    1443                 :                                     int record_index,
    1444                 :                                     void *buffer )
    1445                 : 
    1446               0 : {
    1447                 :     int   absolute_offset;
    1448                 :     int         result;
    1449                 : 
    1450               0 :     if( ds_index < 0 || ds_index >= self->ds_count )
    1451                 :     {
    1452               0 :         SendError( "Attempt to write non-existant dataset in "
    1453                 :                    "EnvisatFile_WriteDatasetRecord()" );
    1454               0 :         return FAILURE;
    1455                 :     }
    1456                 : 
    1457               0 :     if( record_index < 0
    1458                 :         || record_index >=  self->ds_info[ds_index]->num_dsr )
    1459                 :     {
    1460               0 :         SendError( "Attempt to write beyond end of dataset in "
    1461                 :                    "EnvisatFile_WriteDatasetRecord()" );
    1462               0 :         return FAILURE;
    1463                 :     }
    1464                 : 
    1465               0 :     absolute_offset = self->ds_info[ds_index]->ds_offset
    1466                 :         + record_index * self->ds_info[ds_index]->dsr_size;
    1467                 : 
    1468               0 :     if( fseek( self->fp, absolute_offset, SEEK_SET ) != 0 )
    1469                 :     {
    1470               0 :         SendError( "seek failed in EnvisatFile_WriteDatasetRecord()" );
    1471               0 :         return FAILURE;
    1472                 :     }
    1473                 : 
    1474               0 :     result = fwrite( buffer, 1, self->ds_info[ds_index]->dsr_size, self->fp );
    1475               0 :     if( result != self->ds_info[ds_index]->dsr_size )
    1476                 :     {
    1477               0 :         SendError( "write failed in EnvisatFile_WriteDatasetRecord()" );
    1478               0 :         return FAILURE;
    1479                 :     }
    1480                 : 
    1481               0 :     return SUCCESS;
    1482                 : }
    1483                 : 
    1484                 : /*-----------------------------------------------------------------------------
    1485                 : 
    1486                 : Name:
    1487                 :     EnvisatFile_ReadDatasetRecord()
    1488                 : 
    1489                 : Purpose:
    1490                 :     Read an arbitrary dataset record.
    1491                 : 
    1492                 : Description:
    1493                 :     Note that no range checking is made on offset and size, and data may be
    1494                 :     read from outside the dataset if they are inappropriate.
    1495                 : 
    1496                 : Inputs:
    1497                 :     self -- the file to be searched.
    1498                 :     ds_index -- the index of dataset to access.
    1499                 :     record_index -- the record to write.
    1500                 :     record_buffer -- buffer to load data into
    1501                 : 
    1502                 : Outputs:
    1503                 : 
    1504                 : Returns:
    1505                 :     SUCCESS or FAILURE
    1506                 : 
    1507                 : -----------------------------------------------------------------------------*/
    1508                 : 
    1509                 : int EnvisatFile_ReadDatasetRecord( EnvisatFile *self, 
    1510                 :                                     int ds_index,
    1511                 :                                     int record_index,
    1512                 :                                     void *buffer )
    1513                 : 
    1514               0 : {
    1515                 :     int   absolute_offset;
    1516                 :     int         result;
    1517                 : 
    1518               0 :     if( ds_index < 0 || ds_index >= self->ds_count )
    1519                 :     {
    1520               0 :         SendError( "Attempt to write non-existant dataset in "
    1521                 :                    "EnvisatFile_WriteDatasetRecord()" );
    1522               0 :         return FAILURE;
    1523                 :     }
    1524                 : 
    1525               0 :     if( record_index < 0
    1526                 :         || record_index >=  self->ds_info[ds_index]->num_dsr )
    1527                 :     {
    1528               0 :         SendError( "Attempt to write beyond end of dataset in "
    1529                 :                    "EnvisatFile_WriteDatasetRecord()" );
    1530               0 :         return FAILURE;
    1531                 :     }
    1532                 : 
    1533               0 :     absolute_offset = self->ds_info[ds_index]->ds_offset
    1534                 :         + record_index * self->ds_info[ds_index]->dsr_size;
    1535                 : 
    1536               0 :     if( fseek( self->fp, absolute_offset, SEEK_SET ) != 0 )
    1537                 :     {
    1538               0 :         SendError( "seek failed in EnvisatFile_WriteDatasetRecord()" );
    1539               0 :         return FAILURE;
    1540                 :     }
    1541                 : 
    1542               0 :     result = fread( buffer, 1, self->ds_info[ds_index]->dsr_size, self->fp );
    1543               0 :     if( result != self->ds_info[ds_index]->dsr_size )
    1544                 :     {
    1545               0 :         SendError( "read failed in EnvisatFile_ReadDatasetRecord()" );
    1546               0 :         return FAILURE;
    1547                 :     }
    1548                 : 
    1549               0 :     return SUCCESS;
    1550                 : }
    1551                 : 
    1552                 : /*-----------------------------------------------------------------------------
    1553                 : 
    1554                 : Name:
    1555                 :     S_NameValueList_FindKey()
    1556                 : 
    1557                 : Purpose:
    1558                 :     Search for given key in list of name/value pairs. 
    1559                 : 
    1560                 : Description:
    1561                 :     Scans list looking for index of EnvisatNameValue where the key matches
    1562                 :     (case sensitive) the passed in name. 
    1563                 : 
    1564                 : Inputs:
    1565                 :     key -- the key, such as "SLICE_POSITION" being searched for. 
    1566                 :     entry_count -- the number of items in the entries array.
    1567                 :     entries -- array of name/value structures to search. 
    1568                 : 
    1569                 : Outputs:
    1570                 : 
    1571                 : Returns:
    1572                 :     array index into entries, or -1 on failure. 
    1573                 : 
    1574                 : -----------------------------------------------------------------------------*/
    1575                 : 
    1576                 : int S_NameValueList_FindKey( const char *key, 
    1577                 :                              int entry_count, 
    1578                 :                              EnvisatNameValue **entries )
    1579                 : 
    1580               0 : {
    1581                 :     int   i;
    1582                 : 
    1583               0 :     for( i = 0; i < entry_count; i++ )
    1584                 :     {
    1585               0 :         if( strcmp(entries[i]->key,key) == 0 )
    1586               0 :             return i;
    1587                 :     }
    1588                 :     
    1589               0 :     return -1;
    1590                 : }
    1591                 : 
    1592                 : /*-----------------------------------------------------------------------------
    1593                 : 
    1594                 : Name:
    1595                 :     S_NameValueList_FindValue()
    1596                 : 
    1597                 : Purpose:
    1598                 :     Search for given key in list of name/value pairs, and return value.
    1599                 : 
    1600                 : Description:
    1601                 :     Returns value string or default if key not found.
    1602                 : 
    1603                 : Inputs:
    1604                 :     key -- the key, such as "SLICE_POSITION" being searched for. 
    1605                 :     entry_count -- the number of items in the entries array.
    1606                 :     entries -- array of name/value structures to search. 
    1607                 :     default_value -- value to use if key not found.
    1608                 : 
    1609                 : Outputs:
    1610                 : 
    1611                 : Returns:
    1612                 :     value string, or default if key not found.
    1613                 : 
    1614                 : -----------------------------------------------------------------------------*/
    1615                 : 
    1616                 : const char *S_NameValueList_FindValue( const char *key, 
    1617                 :                                        int entry_count, 
    1618                 :                                        EnvisatNameValue **entries,
    1619                 :                                        const char *default_value )
    1620                 : 
    1621               0 : {
    1622                 :     int   i;
    1623                 : 
    1624               0 :     i = S_NameValueList_FindKey( key, entry_count, entries );
    1625               0 :     if( i == -1 )
    1626               0 :         return default_value;
    1627                 :     else
    1628               0 :         return entries[i]->value;
    1629                 : }
    1630                 : 
    1631                 : /*-----------------------------------------------------------------------------
    1632                 : 
    1633                 : Name:
    1634                 :     S_NameValueList_Parse()
    1635                 : 
    1636                 : Purpose:
    1637                 :     Parse a block of envisat style name/value pairs into an
    1638                 :     EnvisatNameValue structure list. 
    1639                 : 
    1640                 : Description:
    1641                 :     The passed in text block should be zero terminated.  The entry_count, 
    1642                 :     and entries should be pre-initialized (normally to 0 and NULL).
    1643                 : 
    1644                 : Inputs:
    1645                 :     text -- the block of text, multiple lines, to be processed.
    1646                 : 
    1647                 : Outputs:
    1648                 :     entry_count -- returns with the updated number of entries in the
    1649                 :                    entries array.
    1650                 :     entries -- returns with updated array info structures. 
    1651                 : 
    1652                 : Returns:
    1653                 :     SUCCESS or FAILURE
    1654                 : 
    1655                 : -----------------------------------------------------------------------------*/
    1656                 : 
    1657                 : int S_NameValueList_Parse( const char *text, int text_offset, 
    1658                 :                            int *entry_count, 
    1659                 :                            EnvisatNameValue ***entries )
    1660                 : 
    1661               0 : {
    1662               0 :     const char  *next_text = text;
    1663                 : 
    1664                 :     /*
    1665                 :      * Loop over each input line in the text block.
    1666                 :      */
    1667               0 :     while( *next_text != '\0' )
    1668                 :     {
    1669                 :         char  line[1024];
    1670               0 :         int     line_len = 0, equal_index, src_char, line_offset;
    1671                 :         EnvisatNameValue *entry;
    1672                 : 
    1673                 :         /*
    1674                 :          * Extract one line of text into the "line" buffer, and remove the
    1675                 :          * newline character.  Eat leading spaces.
    1676                 :          */
    1677               0 :         while( *next_text == ' ' ) 
    1678                 :         {
    1679               0 :             next_text++;
    1680                 :         }
    1681               0 :         line_offset = (int) (next_text - text) + text_offset;
    1682               0 :         while( *next_text != '\0' && *next_text != '\n' )
    1683                 :         {
    1684               0 :             if( line_len > sizeof(line)-1 )
    1685                 :             {
    1686               0 :                 SendError( "S_NameValueList_Parse(): "
    1687                 :                            "Corrupt line, longer than 1024 characters." );
    1688               0 :                 return FAILURE;
    1689                 :             }
    1690                 : 
    1691               0 :             line[line_len++] = *(next_text++);
    1692                 :         }
    1693                 : 
    1694               0 :         line[line_len] = '\0';
    1695               0 :         if( *next_text == '\n' )
    1696               0 :             next_text++;
    1697                 : 
    1698                 :         /*
    1699                 :          * Blank lines are permitted.  We will skip processing of any line
    1700                 :          * that doesn't have an equal sign, under the assumption it is
    1701                 :          * white space.
    1702                 :          */
    1703               0 :         if( strstr( line, "=") == NULL )
    1704               0 :             continue;
    1705                 : 
    1706                 :         /*
    1707                 :          * Create the name/value info structure. 
    1708                 :          */
    1709               0 :         entry = (EnvisatNameValue *) calloc(sizeof(EnvisatNameValue),1);
    1710               0 :         entry->literal_line = strdup(line);
    1711                 : 
    1712                 :         /*
    1713                 :          * Capture the key.  We take everything up to the equal sign.  There
    1714                 :          * shouldn't be any white space, but if so, we take it as part of the
    1715                 :          * key.
    1716                 :          */
    1717               0 :         equal_index = strstr(line, "=") - line;
    1718               0 :         entry->key = (char *) malloc(equal_index+1);
    1719               0 :         strncpy( entry->key, line, equal_index );
    1720               0 :         entry->key[equal_index] = '\0';
    1721               0 :         entry->value_offset = line_offset + equal_index + 1;
    1722                 : 
    1723                 :         /*
    1724                 :          * If the next character after the equal sign is a double quote, then
    1725                 :          * the value is a string.  Suck out the text between the double quotes.
    1726                 :          */
    1727               0 :         if( line[equal_index+1] == '"' )
    1728                 :         {
    1729               0 :             for( src_char = equal_index + 2;
    1730               0 :                  line[src_char] != '\0' && line[src_char] != '"';
    1731               0 :                  src_char++ ) {}
    1732                 : 
    1733               0 :             line[src_char] = '\0';
    1734               0 :             entry->value = strdup( line + equal_index + 2 );
    1735               0 :             entry->value_offset += 1;
    1736                 :         }
    1737                 : 
    1738                 :         /*
    1739                 :          * The value is numeric, and may include a units field.
    1740                 :          */
    1741                 :         else
    1742                 :         {
    1743               0 :             for( src_char = equal_index + 1; 
    1744               0 :                  line[src_char] != '\0' && line[src_char] != '<' 
    1745                 :                      && line[src_char] != ' ';
    1746               0 :                  src_char++ ) {}
    1747                 : 
    1748                 :             /* capture units */
    1749               0 :             if( line[src_char] == '<' )
    1750                 :             {
    1751                 :                 int dst_char;
    1752                 : 
    1753               0 :                 for( dst_char = src_char+1; 
    1754               0 :                      line[dst_char] != '>' && line[dst_char] != '\0';
    1755               0 :                      dst_char++ ) {}
    1756                 : 
    1757               0 :                 line[dst_char] = '\0';
    1758               0 :                 entry->units = strdup( line + src_char + 1 );
    1759                 :             }
    1760                 : 
    1761               0 :             line[src_char] = '\0';
    1762               0 :             entry->value = strdup( line + equal_index + 1 );
    1763                 :         }
    1764                 : 
    1765                 :         /*
    1766                 :          * Add the entry to the name/value list. 
    1767                 :          */
    1768               0 :         if( entries == NULL )
    1769                 :         {
    1770               0 :             *entry_count = 1;
    1771               0 :             *entries = (EnvisatNameValue **) 
    1772                 :                 calloc( 1, sizeof(EnvisatNameValue) );
    1773                 :         }
    1774                 :         else
    1775                 :         {
    1776               0 :             (*entry_count)++;
    1777               0 :             *entries = (EnvisatNameValue **) 
    1778                 :                 realloc( *entries, *entry_count * sizeof(EnvisatNameValue*) );
    1779                 :         }
    1780                 : 
    1781               0 :         if( *entries == NULL )
    1782                 :         {
    1783               0 :             *entry_count = 0;
    1784               0 :             return FAILURE;
    1785                 :         }
    1786                 : 
    1787               0 :         (*entries)[*entry_count-1] = entry;
    1788                 :     }
    1789                 :     
    1790               0 :     return SUCCESS;
    1791                 : }
    1792                 : 
    1793                 : /*-----------------------------------------------------------------------------
    1794                 : 
    1795                 : Name:
    1796                 :     S_NameValueList_Rewrite()
    1797                 : 
    1798                 : Purpose:
    1799                 :     Rewrite the values of a name/value list in the file.
    1800                 : 
    1801                 : Description:
    1802                 : 
    1803                 : Inputs:
    1804                 :     fp -- the FILE to operate on.
    1805                 :     entry_count -- number of entries to write.
    1806                 :     entries -- array of entry descriptions.
    1807                 : 
    1808                 : Returns:
    1809                 :     SUCCESS or FAILURE
    1810                 : 
    1811                 : 
    1812                 : -----------------------------------------------------------------------------*/
    1813                 : 
    1814                 : int S_NameValueList_Rewrite( FILE * fp, int entry_count, 
    1815                 :                               EnvisatNameValue **entries )        
    1816                 : 
    1817               0 : {
    1818                 :     int   i;
    1819                 : 
    1820               0 :     for( i = 0; i < entry_count; i++ )
    1821                 :     {
    1822               0 :         EnvisatNameValue  *entry = entries[i];
    1823                 : 
    1824               0 :         if( fseek( fp, entry->value_offset, SEEK_SET ) != 0 )
    1825                 :         {
    1826               0 :             SendError( "fseek() failed writing name/value list." );
    1827               0 :             return FAILURE;
    1828                 :         }
    1829                 : 
    1830               0 :         if( fwrite( entry->value, 1, strlen(entry->value), fp ) != 
    1831                 :             strlen(entry->value) )
    1832                 :         {
    1833               0 :             SendError( "fwrite() failed writing name/value list." );
    1834               0 :             return FAILURE;
    1835                 :         }
    1836                 :     }
    1837                 : 
    1838               0 :     return SUCCESS;
    1839                 : }
    1840                 : 
    1841                 : 
    1842                 : /*-----------------------------------------------------------------------------
    1843                 : 
    1844                 : Name:
    1845                 :     S_NameValueList_Destroy()
    1846                 : 
    1847                 : Purpose:
    1848                 :     Free resources associated with a name/value list.
    1849                 : 
    1850                 : Description:
    1851                 :     The count, and name/value list pointers are set to 0/NULL on completion.
    1852                 : 
    1853                 : Inputs:
    1854                 :     entry_count -- returns with the updated number of entries in the
    1855                 :                    entries array.
    1856                 :     entries -- returns with updated array info structures. 
    1857                 : 
    1858                 : Outputs:
    1859                 :     entry_count -- Set to zero.
    1860                 :     entries -- Sett o NULL.
    1861                 : 
    1862                 : Returns:
    1863                 : 
    1864                 : 
    1865                 : -----------------------------------------------------------------------------*/
    1866                 : 
    1867                 : void S_NameValueList_Destroy( int *entry_count, 
    1868                 :                               EnvisatNameValue ***entries )       
    1869                 : 
    1870               0 : {
    1871                 :     int   i;
    1872                 : 
    1873               0 :     for( i = 0; i < *entry_count; i++ )
    1874                 :     {
    1875               0 :         free( (*entries)[i]->key );
    1876               0 :         free( (*entries)[i]->value );
    1877               0 :         free( (*entries)[i]->units );
    1878               0 :         free( (*entries)[i]->literal_line );
    1879               0 :         free( (*entries)[i] );
    1880                 :     }
    1881                 : 
    1882               0 :     free( *entries );
    1883                 :     
    1884               0 :     *entry_count = 0;
    1885               0 :     *entries = NULL;
    1886               0 : }
    1887                 : 
    1888                 : /* EOF */
    1889                 : 

Generated by: LTP GCOV extension version 1.5