LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/s57 - s57classregistrar.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 225 166 73.8 %
Date: 2012-04-28 Functions: 17 13 76.5 %

       1                 : /******************************************************************************
       2                 :  * $Id: s57classregistrar.cpp 22616 2011-06-29 19:19:03Z rouault $
       3                 :  *
       4                 :  * Project:  S-57 Translator
       5                 :  * Purpose:  Implements S57ClassRegistrar class for keeping track of
       6                 :  *           information on S57 object classes.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 1999, Frank Warmerdam
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "s57.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35                 : CPL_CVSID("$Id: s57classregistrar.cpp 22616 2011-06-29 19:19:03Z rouault $");
      36                 : 
      37                 : 
      38                 : #ifdef S57_BUILTIN_CLASSES
      39                 : #include "s57tables.h"
      40                 : #endif
      41                 : 
      42                 : /************************************************************************/
      43                 : /*                         S57ClassRegistrar()                          */
      44                 : /************************************************************************/
      45                 : 
      46               2 : S57ClassRegistrar::S57ClassRegistrar()
      47                 : 
      48                 : {
      49               2 :     nClasses = 0;
      50               2 :     papszClassesInfo = NULL;
      51                 :     
      52               2 :     iCurrentClass = -1;
      53                 : 
      54               2 :     papszCurrentFields = NULL;
      55               2 :     papszTempResult = NULL;
      56               2 :     papszNextLine = NULL;
      57               2 :     papapszClassesFields = NULL;
      58               2 :     pachAttrClass = NULL;
      59               2 :     pachAttrType = NULL;
      60               2 :     panAttrIndex = NULL;
      61               2 :     papszAttrNames = NULL;
      62               2 :     papszAttrAcronym = NULL;
      63               2 :     papapszAttrValues = NULL;
      64               2 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                         ~S57ClassRegistrar()                         */
      68                 : /************************************************************************/
      69                 : 
      70               2 : S57ClassRegistrar::~S57ClassRegistrar()
      71                 : 
      72                 : {
      73                 :     int i;
      74                 : 
      75               2 :     CSLDestroy( papszClassesInfo );
      76               2 :     CSLDestroy( papszTempResult );
      77                 :     
      78               2 :     if( papapszClassesFields != NULL )
      79                 :     {
      80             364 :         for( i = 0; i < nClasses; i++ )
      81             362 :             CSLDestroy( papapszClassesFields[i] );
      82               2 :         CPLFree( papapszClassesFields );
      83                 :     }
      84               2 :     if( papszAttrNames )
      85                 :     {
      86          131072 :         for( i = 0; i < MAX_ATTRIBUTES; i++ )
      87                 :         {
      88          131070 :             CPLFree( papszAttrNames[i] );
      89          131070 :             CPLFree( papszAttrAcronym[i] );
      90                 :         }
      91               2 :         CPLFree( papszAttrNames );
      92               2 :         CPLFree( papszAttrAcronym );
      93                 :     }
      94               2 :     CPLFree( pachAttrType );
      95               2 :     CPLFree( pachAttrClass );
      96               2 :     CPLFree( panAttrIndex );
      97               2 : }
      98                 : 
      99                 : /************************************************************************/
     100                 : /*                              FindFile()                              */
     101                 : /************************************************************************/
     102                 : 
     103               4 : int S57ClassRegistrar::FindFile( const char *pszTarget, 
     104                 :                                  const char *pszDirectory, 
     105                 :                                  int bReportErr,
     106                 :                                  FILE **pfp )
     107                 : 
     108                 : {
     109                 :     const char *pszFilename;
     110                 :     
     111               4 :     if( pszDirectory == NULL )
     112                 :     {
     113               4 :         pszFilename = CPLFindFile( "s57", pszTarget );
     114               4 :         if( pszFilename == NULL )
     115               0 :             pszFilename = pszTarget;
     116                 :     }
     117                 :     else
     118                 :     {
     119               0 :         pszFilename = CPLFormFilename( pszDirectory, pszTarget, NULL );
     120                 :     }
     121                 : 
     122               4 :     *pfp = VSIFOpen( pszFilename, "rb" );
     123                 : 
     124                 : #ifdef S57_BUILTIN_CLASSES
     125                 :     if( *pfp == NULL )
     126                 :     {
     127                 :         if( EQUAL(pszTarget, "s57objectclasses.csv") )
     128                 :             papszNextLine = gpapszS57Classes;
     129                 :         else
     130                 :             papszNextLine = gpapszS57attributes;
     131                 :     }
     132                 : #else
     133               4 :     if( *pfp == NULL )
     134                 :     {
     135               0 :         if( bReportErr )
     136                 :             CPLError( CE_Failure, CPLE_OpenFailed,
     137                 :                       "Failed to open %s.\n",
     138               0 :                       pszFilename );
     139               0 :         return FALSE;
     140                 :     }
     141                 : #endif
     142                 : 
     143               4 :     return TRUE;
     144                 : }
     145                 : 
     146                 : /************************************************************************/
     147                 : /*                              ReadLine()                              */
     148                 : /*                                                                      */
     149                 : /*      Read a line from the provided file, or from the "built-in"      */
     150                 : /*      configuration file line list if the file is NULL.               */
     151                 : /************************************************************************/
     152                 : 
     153             764 : const char *S57ClassRegistrar::ReadLine( FILE * fp )
     154                 : 
     155                 : {
     156             764 :     if( fp != NULL )
     157             764 :         return CPLReadLine( fp );
     158                 : 
     159               0 :     if( papszNextLine == NULL )
     160               0 :         return NULL;
     161                 : 
     162               0 :     if( *papszNextLine == NULL )
     163                 :     {
     164               0 :         papszNextLine = NULL;
     165               0 :         return NULL;
     166                 :     }
     167                 :     else
     168               0 :         return *(papszNextLine++);
     169                 : }
     170                 : 
     171                 : /************************************************************************/
     172                 : /*                              LoadInfo()                              */
     173                 : /************************************************************************/
     174                 : 
     175               2 : int S57ClassRegistrar::LoadInfo( const char * pszDirectory, 
     176                 :                                  const char * pszProfile,
     177                 :                                  int bReportErr )
     178                 : 
     179                 : {
     180                 :     FILE        *fp;
     181                 :     char        szTargetFile[1024];
     182                 : 
     183               2 :     if( pszDirectory == NULL )
     184               2 :         pszDirectory = CPLGetConfigOption("S57_CSV",NULL);
     185                 : 
     186                 : /* ==================================================================== */
     187                 : /*      Read the s57objectclasses file.                                 */
     188                 : /* ==================================================================== */
     189               2 :     if( pszProfile == NULL )
     190               2 :         pszProfile = CPLGetConfigOption( "S57_PROFILE", "" );
     191                 :     
     192               2 :     if( EQUAL(pszProfile, "Additional_Military_Layers") )
     193                 :     {
     194               0 :        sprintf( szTargetFile, "s57objectclasses_%s.csv", "aml" );
     195                 :     }
     196               2 :     else if ( EQUAL(pszProfile, "Inland_Waterways") )
     197                 :     {
     198               0 :        sprintf( szTargetFile, "s57objectclasses_%s.csv", "iw" );
     199                 :     }
     200               2 :     else if( strlen(pszProfile) > 0 )
     201                 :     {
     202               0 :        snprintf( szTargetFile, sizeof(szTargetFile), "s57objectclasses_%s.csv", pszProfile );
     203                 :     }
     204                 :     else
     205                 :     {
     206               2 :        strcpy( szTargetFile, "s57objectclasses.csv" );
     207                 :     }
     208                 : 
     209               2 :     if( !FindFile( szTargetFile, pszDirectory, bReportErr, &fp ) )
     210               0 :         return FALSE;
     211                 : 
     212                 : /* -------------------------------------------------------------------- */
     213                 : /*      Skip the line defining the column titles.                       */
     214                 : /* -------------------------------------------------------------------- */
     215               2 :     const char * pszLine = ReadLine( fp );
     216                 : 
     217               2 :     if( !EQUAL(pszLine,
     218                 :                "\"Code\",\"ObjectClass\",\"Acronym\",\"Attribute_A\","
     219                 :                "\"Attribute_B\",\"Attribute_C\",\"Class\",\"Primitives\"" ) )
     220                 :     {
     221                 :         CPLError( CE_Failure, CPLE_AppDefined,
     222               0 :                   "s57objectclasses columns don't match expected format!\n" );
     223               0 :         if( fp != NULL )
     224               0 :             VSIFClose( fp );
     225               0 :         return FALSE;
     226                 :     }
     227                 : 
     228                 : /* -------------------------------------------------------------------- */
     229                 : /*      Read and form string list.                                      */
     230                 : /* -------------------------------------------------------------------- */
     231                 :     
     232               2 :     CSLDestroy( papszClassesInfo );
     233               2 :     papszClassesInfo = (char **) CPLCalloc(sizeof(char *),MAX_CLASSES);
     234                 : 
     235               2 :     nClasses = 0;
     236                 : 
     237             366 :     while( nClasses < MAX_CLASSES
     238                 :            && (pszLine = ReadLine(fp)) != NULL )
     239                 :     {
     240             362 :         papszClassesInfo[nClasses] = CPLStrdup(pszLine);
     241             362 :         if( papszClassesInfo[nClasses] == NULL )
     242               0 :             break;
     243                 : 
     244             362 :         nClasses++;
     245                 :     }
     246                 : 
     247               2 :     if( nClasses == MAX_CLASSES )
     248                 :         CPLError( CE_Warning, CPLE_AppDefined,
     249               0 :                   "MAX_CLASSES exceeded in S57ClassRegistrar::LoadInfo().\n" );
     250                 : 
     251                 : /* -------------------------------------------------------------------- */
     252                 : /*      Cleanup, and establish state.                                   */
     253                 : /* -------------------------------------------------------------------- */
     254               2 :     if( fp != NULL )
     255               2 :         VSIFClose( fp );
     256               2 :     iCurrentClass = -1;
     257                 : 
     258               2 :     if( nClasses == 0 )
     259               0 :         return FALSE;
     260                 : 
     261                 : /* ==================================================================== */
     262                 : /*      Read the attributes list.                                       */
     263                 : /* ==================================================================== */
     264                 : 
     265               2 :     if( EQUAL(pszProfile, "Additional_Military_Layers") )
     266                 :     {
     267               0 :         sprintf( szTargetFile, "s57attributes_%s.csv", "aml" );
     268                 :     }
     269               2 :     else if ( EQUAL(pszProfile, "Inland_Waterways") )
     270                 :     {
     271               0 :        sprintf( szTargetFile, "s57attributes_%s.csv", "iw" );
     272                 :     }
     273               2 :     else if( strlen(pszProfile) > 0 )
     274                 :     {
     275               0 :        snprintf( szTargetFile, sizeof(szTargetFile), "s57attributes_%s.csv", pszProfile );
     276                 :     }
     277                 :     else
     278                 :     {
     279               2 :        strcpy( szTargetFile, "s57attributes.csv" );
     280                 :     }
     281                 :        
     282               2 :     if( !FindFile( szTargetFile, pszDirectory, bReportErr, &fp ) )
     283               0 :         return FALSE;
     284                 : 
     285                 : /* -------------------------------------------------------------------- */
     286                 : /*      Skip the line defining the column titles.                       */
     287                 : /* -------------------------------------------------------------------- */
     288               2 :     pszLine = ReadLine( fp );
     289                 : 
     290               2 :     if( !EQUAL(pszLine,
     291                 :           "\"Code\",\"Attribute\",\"Acronym\",\"Attributetype\",\"Class\"") )
     292                 :     {
     293                 :         CPLError( CE_Failure, CPLE_AppDefined,
     294               0 :                   "s57attributes columns don't match expected format!\n" );
     295               0 :         if( fp != NULL )
     296               0 :             VSIFClose( fp );
     297               0 :         return FALSE;
     298                 :     }
     299                 :     
     300                 : /* -------------------------------------------------------------------- */
     301                 : /*      Prepare arrays for the per-attribute information.               */
     302                 : /* -------------------------------------------------------------------- */
     303               2 :     nAttrMax = MAX_ATTRIBUTES-1;
     304               2 :     papszAttrNames = (char **) CPLCalloc(sizeof(char *),MAX_ATTRIBUTES);
     305               2 :     papszAttrAcronym = (char **) CPLCalloc(sizeof(char *),MAX_ATTRIBUTES);
     306                 :     //papapszAttrValues = (char ***) CPLCalloc(sizeof(char **),MAX_ATTRIBUTES);
     307               2 :     pachAttrType = (char *) CPLCalloc(sizeof(char),MAX_ATTRIBUTES);
     308               2 :     pachAttrClass = (char *) CPLCalloc(sizeof(char),MAX_ATTRIBUTES);
     309               2 :     panAttrIndex = (GUInt16 *) CPLCalloc(sizeof(GUInt16),MAX_ATTRIBUTES);
     310                 :     
     311                 : /* -------------------------------------------------------------------- */
     312                 : /*      Read and form string list.                                      */
     313                 : /* -------------------------------------------------------------------- */
     314                 :     GUInt16         iAttr;
     315                 :     
     316             398 :     while( (pszLine = ReadLine(fp)) != NULL )
     317                 :     {
     318                 :         char    **papszTokens = CSLTokenizeStringComplex( pszLine, ",",
     319             394 :                                                           TRUE, TRUE );
     320                 : 
     321             394 :         if( CSLCount(papszTokens) < 5 )
     322                 :         {
     323               0 :             CPLAssert( FALSE );
     324               0 :             continue;
     325                 :         }
     326                 :         
     327             394 :         iAttr = (GUInt16) atoi(papszTokens[0]);
     328             788 :         if( iAttr < 0 || iAttr >= nAttrMax
     329             394 :             || papszAttrNames[iAttr] != NULL )
     330                 :         {
     331                 :             CPLDebug( "S57", "Duplicate definition for attribute %d:%s", 
     332               0 :                       iAttr, papszTokens[2] );
     333               0 :             continue;
     334                 :         }
     335                 :         
     336             394 :         papszAttrNames[iAttr] = CPLStrdup(papszTokens[1]);
     337             394 :         papszAttrAcronym[iAttr] = CPLStrdup(papszTokens[2]);
     338             394 :         pachAttrType[iAttr] = papszTokens[3][0];
     339             394 :         pachAttrClass[iAttr] = papszTokens[4][0];
     340                 : 
     341             394 :         CSLDestroy( papszTokens );
     342                 :     }
     343                 : 
     344               2 :     if( fp != NULL )
     345               2 :         VSIFClose( fp );
     346                 :     
     347                 : /* -------------------------------------------------------------------- */
     348                 : /*      Build unsorted index of attributes.                             */
     349                 : /* -------------------------------------------------------------------- */
     350               2 :     nAttrCount = 0;
     351          131070 :     for( iAttr = 0; iAttr < nAttrMax; iAttr++ )
     352                 :     {
     353          131068 :         if( papszAttrAcronym[iAttr] != NULL )
     354             394 :             panAttrIndex[nAttrCount++] = iAttr;
     355                 :     }
     356                 : 
     357                 : /* -------------------------------------------------------------------- */
     358                 : /*      Sort index by acronym.                                          */
     359                 : /* -------------------------------------------------------------------- */
     360                 :     int         bModified;
     361                 : 
     362             378 :     do
     363                 :     {
     364             378 :         bModified = FALSE;
     365           74466 :         for( iAttr = 0; iAttr < nAttrCount-1; iAttr++ )
     366                 :         {
     367          222264 :             if( strcmp(papszAttrAcronym[panAttrIndex[iAttr]],
     368          148176 :                        papszAttrAcronym[panAttrIndex[iAttr+1]]) > 0 )
     369                 :             {
     370                 :                 GInt16     nTemp;
     371                 : 
     372            4004 :                 nTemp = panAttrIndex[iAttr];
     373            4004 :                 panAttrIndex[iAttr] = panAttrIndex[iAttr+1];
     374            4004 :                 panAttrIndex[iAttr+1] = nTemp;
     375                 : 
     376            4004 :                 bModified = TRUE;
     377                 :             }
     378                 :         }
     379                 :     } while( bModified );
     380                 :     
     381               2 :     return TRUE;
     382                 : }
     383                 : 
     384                 : /************************************************************************/
     385                 : /*                         SelectClassByIndex()                         */
     386                 : /************************************************************************/
     387                 : 
     388           31738 : int S57ClassRegistrar::SelectClassByIndex( int nNewIndex )
     389                 : 
     390                 : {
     391           31738 :     if( nNewIndex < 0 || nNewIndex >= nClasses )
     392               0 :         return FALSE;
     393                 : 
     394                 : /* -------------------------------------------------------------------- */
     395                 : /*      Do we have our cache of class information field lists?          */
     396                 : /* -------------------------------------------------------------------- */
     397           31738 :     if( papapszClassesFields == NULL )
     398                 :     {
     399               2 :         papapszClassesFields = (char ***) CPLCalloc(sizeof(void*),nClasses);
     400                 :     }
     401                 : 
     402                 : /* -------------------------------------------------------------------- */
     403                 : /*      Has this info been parsed yet?                                  */
     404                 : /* -------------------------------------------------------------------- */
     405           31738 :     if( papapszClassesFields[nNewIndex] == NULL )
     406             362 :         papapszClassesFields[nNewIndex] = 
     407             362 :             CSLTokenizeStringComplex( papszClassesInfo[nNewIndex],
     408             724 :                                       ",", TRUE, TRUE );
     409                 : 
     410           31738 :     papszCurrentFields = papapszClassesFields[nNewIndex];
     411                 : 
     412           31738 :     iCurrentClass = nNewIndex;
     413                 : 
     414           31738 :     return TRUE;
     415                 : }
     416                 : 
     417                 : /************************************************************************/
     418                 : /*                             SelectClass()                            */
     419                 : /************************************************************************/
     420                 : 
     421             694 : int S57ClassRegistrar::SelectClass( int nOBJL )
     422                 : 
     423                 : {
     424           92930 :     for( int i = 0; i < nClasses; i++ )
     425                 :     {
     426           92576 :         if( atoi(papszClassesInfo[i]) == nOBJL )
     427             340 :             return SelectClassByIndex( i );
     428                 :     }
     429                 : 
     430             354 :     return FALSE;
     431                 : }
     432                 : 
     433                 : /************************************************************************/
     434                 : /*                            SelectClass()                             */
     435                 : /************************************************************************/
     436                 : 
     437             356 : int S57ClassRegistrar::SelectClass( const char *pszAcronym )
     438                 : 
     439                 : {
     440           31414 :     for( int i = 0; i < nClasses; i++ )
     441                 :     {
     442           31398 :         if( !SelectClassByIndex( i ) )
     443               0 :             continue;
     444                 : 
     445           31398 :         if( strcmp(GetAcronym(),pszAcronym) == 0 )
     446             340 :             return TRUE;
     447                 :     }
     448                 : 
     449              16 :     return FALSE;
     450                 : }
     451                 : 
     452                 : /************************************************************************/
     453                 : /*                              GetOBJL()                               */
     454                 : /************************************************************************/
     455                 : 
     456             340 : int S57ClassRegistrar::GetOBJL()
     457                 : 
     458                 : {
     459             340 :     if( iCurrentClass >= 0 )
     460             340 :         return atoi(papszClassesInfo[iCurrentClass]);
     461                 :     else
     462               0 :         return -1;
     463                 : }
     464                 : 
     465                 : /************************************************************************/
     466                 : /*                           GetDescription()                           */
     467                 : /************************************************************************/
     468                 : 
     469               0 : const char * S57ClassRegistrar::GetDescription()
     470                 : 
     471                 : {
     472               0 :     if( iCurrentClass >= 0 && papszCurrentFields[0] != NULL )
     473               0 :         return papszCurrentFields[1];
     474                 :     else
     475               0 :         return NULL;
     476                 : }
     477                 : 
     478                 : /************************************************************************/
     479                 : /*                             GetAcronym()                             */
     480                 : /************************************************************************/
     481                 : 
     482           32158 : const char * S57ClassRegistrar::GetAcronym()
     483                 : 
     484                 : {
     485           96474 :     if( iCurrentClass >= 0 
     486           32158 :         && papszCurrentFields[0] != NULL 
     487           32158 :         && papszCurrentFields[1] != NULL )
     488           32158 :         return papszCurrentFields[2];
     489                 :     else
     490               0 :         return NULL;
     491                 : }
     492                 : 
     493                 : /************************************************************************/
     494                 : /*                          GetAttributeList()                          */
     495                 : /*                                                                      */
     496                 : /*      The passed string can be "a", "b", "c" or NULL for all.  The    */
     497                 : /*      returned list remained owned by this object, not the caller.    */
     498                 : /************************************************************************/
     499                 : 
     500             340 : char **S57ClassRegistrar::GetAttributeList( const char * pszType )
     501                 : 
     502                 : {
     503             340 :     if( iCurrentClass < 0 )
     504               0 :         return NULL;
     505                 :     
     506             340 :     CSLDestroy( papszTempResult );
     507             340 :     papszTempResult = NULL;
     508                 :     
     509            1360 :     for( int iColumn = 3; iColumn < 6; iColumn++ )
     510                 :     {
     511            1020 :         if( pszType != NULL && iColumn == 3 && !EQUAL(pszType,"a") )
     512               0 :             continue;
     513                 :         
     514            1020 :         if( pszType != NULL && iColumn == 4 && !EQUAL(pszType,"b") )
     515               0 :             continue;
     516                 :         
     517            1020 :         if( pszType != NULL && iColumn == 5 && !EQUAL(pszType,"c") )
     518               0 :             continue;
     519                 : 
     520                 :         char    **papszTokens;
     521                 : 
     522                 :         papszTokens =
     523            1020 :             CSLTokenizeStringComplex( papszCurrentFields[iColumn], ";",
     524            2040 :                                       TRUE, FALSE );
     525                 : 
     526                 :         papszTempResult = CSLInsertStrings( papszTempResult, -1,
     527            1020 :                                             papszTokens );
     528                 : 
     529            1020 :         CSLDestroy( papszTokens );
     530                 :     }
     531                 : 
     532             340 :     return papszTempResult;
     533                 : }
     534                 : 
     535                 : /************************************************************************/
     536                 : /*                            GetClassCode()                            */
     537                 : /************************************************************************/
     538                 : 
     539               0 : char S57ClassRegistrar::GetClassCode()
     540                 : 
     541                 : {
     542               0 :     if( iCurrentClass >= 0
     543               0 :         && papszCurrentFields[0] != NULL
     544               0 :         && papszCurrentFields[1] != NULL
     545               0 :         && papszCurrentFields[2] != NULL
     546               0 :         && papszCurrentFields[3] != NULL
     547               0 :         && papszCurrentFields[4] != NULL
     548               0 :         && papszCurrentFields[5] != NULL 
     549               0 :         && papszCurrentFields[6] != NULL )
     550               0 :         return papszCurrentFields[6][0];
     551                 :     else
     552               0 :         return '\0';
     553                 : }
     554                 : 
     555                 : /************************************************************************/
     556                 : /*                           GetPrimitives()                            */
     557                 : /************************************************************************/
     558                 : 
     559             340 : char **S57ClassRegistrar::GetPrimitives()
     560                 : 
     561                 : {
     562             340 :     if( iCurrentClass >= 0
     563                 :         && CSLCount(papszCurrentFields) > 7 )
     564                 :     {
     565             340 :         CSLDestroy( papszTempResult );
     566                 :         papszTempResult = 
     567             340 :             CSLTokenizeStringComplex( papszCurrentFields[7], ";",
     568             680 :                                       TRUE, FALSE );
     569             340 :         return papszTempResult;
     570                 :     }
     571                 :     else
     572               0 :         return NULL;
     573                 : }
     574                 : 
     575                 : /************************************************************************/
     576                 : /*                         FindAttrByAcronym()                          */
     577                 : /************************************************************************/
     578                 : 
     579            6822 : GInt16    S57ClassRegistrar::FindAttrByAcronym( const char * pszName )
     580                 : 
     581                 : {
     582                 :     int         iStart, iEnd, iCandidate;
     583                 : 
     584            6822 :     iStart = 0;
     585            6822 :     iEnd = nAttrCount-1;
     586                 : 
     587           53750 :     while( iStart <= iEnd )
     588                 :     {
     589                 :         int     nCompareValue;
     590                 :         
     591           46928 :         iCandidate = (iStart + iEnd)/2;
     592                 :         nCompareValue =
     593           46928 :             strcmp( pszName, papszAttrAcronym[panAttrIndex[iCandidate]] );
     594                 : 
     595           46928 :         if( nCompareValue < 0 )
     596                 :         {
     597           15160 :             iEnd = iCandidate-1;
     598                 :         }
     599           31768 :         else if( nCompareValue > 0 )
     600                 :         {
     601           24946 :             iStart = iCandidate+1;
     602                 :         }
     603                 :         else
     604            6822 :             return panAttrIndex[iCandidate];
     605                 :     }
     606                 : 
     607               0 :     return -1;
     608                 : }

Generated by: LCOV version 1.7