LCOV - code coverage report
Current view: directory - apps - test_ogrsf.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 626 459 73.3 %
Date: 2011-12-18 Functions: 12 11 91.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: test_ogrsf.cpp 23539 2011-12-11 23:50:43Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Formal test harnass for OGRLayer implementations.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      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 "ogrsf_frmts.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "ogr_api.h"
      33                 : #include "ogr_p.h"
      34                 : 
      35                 : CPL_CVSID("$Id: test_ogrsf.cpp 23539 2011-12-11 23:50:43Z rouault $");
      36                 : 
      37                 : int     bReadOnly = FALSE;
      38                 : int     bVerbose = TRUE;
      39                 : 
      40                 : static void Usage();
      41                 : static int TestOGRLayer( OGRDataSource * poDS, OGRLayer * poLayer, int bIsSQLLayer );
      42                 : static int TestInterleavedReading( const char* pszDataSource, char** papszLayers );
      43                 : 
      44                 : /************************************************************************/
      45                 : /*                                main()                                */
      46                 : /************************************************************************/
      47                 : 
      48              23 : int main( int nArgc, char ** papszArgv )
      49                 : 
      50                 : {
      51              23 :     const char  *pszDataSource = NULL;
      52              23 :     char** papszLayers = NULL;
      53              23 :     const char  *pszSQLStatement = NULL;
      54              23 :     int bRet = TRUE;
      55                 : 
      56                 :     /* Must process OGR_SKIP before OGRRegisterAll(), but we can't call */
      57                 :     /* OGRGeneralCmdLineProcessor before it needs the drivers to be registered */
      58                 :     /* for the --format or --formats options */
      59              75 :     for( int iArg = 1; iArg < nArgc; iArg++ )
      60                 :     {
      61              57 :         if( EQUAL(papszArgv[iArg], "--config") && iArg + 2 < nArgc &&
      62               3 :             EQUAL(papszArgv[iArg+1], "OGR_SKIP") )
      63                 :         {
      64               2 :             CPLSetConfigOption(papszArgv[iArg+1], papszArgv[iArg+2]);
      65               2 :             break;
      66                 :         }
      67                 :     }
      68                 :     
      69                 : /* -------------------------------------------------------------------- */
      70                 : /*      Register format(s).                                             */
      71                 : /* -------------------------------------------------------------------- */
      72              23 :     OGRRegisterAll();
      73                 : 
      74                 : /* -------------------------------------------------------------------- */
      75                 : /*      Processing command line arguments.                              */
      76                 : /* -------------------------------------------------------------------- */
      77              23 :     nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
      78                 : 
      79              23 :     if( nArgc < 1 )
      80               0 :         exit( -nArgc );
      81                 : 
      82                 : /* -------------------------------------------------------------------- */
      83                 : /*      Processing command line arguments.                              */
      84                 : /* -------------------------------------------------------------------- */
      85              71 :     for( int iArg = 1; iArg < nArgc; iArg++ )
      86                 :     {
      87              49 :         if( EQUAL(papszArgv[iArg], "--utility_version") )
      88                 :         {
      89                 :             printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
      90               1 :                    papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
      91               1 :             return 0;
      92                 :         }
      93              48 :         else if( EQUAL(papszArgv[iArg],"-ro") )
      94              12 :             bReadOnly = TRUE;
      95              36 :         else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet"))
      96               0 :             bVerbose = FALSE;
      97              40 :         else if( EQUAL(papszArgv[iArg],"-sql") && iArg + 1 < nArgc)
      98               4 :             pszSQLStatement = papszArgv[++iArg];
      99              32 :         else if( papszArgv[iArg][0] == '-' )
     100                 :         {
     101               0 :             Usage();
     102                 :         }
     103              32 :         else if (pszDataSource == NULL)
     104              22 :             pszDataSource = papszArgv[iArg];
     105                 :         else
     106              10 :             papszLayers = CSLAddString(papszLayers, papszArgv[iArg]);
     107                 :     }
     108                 : 
     109              22 :     if( pszDataSource == NULL )
     110               0 :         Usage();
     111                 : 
     112                 : /* -------------------------------------------------------------------- */
     113                 : /*      Open data source.                                               */
     114                 : /* -------------------------------------------------------------------- */
     115                 :     OGRDataSource       *poDS;
     116                 :     OGRSFDriver         *poDriver;
     117                 : 
     118              22 :     poDS = OGRSFDriverRegistrar::Open( pszDataSource, !bReadOnly, &poDriver );
     119              22 :     if( poDS == NULL && !bReadOnly )
     120                 :     {
     121               0 :         poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, &poDriver );
     122               0 :         if( poDS != NULL && bVerbose )
     123                 :         {
     124               0 :             printf( "Had to open data source read-only.\n" );
     125               0 :             bReadOnly = TRUE;
     126                 :         }
     127                 :     }
     128                 : 
     129                 : /* -------------------------------------------------------------------- */
     130                 : /*      Report failure                                                  */
     131                 : /* -------------------------------------------------------------------- */
     132              22 :     if( poDS == NULL )
     133                 :     {
     134               0 :         OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
     135                 :         
     136                 :         printf( "FAILURE:\n"
     137                 :                 "Unable to open datasource `%s' with the following drivers.\n",
     138               0 :                 pszDataSource );
     139                 : 
     140               0 :         for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
     141                 :         {
     142               0 :             printf( "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
     143                 :         }
     144                 : 
     145               0 :         exit( 1 );
     146                 :     }
     147                 : 
     148                 : /* -------------------------------------------------------------------- */
     149                 : /*      Some information messages.                                      */
     150                 : /* -------------------------------------------------------------------- */
     151              22 :     if( bVerbose )
     152                 :         printf( "INFO: Open of `%s' using driver `%s' successful.\n",
     153              22 :                 pszDataSource, poDriver->GetName() );
     154                 : 
     155              22 :     if( bVerbose && !EQUAL(pszDataSource,poDS->GetName()) )
     156                 :     {
     157                 :         printf( "INFO: Internal data source name `%s'\n"
     158                 :                 "      different from user name `%s'.\n",
     159               0 :                 poDS->GetName(), pszDataSource );
     160                 :     }
     161                 :     
     162                 : /* -------------------------------------------------------------------- */
     163                 : /*      Process optionnal SQL request.                                  */
     164                 : /* -------------------------------------------------------------------- */
     165              22 :     if (pszSQLStatement != NULL)
     166                 :     {
     167               4 :         OGRLayer  *poResultSet = poDS->ExecuteSQL(pszSQLStatement, NULL, NULL);
     168               4 :         if (poResultSet == NULL)
     169               0 :             exit(1);
     170                 :             
     171                 :         printf( "INFO: Testing layer %s.\n",
     172               4 :                     poResultSet->GetName() );
     173               4 :         bRet = TestOGRLayer( poDS, poResultSet, TRUE );
     174                 :         
     175               4 :         poDS->ReleaseResultSet(poResultSet);
     176                 :     }
     177                 : /* -------------------------------------------------------------------- */
     178                 : /*      Process each data source layer.                                 */
     179                 : /* -------------------------------------------------------------------- */
     180              18 :     else if (papszLayers == NULL)
     181                 :     {
     182              76 :         for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
     183                 :         {
     184              63 :             OGRLayer        *poLayer = poDS->GetLayer(iLayer);
     185                 : 
     186              63 :             if( poLayer == NULL )
     187                 :             {
     188                 :                 printf( "FAILURE: Couldn't fetch advertised layer %d!\n",
     189               0 :                         iLayer );
     190               0 :                 exit( 1 );
     191                 :             }
     192                 : 
     193                 :             printf( "INFO: Testing layer %s.\n",
     194              63 :                     poLayer->GetName() );
     195              63 :             bRet &= TestOGRLayer( poDS, poLayer, FALSE );
     196                 :         }
     197                 : 
     198              13 :         if (poDS->GetLayerCount() >= 2)
     199                 :         {
     200               7 :             OGRDataSource::DestroyDataSource(poDS);
     201               7 :             poDS = NULL;
     202               7 :             bRet &= TestInterleavedReading( pszDataSource, NULL );
     203                 :         }
     204                 :     }
     205                 :     else
     206                 :     {
     207                 : /* -------------------------------------------------------------------- */
     208                 : /*      Or process layers specified by the user                         */
     209                 : /* -------------------------------------------------------------------- */
     210               5 :         char** papszLayerIter = papszLayers;
     211              20 :         while (*papszLayerIter)
     212                 :         {
     213              10 :             OGRLayer        *poLayer = poDS->GetLayerByName(*papszLayerIter);
     214                 : 
     215              10 :             if( poLayer == NULL )
     216                 :             {
     217                 :                 printf( "FAILURE: Couldn't fetch requested layer %s!\n",
     218               0 :                         *papszLayerIter );
     219               0 :                 exit( 1 );
     220                 :             }
     221                 :             
     222                 :             printf( "INFO: Testing layer %s.\n",
     223              10 :                     poLayer->GetName() );
     224              10 :             bRet &= TestOGRLayer( poDS, poLayer, FALSE );
     225                 :             
     226              10 :             papszLayerIter ++;
     227                 :         }
     228                 : 
     229               5 :         if (CSLCount(papszLayers) >= 2)
     230                 :         {
     231               3 :             OGRDataSource::DestroyDataSource(poDS);
     232               3 :             poDS = NULL;
     233               3 :             bRet &= TestInterleavedReading( pszDataSource, papszLayers );
     234                 :         }
     235                 :     }
     236                 : 
     237                 : /* -------------------------------------------------------------------- */
     238                 : /*      Close down.                                                     */
     239                 : /* -------------------------------------------------------------------- */
     240              22 :     OGRDataSource::DestroyDataSource(poDS);
     241                 : 
     242              22 :     OGRCleanupAll();
     243                 : 
     244              22 :     CSLDestroy(papszLayers);
     245              22 :     CSLDestroy(papszArgv);
     246                 :     
     247                 : #ifdef DBMALLOC
     248                 :     malloc_dump(1);
     249                 : #endif
     250                 :     
     251              22 :     return (bRet) ? 0 : 1;
     252                 : }
     253                 : 
     254                 : /************************************************************************/
     255                 : /*                               Usage()                                */
     256                 : /************************************************************************/
     257                 : 
     258               0 : static void Usage()
     259                 : 
     260                 : {
     261               0 :     printf( "Usage: test_ogrsf [-ro] [-q] datasource_name [[layer1_name, layer2_name, ...] | [-sql statement]]\n" );
     262               0 :     exit( 1 );
     263                 : }
     264                 : 
     265                 : /************************************************************************/
     266                 : /*                      TestOGRLayerFeatureCount()                      */
     267                 : /*                                                                      */
     268                 : /*      Verify that the feature count matches the actual number of      */
     269                 : /*      features returned during sequential reading.                    */
     270                 : /************************************************************************/
     271                 : 
     272              77 : static int TestOGRLayerFeatureCount( OGRDataSource* poDS, OGRLayer *poLayer, int bIsSQLLayer )
     273                 : 
     274                 : {
     275              77 :     int bRet = TRUE;
     276              77 :     int         nFC = 0, nClaimedFC = poLayer->GetFeatureCount();
     277                 :     OGRFeature  *poFeature;
     278              77 :     OGRSpatialReference * poSRS = poLayer->GetSpatialRef();
     279              77 :     int         bWarnAboutSRS = FALSE;
     280              77 :     OGRFeatureDefn* poLayerDefn = poLayer->GetLayerDefn();
     281                 : 
     282              77 :     poLayer->ResetReading();
     283                 : 
     284          145469 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
     285                 :     {
     286          145315 :         nFC++;
     287                 : 
     288          145315 :         if (poFeature->GetDefnRef() != poLayerDefn)
     289                 :         {
     290               0 :             bRet = FALSE;
     291                 :             printf( "ERROR: Feature defn differs from layer defn.\n"
     292                 :                     "Feature defn = %p\n"
     293                 :                     "Layer defn = %p\n",
     294               0 :                      poFeature->GetDefnRef(), poLayerDefn);
     295                 :         }
     296                 : 
     297          145315 :         if( poFeature->GetGeometryRef() != NULL
     298                 :             && poFeature->GetGeometryRef()->getSpatialReference() != poSRS
     299                 :             && !bWarnAboutSRS )
     300                 :         {
     301                 :             char        *pszLayerSRSWKT, *pszFeatureSRSWKT;
     302                 :             
     303               0 :             bWarnAboutSRS = TRUE;
     304                 : 
     305               0 :             if( poSRS != NULL )
     306               0 :                 poSRS->exportToWkt( &pszLayerSRSWKT );
     307                 :             else
     308               0 :                 pszLayerSRSWKT = CPLStrdup("(NULL)");
     309                 : 
     310               0 :             if( poFeature->GetGeometryRef()->getSpatialReference() != NULL )
     311                 :                 poFeature->GetGeometryRef()->
     312               0 :                     getSpatialReference()->exportToWkt( &pszFeatureSRSWKT );
     313                 :             else
     314               0 :                 pszFeatureSRSWKT = CPLStrdup("(NULL)");
     315                 : 
     316               0 :             bRet = FALSE;
     317                 :             printf( "ERROR: Feature SRS differs from layer SRS.\n"
     318                 :                     "Feature SRS = %s (%p)\n"
     319                 :                     "Layer SRS = %s (%p)\n",
     320                 :                     pszFeatureSRSWKT, poFeature->GetGeometryRef()->getSpatialReference(),
     321               0 :                     pszLayerSRSWKT, poSRS );
     322               0 :             CPLFree( pszLayerSRSWKT );
     323               0 :             CPLFree( pszFeatureSRSWKT );
     324                 :         }
     325                 :         
     326          145315 :         OGRFeature::DestroyFeature(poFeature);
     327                 :     }
     328                 : 
     329              77 :     if( nFC != nClaimedFC )
     330                 :     {
     331               0 :         bRet = FALSE;
     332                 :         printf( "ERROR: Claimed feature count %d doesn't match actual, %d.\n",
     333               0 :                 nClaimedFC, nFC );
     334                 :     }
     335              77 :     else if( nFC != poLayer->GetFeatureCount() )
     336                 :     {
     337               0 :         bRet = FALSE;
     338                 :         printf( "ERROR: Feature count at end of layer %d differs "
     339                 :                 "from at start, %d.\n",
     340               0 :                 nFC, poLayer->GetFeatureCount() );
     341                 :     }
     342              77 :     else if( bVerbose )
     343              77 :         printf( "INFO: Feature count verified.\n" );
     344                 :         
     345              77 :     if (!bIsSQLLayer)
     346                 :     {
     347              73 :         CPLString osSQL;
     348              73 :         const char* pszLayerName = poLayer->GetName();
     349                 :         int i;
     350                 :         char ch;
     351             694 :         for(i=0;(ch = pszLayerName[i]) != 0;i++)
     352                 :         {
     353             654 :             if (ch >= '0' && ch <= '9')
     354                 :             {
     355              16 :                 if (i == 0)
     356               0 :                     break;
     357                 :             }
     358             622 :             else if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')))
     359              17 :                 break;
     360                 :         }
     361                 :         /* Only quote if needed. Quoting conventions depend on the driver... */
     362              73 :         if (ch == 0)
     363              56 :             osSQL.Printf("SELECT COUNT(*) FROM %s", pszLayerName);
     364                 :         else
     365                 :         {
     366              17 :             if (EQUAL(poDS->GetDriver()->GetName(), "MYSQL"))
     367               0 :                 osSQL.Printf("SELECT COUNT(*) FROM `%s`", pszLayerName);
     368              17 :             else if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
     369                 :                      strchr(pszLayerName, '.'))
     370                 :             {
     371               0 :                 char** papszTokens = CSLTokenizeStringComplex(pszLayerName, ".", 0, 0);
     372               0 :                 if (CSLCount(papszTokens) == 2)
     373                 :                 {
     374               0 :                     osSQL.Printf("SELECT COUNT(*) FROM \"%s\".\"%s\"", papszTokens[0], papszTokens[1]);
     375                 :                 }
     376                 :                 else
     377               0 :                     osSQL.Printf("SELECT COUNT(*) FROM \"%s\"", pszLayerName);
     378               0 :                 CSLDestroy(papszTokens);
     379                 :             }
     380                 :             else
     381              17 :                 osSQL.Printf("SELECT COUNT(*) FROM \"%s\"", pszLayerName);
     382                 :         }
     383              73 :         OGRLayer* poSQLLyr = poDS->ExecuteSQL(osSQL.c_str(), NULL, NULL);
     384              73 :         if (poSQLLyr)
     385                 :         {
     386              73 :             OGRFeature* poFeatCount = poSQLLyr->GetNextFeature();
     387              73 :             if (poFeatCount == NULL)
     388                 :             {
     389               0 :                 bRet = FALSE;
     390               0 :                 printf( "ERROR: '%s' failed.\n", osSQL.c_str() );
     391                 :             }
     392              73 :             else if (nClaimedFC != poFeatCount->GetFieldAsInteger(0))
     393                 :             {
     394               0 :                 bRet = FALSE;
     395                 :                 printf( "ERROR: Claimed feature count %d doesn't match '%s' one, %d.\n",
     396               0 :                         nClaimedFC, osSQL.c_str(), poFeatCount->GetFieldAsInteger(0) );
     397                 :             }
     398              73 :             OGRFeature::DestroyFeature(poFeatCount);
     399              73 :             poDS->ReleaseResultSet(poSQLLyr);
     400              73 :         }
     401                 :     }
     402                 : 
     403              77 :     if( bVerbose && !bWarnAboutSRS )
     404                 :     {
     405              77 :         printf("INFO: Feature/layer spatial ref. consistency verified.\n");
     406                 :     }
     407                 : 
     408              77 :     return bRet;
     409                 : }
     410                 : 
     411                 : /************************************************************************/
     412                 : /*                       TestOGRLayerRandomRead()                       */
     413                 : /*                                                                      */
     414                 : /*      Read the first 5 features, and then try to use random           */
     415                 : /*      reading to reread 2 and 5 and verify that this works OK.        */
     416                 : /*      Don't attempt if there aren't at least 5 features.              */
     417                 : /************************************************************************/
     418                 : 
     419              48 : static int TestOGRLayerRandomRead( OGRLayer *poLayer )
     420                 : 
     421                 : {
     422              48 :     int bRet = TRUE;
     423              48 :     OGRFeature  *papoFeatures[5], *poFeature = NULL;
     424                 :     int         iFeature;
     425                 : 
     426              48 :     poLayer->SetSpatialFilter( NULL );
     427                 :     
     428              48 :     if( poLayer->GetFeatureCount() < 5 )
     429                 :     {
     430              22 :         if( bVerbose )
     431                 :             printf( "INFO: Only %d features on layer,"
     432                 :                     "skipping random read test.\n",
     433              22 :                     poLayer->GetFeatureCount() );
     434                 :         
     435              22 :         return bRet;
     436                 :     }
     437                 : 
     438                 : /* -------------------------------------------------------------------- */
     439                 : /*      Fetch five features.                                            */
     440                 : /* -------------------------------------------------------------------- */
     441              26 :     poLayer->ResetReading();
     442                 :     
     443             156 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     444                 :     {
     445             130 :         papoFeatures[iFeature] = NULL;
     446                 :     }
     447             156 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     448                 :     {
     449             130 :         papoFeatures[iFeature] = poLayer->GetNextFeature();
     450             130 :         if( papoFeatures[iFeature] == NULL )
     451                 :         {
     452               0 :             if( bVerbose )
     453                 :                 printf( "INFO: Only %d features on layer,"
     454                 :                         "skipping random read test.\n",
     455               0 :                         iFeature );
     456               0 :             goto end;
     457                 :         }
     458                 :     }
     459                 : 
     460                 : /* -------------------------------------------------------------------- */
     461                 : /*      Test feature 2.                                                 */
     462                 : /* -------------------------------------------------------------------- */
     463              26 :     poFeature = poLayer->GetFeature( papoFeatures[1]->GetFID() );
     464              26 :     if (poFeature == NULL)
     465                 :     {
     466                 :         printf( "ERROR: Cannot fetch feature %ld.\n",
     467               0 :                  papoFeatures[1]->GetFID() );
     468               0 :         goto end;
     469                 :     }
     470                 : 
     471              26 :     if( !poFeature->Equal( papoFeatures[1] ) )
     472                 :     {
     473               0 :         bRet = FALSE;
     474                 :         printf( "ERROR: Attempt to randomly read feature %ld appears to\n"
     475                 :                 "       have returned a different feature than sequential\n"
     476                 :                 "       reading indicates should have happened.\n",
     477               0 :                 papoFeatures[1]->GetFID() );
     478               0 :         poFeature->DumpReadable(stdout);
     479               0 :         papoFeatures[1]->DumpReadable(stdout);
     480                 : 
     481               0 :         goto end;
     482                 :     }
     483                 : 
     484              26 :     OGRFeature::DestroyFeature(poFeature);
     485                 : 
     486                 : /* -------------------------------------------------------------------- */
     487                 : /*      Test feature 5.                                                 */
     488                 : /* -------------------------------------------------------------------- */
     489              26 :     poFeature = poLayer->GetFeature( papoFeatures[4]->GetFID() );
     490              26 :     if( !poFeature->Equal( papoFeatures[4] ) )
     491                 :     {
     492               0 :         bRet = FALSE;
     493                 :         printf( "ERROR: Attempt to randomly read feature %ld appears to\n"
     494                 :                 "       have returned a different feature than sequential\n"
     495                 :                 "       reading indicates should have happened.\n",
     496               0 :                 papoFeatures[4]->GetFID() );
     497                 : 
     498               0 :         goto end;
     499                 :     }
     500                 : 
     501              26 :     if( bVerbose )
     502              26 :         printf( "INFO: Random read test passed.\n" );
     503                 : 
     504                 : end:
     505              26 :     OGRFeature::DestroyFeature(poFeature);
     506                 : 
     507                 : /* -------------------------------------------------------------------- */
     508                 : /*      Cleanup.                                                        */
     509                 : /* -------------------------------------------------------------------- */
     510             156 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     511             130 :         OGRFeature::DestroyFeature(papoFeatures[iFeature]);
     512                 : 
     513              26 :     return bRet;
     514                 : }
     515                 : 
     516                 : 
     517                 : /************************************************************************/
     518                 : /*                       TestOGRLayerSetNextByIndex()                   */
     519                 : /*                                                                      */
     520                 : /************************************************************************/
     521                 : 
     522               9 : static int TestOGRLayerSetNextByIndex( OGRLayer *poLayer )
     523                 : 
     524                 : {
     525               9 :     int bRet = TRUE;
     526               9 :     OGRFeature  *papoFeatures[5], *poFeature = NULL;
     527                 :     int         iFeature;
     528                 : 
     529               9 :     memset(papoFeatures, 0, sizeof(papoFeatures));
     530                 : 
     531               9 :     poLayer->SetSpatialFilter( NULL );
     532                 :     
     533               9 :     if( poLayer->GetFeatureCount() < 5 )
     534                 :     {
     535               2 :         if( bVerbose )
     536                 :             printf( "INFO: Only %d features on layer,"
     537                 :                     "skipping SetNextByIndex test.\n",
     538               2 :                     poLayer->GetFeatureCount() );
     539                 :         
     540               2 :         return bRet;
     541                 :     }
     542                 : 
     543                 : /* -------------------------------------------------------------------- */
     544                 : /*      Fetch five features.                                            */
     545                 : /* -------------------------------------------------------------------- */
     546               7 :     poLayer->ResetReading();
     547                 :     
     548              42 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     549                 :     {
     550              35 :         papoFeatures[iFeature] = poLayer->GetNextFeature();
     551              35 :         if( papoFeatures[iFeature] == NULL )
     552                 :         {
     553               0 :             bRet = FALSE;
     554               0 :             printf( "ERROR: Cannot get feature %d.\n", iFeature );
     555               0 :             goto end;
     556                 :         }
     557                 :     }
     558                 : 
     559                 : /* -------------------------------------------------------------------- */
     560                 : /*      Test feature at index 1.                                        */
     561                 : /* -------------------------------------------------------------------- */
     562               7 :     if (poLayer->SetNextByIndex(1) != OGRERR_NONE)
     563                 :     {
     564               0 :         bRet = FALSE;
     565               0 :         printf( "ERROR: SetNextByIndex(%d) failed.\n", 1 );
     566               0 :         goto end;
     567                 :     }
     568                 :     
     569               7 :     poFeature = poLayer->GetNextFeature();
     570               7 :     if( !poFeature->Equal( papoFeatures[1] ) )
     571                 :     {
     572               0 :         bRet = FALSE;
     573                 :         printf( "ERROR: Attempt to read feature at index %d appears to\n"
     574                 :                 "       have returned a different feature than sequential\n"
     575                 :                 "       reading indicates should have happened.\n",
     576               0 :                 1 );
     577                 : 
     578               0 :         goto end;
     579                 :     }
     580                 : 
     581               7 :     OGRFeature::DestroyFeature(poFeature);
     582                 :     
     583               7 :     poFeature = poLayer->GetNextFeature();
     584               7 :     if( !poFeature->Equal( papoFeatures[2] ) )
     585                 :     {
     586               0 :         bRet = FALSE;
     587                 :         printf( "ERROR: Attempt to read feature after feature at index %d appears to\n"
     588                 :                 "       have returned a different feature than sequential\n"
     589                 :                 "       reading indicates should have happened.\n",
     590               0 :                 1 );
     591                 : 
     592               0 :         goto end;
     593                 :     }
     594                 : 
     595               7 :     OGRFeature::DestroyFeature(poFeature);
     596               7 :     poFeature = NULL;
     597                 :     
     598                 : /* -------------------------------------------------------------------- */
     599                 : /*      Test feature at index 3.                                        */
     600                 : /* -------------------------------------------------------------------- */
     601               7 :     if (poLayer->SetNextByIndex(3) != OGRERR_NONE)
     602                 :     {
     603               0 :         bRet = FALSE;
     604               0 :         printf( "ERROR: SetNextByIndex(%d) failed.\n", 3 );
     605               0 :         goto end;
     606                 :     }
     607                 :     
     608               7 :     poFeature = poLayer->GetNextFeature();
     609               7 :     if( !poFeature->Equal( papoFeatures[3] ) )
     610                 :     {
     611               0 :         bRet = FALSE;
     612                 :         printf( "ERROR: Attempt to read feature at index %d appears to\n"
     613                 :                 "       have returned a different feature than sequential\n"
     614                 :                 "       reading indicates should have happened.\n",
     615               0 :                 3 );
     616                 : 
     617               0 :         goto end;
     618                 :     }
     619                 : 
     620               7 :     OGRFeature::DestroyFeature(poFeature);
     621                 :     
     622               7 :     poFeature = poLayer->GetNextFeature();
     623               7 :     if( !poFeature->Equal( papoFeatures[4] ) )
     624                 :     {
     625               0 :         bRet = FALSE;
     626                 :         printf( "ERROR: Attempt to read feature after feature at index %d appears to\n"
     627                 :                 "       have returned a different feature than sequential\n"
     628                 :                 "       reading indicates should have happened.\n",
     629               0 :                 3 );
     630                 : 
     631               0 :         goto end;
     632                 :     }
     633                 : 
     634                 : 
     635               7 :     if( bVerbose )
     636               7 :         printf( "INFO: SetNextByIndex() read test passed.\n" );
     637                 : 
     638                 : end:
     639               7 :     OGRFeature::DestroyFeature(poFeature);
     640                 : 
     641                 : /* -------------------------------------------------------------------- */
     642                 : /*      Cleanup.                                                        */
     643                 : /* -------------------------------------------------------------------- */
     644              42 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     645              35 :         OGRFeature::DestroyFeature(papoFeatures[iFeature]);
     646                 : 
     647               7 :     return bRet;
     648                 : }
     649                 : 
     650                 : /************************************************************************/
     651                 : /*                      TestOGRLayerRandomWrite()                       */
     652                 : /*                                                                      */
     653                 : /*      Test random writing by trying to switch the 2nd and 5th         */
     654                 : /*      features.                                                       */
     655                 : /************************************************************************/
     656                 : 
     657              10 : static int TestOGRLayerRandomWrite( OGRLayer *poLayer )
     658                 : 
     659                 : {
     660              10 :     int bRet = TRUE;
     661                 :     OGRFeature  *papoFeatures[5], *poFeature;
     662                 :     int         iFeature;
     663                 :     long        nFID2, nFID5;
     664                 : 
     665              10 :     memset(papoFeatures, 0, sizeof(papoFeatures));
     666                 : 
     667              10 :     poLayer->SetSpatialFilter( NULL );
     668                 : 
     669              10 :     if( poLayer->GetFeatureCount() < 5 )
     670                 :     {
     671               7 :         if( bVerbose )
     672                 :             printf( "INFO: Only %d features on layer,"
     673                 :                     "skipping random write test.\n",
     674               7 :                     poLayer->GetFeatureCount() );
     675                 :         
     676               7 :         return bRet;
     677                 :     }
     678                 : 
     679               3 :     if( !poLayer->TestCapability( OLCRandomRead ) )
     680                 :     {
     681               0 :         if( bVerbose )
     682                 :             printf( "INFO: Skipping random write test since this layer "
     683               0 :                     "doesn't support random read.\n" );
     684               0 :         return bRet;
     685                 :     }
     686                 : 
     687                 : /* -------------------------------------------------------------------- */
     688                 : /*      Fetch five features.                                            */
     689                 : /* -------------------------------------------------------------------- */
     690               3 :     poLayer->ResetReading();
     691                 :     
     692              18 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     693                 :     {
     694              15 :         papoFeatures[iFeature] = poLayer->GetNextFeature();
     695              15 :         if( papoFeatures[iFeature] == NULL )
     696                 :         {
     697               0 :             bRet = FALSE;
     698               0 :             printf( "ERROR: Cannot get feature %d.\n", iFeature );
     699               0 :             goto end;
     700                 :         }
     701                 :     }
     702                 : 
     703                 : /* -------------------------------------------------------------------- */
     704                 : /*      Switch feature ids of feature 2 and 5.                          */
     705                 : /* -------------------------------------------------------------------- */
     706               3 :     nFID2 = papoFeatures[1]->GetFID();
     707               3 :     nFID5 = papoFeatures[4]->GetFID();
     708                 : 
     709               3 :     papoFeatures[1]->SetFID( nFID5 );
     710               3 :     papoFeatures[4]->SetFID( nFID2 );
     711                 : 
     712                 : /* -------------------------------------------------------------------- */
     713                 : /*      Rewrite them.                                                   */
     714                 : /* -------------------------------------------------------------------- */
     715               3 :     if( poLayer->SetFeature( papoFeatures[1] ) != OGRERR_NONE )
     716                 :     {
     717               0 :         bRet = FALSE;
     718               0 :         printf( "ERROR: Attempt to SetFeature(1) failed.\n" );
     719               0 :         goto end;
     720                 :     }
     721               3 :     if( poLayer->SetFeature( papoFeatures[4] ) != OGRERR_NONE )
     722                 :     {
     723               0 :         bRet = FALSE;
     724               0 :         printf( "ERROR: Attempt to SetFeature(4) failed.\n" );
     725               0 :         goto end;
     726                 :     }
     727                 : 
     728                 : /* -------------------------------------------------------------------- */
     729                 : /*      Now re-read feature 2 to verify the effect stuck.               */
     730                 : /* -------------------------------------------------------------------- */
     731               3 :     poFeature = poLayer->GetFeature( nFID5 );
     732               3 :     if(poFeature == NULL)
     733                 :     {
     734               0 :         bRet = FALSE;
     735               0 :         printf( "ERROR: Attempt to GetFeature( nFID5 ) failed.\n" );
     736               0 :         goto end;
     737                 :     }
     738               3 :     if( !poFeature->Equal(papoFeatures[1]) )
     739                 :     {
     740               0 :         bRet = FALSE;
     741               0 :         printf( "ERROR: Written feature didn't seem to retain value.\n" );
     742                 :     }
     743                 :     else
     744                 :     {
     745               3 :         printf( "INFO: Random write test passed.\n" );
     746                 :     }
     747               3 :     OGRFeature::DestroyFeature(poFeature);
     748                 : 
     749                 : /* -------------------------------------------------------------------- */
     750                 : /*      Re-invert the features to restore to original state             */
     751                 : /* -------------------------------------------------------------------- */
     752                 : 
     753               3 :     papoFeatures[1]->SetFID( nFID2 );
     754               3 :     papoFeatures[4]->SetFID( nFID5 );
     755                 : 
     756               3 :     if( poLayer->SetFeature( papoFeatures[1] ) != OGRERR_NONE )
     757                 :     {
     758               0 :         bRet = FALSE;
     759               0 :         printf( "ERROR: Attempt to restore SetFeature(1) failed.\n" );
     760                 :     }
     761               3 :     if( poLayer->SetFeature( papoFeatures[4] ) != OGRERR_NONE )
     762                 :     {
     763               0 :         bRet = FALSE;
     764               0 :         printf( "ERROR: Attempt to restore SetFeature(4) failed.\n" );
     765                 :     }
     766                 : 
     767                 : end:
     768                 : /* -------------------------------------------------------------------- */
     769                 : /*      Cleanup.                                                        */
     770                 : /* -------------------------------------------------------------------- */
     771                 : 
     772              18 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     773              15 :         OGRFeature::DestroyFeature(papoFeatures[iFeature]);
     774                 : 
     775               3 :     return bRet;
     776                 : }
     777                 : 
     778                 : /************************************************************************/
     779                 : /*                         TestSpatialFilter()                          */
     780                 : /*                                                                      */
     781                 : /*      This is intended to be a simple test of the spatial             */
     782                 : /*      filtering.  We read the first feature.  Then construct a        */
     783                 : /*      spatial filter geometry which includes it, install and          */
     784                 : /*      verify that we get the feature.  Next install a spatial         */
     785                 : /*      filter that doesn't include this feature, and test again.       */
     786                 : /************************************************************************/
     787                 : 
     788              77 : static int TestSpatialFilter( OGRLayer *poLayer )
     789                 : 
     790                 : {
     791              77 :     int bRet = TRUE;
     792                 :     OGRFeature  *poFeature, *poTargetFeature;
     793              77 :     OGRPolygon  oInclusiveFilter, oExclusiveFilter;
     794              77 :     OGRLinearRing oRing;
     795              77 :     OGREnvelope sEnvelope;
     796                 :     int         nInclusiveCount;
     797                 : 
     798                 : /* -------------------------------------------------------------------- */
     799                 : /*      Read the target feature.                                        */
     800                 : /* -------------------------------------------------------------------- */
     801              77 :     poLayer->ResetReading();
     802              77 :     poTargetFeature = poLayer->GetNextFeature();
     803                 : 
     804              77 :     if( poTargetFeature == NULL )
     805                 :     {
     806                 :         printf( "INFO: Skipping Spatial Filter test for %s.\n"
     807                 :                 "      No features in layer.\n",
     808               6 :                 poLayer->GetName() );
     809               6 :         return bRet;
     810                 :     }
     811                 : 
     812              71 :     if( poTargetFeature->GetGeometryRef() == NULL )
     813                 :     {
     814                 :         printf( "INFO: Skipping Spatial Filter test for %s,\n"
     815                 :                 "      target feature has no geometry.\n",
     816              18 :                 poTargetFeature->GetDefnRef()->GetName() );
     817              18 :         OGRFeature::DestroyFeature(poTargetFeature);
     818              18 :         return bRet;
     819                 :     }
     820                 : 
     821              53 :     poTargetFeature->GetGeometryRef()->getEnvelope( &sEnvelope );
     822                 : 
     823                 : /* -------------------------------------------------------------------- */
     824                 : /*      Construct inclusive filter.                                     */
     825                 : /* -------------------------------------------------------------------- */
     826                 :     
     827              53 :     oRing.setPoint( 0, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     828              53 :     oRing.setPoint( 1, sEnvelope.MinX - 20.0, sEnvelope.MaxY + 10.0 );
     829              53 :     oRing.setPoint( 2, sEnvelope.MaxX + 10.0, sEnvelope.MaxY + 10.0 );
     830              53 :     oRing.setPoint( 3, sEnvelope.MaxX + 10.0, sEnvelope.MinY - 20.0 );
     831              53 :     oRing.setPoint( 4, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     832                 :     
     833              53 :     oInclusiveFilter.addRing( &oRing );
     834                 : 
     835              53 :     poLayer->SetSpatialFilter( &oInclusiveFilter );
     836                 : 
     837                 : /* -------------------------------------------------------------------- */
     838                 : /*      Verify that we can find the target feature.                     */
     839                 : /* -------------------------------------------------------------------- */
     840              53 :     poLayer->ResetReading();
     841                 : 
     842             106 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
     843                 :     {
     844              53 :         if( poFeature->Equal(poTargetFeature) )
     845                 :         {
     846              53 :             OGRFeature::DestroyFeature(poFeature);
     847              53 :             break;
     848                 :         }
     849                 :         else
     850               0 :             OGRFeature::DestroyFeature(poFeature);
     851                 :     }
     852                 : 
     853              53 :     if( poFeature == NULL )
     854                 :     {
     855               0 :         bRet = FALSE;
     856               0 :         printf( "ERROR: Spatial filter eliminated a feature unexpectedly!\n");
     857                 :     }
     858              53 :     else if( bVerbose )
     859                 :     {
     860              53 :         printf( "INFO: Spatial filter inclusion seems to work.\n" );
     861                 :     }
     862                 : 
     863              53 :     nInclusiveCount = poLayer->GetFeatureCount();
     864                 : 
     865                 : /* -------------------------------------------------------------------- */
     866                 : /*      Construct exclusive filter.                                     */
     867                 : /* -------------------------------------------------------------------- */
     868              53 :     oRing.setPoint( 0, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     869              53 :     oRing.setPoint( 1, sEnvelope.MinX - 10.0, sEnvelope.MinY - 20.0 );
     870              53 :     oRing.setPoint( 2, sEnvelope.MinX - 10.0, sEnvelope.MinY - 10.0 );
     871              53 :     oRing.setPoint( 3, sEnvelope.MinX - 20.0, sEnvelope.MinY - 10.0 );
     872              53 :     oRing.setPoint( 4, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     873                 :     
     874              53 :     oExclusiveFilter.addRing( &oRing );
     875                 : 
     876              53 :     poLayer->SetSpatialFilter( &oExclusiveFilter );
     877                 : 
     878                 : /* -------------------------------------------------------------------- */
     879                 : /*      Verify that we can find the target feature.                     */
     880                 : /* -------------------------------------------------------------------- */
     881              53 :     poLayer->ResetReading();
     882                 : 
     883             261 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
     884                 :     {
     885             155 :         if( poFeature->Equal(poTargetFeature) )
     886                 :         {
     887               0 :             OGRFeature::DestroyFeature(poFeature);
     888               0 :             break;
     889                 :         }
     890                 :         else
     891             155 :             OGRFeature::DestroyFeature(poFeature);
     892                 :     }
     893                 : 
     894              53 :     if( poFeature != NULL )
     895                 :     {
     896               0 :         bRet = FALSE;
     897                 :         printf( "ERROR: Spatial filter failed to eliminate"
     898               0 :                 "a feature unexpectedly!\n");
     899                 :     }
     900              53 :     else if( poLayer->GetFeatureCount() >= nInclusiveCount )
     901                 :     {
     902               0 :         bRet = FALSE;
     903                 :         printf( "ERROR: GetFeatureCount() may not be taking spatial "
     904               0 :                 "filter into account.\n" );
     905                 :     }
     906              53 :     else if( bVerbose )
     907                 :     {
     908              53 :         printf( "INFO: Spatial filter exclusion seems to work.\n" );
     909                 :     }
     910                 : 
     911              53 :     OGRFeature::DestroyFeature(poTargetFeature);
     912                 : 
     913              53 :     poLayer->SetSpatialFilter( NULL );
     914                 : 
     915              53 :     return bRet;
     916                 : }
     917                 : 
     918                 : 
     919                 : /************************************************************************/
     920                 : /*                      TestAttributeFilter()                           */
     921                 : /*                                                                      */
     922                 : /*      This is intended to be a simple test of the attribute           */
     923                 : /*      filtering.  We read the first feature.  Then construct a        */
     924                 : /*      attribute filter which includes it, install and                 */
     925                 : /*      verify that we get the feature.  Next install a attribute       */
     926                 : /*      filter that doesn't include this feature, and test again.       */
     927                 : /************************************************************************/
     928                 : 
     929              77 : static int TestAttributeFilter( OGRDataSource* poDS, OGRLayer *poLayer )
     930                 : 
     931                 : {
     932              77 :     int bRet = TRUE;
     933                 :     OGRFeature  *poFeature, *poTargetFeature;
     934                 :     int         nInclusiveCount, nExclusiveCount, nTotalCount;
     935              77 :     CPLString osAttributeFilter;
     936                 : 
     937                 : /* -------------------------------------------------------------------- */
     938                 : /*      Read the target feature.                                        */
     939                 : /* -------------------------------------------------------------------- */
     940              77 :     poLayer->ResetReading();
     941              77 :     poTargetFeature = poLayer->GetNextFeature();
     942                 : 
     943              77 :     if( poTargetFeature == NULL )
     944                 :     {
     945                 :         printf( "INFO: Skipping Attribute Filter test for %s.\n"
     946                 :                 "      No features in layer.\n",
     947               6 :                 poLayer->GetName() );
     948               6 :         return bRet;
     949                 :     }
     950                 : 
     951                 :     int i;
     952              71 :     OGRFieldType eType = OFTString;
     953              71 :     for(i=0;i<poTargetFeature->GetFieldCount();i++)
     954                 :     {
     955              66 :         eType = poTargetFeature->GetFieldDefnRef(i)->GetType();
     956              66 :         if (poTargetFeature->IsFieldSet(i) &&
     957                 :             (eType == OFTString || eType == OFTInteger || eType == OFTReal))
     958                 :         {
     959              66 :             break;
     960                 :         }
     961                 :     }
     962              71 :     if( i == poTargetFeature->GetFieldCount() )
     963                 :     {
     964                 :         printf( "INFO: Skipping Attribute Filter test for %s.\n"
     965                 :                 "      Could not find non NULL field.\n",
     966               5 :                 poLayer->GetName() );
     967               5 :         OGRFeature::DestroyFeature(poTargetFeature);
     968               5 :         return bRet;
     969                 :     }
     970                 : 
     971              66 :     const char* pszFieldName = poTargetFeature->GetFieldDefnRef(i)->GetNameRef();
     972              66 :     CPLString osValue = poTargetFeature->GetFieldAsString(i);
     973                 : 
     974                 : /* -------------------------------------------------------------------- */
     975                 : /*      Construct inclusive filter.                                     */
     976                 : /* -------------------------------------------------------------------- */
     977                 : 
     978              66 :     if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
     979                 :         (strchr(pszFieldName, '_') || strchr(pszFieldName, ' ')))
     980                 :     {
     981               0 :         osAttributeFilter = "\"";
     982               0 :         osAttributeFilter += pszFieldName;
     983               0 :         osAttributeFilter += "\"";
     984                 :     }
     985              66 :     else if (strchr(pszFieldName, ' ') || pszFieldName[0] == '_')
     986                 :     {
     987               0 :         osAttributeFilter = "'";
     988               0 :         osAttributeFilter += pszFieldName;
     989               0 :         osAttributeFilter += "'";
     990                 :     }
     991                 :     else
     992              66 :         osAttributeFilter = pszFieldName;
     993              66 :     osAttributeFilter += " = ";
     994              66 :     if (eType == OFTString)
     995              47 :         osAttributeFilter += "'";
     996              66 :     osAttributeFilter += osValue;
     997              66 :     if (eType == OFTString)
     998              47 :         osAttributeFilter += "'";
     999                 :     /* Make sure that the literal will be recognized as a float value */
    1000                 :     /* to avoid int underflow/overflow */
    1001              19 :     else if (eType == OFTReal && strchr(osValue, '.') == NULL)
    1002               0 :         osAttributeFilter += ".";
    1003              66 :     poLayer->SetAttributeFilter( osAttributeFilter );
    1004                 : 
    1005                 : /* -------------------------------------------------------------------- */
    1006                 : /*      Verify that we can find the target feature.                     */
    1007                 : /* -------------------------------------------------------------------- */
    1008              66 :     poLayer->ResetReading();
    1009                 : 
    1010             132 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
    1011                 :     {
    1012              66 :         if( poFeature->Equal(poTargetFeature) )
    1013                 :         {
    1014              66 :             OGRFeature::DestroyFeature(poFeature);
    1015              66 :             break;
    1016                 :         }
    1017                 :         else
    1018               0 :             OGRFeature::DestroyFeature(poFeature);
    1019                 :     }
    1020                 : 
    1021              66 :     if( poFeature == NULL )
    1022                 :     {
    1023               0 :         bRet = FALSE;
    1024               0 :         printf( "ERROR: Attribute filter eliminated a feature unexpectedly!\n");
    1025                 :     }
    1026              66 :     else if( bVerbose )
    1027                 :     {
    1028              66 :         printf( "INFO: Attribute filter inclusion seems to work.\n" );
    1029                 :     }
    1030                 : 
    1031              66 :     nInclusiveCount = poLayer->GetFeatureCount();
    1032                 : 
    1033                 : /* -------------------------------------------------------------------- */
    1034                 : /*      Construct exclusive filter.                                     */
    1035                 : /* -------------------------------------------------------------------- */
    1036              66 :     if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
    1037                 :         (strchr(pszFieldName, '_') || strchr(pszFieldName, ' ')))
    1038                 :     {
    1039               0 :         osAttributeFilter = "\"";
    1040               0 :         osAttributeFilter += pszFieldName;
    1041               0 :         osAttributeFilter += "\"";
    1042                 :     }
    1043              66 :     else if (strchr(pszFieldName, ' ') || pszFieldName[0] == '_')
    1044                 :     {
    1045               0 :         osAttributeFilter = "'";
    1046               0 :         osAttributeFilter += pszFieldName;
    1047               0 :         osAttributeFilter += "'";
    1048                 :     }
    1049                 :     else
    1050              66 :         osAttributeFilter = pszFieldName;
    1051              66 :     osAttributeFilter += " <> ";
    1052              66 :     if (eType == OFTString)
    1053              47 :         osAttributeFilter += "'";
    1054              66 :     osAttributeFilter += osValue;
    1055              66 :     if (eType == OFTString)
    1056              47 :         osAttributeFilter += "'";
    1057                 :     /* Make sure that the literal will be recognized as a float value */
    1058                 :     /* to avoid int underflow/overflow */
    1059              19 :     else if (eType == OFTReal && strchr(osValue, '.') == NULL)
    1060               0 :         osAttributeFilter += ".";
    1061              66 :     poLayer->SetAttributeFilter( osAttributeFilter );
    1062                 : 
    1063                 : /* -------------------------------------------------------------------- */
    1064                 : /*      Verify that we can find the target feature.                     */
    1065                 : /* -------------------------------------------------------------------- */
    1066              66 :     poLayer->ResetReading();
    1067                 : 
    1068              66 :     int nExclusiveCountWhileIterating = 0;
    1069           20586 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
    1070                 :     {
    1071           20454 :         if( poFeature->Equal(poTargetFeature) )
    1072                 :         {
    1073               0 :             OGRFeature::DestroyFeature(poFeature);
    1074               0 :             break;
    1075                 :         }
    1076                 :         else
    1077           20454 :             OGRFeature::DestroyFeature(poFeature);
    1078           20454 :         nExclusiveCountWhileIterating ++;
    1079                 :     }
    1080                 : 
    1081              66 :     nExclusiveCount = poLayer->GetFeatureCount();
    1082                 : 
    1083              66 :     poLayer->SetAttributeFilter( NULL );
    1084                 : 
    1085              66 :     nTotalCount = poLayer->GetFeatureCount();
    1086                 : 
    1087              66 :     if( poFeature != NULL )
    1088                 :     {
    1089               0 :         bRet = FALSE;
    1090                 :         printf( "ERROR: Attribute filter failed to eliminate "
    1091               0 :                 "a feature unexpectedly!\n");
    1092                 :     }
    1093              66 :     else if( nExclusiveCountWhileIterating != nExclusiveCount ||
    1094                 :              nExclusiveCount >= nTotalCount ||
    1095                 :              nInclusiveCount > nTotalCount ||
    1096                 :              (nInclusiveCount == nTotalCount && nExclusiveCount != 0))
    1097                 :     {
    1098               0 :         bRet = FALSE;
    1099                 :         printf( "ERROR: GetFeatureCount() may not be taking attribute "
    1100                 :                 "filter into account (nInclusiveCount = %d, nExclusiveCount = %d, nExclusiveCountWhileIterating = %d, nTotalCount = %d).\n",
    1101               0 :                  nInclusiveCount, nExclusiveCount, nExclusiveCountWhileIterating, nTotalCount);
    1102                 :     }
    1103              66 :     else if( bVerbose )
    1104                 :     {
    1105              66 :         printf( "INFO: Attribute filter exclusion seems to work.\n" );
    1106                 :     }
    1107                 : 
    1108              66 :     OGRFeature::DestroyFeature(poTargetFeature);
    1109                 : 
    1110              66 :     return bRet;
    1111                 : }
    1112                 : 
    1113                 : /************************************************************************/
    1114                 : /*                         TestOGRLayerUTF8()                           */
    1115                 : /************************************************************************/
    1116                 : 
    1117              77 : static int TestOGRLayerUTF8 ( OGRLayer *poLayer )
    1118                 : {
    1119              77 :     int bRet = TRUE;
    1120                 : 
    1121              77 :     poLayer->SetSpatialFilter( NULL );
    1122              77 :     poLayer->SetAttributeFilter( NULL );
    1123              77 :     poLayer->ResetReading();
    1124                 : 
    1125              77 :     int bIsAdvertizedAsUTF8 = poLayer->TestCapability( OLCStringsAsUTF8 );
    1126              77 :     int nFields = poLayer->GetLayerDefn()->GetFieldCount();
    1127              77 :     int bFoundString = FALSE;
    1128              77 :     int bFoundNonASCII = FALSE;
    1129              77 :     int bFoundUTF8 = FALSE;
    1130              77 :     int bCanAdvertizeUTF8 = TRUE;
    1131                 : 
    1132              77 :     OGRFeature* poFeature = NULL;
    1133          145469 :     while( bRet && (poFeature = poLayer->GetNextFeature()) != NULL )
    1134                 :     {
    1135         2353683 :         for(int i = 0; i<nFields; i++)
    1136                 :         {
    1137         2208368 :             if (!poFeature->IsFieldSet(i))
    1138          934034 :                 continue;
    1139         1274334 :             if (poFeature->GetFieldDefnRef(i)->GetType() == OFTString)
    1140                 :             {
    1141          468829 :                 const char* pszVal = poFeature->GetFieldAsString(i);
    1142          468829 :                 if (pszVal[0] != 0)
    1143                 :                 {
    1144          468297 :                     bFoundString = TRUE;
    1145          468297 :                     const GByte* pszIter = (const GByte*) pszVal;
    1146          468297 :                     int bIsASCII = TRUE;
    1147         3595743 :                     while(*pszIter)
    1148                 :                     {
    1149         2659170 :                         if (*pszIter >= 128)
    1150                 :                         {
    1151              21 :                             bFoundNonASCII = TRUE;
    1152              21 :                             bIsASCII = FALSE;
    1153              21 :                             break;
    1154                 :                         }
    1155         2659149 :                         pszIter ++;
    1156                 :                     }
    1157          468297 :                     int bIsUTF8 = CPLIsUTF8(pszVal, -1);
    1158          468297 :                     if (bIsUTF8 && !bIsASCII)
    1159              21 :                         bFoundUTF8 = TRUE;
    1160          468297 :                     if (bIsAdvertizedAsUTF8)
    1161                 :                     {
    1162             251 :                         if (!bIsUTF8)
    1163                 :                         {
    1164                 :                             printf( "ERROR: Found non-UTF8 content at field %d of feature %ld, but layer is advertized as UTF-8.\n",
    1165               0 :                                     i, poFeature->GetFID() );
    1166               0 :                             bRet = FALSE;
    1167               0 :                             break;
    1168                 :                         }
    1169                 :                     }
    1170                 :                     else
    1171                 :                     {
    1172          468046 :                         if (!bIsUTF8)
    1173               0 :                             bCanAdvertizeUTF8 = FALSE;
    1174                 :                     }
    1175                 :                 }
    1176                 :             }
    1177                 :         }
    1178          145315 :         OGRFeature::DestroyFeature(poFeature);
    1179                 :     }
    1180                 : 
    1181              77 :     if (!bFoundString)
    1182                 :     {
    1183                 :     }
    1184              66 :     else if (bCanAdvertizeUTF8)
    1185                 :     {
    1186              66 :         if (bIsAdvertizedAsUTF8)
    1187                 :         {
    1188              33 :             if (bFoundUTF8)
    1189                 :             {
    1190              16 :                 printf( "INFO: Layer has UTF-8 content and is consistently declared as having UTF-8 content.\n" );
    1191                 :             }
    1192              17 :             else if (!bFoundNonASCII)
    1193                 :             {
    1194              17 :                 printf( "INFO: Layer has ASCII only content and is consistently declared as having UTF-8 content.\n" );
    1195                 :             }
    1196                 :         }
    1197                 :         else
    1198                 :         {
    1199              33 :             if (bFoundUTF8)
    1200                 :             {
    1201               1 :                 printf( "INFO: Layer could perhaps be advertized as UTF-8 compatible (and it has non-ASCII UTF-8 content).\n" );
    1202                 :             }
    1203              32 :             else if (!bFoundNonASCII)
    1204                 :             {
    1205              32 :                 printf( "INFO: Layer could perhaps be advertized as UTF-8 compatible (it has only ASCII content).\n" );
    1206                 :             }
    1207                 :         }
    1208                 :     }
    1209                 :     else
    1210                 :     {
    1211               0 :         printf( "INFO: Layer has non UTF-8 content (and is consistently declared as not being UTF-8 compatible).\n" );
    1212                 :     }
    1213                 : 
    1214              77 :     return bRet;
    1215                 : }
    1216                 : 
    1217                 : /************************************************************************/
    1218                 : /*                         TestGetExtent()                              */
    1219                 : /************************************************************************/
    1220                 : 
    1221              77 : static int TestGetExtent ( OGRLayer *poLayer )
    1222                 : {
    1223              77 :     int bRet = TRUE;
    1224                 : 
    1225              77 :     poLayer->SetSpatialFilter( NULL );
    1226              77 :     poLayer->SetAttributeFilter( NULL );
    1227              77 :     poLayer->ResetReading();
    1228                 : 
    1229              77 :     OGREnvelope sExtent;
    1230              77 :     OGREnvelope sExtentSlow;
    1231                 : 
    1232              77 :     OGRErr eErr = poLayer->GetExtent(&sExtent, TRUE);
    1233              77 :     OGRErr eErr2 = poLayer->OGRLayer::GetExtent(&sExtentSlow, TRUE);
    1234                 : 
    1235              77 :     if (eErr != eErr2)
    1236                 :     {
    1237               4 :         if (eErr == OGRERR_NONE && eErr2 != OGRERR_NONE)
    1238                 :         {
    1239                 :             /* with the LIBKML driver and test_ogrsf ../autotest/ogr/data/samples.kml "Styles and Markup" */
    1240               2 :             printf("INFO: GetExtent() succeeded but OGRLayer::GetExtent() failed.\n");
    1241                 :         }
    1242                 :         else
    1243                 :         {
    1244               0 :             bRet = FALSE;
    1245               0 :             printf("ERROR: GetExtent() failed but OGRLayer::GetExtent() succeeded.\n");
    1246                 :         }
    1247                 :     }
    1248              75 :     else if (eErr == OGRERR_NONE)
    1249                 :     {
    1250             103 :         if (fabs(sExtentSlow.MinX - sExtent.MinX) < 1e-10 &&
    1251                 :             fabs(sExtentSlow.MinY - sExtent.MinY) < 1e-10 &&
    1252                 :             fabs(sExtentSlow.MaxX - sExtent.MaxX) < 1e-10 &&
    1253                 :             fabs(sExtentSlow.MaxY - sExtent.MaxY) < 1e-10)
    1254                 :         {
    1255              50 :             printf("INFO: GetExtent() test passed.\n");
    1256                 :         }
    1257                 :         else
    1258                 :         {
    1259               3 :             if (sExtentSlow.Contains(sExtent))
    1260                 :             {
    1261               1 :                 printf("INFO: sExtentSlow.Contains(sExtent)\n");
    1262                 :             }
    1263               2 :             else if (sExtent.Contains(sExtentSlow))
    1264                 :             {
    1265               1 :                 printf("INFO: sExtent.Contains(sExtentSlow)\n");
    1266                 :             }
    1267                 :             else
    1268                 :             {
    1269               1 :                 printf("INFO: unknown relationship between sExtent and sExentSlow.\n");
    1270                 :             }
    1271               3 :             printf("INFO: sExtentSlow.MinX = %.15f\n", sExtentSlow.MinX);
    1272               3 :             printf("INFO: sExtentSlow.MinY = %.15f\n", sExtentSlow.MinY);
    1273               3 :             printf("INFO: sExtentSlow.MaxX = %.15f\n", sExtentSlow.MaxX);
    1274               3 :             printf("INFO: sExtentSlow.MaxY = %.15f\n", sExtentSlow.MaxY);
    1275               3 :             printf("INFO: sExtent.MinX = %.15f\n", sExtent.MinX);
    1276               3 :             printf("INFO: sExtent.MinY = %.15f\n", sExtent.MinY);
    1277               3 :             printf("INFO: sExtent.MaxX = %.15f\n", sExtent.MaxX);
    1278               3 :             printf("INFO: sExtent.MaxY = %.15f\n", sExtent.MaxY);
    1279                 :         }
    1280                 :     }
    1281                 : 
    1282              77 :     return bRet;
    1283                 : }
    1284                 : 
    1285                 : /************************************************************************/
    1286                 : /*                            TestOGRLayer()                            */
    1287                 : /************************************************************************/
    1288                 : 
    1289              77 : static int TestOGRLayer( OGRDataSource* poDS, OGRLayer * poLayer, int bIsSQLLayer )
    1290                 : 
    1291                 : {
    1292              77 :     int bRet = TRUE;
    1293                 : 
    1294                 : /* -------------------------------------------------------------------- */
    1295                 : /*      Verify that there is no spatial filter in place by default.     */
    1296                 : /* -------------------------------------------------------------------- */
    1297              77 :     if( poLayer->GetSpatialFilter() != NULL )
    1298                 :     {
    1299                 :         printf( "WARN: Spatial filter in place by default on layer %s.\n",
    1300               0 :                 poLayer->GetName() );
    1301               0 :         poLayer->SetSpatialFilter( NULL );
    1302                 :     }
    1303                 : 
    1304                 : /* -------------------------------------------------------------------- */
    1305                 : /*      Test feature count accuracy.                                    */
    1306                 : /* -------------------------------------------------------------------- */
    1307              77 :     bRet &= TestOGRLayerFeatureCount( poDS, poLayer, bIsSQLLayer );
    1308                 : 
    1309                 : /* -------------------------------------------------------------------- */
    1310                 : /*      Test spatial filtering                                          */
    1311                 : /* -------------------------------------------------------------------- */
    1312              77 :     bRet &= TestSpatialFilter( poLayer );
    1313                 : 
    1314                 : /* -------------------------------------------------------------------- */
    1315                 : /*      Test attribute filtering                                        */
    1316                 : /* -------------------------------------------------------------------- */
    1317              77 :     bRet &= TestAttributeFilter( poDS, poLayer );
    1318                 : 
    1319                 : /* -------------------------------------------------------------------- */
    1320                 : /*      Test GetExtent()                                                */
    1321                 : /* -------------------------------------------------------------------- */
    1322              77 :     bRet &= TestGetExtent( poLayer );
    1323                 : 
    1324                 : /* -------------------------------------------------------------------- */
    1325                 : /*      Test random reading.                                            */
    1326                 : /* -------------------------------------------------------------------- */
    1327              77 :     if( poLayer->TestCapability( OLCRandomRead ) )
    1328                 :     {
    1329              48 :         bRet &= TestOGRLayerRandomRead( poLayer );
    1330                 :     }
    1331                 :     
    1332                 : /* -------------------------------------------------------------------- */
    1333                 : /*      Test SetNextByIndex.                                            */
    1334                 : /* -------------------------------------------------------------------- */
    1335              77 :     if( poLayer->TestCapability( OLCFastSetNextByIndex ) )
    1336                 :     {
    1337               9 :         bRet &= TestOGRLayerSetNextByIndex( poLayer );
    1338                 :     }
    1339                 :     
    1340                 : /* -------------------------------------------------------------------- */
    1341                 : /*      Test random writing.                                            */
    1342                 : /* -------------------------------------------------------------------- */
    1343              77 :     if( poLayer->TestCapability( OLCRandomWrite ) )
    1344                 :     {
    1345              10 :         bRet &= TestOGRLayerRandomWrite( poLayer );
    1346                 :     }
    1347                 : 
    1348              77 :     bRet &= TestOGRLayerUTF8( poLayer );
    1349                 : 
    1350              77 :     return bRet;
    1351                 : }
    1352                 : 
    1353                 : /************************************************************************/
    1354                 : /*                        TestInterleavedReading()                      */
    1355                 : /************************************************************************/
    1356                 : 
    1357              10 : static int TestInterleavedReading( const char* pszDataSource, char** papszLayers )
    1358                 : {
    1359              10 :     int bRet = TRUE;
    1360              10 :     OGRDataSource* poDS = NULL;
    1361              10 :     OGRDataSource* poDS2 = NULL;
    1362              10 :     OGRLayer* poLayer1 = NULL;
    1363              10 :     OGRLayer* poLayer2 = NULL;
    1364              10 :     OGRFeature* poFeature11_Ref = NULL;
    1365              10 :     OGRFeature* poFeature12_Ref = NULL;
    1366              10 :     OGRFeature* poFeature21_Ref = NULL;
    1367              10 :     OGRFeature* poFeature22_Ref = NULL;
    1368              10 :     OGRFeature* poFeature11 = NULL;
    1369              10 :     OGRFeature* poFeature12 = NULL;
    1370              10 :     OGRFeature* poFeature21 = NULL;
    1371              10 :     OGRFeature* poFeature22 = NULL;
    1372                 : 
    1373                 :     /* Check that we have 2 layers with at least 2 features */
    1374              10 :     poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
    1375              10 :     if (poDS == NULL)
    1376                 :     {
    1377               0 :         printf( "INFO: Skipping TestInterleavedReading(). Cannot reopen datasource\n" );
    1378               0 :         goto bye;
    1379                 :     }
    1380                 : 
    1381              10 :     poLayer1 = papszLayers ? poDS->GetLayerByName(papszLayers[0]) : poDS->GetLayer(0);
    1382              10 :     poLayer2 = papszLayers ? poDS->GetLayerByName(papszLayers[1]) : poDS->GetLayer(1);
    1383              28 :     if (poLayer1 == NULL || poLayer2 == NULL ||
    1384              18 :         poLayer1->GetFeatureCount() < 2 || poLayer2->GetFeatureCount() < 2)
    1385                 :     {
    1386               6 :         printf( "INFO: Skipping TestInterleavedReading(). Test conditions are not met\n" );
    1387               6 :         goto bye;
    1388                 :     }
    1389                 : 
    1390                 :     /* Test normal reading */
    1391               4 :     OGRDataSource::DestroyDataSource(poDS);
    1392               4 :     poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
    1393               4 :     poDS2 = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
    1394               4 :     if (poDS == NULL || poDS2 == NULL)
    1395                 :     {
    1396               0 :         printf( "INFO: Skipping TestInterleavedReading(). Cannot reopen datasource\n" );
    1397               0 :         goto bye;
    1398                 :     }
    1399                 : 
    1400               4 :     poLayer1 = papszLayers ? poDS->GetLayerByName(papszLayers[0]) : poDS->GetLayer(0);
    1401               4 :     poLayer2 = papszLayers ? poDS->GetLayerByName(papszLayers[1]) : poDS->GetLayer(1);
    1402               4 :     if (poLayer1 == NULL || poLayer2 == NULL)
    1403                 :     {
    1404               0 :         printf( "ERROR: Skipping TestInterleavedReading(). Test conditions are not met\n" );
    1405               0 :         bRet = FALSE;
    1406               0 :         goto bye;
    1407                 :     }
    1408                 : 
    1409               4 :     poFeature11_Ref = poLayer1->GetNextFeature();
    1410               4 :     poFeature12_Ref = poLayer1->GetNextFeature();
    1411               4 :     poFeature21_Ref = poLayer2->GetNextFeature();
    1412               4 :     poFeature22_Ref = poLayer2->GetNextFeature();
    1413               4 :     if (poFeature11_Ref == NULL || poFeature12_Ref == NULL || poFeature21_Ref == NULL || poFeature22_Ref == NULL)
    1414                 :     {
    1415                 :         printf( "ERROR: TestInterleavedReading() failed: poFeature11_Ref=%p, poFeature12_Ref=%p, poFeature21_Ref=%p, poFeature22_Ref=%p\n",
    1416               0 :                 poFeature11_Ref, poFeature12_Ref, poFeature21_Ref, poFeature22_Ref);
    1417               0 :         bRet = FALSE;
    1418               0 :         goto bye;
    1419                 :     }
    1420                 : 
    1421                 :     /* Test interleaved reading */
    1422               4 :     poLayer1 = papszLayers ? poDS2->GetLayerByName(papszLayers[0]) : poDS2->GetLayer(0);
    1423               4 :     poLayer2 = papszLayers ? poDS2->GetLayerByName(papszLayers[1]) : poDS2->GetLayer(1);
    1424               4 :     if (poLayer1 == NULL || poLayer2 == NULL)
    1425                 :     {
    1426               0 :         printf( "ERROR: Skipping TestInterleavedReading(). Test conditions are not met\n" );
    1427               0 :         bRet = FALSE;
    1428               0 :         goto bye;
    1429                 :     }
    1430                 : 
    1431               4 :     poFeature11 = poLayer1->GetNextFeature();
    1432               4 :     poFeature21 = poLayer2->GetNextFeature();
    1433               4 :     poFeature12 = poLayer1->GetNextFeature();
    1434               4 :     poFeature22 = poLayer2->GetNextFeature();
    1435                 : 
    1436               4 :     if (poFeature11 == NULL || poFeature21 == NULL || poFeature12 == NULL || poFeature22 == NULL)
    1437                 :     {
    1438                 :         printf( "ERROR: TestInterleavedReading() failed: poFeature11=%p, poFeature21=%p, poFeature12=%p, poFeature22=%p\n",
    1439               0 :                 poFeature11, poFeature21, poFeature12, poFeature22);
    1440               0 :         bRet = FALSE;
    1441               0 :         goto bye;
    1442                 :     }
    1443                 : 
    1444               4 :     if (poFeature12->Equal(poFeature11))
    1445                 :     {
    1446                 :         printf( "WARN: TestInterleavedReading() failed: poFeature12 == poFeature11. "
    1447               1 :                 "The datasource resets the layer reading when interleaved layer reading pattern is detected. Acceptable but could be improved\n" );
    1448               1 :         goto bye;
    1449                 :     }
    1450                 : 
    1451                 :     /* We cannot directly compare the feature as they don't share */
    1452                 :     /* the same (pointer) layer definition, so just compare FIDs */
    1453               3 :     if (poFeature12_Ref->GetFID() != poFeature12->GetFID())
    1454                 :     {
    1455               0 :         printf( "ERROR: TestInterleavedReading() failed: poFeature12_Ref != poFeature12\n" );
    1456               0 :         poFeature12_Ref->DumpReadable(stdout, NULL);
    1457               0 :         poFeature12->DumpReadable(stdout, NULL);
    1458               0 :         bRet = FALSE;
    1459               0 :         goto bye;
    1460                 :     }
    1461                 : 
    1462               3 :     if( bVerbose )
    1463                 :     {
    1464               3 :         printf("INFO: TestInterleavedReading() successfull.\n");
    1465                 :     }
    1466                 : 
    1467                 : bye:
    1468              10 :     OGRFeature::DestroyFeature(poFeature11_Ref);
    1469              10 :     OGRFeature::DestroyFeature(poFeature12_Ref);
    1470              10 :     OGRFeature::DestroyFeature(poFeature21_Ref);
    1471              10 :     OGRFeature::DestroyFeature(poFeature22_Ref);
    1472              10 :     OGRFeature::DestroyFeature(poFeature11);
    1473              10 :     OGRFeature::DestroyFeature(poFeature21);
    1474              10 :     OGRFeature::DestroyFeature(poFeature12);
    1475              10 :     OGRFeature::DestroyFeature(poFeature22);
    1476              10 :     OGRDataSource::DestroyDataSource(poDS);
    1477              10 :     OGRDataSource::DestroyDataSource(poDS2);
    1478              10 :     return bRet;
    1479                 : }

Generated by: LCOV version 1.7