LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/tiger - tigerfilebase.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 171
Code covered: 0.0 % Executed lines: 0

       1                 : /******************************************************************************
       2                 :  * $Id: tigerfilebase.cpp 17225 2009-06-07 20:59:19Z rouault $
       3                 :  *
       4                 :  * Project:  TIGER/Line Translator
       5                 :  * Purpose:  Implements TigerBaseFile class, providing common services to all
       6                 :  *           the tiger file readers.
       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 "ogr_tiger.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_error.h"
      34                 : #include "cpl_string.h"
      35                 : 
      36                 : CPL_CVSID("$Id: tigerfilebase.cpp 17225 2009-06-07 20:59:19Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                           TigerFileBase()                            */
      40                 : /************************************************************************/
      41                 : 
      42               0 : TigerFileBase::TigerFileBase()
      43                 : 
      44                 : {
      45               0 :     pszShortModule = NULL;
      46               0 :     pszModule = NULL;
      47               0 :     fpPrimary = NULL;
      48               0 :     poFeatureDefn = NULL;
      49               0 :     nFeatures = 0;
      50               0 :     nVersionCode = 0;
      51               0 :     nVersion = TIGER_Unknown;
      52               0 : }
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                           ~TigerFileBase()                           */
      56                 : /************************************************************************/
      57                 : 
      58               0 : TigerFileBase::~TigerFileBase()
      59                 : 
      60                 : {
      61               0 :     CPLFree( pszModule );
      62               0 :     CPLFree( pszShortModule );
      63                 : 
      64               0 :     if( poFeatureDefn != NULL )
      65                 :     {
      66               0 :         poFeatureDefn->Release();
      67               0 :         poFeatureDefn = NULL;
      68                 :     }
      69                 : 
      70               0 :     if( fpPrimary != NULL )
      71                 :     {
      72               0 :         VSIFClose( fpPrimary );
      73               0 :         fpPrimary = NULL;
      74                 :     }
      75               0 : }
      76                 : 
      77                 : /************************************************************************/
      78                 : /*                              OpenFile()                              */
      79                 : /************************************************************************/
      80                 : 
      81                 : int TigerFileBase::OpenFile( const char * pszModuleToOpen,
      82               0 :                              const char *pszExtension )
      83                 : 
      84                 : {
      85                 :     char        *pszFilename;
      86                 : 
      87               0 :     CPLFree( pszModule );
      88               0 :     pszModule = NULL;
      89               0 :     CPLFree( pszShortModule );
      90               0 :     pszShortModule = NULL;
      91                 :     
      92               0 :     if( fpPrimary != NULL )
      93                 :     {
      94               0 :         VSIFClose( fpPrimary );
      95               0 :         fpPrimary = NULL;
      96                 :     }
      97                 : 
      98               0 :     if( pszModuleToOpen == NULL )
      99               0 :         return TRUE;
     100                 : 
     101               0 :     pszFilename = poDS->BuildFilename( pszModuleToOpen, pszExtension );
     102                 : 
     103               0 :     fpPrimary = VSIFOpen( pszFilename, "rb" );
     104                 : 
     105               0 :     CPLFree( pszFilename );
     106                 : 
     107               0 :     if( fpPrimary != NULL )
     108                 :     {
     109               0 :         pszModule = CPLStrdup(pszModuleToOpen);
     110               0 :         pszShortModule = CPLStrdup(pszModuleToOpen);
     111               0 :         for( int i = 0; pszShortModule[i] != '\0'; i++ )
     112                 :         {
     113               0 :             if( pszShortModule[i] == '.' )
     114               0 :                 pszShortModule[i] = '\0';
     115                 :         }
     116                 : 
     117               0 :         SetupVersion();
     118                 : 
     119               0 :         return TRUE;
     120                 :     }
     121                 :     else
     122               0 :         return FALSE;
     123                 : }
     124                 : 
     125                 : /************************************************************************/
     126                 : /*                            SetupVersion()                            */
     127                 : /************************************************************************/
     128                 : 
     129               0 : void TigerFileBase::SetupVersion()
     130                 : 
     131                 : {
     132                 :     char        aszRecordHead[6];
     133                 : 
     134               0 :     VSIFSeek( fpPrimary, 0, SEEK_SET );
     135               0 :     VSIFRead( aszRecordHead, 1, 5, fpPrimary );
     136               0 :     aszRecordHead[5] = '\0';
     137               0 :     nVersionCode = atoi(aszRecordHead+1);
     138               0 :     VSIFSeek( fpPrimary, 0, SEEK_SET );
     139                 : 
     140               0 :     nVersion = TigerClassifyVersion( nVersionCode );
     141               0 : }
     142                 : 
     143                 : /************************************************************************/
     144                 : /*                       EstablishRecordLength()                        */
     145                 : /************************************************************************/
     146                 : 
     147               0 : int TigerFileBase::EstablishRecordLength( FILE * fp )
     148                 : 
     149                 : {
     150                 :     char        chCurrent;
     151               0 :     int         nRecLen = 0;
     152                 :     
     153               0 :     if( fp == NULL || VSIFSeek( fp, 0, SEEK_SET ) != 0 )
     154               0 :         return -1;
     155                 : 
     156                 : /* -------------------------------------------------------------------- */
     157                 : /*      Read through to the end of line.                                */
     158                 : /* -------------------------------------------------------------------- */
     159               0 :     chCurrent = '\0';
     160               0 :     while( VSIFRead( &chCurrent, 1, 1, fp ) == 1
     161                 :            && chCurrent != 10
     162                 :            && chCurrent != 13 )
     163                 :     {
     164               0 :         nRecLen++;
     165                 :     }
     166                 : 
     167                 : /* -------------------------------------------------------------------- */
     168                 : /*      Is the file zero length?                                        */
     169                 : /* -------------------------------------------------------------------- */
     170               0 :     if( nRecLen == 0 )
     171                 :     {
     172               0 :         return -1;
     173                 :     }
     174                 :     
     175               0 :     nRecLen++; /* for the 10 or 13 we encountered */
     176                 : 
     177                 : /* -------------------------------------------------------------------- */
     178                 : /*      Read through line terminator characters.  We are trying to      */
     179                 : /*      handle cases of CR, CR/LF and LF/CR gracefully.                 */
     180                 : /* -------------------------------------------------------------------- */
     181               0 :     while( VSIFRead( &chCurrent, 1, 1, fp ) == 1
     182                 :            && (chCurrent == 10 || chCurrent == 13 ) )
     183                 :     {
     184               0 :         nRecLen++;
     185                 :     }
     186                 : 
     187               0 :     VSIFSeek( fp, 0, SEEK_SET );
     188                 : 
     189               0 :     return nRecLen;
     190                 : }
     191                 : 
     192                 : /************************************************************************/
     193                 : /*                       EstablishFeatureCount()                        */
     194                 : /************************************************************************/
     195                 : 
     196               0 : void TigerFileBase::EstablishFeatureCount()
     197                 : 
     198                 : {
     199               0 :     if( fpPrimary == NULL )
     200               0 :         return;
     201                 : 
     202               0 :     nRecordLength = EstablishRecordLength( fpPrimary );
     203                 : 
     204               0 :     if( nRecordLength == -1 )
     205                 :     {
     206               0 :         nRecordLength = 1;
     207               0 :         nFeatures = 0;
     208               0 :         return;
     209                 :     }
     210                 : 
     211                 : /* -------------------------------------------------------------------- */
     212                 : /*      Now we think we know the fixed record length for the file       */
     213                 : /*      (including line terminators).  Get the total file size, and     */
     214                 : /*      divide by this length to get the presumed number of records.    */
     215                 : /* -------------------------------------------------------------------- */
     216                 :     long        nFileSize;
     217                 :     
     218               0 :     VSIFSeek( fpPrimary, 0, SEEK_END );
     219               0 :     nFileSize = VSIFTell( fpPrimary );
     220                 : 
     221               0 :     if( (nFileSize % nRecordLength) != 0 )
     222                 :     {
     223                 :         CPLError( CE_Warning, CPLE_FileIO,
     224                 :                   "TigerFileBase::EstablishFeatureCount(): "
     225                 :                   "File length %d doesn't divide by record length %d.\n",
     226               0 :                   (int) nFileSize, (int) nRecordLength );
     227                 :     }
     228                 : 
     229               0 :     nFeatures = nFileSize / nRecordLength;
     230                 : }
     231                 : 
     232                 : /************************************************************************/
     233                 : /*                              GetField()                              */
     234                 : /************************************************************************/
     235                 : 
     236                 : CPLString TigerFileBase::GetField( const char * pachRawDataRecord,
     237               0 :                                      int nStartChar, int nEndChar )
     238                 : 
     239                 : {
     240                 :     char         aszField[128];
     241               0 :     int                 nLength = nEndChar - nStartChar + 1;
     242                 :     
     243               0 :     CPLAssert( nEndChar - nStartChar + 2 < (int) sizeof(aszField) );
     244                 : 
     245               0 :     strncpy( aszField, pachRawDataRecord + nStartChar - 1, nLength );
     246                 : 
     247               0 :     aszField[nLength] = '\0';
     248               0 :     while( nLength > 0 && aszField[nLength-1] == ' ' )
     249               0 :         aszField[--nLength] = '\0';
     250                 : 
     251               0 :     return aszField;
     252                 : }
     253                 : 
     254                 : /************************************************************************/
     255                 : /*                              SetField()                              */
     256                 : /*                                                                      */
     257                 : /*      Set a field on an OGRFeature from a tiger record, or leave      */
     258                 : /*      NULL if the value isn't found.                                  */
     259                 : /************************************************************************/
     260                 : 
     261                 : void TigerFileBase::SetField( OGRFeature *poFeature, const char *pszField,
     262               0 :                               const char *pachRecord, int nStart, int nEnd )
     263                 : 
     264                 : {
     265               0 :     const char *pszFieldValue = GetField( pachRecord, nStart, nEnd );
     266                 : 
     267               0 :     if( pszFieldValue[0] == '\0' )
     268               0 :         return;
     269                 : 
     270               0 :     poFeature->SetField( pszField, pszFieldValue );
     271                 : }
     272                 : 
     273                 : /************************************************************************/
     274                 : /*                             WriteField()                             */
     275                 : /*                                                                      */
     276                 : /*      Write a field into a record buffer with the indicated           */
     277                 : /*      formatting, or leave blank if not found.                        */
     278                 : /************************************************************************/
     279                 : 
     280                 : int TigerFileBase::WriteField( OGRFeature *poFeature, const char *pszField, 
     281                 :                                char *pachRecord, int nStart, int nEnd, 
     282               0 :                                char chFormat, char chType )
     283                 : 
     284                 : {
     285               0 :     int         iField = poFeature->GetFieldIndex( pszField );
     286                 :     char        szValue[512], szFormat[32];
     287                 : 
     288               0 :     CPLAssert( nEnd - nStart + 1 < (int) sizeof(szValue)-1 );
     289                 : 
     290               0 :     if( iField < 0 || !poFeature->IsFieldSet( iField ) )
     291               0 :         return FALSE;
     292                 : 
     293               0 :     if( chType == 'N' && chFormat == 'L' )
     294                 :     {
     295               0 :         sprintf( szFormat, "%%0%dd", nEnd - nStart + 1 );
     296               0 :         sprintf( szValue, szFormat, poFeature->GetFieldAsInteger( iField ) );
     297                 :     }
     298               0 :     else if( chType == 'N' && chFormat == 'R' )
     299                 :     {
     300               0 :         sprintf( szFormat, "%%%dd", nEnd - nStart + 1 );
     301               0 :         sprintf( szValue, szFormat, poFeature->GetFieldAsInteger( iField ) );
     302                 :     }
     303               0 :     else if( chType == 'A' && chFormat == 'L' )
     304                 :     {
     305                 :         strncpy( szValue, poFeature->GetFieldAsString( iField ), 
     306               0 :                  sizeof(szValue) - 1 );
     307               0 :         if( (int) strlen(szValue) < nEnd - nStart + 1 )
     308                 :             memset( szValue + strlen(szValue), ' ', 
     309               0 :                     nEnd - nStart + 1 - strlen(szValue) );
     310                 :     }
     311               0 :     else if( chType == 'A' && chFormat == 'R' )
     312                 :     {
     313               0 :         sprintf( szFormat, "%%%ds", nEnd - nStart + 1 );
     314               0 :         sprintf( szValue, szFormat, poFeature->GetFieldAsString( iField ) );
     315                 :     }
     316                 :     else
     317                 :     {
     318               0 :         CPLAssert( FALSE );
     319               0 :         return FALSE;
     320                 :     }
     321                 : 
     322               0 :     strncpy( pachRecord + nStart - 1, szValue, nEnd - nStart + 1 );
     323                 : 
     324               0 :     return TRUE;
     325                 : }
     326                 : 
     327                 : /************************************************************************/
     328                 : /*                             WritePoint()                             */
     329                 : /************************************************************************/
     330                 : 
     331                 : int TigerFileBase::WritePoint( char *pachRecord, int nStart, 
     332               0 :                                double dfX, double dfY )
     333                 : 
     334                 : {
     335                 :     char        szTemp[20];
     336                 : 
     337               0 :     if( dfX == 0.0 && dfY == 0.0 )
     338                 :     {
     339               0 :         strncpy( pachRecord + nStart - 1, "+000000000+00000000", 19 );
     340                 :     }
     341                 :     else
     342                 :     {
     343                 :         sprintf( szTemp, "%+10d%+9d", 
     344                 :                  (int) floor(dfX * 1000000 + 0.5),
     345               0 :                  (int) floor(dfY * 1000000 + 0.5) );
     346               0 :         strncpy( pachRecord + nStart - 1, szTemp, 19 );
     347                 :     }
     348                 : 
     349               0 :     return TRUE;
     350                 : }
     351                 : 
     352                 : /************************************************************************/
     353                 : /*                            WriteRecord()                             */
     354                 : /************************************************************************/
     355                 : 
     356                 : int TigerFileBase::WriteRecord( char *pachRecord, int nRecLen, 
     357               0 :                                 const char *pszType, FILE * fp )
     358                 : 
     359                 : {
     360               0 :     if( fp == NULL )
     361               0 :         fp = fpPrimary;
     362                 : 
     363               0 :     pachRecord[0] = *pszType;
     364                 : 
     365                 : 
     366                 :     /*
     367                 :      * Prior to TIGER_2002, type 5 files lacked the version.  So write
     368                 :      * the version in the record iff we're using TIGER_2002 or higher,
     369                 :      * or if this is not type "5"
     370                 :      */
     371               0 :     if ( (poDS->GetVersion() >= TIGER_2002) ||
     372                 :          (!EQUAL(pszType, "5")) )
     373                 :     {
     374                 :         char    szVersion[5];
     375               0 :         sprintf( szVersion, "%04d", poDS->GetVersionCode() );
     376               0 :         strncpy( pachRecord + 1, szVersion, 4 );
     377                 :     }
     378                 : 
     379               0 :     VSIFWrite( pachRecord, nRecLen, 1, fp );
     380               0 :     VSIFWrite( (void *) "\r\n", 2, 1, fp );
     381                 : 
     382               0 :     return TRUE;
     383                 : }
     384                 : 
     385                 : /************************************************************************/
     386                 : /*                           SetWriteModule()                           */
     387                 : /*                                                                      */
     388                 : /*      Setup our access to be to the module indicated in the feature.  */
     389                 : /************************************************************************/
     390                 : 
     391                 : int TigerFileBase::SetWriteModule( const char *pszExtension, int nRecLen,
     392               0 :                                    OGRFeature *poFeature )
     393                 : 
     394                 : {
     395                 : /* -------------------------------------------------------------------- */
     396                 : /*      Work out what module we should be writing to.                   */
     397                 : /* -------------------------------------------------------------------- */
     398               0 :     const char *pszTargetModule = poFeature->GetFieldAsString( "MODULE" );
     399                 :     char        szFullModule[30];
     400                 : 
     401                 :     /* TODO/notdef: eventually more logic based on FILE and STATE/COUNTY can 
     402                 :        be inserted here. */
     403                 : 
     404               0 :     if( pszTargetModule == NULL )
     405               0 :         return FALSE;
     406                 : 
     407               0 :     sprintf( szFullModule, "%s.RT", pszTargetModule );
     408                 : 
     409                 : /* -------------------------------------------------------------------- */
     410                 : /*      Is this our current module?                                     */
     411                 : /* -------------------------------------------------------------------- */
     412               0 :     if( pszModule != NULL && EQUAL(szFullModule,pszModule) )
     413               0 :         return TRUE;
     414                 : 
     415                 : /* -------------------------------------------------------------------- */
     416                 : /*      Cleanup the previous file, if any.                              */
     417                 : /* -------------------------------------------------------------------- */
     418               0 :     if( fpPrimary != NULL )
     419                 :     {
     420               0 :         VSIFClose( fpPrimary );
     421               0 :         fpPrimary = NULL;
     422                 :     }
     423                 : 
     424               0 :     if( pszModule != NULL )
     425                 :     {
     426               0 :         CPLFree( pszModule );
     427               0 :         pszModule = NULL;
     428                 :     }
     429                 : 
     430                 : /* -------------------------------------------------------------------- */
     431                 : /*      Is this a module we have never written to before?  If so, we    */
     432                 : /*      will try to blow away any existing files in this file set.      */
     433                 : /* -------------------------------------------------------------------- */
     434               0 :     if( !poDS->CheckModule( szFullModule ) )
     435                 :     {
     436               0 :         poDS->DeleteModuleFiles( szFullModule );
     437               0 :         poDS->AddModule( szFullModule );
     438                 :     }
     439                 :     
     440                 : /* -------------------------------------------------------------------- */
     441                 : /*      Does this file already exist?                                   */
     442                 : /* -------------------------------------------------------------------- */
     443                 :     const char *pszFilename;
     444                 : 
     445               0 :     pszFilename = poDS->BuildFilename( szFullModule, pszExtension );
     446                 : 
     447               0 :     fpPrimary = VSIFOpen( pszFilename, "ab" );
     448               0 :     if( fpPrimary == NULL )
     449               0 :         return FALSE;
     450                 : 
     451               0 :     pszModule = CPLStrdup( szFullModule );
     452                 : 
     453               0 :     return TRUE;
     454                 : }
     455                 : 
     456                 : /************************************************************************/
     457                 : /*                           AddFieldDefns()                            */
     458                 : /************************************************************************/
     459                 : void TigerFileBase::AddFieldDefns(TigerRecordInfo *psRTInfo,
     460               0 :                                   OGRFeatureDefn  *poFeatureDefn)
     461                 : {
     462               0 :     OGRFieldDefn        oField("",OFTInteger);
     463                 :     int i, bLFieldHack;
     464                 : 
     465                 :     bLFieldHack = 
     466               0 :         CSLTestBoolean( CPLGetConfigOption( "TIGER_LFIELD_AS_STRING", "NO" ) );
     467                 :     
     468               0 :     for (i=0; i<psRTInfo->nFieldCount; ++i) {
     469               0 :         if (psRTInfo->pasFields[i].bDefine) {
     470               0 :             OGRFieldType eFT = psRTInfo->pasFields[i].OGRtype;
     471                 : 
     472               0 :             if( bLFieldHack 
     473                 :                 && psRTInfo->pasFields[i].cFmt == 'L' 
     474                 :                 && psRTInfo->pasFields[i].cType == 'N' )
     475               0 :                 eFT = OFTString;
     476                 : 
     477                 :             oField.Set( psRTInfo->pasFields[i].pszFieldName, eFT, 
     478               0 :                         psRTInfo->pasFields[i].nLen );
     479               0 :             poFeatureDefn->AddFieldDefn( &oField );
     480                 :         }
     481               0 :     }
     482               0 : }
     483                 : 
     484                 : /************************************************************************/
     485                 : /*                             SetFields()                              */
     486                 : /************************************************************************/
     487                 : 
     488                 : void TigerFileBase::SetFields(TigerRecordInfo *psRTInfo,
     489                 :                               OGRFeature      *poFeature,
     490               0 :                               char            *achRecord)
     491                 : {
     492                 :   int i;
     493               0 :   for (i=0; i<psRTInfo->nFieldCount; ++i) {
     494               0 :     if (psRTInfo->pasFields[i].bSet) {
     495                 :       SetField( poFeature,
     496                 :                 psRTInfo->pasFields[i].pszFieldName,
     497                 :                 achRecord, 
     498                 :                 psRTInfo->pasFields[i].nBeg,
     499               0 :                 psRTInfo->pasFields[i].nEnd );
     500                 :     }
     501                 :   }
     502               0 : }
     503                 : 
     504                 : /************************************************************************/
     505                 : /*                             WriteField()                             */
     506                 : /************************************************************************/
     507                 : void TigerFileBase::WriteFields(TigerRecordInfo *psRTInfo,
     508                 :                                 OGRFeature      *poFeature,
     509               0 :                                 char            *szRecord)
     510                 : {
     511                 :   int i;
     512               0 :   for (i=0; i<psRTInfo->nFieldCount; ++i) {
     513               0 :     if (psRTInfo->pasFields[i].bWrite) {
     514                 :       WriteField( poFeature,
     515                 :                   psRTInfo->pasFields[i].pszFieldName,
     516                 :                   szRecord, 
     517                 :                   psRTInfo->pasFields[i].nBeg,
     518                 :                   psRTInfo->pasFields[i].nEnd,
     519                 :                   psRTInfo->pasFields[i].cFmt,
     520               0 :                   psRTInfo->pasFields[i].cType );
     521                 :     }
     522                 :   }
     523               0 : }

Generated by: LTP GCOV extension version 1.5