LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/mitab - mitab_ogr_datasource.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 127
Code covered: 83.5 % Executed lines: 106

       1                 : /**********************************************************************
       2                 :  * $Id: mitab_ogr_datasource.cpp,v 1.12 2007/03/22 20:01:36 dmorissette Exp $
       3                 :  *
       4                 :  * Name:     mitab_ogr_datasource.cpp
       5                 :  * Project:  MapInfo Mid/Mif, Tab ogr support
       6                 :  * Language: C++
       7                 :  * Purpose:  Implementation of OGRTABDataSource.
       8                 :  * Author:   Stephane Villeneuve, stephane.v@videotron.ca
       9                 :  *           and Frank Warmerdam, warmerdam@pobox.com
      10                 :  *
      11                 :  **********************************************************************
      12                 :  * Copyright (c) 1999, 2000, Stephane Villeneuve
      13                 :  *
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  * 
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  * 
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      25                 :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  **********************************************************************
      32                 :  *
      33                 :  * $Log: mitab_ogr_datasource.cpp,v $
      34                 :  * Revision 1.12  2007/03/22 20:01:36  dmorissette
      35                 :  * Added SPATIAL_INDEX_MODE=QUICK creation option (MITAB bug 1669)
      36                 :  *
      37                 :  * Revision 1.11  2006/01/27 14:27:35  fwarmerdam
      38                 :  * fixed ogr bounds setting problems (bug 1198)
      39                 :  *
      40                 :  * Revision 1.10  2005/09/20 04:40:02  fwarmerdam
      41                 :  * fixed CPLReadDir memory leak
      42                 :  *
      43                 :  * Revision 1.9  2004/10/15 01:52:30  fwarmerdam
      44                 :  * Modified CreateLayer() to use  -1000,-1000,1000,1000 bounds for GEOGCS
      45                 :  * much like in mitab_bounds.cpp.  This ensures that geographic files in
      46                 :  * the range 0-360 works as well as -180 to 180.
      47                 :  *
      48                 :  * Revision 1.8  2004/07/07 15:42:46  fwarmerdam
      49                 :  * fixed up some single layer creation issues
      50                 :  *
      51                 :  * Revision 1.7  2004/02/27 21:06:03  fwarmerdam
      52                 :  * Better support for "single file" creation ... don't allow other layers to
      53                 :  * be created.  But *do* single file to satisfy the first layer creation request
      54                 :  * made.  Also, allow creating a datasource "on" an existing directory.
      55                 :  *
      56                 :  * Revision 1.6  2003/03/21 14:20:49  warmerda
      57                 :  * fixed email
      58                 :  *
      59                 :  * Revision 1.5  2002/02/08 16:52:16  warmerda
      60                 :  * added support for FORMAT=MIF option for creating layers
      61                 :  *
      62                 :  * Revision 1.4  2001/02/06 22:13:54  warmerda
      63                 :  * fixed memory leak in OGRTABDataSource::CreateLayer()
      64                 :  *
      65                 :  * Revision 1.3  2001/01/22 16:03:58  warmerda
      66                 :  * expanded tabs
      67                 :  *
      68                 :  * Revision 1.2  2000/07/04 01:46:23  warmerda
      69                 :  * Avoid warnings on unused arguments.
      70                 :  *
      71                 :  * Revision 1.1  2000/01/26 18:17:09  warmerda
      72                 :  * New
      73                 :  *
      74                 :  **********************************************************************/
      75                 : 
      76                 : #include "mitab_ogr_driver.h"
      77                 : 
      78                 : 
      79                 : /*=======================================================================
      80                 :  *                 OGRTABDataSource
      81                 :  *
      82                 :  * We need one single OGRDataSource/Driver set of classes to handle all
      83                 :  * the MapInfo file types.  They all deal with the IMapInfoFile abstract
      84                 :  * class.
      85                 :  *=====================================================================*/
      86                 : 
      87                 : /************************************************************************/
      88                 : /*                         OGRTABDataSource()                           */
      89                 : /************************************************************************/
      90                 : 
      91             197 : OGRTABDataSource::OGRTABDataSource()
      92                 : 
      93                 : {
      94             197 :     m_pszName = NULL;
      95             197 :     m_pszDirectory = NULL;
      96             197 :     m_nLayerCount = 0;
      97             197 :     m_papoLayers = NULL;
      98             197 :     m_papszOptions = NULL;
      99             197 :     m_bCreateMIF = FALSE;
     100             197 :     m_bSingleFile = FALSE;
     101             197 :     m_bSingleLayerAlreadyCreated = FALSE;
     102             197 :     m_bQuickSpatialIndexMode = FALSE;
     103             197 : }
     104                 : 
     105                 : /************************************************************************/
     106                 : /*                         ~OGRTABDataSource()                          */
     107                 : /************************************************************************/
     108                 : 
     109             197 : OGRTABDataSource::~OGRTABDataSource()
     110                 : 
     111                 : {
     112             197 :     CPLFree( m_pszName ); 
     113             197 :     CPLFree( m_pszDirectory );
     114                 : 
     115             219 :     for( int i = 0; i < m_nLayerCount; i++ )
     116              22 :         delete m_papoLayers[i];
     117                 : 
     118             197 :     CPLFree( m_papoLayers );
     119             197 :     CSLDestroy( m_papszOptions );
     120             197 : }
     121                 : 
     122                 : /************************************************************************/
     123                 : /*                               Create()                               */
     124                 : /*                                                                      */
     125                 : /*      Create a new dataset (directory or file).                       */
     126                 : /************************************************************************/
     127                 : 
     128               9 : int OGRTABDataSource::Create( const char * pszName, char **papszOptions )
     129                 : 
     130                 : {
     131                 :     VSIStatBuf  sStat;
     132                 :     const char *pszOpt;
     133                 : 
     134               9 :     CPLAssert( m_pszName == NULL );
     135                 :     
     136               9 :     m_pszName = CPLStrdup( pszName );
     137               9 :     m_papszOptions = CSLDuplicate( papszOptions );
     138                 : 
     139               9 :     if( (pszOpt=CSLFetchNameValue(papszOptions,"FORMAT")) != NULL 
     140                 :         && EQUAL(pszOpt, "MIF") )
     141               1 :         m_bCreateMIF = TRUE;
     142               8 :     else if( EQUAL(CPLGetExtension(pszName),"mif")
     143                 :              || EQUAL(CPLGetExtension(pszName),"mid") )
     144               6 :         m_bCreateMIF = TRUE;
     145                 : 
     146               9 :     if( (pszOpt=CSLFetchNameValue(papszOptions,"SPATIAL_INDEX_MODE")) != NULL 
     147                 :         && EQUAL(pszOpt, "QUICK") )
     148               0 :         m_bQuickSpatialIndexMode = TRUE;
     149                 : 
     150                 : /* -------------------------------------------------------------------- */
     151                 : /*      Create a new empty directory.                                   */
     152                 : /* -------------------------------------------------------------------- */
     153               9 :     if( strlen(CPLGetExtension(pszName)) == 0 )
     154                 :     {
     155               2 :         if( VSIStat( pszName, &sStat ) == 0 )
     156                 :         {
     157               2 :             if( !VSI_ISDIR(sStat.st_mode) )
     158                 :             {
     159                 :                 CPLError( CE_Failure, CPLE_OpenFailed,
     160                 :                           "Attempt to create dataset named %s,\n"
     161                 :                           "but that is an existing file.\n",
     162               0 :                           pszName );
     163               0 :                 return FALSE;
     164                 :             }
     165                 :         }
     166                 :         else
     167                 :         {
     168               0 :             if( VSIMkdir( pszName, 0755 ) != 0 )
     169                 :             {
     170                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     171                 :                           "Unable to create directory %s.\n",
     172               0 :                           pszName );
     173               0 :                 return FALSE;
     174                 :             }
     175                 :         }
     176                 :         
     177               2 :         m_pszDirectory = CPLStrdup(pszName);
     178                 :     }
     179                 : 
     180                 : /* -------------------------------------------------------------------- */
     181                 : /*      Create a new single file.                                       */
     182                 : /* -------------------------------------------------------------------- */
     183                 :     else
     184                 :     {
     185                 :         IMapInfoFile    *poFile;
     186                 : 
     187               7 :         if( m_bCreateMIF )
     188               6 :             poFile = new MIFFile;
     189                 :         else
     190               1 :             poFile = new TABFile;
     191                 : 
     192               7 :         if( poFile->Open( pszName, "wb", FALSE ) != 0 )
     193                 :         {
     194               0 :             delete poFile;
     195               0 :             return FALSE;
     196                 :         }
     197                 :         
     198               7 :         m_nLayerCount = 1;
     199               7 :         m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*));
     200               7 :         m_papoLayers[0] = poFile;
     201                 :         
     202               7 :         m_pszDirectory = CPLStrdup( CPLGetPath(pszName) );
     203               7 :         m_bSingleFile = TRUE;
     204                 :     }
     205                 : 
     206               9 :     return TRUE;
     207                 : }
     208                 : 
     209                 : /************************************************************************/
     210                 : /*                                Open()                                */
     211                 : /*                                                                      */
     212                 : /*      Open an existing file, or directory of files.                   */
     213                 : /************************************************************************/
     214                 : 
     215             188 : int OGRTABDataSource::Open( const char * pszName, int bTestOpen )
     216                 : 
     217                 : {
     218                 :     VSIStatBuf  stat;
     219                 : 
     220             188 :     CPLAssert( m_pszName == NULL );
     221                 :     
     222             188 :     m_pszName = CPLStrdup( pszName );
     223                 : 
     224                 : /* -------------------------------------------------------------------- */
     225                 : /*      Is this a file or directory?                                    */
     226                 : /* -------------------------------------------------------------------- */
     227             188 :     if( VSIStat( pszName, &stat ) != 0 
     228                 :         || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) )
     229                 :     {
     230              18 :         if( !bTestOpen )
     231                 :         {
     232                 :             CPLError( CE_Failure, CPLE_OpenFailed,
     233                 :                       "%s is not a file or directory.\n"
     234                 :                       "Unable to open as a Mapinfo dataset.\n",
     235               0 :                       pszName );
     236                 :         }
     237                 : 
     238              18 :         return FALSE;
     239                 :     }
     240                 : 
     241                 : /* -------------------------------------------------------------------- */
     242                 : /*      If it is a file, try to open as a Mapinfo file.                 */
     243                 : /* -------------------------------------------------------------------- */
     244             170 :     if( VSI_ISREG(stat.st_mode) )
     245                 :     {
     246                 :         IMapInfoFile    *poFile;
     247                 : 
     248             165 :         poFile = IMapInfoFile::SmartOpen( pszName, bTestOpen );
     249             165 :         if( poFile == NULL )
     250             154 :             return FALSE;
     251                 : 
     252              11 :         m_nLayerCount = 1;
     253              11 :         m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*));
     254              11 :         m_papoLayers[0] = poFile;
     255                 : 
     256              11 :         m_pszDirectory = CPLStrdup( CPLGetPath(pszName) );
     257                 :     }
     258                 : 
     259                 : /* -------------------------------------------------------------------- */
     260                 : /*      Otherwise, we need to scan the whole directory for files        */
     261                 : /*      ending in .tab or .mif.                                         */
     262                 : /* -------------------------------------------------------------------- */
     263                 :     else
     264                 :     {
     265               5 :         char    **papszFileList = CPLReadDir( pszName );
     266                 :         
     267               5 :         m_pszDirectory = CPLStrdup( pszName );
     268                 : 
     269              56 :         for( int iFile = 0;
     270                 :              papszFileList != NULL && papszFileList[iFile] != NULL;
     271                 :              iFile++ )
     272                 :         {
     273                 :             IMapInfoFile *poFile;
     274              51 :             const char  *pszExtension = CPLGetExtension(papszFileList[iFile]);
     275                 :             char        *pszSubFilename;
     276                 : 
     277              51 :             if( !EQUAL(pszExtension,"tab") && !EQUAL(pszExtension,"mif") )
     278              49 :                 continue;
     279                 : 
     280                 :             pszSubFilename = CPLStrdup(
     281               2 :                 CPLFormFilename( m_pszDirectory, papszFileList[iFile], NULL ));
     282                 : 
     283               2 :             poFile = IMapInfoFile::SmartOpen( pszSubFilename, bTestOpen );
     284               2 :             CPLFree( pszSubFilename );
     285                 :             
     286               2 :             if( poFile == NULL )
     287                 :             {
     288               0 :                 CSLDestroy( papszFileList );
     289               0 :                 return FALSE;
     290                 :             }
     291                 : 
     292               2 :             m_nLayerCount++;
     293                 :             m_papoLayers = (IMapInfoFile **)
     294               2 :                 CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount);
     295               2 :             m_papoLayers[m_nLayerCount-1] = poFile;
     296                 :         }
     297                 : 
     298               5 :         CSLDestroy( papszFileList );
     299                 : 
     300               5 :         if( m_nLayerCount == 0 )
     301                 :         {
     302               3 :             if( !bTestOpen )
     303                 :                 CPLError( CE_Failure, CPLE_OpenFailed,
     304                 :                           "No mapinfo files found in directory %s.\n",
     305               0 :                           m_pszDirectory );
     306                 :             
     307               3 :             return FALSE;
     308                 :         }
     309                 :     }
     310                 : 
     311              13 :     return TRUE;
     312                 : }
     313                 : 
     314                 : /************************************************************************/
     315                 : /*                           GetLayerCount()                            */
     316                 : /************************************************************************/
     317                 : 
     318              59 : int OGRTABDataSource::GetLayerCount()
     319                 : 
     320                 : {
     321              59 :     if( m_bSingleFile && !m_bSingleLayerAlreadyCreated )
     322               4 :         return 0;
     323                 :     else
     324              55 :         return m_nLayerCount;
     325                 : }
     326                 : 
     327                 : /************************************************************************/
     328                 : /*                              GetLayer()                              */
     329                 : /************************************************************************/
     330                 : 
     331              33 : OGRLayer *OGRTABDataSource::GetLayer( int iLayer )
     332                 : 
     333                 : {
     334              33 :     if( iLayer < 0 || iLayer >= GetLayerCount() )
     335               0 :         return NULL;
     336                 :     else
     337              33 :         return m_papoLayers[iLayer];
     338                 : }
     339                 : 
     340                 : /************************************************************************/
     341                 : /*                            CreateLayer()                             */
     342                 : /************************************************************************/
     343                 : 
     344                 : OGRLayer *
     345                 : OGRTABDataSource::CreateLayer( const char * pszLayerName,
     346                 :                                OGRSpatialReference *poSRSIn,
     347                 :                                OGRwkbGeometryType /* eGeomTypeIn */,
     348               9 :                                char ** /* papszOptions */ )
     349                 : 
     350                 : {
     351                 :     IMapInfoFile        *poFile;
     352                 :     char                *pszFullFilename;
     353                 : 
     354                 : /* -------------------------------------------------------------------- */
     355                 : /*      If it's a single file mode file, then we may have already       */
     356                 : /*      instantiated the low level layer.   We would just need to       */
     357                 : /*      reset the coordinate system and (potentially) bounds.           */
     358                 : /* -------------------------------------------------------------------- */
     359               9 :     if( m_bSingleFile )
     360                 :     {
     361               7 :         if( m_bSingleLayerAlreadyCreated )
     362                 :         {
     363                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     364               0 :                       "Unable to create new layers in this single file dataset.");
     365               0 :             return NULL;
     366                 :         }
     367                 : 
     368               7 :         m_bSingleLayerAlreadyCreated = TRUE;
     369                 : 
     370               7 :         poFile = (IMapInfoFile *) m_papoLayers[0];
     371                 :     }
     372                 : 
     373                 : /* -------------------------------------------------------------------- */
     374                 : /*      We need to initially create the file, and add it as a layer.    */
     375                 : /* -------------------------------------------------------------------- */
     376                 :     else
     377                 :     {
     378               2 :         if( m_bCreateMIF )
     379                 :         {
     380                 :             pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory,
     381               1 :                                                           pszLayerName, "mif" ) );
     382                 :             
     383               1 :             poFile = new MIFFile;
     384                 :         }
     385                 :         else
     386                 :         {
     387                 :             pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory,
     388               1 :                                                           pszLayerName, "tab" ) );
     389                 :             
     390               1 :             poFile = new TABFile;
     391                 :         }
     392                 :         
     393               2 :         if( poFile->Open( pszFullFilename, "wb", FALSE ) != 0 )
     394                 :         {
     395               0 :             CPLFree( pszFullFilename );
     396               0 :             delete poFile;
     397               0 :             return FALSE;
     398                 :         }
     399                 : 
     400               2 :         m_nLayerCount++;
     401                 :         m_papoLayers = (IMapInfoFile **)
     402               2 :             CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount);
     403               2 :         m_papoLayers[m_nLayerCount-1] = poFile;
     404                 : 
     405               2 :         CPLFree( pszFullFilename );
     406                 :     }
     407                 : 
     408                 : /* -------------------------------------------------------------------- */
     409                 : /*      Assign the coordinate system (if provided) and set              */
     410                 : /*      reasonable bounds.                                              */
     411                 : /* -------------------------------------------------------------------- */
     412               9 :     if( poSRSIn != NULL )
     413               1 :         poFile->SetSpatialRef( poSRSIn );
     414                 : 
     415               9 :     if( !poFile->IsBoundsSet() && !m_bCreateMIF )
     416                 :     {
     417               1 :         if( poSRSIn != NULL && poSRSIn->GetRoot() != NULL
     418                 :             && EQUAL(poSRSIn->GetRoot()->GetValue(),"GEOGCS") )
     419               0 :             poFile->SetBounds( -1000, -1000, 1000, 1000 );
     420                 :         else
     421               1 :             poFile->SetBounds( -30000000, -15000000, 30000000, 15000000 );
     422                 :     }
     423                 : 
     424               9 :     if (m_bQuickSpatialIndexMode && poFile->SetQuickSpatialIndexMode() != 0)
     425                 :     {
     426                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     427               0 :                   "Setting Quick Spatial Index Mode failed.");
     428                 :     }
     429                 : 
     430               9 :     return poFile;
     431                 : }
     432                 : 
     433                 : /************************************************************************/
     434                 : /*                           TestCapability()                           */
     435                 : /************************************************************************/
     436                 : 
     437               4 : int OGRTABDataSource::TestCapability( const char * pszCap )
     438                 : 
     439                 : {
     440               4 :     if( EQUAL(pszCap,ODsCCreateLayer) )
     441               4 :         return !m_bSingleFile || !m_bSingleLayerAlreadyCreated;
     442                 :     else
     443               0 :         return FALSE;
     444                 : }
     445                 : 

Generated by: LTP GCOV extension version 1.5