LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/rec - ogrreclayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 117 92 78.6 %
Date: 2012-12-26 Functions: 9 6 66.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrreclayer.cpp 25185 2012-10-27 19:40:46Z rouault $
       3                 :  *
       4                 :  * Project:  EPIInfo .REC Reader
       5                 :  * Purpose:  Implements OGRRECLayer class.
       6                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com>
      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                 : #include "ogr_rec.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ogrreclayer.cpp 25185 2012-10-27 19:40:46Z rouault $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /*                            OGRRECLayer()                             */
      38                 : /*                                                                      */
      39                 : /*      Note that the OGRRECLayer assumes ownership of the passed       */
      40                 : /*      file pointer.                                                   */
      41                 : /************************************************************************/
      42                 : 
      43               1 : OGRRECLayer::OGRRECLayer( const char *pszLayerNameIn, 
      44               1 :                           FILE * fp, int nFieldCountIn )
      45                 : 
      46                 : {
      47               1 :     fpREC = fp;
      48               1 :     bIsValid = FALSE;
      49               1 :     nStartOfData = 0;
      50                 : 
      51               1 :     nNextFID = 1;
      52                 : 
      53               1 :     poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn );
      54               1 :     poFeatureDefn->Reference();
      55                 : 
      56               1 :     nFieldCount = 0;
      57               1 :     panFieldOffset = (int *) CPLCalloc(sizeof(int),nFieldCountIn);
      58               1 :     panFieldWidth = (int *) CPLCalloc(sizeof(int),nFieldCountIn);
      59                 : 
      60                 : /* -------------------------------------------------------------------- */
      61                 : /*      Read field definition lines.                                    */
      62                 : /* -------------------------------------------------------------------- */
      63                 :     int         iField;
      64                 : 
      65               1 :     for( nFieldCount=0, iField = 0; iField < nFieldCountIn; iField++ )
      66                 :     {
      67               2 :         const char *pszLine = CPLReadLine( fp );
      68                 :         int         nTypeCode;
      69               2 :         OGRFieldType eFType = OFTString;
      70                 : 
      71               2 :         if( pszLine == NULL )
      72               0 :             return;
      73                 : 
      74               2 :         if( strlen(pszLine) < 44 )
      75               0 :             return;
      76                 : 
      77                 :         // Extract field width. 
      78               2 :         panFieldWidth[nFieldCount] = atoi( RECGetField( pszLine, 37, 4 ) );
      79               2 :         if( panFieldWidth[nFieldCount] < 0 )
      80               0 :             return;
      81                 : 
      82                 :         // Is this an real, integer or string field?  Default to string.
      83               2 :         nTypeCode = atoi(RECGetField(pszLine,33,4));
      84               2 :         if( nTypeCode == 12 )
      85               0 :             eFType = OFTInteger;
      86               2 :         else if( nTypeCode > 100 && nTypeCode < 120 )
      87                 :         {
      88               0 :             eFType = OFTReal;
      89                 :         }
      90               4 :         else if( nTypeCode == 0 || nTypeCode == 6 || nTypeCode == 102 )
      91                 :         {
      92               2 :             if( panFieldWidth[nFieldCount] < 3 )
      93               2 :                 eFType = OFTInteger;
      94                 :             else
      95               0 :                 eFType = OFTReal;
      96                 :         }
      97                 :         else
      98               0 :             eFType = OFTString;
      99                 : 
     100               2 :         OGRFieldDefn oField( RECGetField( pszLine, 2, 10 ), eFType );
     101                 : 
     102                 :         // Establish field offset. 
     103               2 :         if( nFieldCount > 0 )
     104               1 :             panFieldOffset[nFieldCount]
     105               1 :                 = panFieldOffset[nFieldCount-1] + panFieldWidth[nFieldCount-1];
     106                 : 
     107               2 :         if( nTypeCode > 100 && nTypeCode < 120 )
     108                 :         {
     109               0 :             oField.SetWidth( panFieldWidth[nFieldCount] );
     110               0 :             oField.SetPrecision( nTypeCode - 100 );
     111                 :         }
     112               2 :         else if( eFType == OFTReal )
     113                 :         {
     114               0 :             oField.SetWidth( panFieldWidth[nFieldCount]*2 );
     115               0 :             oField.SetPrecision( panFieldWidth[nFieldCount]-1 );
     116                 :         }
     117                 :         else
     118               2 :             oField.SetWidth( panFieldWidth[nFieldCount] );
     119                 : 
     120                 :         // Skip fields that are only screen labels.
     121               2 :         if( panFieldWidth[nFieldCount] == 0 )
     122               0 :             continue;
     123                 : 
     124               2 :         poFeatureDefn->AddFieldDefn( &oField );
     125               2 :         nFieldCount++;
     126                 :     }
     127                 : 
     128               1 :     if( nFieldCount == 0 )
     129               0 :         return;
     130                 : 
     131               1 :     nRecordLength = panFieldOffset[nFieldCount-1]+panFieldWidth[nFieldCount-1];
     132               1 :     bIsValid = TRUE;
     133                 : 
     134               1 :     nStartOfData = VSIFTell( fp );
     135               0 : }
     136                 : 
     137                 : /************************************************************************/
     138                 : /*                           ~OGRRECLayer()                           */
     139                 : /************************************************************************/
     140                 : 
     141               1 : OGRRECLayer::~OGRRECLayer()
     142                 : 
     143                 : {
     144               1 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
     145                 :     {
     146                 :         CPLDebug( "REC", "%d features read on layer '%s'.",
     147                 :                   (int) m_nFeaturesRead, 
     148               1 :                   poFeatureDefn->GetName() );
     149                 :     }
     150                 :     
     151               1 :     if( fpREC != NULL )
     152               1 :         VSIFClose( fpREC );
     153                 : 
     154               1 :     if( poFeatureDefn )
     155               1 :         poFeatureDefn->Release();
     156                 : 
     157               1 :     CPLFree( panFieldOffset );
     158               1 :     CPLFree( panFieldWidth );
     159               1 : }
     160                 : 
     161                 : /************************************************************************/
     162                 : /*                            ResetReading()                            */
     163                 : /************************************************************************/
     164                 : 
     165              33 : void OGRRECLayer::ResetReading()
     166                 : 
     167                 : {
     168              33 :     VSIFSeek( fpREC, nStartOfData, SEEK_SET );
     169              33 :     nNextFID = 1;
     170              33 : }
     171                 : 
     172                 : /************************************************************************/
     173                 : /*                      GetNextUnfilteredFeature()                      */
     174                 : /************************************************************************/
     175                 : 
     176              48 : OGRFeature * OGRRECLayer::GetNextUnfilteredFeature()
     177                 : 
     178                 : {
     179                 : /* -------------------------------------------------------------------- */
     180                 : /*      Read and assemble the source data record.                       */
     181                 : /* -------------------------------------------------------------------- */
     182              48 :     int        nDataLen = 0;
     183              48 :     char       *pszRecord = (char *) CPLMalloc(nRecordLength + 2 );
     184                 : 
     185             129 :     while( nDataLen < nRecordLength )
     186                 :     {
     187              48 :         const char *pszLine = CPLReadLine( fpREC );
     188                 :         int         iSegLen;
     189                 : 
     190              48 :         if( pszLine == NULL )
     191                 :         {
     192              15 :             CPLFree( pszRecord );
     193              15 :             return NULL;
     194                 :         }
     195                 : 
     196              33 :         if( *pszLine == 0 || *pszLine == 26 /* Cntl-Z - DOS EOF */ )
     197                 :         {
     198               0 :             CPLFree( pszRecord );
     199               0 :             return NULL;
     200                 :         }
     201                 : 
     202                 :         // If the end-of-line markers is '?' the record is deleted.
     203              33 :         iSegLen = strlen(pszLine);
     204              33 :         if( pszLine[iSegLen-1] == '?' )
     205                 :         {
     206               0 :             pszRecord[0] = '\0';
     207               0 :             nDataLen = 0;
     208               0 :             continue;
     209                 :         }
     210                 : 
     211                 :         // Strip off end-of-line '!' marker. 
     212              66 :         if( pszLine[iSegLen-1] != '!' 
     213              33 :             && pszLine[iSegLen-1] != '^' )
     214                 :         {
     215                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     216                 :                       "Apparent corrupt data line .. record FID=%d", 
     217               0 :                       nNextFID );
     218               0 :             CPLFree( pszRecord );
     219               0 :             return NULL;
     220                 :         }
     221                 : 
     222              33 :         iSegLen--;
     223              33 :         if( nDataLen + iSegLen > nRecordLength )
     224                 :         {
     225                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     226                 :                       "Too much data for record %d.", 
     227               0 :                       nNextFID );
     228               0 :             CPLFree( pszRecord );
     229               0 :             return NULL;
     230                 :         }
     231                 : 
     232              33 :         strncpy( pszRecord+nDataLen, pszLine, iSegLen );
     233              33 :         pszRecord[nDataLen+iSegLen] = '\0';
     234              33 :         nDataLen += iSegLen;
     235                 :     }
     236                 : 
     237                 : /* -------------------------------------------------------------------- */
     238                 : /*      Create the OGR feature.                                         */
     239                 : /* -------------------------------------------------------------------- */
     240                 :     OGRFeature *poFeature;
     241                 : 
     242              33 :     poFeature = new OGRFeature( poFeatureDefn );
     243                 : 
     244                 : /* -------------------------------------------------------------------- */
     245                 : /*      Set attributes for any indicated attribute records.             */
     246                 : /* -------------------------------------------------------------------- */
     247                 :     int         iAttr;
     248                 :     
     249              99 :     for( iAttr = 0; iAttr < nFieldCount; iAttr++)
     250                 :     {
     251                 :         const char *pszFieldText = 
     252                 :             RECGetField( pszRecord, 
     253              66 :                          panFieldOffset[iAttr] + 1,
     254             132 :                          panFieldWidth[iAttr] );
     255                 : 
     256              66 :         if( strlen(pszFieldText) != 0 )
     257              66 :             poFeature->SetField( iAttr, pszFieldText );
     258                 :     }
     259                 :     
     260                 : /* -------------------------------------------------------------------- */
     261                 : /*      Translate the record id.                                        */
     262                 : /* -------------------------------------------------------------------- */
     263              33 :     poFeature->SetFID( nNextFID++ );
     264              33 :     m_nFeaturesRead++;
     265                 : 
     266              33 :     CPLFree( pszRecord );
     267                 : 
     268              33 :     return poFeature;
     269                 : }
     270                 : 
     271                 : 
     272                 : /************************************************************************/
     273                 : /*                           GetNextFeature()                           */
     274                 : /************************************************************************/
     275                 : 
     276              43 : OGRFeature *OGRRECLayer::GetNextFeature()
     277                 : 
     278                 : {
     279              43 :     OGRFeature  *poFeature = NULL;
     280                 :     
     281                 : /* -------------------------------------------------------------------- */
     282                 : /*      Read features till we find one that satisfies our current       */
     283                 : /*      spatial criteria.                                               */
     284                 : /* -------------------------------------------------------------------- */
     285               5 :     while( TRUE )
     286                 :     {
     287              48 :         poFeature = GetNextUnfilteredFeature();
     288              48 :         if( poFeature == NULL )
     289              15 :             break;
     290                 : 
     291              33 :         if( m_poAttrQuery == NULL || m_poAttrQuery->Evaluate( poFeature ) )
     292              28 :             break;
     293                 : 
     294               5 :         delete poFeature;
     295                 :     }
     296                 : 
     297              43 :     return poFeature;
     298                 : }
     299                 : 
     300                 : /************************************************************************/
     301                 : /*                           TestCapability()                           */
     302                 : /************************************************************************/
     303                 : 
     304               8 : int OGRRECLayer::TestCapability( const char * pszCap )
     305                 : 
     306                 : {
     307               8 :     return FALSE;
     308                 : }
     309                 : 

Generated by: LCOV version 1.7