LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/csv - ogrcsvdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 234 146 62.4 %
Date: 2012-04-28 Functions: 11 8 72.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrcsvdatasource.cpp 23244 2011-10-16 21:52:16Z rouault $
       3                 :  *
       4                 :  * Project:  CSV Translator
       5                 :  * Purpose:  Implements OGRCSVDataSource class
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_csv.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "cpl_csv.h"
      34                 : #include "cpl_vsi_virtual.h"
      35                 : 
      36                 : CPL_CVSID("$Id: ogrcsvdatasource.cpp 23244 2011-10-16 21:52:16Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                          OGRCSVDataSource()                          */
      40                 : /************************************************************************/
      41                 : 
      42            1206 : OGRCSVDataSource::OGRCSVDataSource()
      43                 : 
      44                 : {
      45            1206 :     papoLayers = NULL;
      46            1206 :     nLayers = 0;
      47                 : 
      48            1206 :     pszName = NULL;
      49                 : 
      50            1206 :     bUpdate = FALSE;
      51            1206 : }
      52                 : 
      53                 : /************************************************************************/
      54                 : /*                         ~OGRCSVDataSource()                          */
      55                 : /************************************************************************/
      56                 : 
      57            1206 : OGRCSVDataSource::~OGRCSVDataSource()
      58                 : 
      59                 : {
      60            1422 :     for( int i = 0; i < nLayers; i++ )
      61             216 :         delete papoLayers[i];
      62            1206 :     CPLFree( papoLayers );
      63                 : 
      64            1206 :     CPLFree( pszName );
      65            1206 : }
      66                 : 
      67                 : /************************************************************************/
      68                 : /*                           TestCapability()                           */
      69                 : /************************************************************************/
      70                 : 
      71              10 : int OGRCSVDataSource::TestCapability( const char * pszCap )
      72                 : 
      73                 : {
      74              10 :     if( EQUAL(pszCap,ODsCCreateLayer) )
      75               6 :         return bUpdate;
      76               4 :     else if( EQUAL(pszCap,ODsCDeleteLayer) )
      77               4 :         return bUpdate;
      78                 :     else
      79               0 :         return FALSE;
      80                 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                              GetLayer()                              */
      84                 : /************************************************************************/
      85                 : 
      86             286 : OGRLayer *OGRCSVDataSource::GetLayer( int iLayer )
      87                 : 
      88                 : {
      89             286 :     if( iLayer < 0 || iLayer >= nLayers )
      90               0 :         return NULL;
      91                 :     else
      92             286 :         return papoLayers[iLayer];
      93                 : }
      94                 : 
      95                 : /************************************************************************/
      96                 : /*                                Open()                                */
      97                 : /************************************************************************/
      98                 : 
      99            1206 : int OGRCSVDataSource::Open( const char * pszFilename, int bUpdateIn,
     100                 :                             int bForceOpen )
     101                 : 
     102                 : {
     103            1206 :     pszName = CPLStrdup( pszFilename );
     104            1206 :     bUpdate = bUpdateIn;
     105                 : 
     106            1206 :     if (bUpdateIn && bForceOpen && EQUAL(pszFilename, "/vsistdout/"))
     107               2 :         return TRUE;
     108                 : 
     109                 :     /* For writable /vsizip/, do nothing more */
     110            1204 :     if (bUpdateIn && bForceOpen && strncmp(pszFilename, "/vsizip/", 8) == 0)
     111               0 :         return TRUE;
     112                 : 
     113            1204 :     CPLString osFilename(pszFilename);
     114            1204 :     CPLString osBaseFilename = CPLGetFilename(pszFilename);
     115            1204 :     CPLString osExt = CPLGetExtension(osFilename);
     116            1204 :     pszFilename = NULL;
     117                 : 
     118            1204 :     int bIgnoreExtension = EQUALN(osFilename, "CSV:", 4);
     119            1204 :     int bUSGeonamesFile = FALSE;
     120            1204 :     int bGeonamesOrgFile = FALSE;
     121            1204 :     if (bIgnoreExtension)
     122                 :     {
     123               0 :         osFilename = osFilename + 4;
     124                 :     }
     125                 : 
     126                 :     /* Those are *not* real .XLS files, but text file with tab as column separator */
     127            1204 :     if (EQUAL(osBaseFilename, "NfdcFacilities.xls") ||
     128                 :         EQUAL(osBaseFilename, "NfdcRunways.xls") ||
     129                 :         EQUAL(osBaseFilename, "NfdcRemarks.xls") ||
     130                 :         EQUAL(osBaseFilename, "NfdcSchedules.xls"))
     131                 :     {
     132               0 :         if (bUpdateIn)
     133               0 :             return FALSE;
     134               0 :         bIgnoreExtension = TRUE;
     135                 :     }
     136            1204 :     else if ((EQUALN(osBaseFilename, "NationalFile_", 13) ||
     137                 :               EQUALN(osBaseFilename, "POP_PLACES_", 11) ||
     138                 :               EQUALN(osBaseFilename, "HIST_FEATURES_", 14) ||
     139                 :               EQUALN(osBaseFilename, "US_CONCISE_", 11) ||
     140                 :               EQUALN(osBaseFilename, "AllNames_", 9) ||
     141                 :               EQUALN(osBaseFilename, "Feature_Description_History_", 28) ||
     142                 :               EQUALN(osBaseFilename, "ANTARCTICA_", 11) ||
     143                 :               EQUALN(osBaseFilename, "GOVT_UNITS_", 11) ||
     144                 :               EQUALN(osBaseFilename, "NationalFedCodes_", 17) ||
     145                 :               EQUALN(osBaseFilename, "AllStates_", 10) ||
     146                 :               EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) ||
     147                 :               (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_Features_", 10)) ||
     148                 :               (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10))) &&
     149                 :              (EQUAL(osExt, "txt") || EQUAL(osExt, "zip")) )
     150                 :     {
     151               0 :         if (bUpdateIn)
     152               0 :             return FALSE;
     153               0 :         bIgnoreExtension = TRUE;
     154               0 :         bUSGeonamesFile = TRUE;
     155                 : 
     156               0 :         if (EQUAL(osExt, "zip") &&
     157                 :             strstr(osFilename, "/vsizip/") == NULL )
     158                 :         {
     159               0 :             osFilename = "/vsizip/" + osFilename;
     160                 :         }
     161                 :     }
     162            1204 :     else if (EQUAL(osBaseFilename, "allCountries.txt") ||
     163                 :              EQUAL(osBaseFilename, "allCountries.zip"))
     164                 :     {
     165               0 :         if (bUpdateIn)
     166               0 :             return FALSE;
     167               0 :         bIgnoreExtension = TRUE;
     168               0 :         bGeonamesOrgFile = TRUE;
     169                 : 
     170               0 :         if (EQUAL(osExt, "zip") &&
     171                 :             strstr(osFilename, "/vsizip/") == NULL )
     172                 :         {
     173               0 :             osFilename = "/vsizip/" + osFilename;
     174                 :         }
     175                 :     }
     176                 : 
     177                 : /* -------------------------------------------------------------------- */
     178                 : /*      Determine what sort of object this is.                          */
     179                 : /* -------------------------------------------------------------------- */
     180                 :     VSIStatBufL sStatBuf;
     181                 : 
     182            1204 :     if( VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0 )
     183             342 :         return FALSE;
     184                 : 
     185                 : /* -------------------------------------------------------------------- */
     186                 : /*      Is this a single CSV file?                                      */
     187                 : /* -------------------------------------------------------------------- */
     188             862 :     if( VSI_ISREG(sStatBuf.st_mode)
     189                 :         && (bIgnoreExtension || EQUAL(osExt,"csv")) )
     190                 :     {
     191             146 :         if (EQUAL(CPLGetFilename(osFilename), "NfdcFacilities.xls"))
     192                 :         {
     193               0 :             return OpenTable( osFilename, "ARP");
     194                 :         }
     195             146 :         else if (EQUAL(CPLGetFilename(osFilename), "NfdcRunways.xls"))
     196                 :         {
     197               0 :             OpenTable( osFilename, "BaseEndPhysical");
     198               0 :             OpenTable( osFilename, "BaseEndDisplaced");
     199               0 :             OpenTable( osFilename, "ReciprocalEndPhysical");
     200               0 :             OpenTable( osFilename, "ReciprocalEndDisplaced");
     201               0 :             return nLayers != 0;
     202                 :         }
     203             146 :         else if (bUSGeonamesFile)
     204                 :         {
     205                 :             /* GNIS specific */
     206               0 :             if (EQUALN(osBaseFilename, "NationalFedCodes_", 17) ||
     207                 :                 EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) ||
     208                 :                 EQUALN(osBaseFilename, "ANTARCTICA_", 11) ||
     209                 :                 (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10)))
     210                 :             {
     211               0 :                 OpenTable( osFilename, NULL, "PRIMARY");
     212                 :             }
     213               0 :             else if (EQUALN(osBaseFilename, "GOVT_UNITS_", 11) ||
     214                 :                      EQUALN(osBaseFilename, "Feature_Description_History_", 28))
     215                 :             {
     216               0 :                 OpenTable( osFilename, NULL, "");
     217                 :             }
     218                 :             else
     219                 :             {
     220               0 :                 OpenTable( osFilename, NULL, "PRIM");
     221               0 :                 OpenTable( osFilename, NULL, "SOURCE");
     222                 :             }
     223               0 :             return nLayers != 0;
     224                 :         }
     225                 : 
     226             146 :         return OpenTable( osFilename );
     227                 :     }
     228                 : 
     229                 : /* -------------------------------------------------------------------- */
     230                 : /*      Is this a single a ZIP file with only a CSV file inside ?       */
     231                 : /* -------------------------------------------------------------------- */
     232             716 :     if( strncmp(osFilename, "/vsizip/", 8) == 0 &&
     233                 :         EQUAL(osExt, "zip") &&
     234                 :         VSI_ISREG(sStatBuf.st_mode) )
     235                 :     {
     236               0 :         char** papszFiles = VSIReadDir(osFilename);
     237               0 :         if (CSLCount(papszFiles) != 1 ||
     238               0 :             !EQUAL(CPLGetExtension(papszFiles[0]), "CSV"))
     239                 :         {
     240               0 :             CSLDestroy(papszFiles);
     241               0 :             return FALSE;
     242                 :         }
     243               0 :         CPLString osFilename = CPLFormFilename(osFilename, papszFiles[0], NULL);
     244               0 :         CSLDestroy(papszFiles);
     245               0 :         return OpenTable( osFilename );
     246                 :     }
     247                 : 
     248                 : /* -------------------------------------------------------------------- */
     249                 : /*      Otherwise it has to be a directory.                             */
     250                 : /* -------------------------------------------------------------------- */
     251             716 :     if( !VSI_ISDIR(sStatBuf.st_mode) )
     252             668 :         return FALSE;
     253                 : 
     254                 : /* -------------------------------------------------------------------- */
     255                 : /*      Scan through for entries ending in .csv.                        */
     256                 : /* -------------------------------------------------------------------- */
     257              48 :     int nNotCSVCount = 0, i;
     258              48 :     char **papszNames = CPLReadDir( osFilename );
     259                 : 
     260              48 :     for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ )
     261                 :     {
     262                 :         CPLString oSubFilename = 
     263            2296 :             CPLFormFilename( osFilename, papszNames[i], NULL );
     264                 : 
     265            2296 :         if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") )
     266              84 :             continue;
     267                 : 
     268            2212 :         if (EQUAL(CPLGetExtension(oSubFilename),"csvt"))
     269              26 :             continue;
     270                 : 
     271            2186 :         if( VSIStatL( oSubFilename, &sStatBuf ) != 0 
     272                 :             || !VSI_ISREG(sStatBuf.st_mode) )
     273                 :         {
     274               4 :             nNotCSVCount++;
     275               4 :             continue;
     276                 :         }
     277                 : 
     278            2182 :         if (EQUAL(CPLGetExtension(oSubFilename),"csv"))
     279                 :         {
     280              46 :             if( !OpenTable( oSubFilename ) )
     281                 :             {
     282               0 :                 CSLDestroy( papszNames );
     283               0 :                 nNotCSVCount++;
     284               0 :                 return FALSE;
     285                 :             }
     286                 :         }
     287                 : 
     288                 :         /* GNIS specific */
     289            4272 :         else if ( strlen(papszNames[i]) > 2 &&
     290            2136 :                   EQUALN(papszNames[i]+2, "_Features_", 10) &&
     291               0 :                   EQUAL(CPLGetExtension(papszNames[i]), "txt") )
     292                 :         {
     293               0 :             int bRet = OpenTable( oSubFilename, NULL, "PRIM");
     294               0 :             bRet |= OpenTable( oSubFilename, NULL, "SOURCE");
     295               0 :             if ( !bRet )
     296                 :             {
     297               0 :                 CSLDestroy( papszNames );
     298               0 :                 nNotCSVCount++;
     299               0 :                 return FALSE;
     300                 :             }
     301                 :         }
     302                 :         /* GNIS specific */
     303            4272 :         else if ( strlen(papszNames[i]) > 2 &&
     304            2136 :                   EQUALN(papszNames[i]+2, "_FedCodes_", 10) &&
     305               0 :                   EQUAL(CPLGetExtension(papszNames[i]), "txt") )
     306                 :         {
     307               0 :             if ( !OpenTable( oSubFilename, NULL, "PRIMARY") )
     308                 :             {
     309               0 :                 CSLDestroy( papszNames );
     310               0 :                 nNotCSVCount++;
     311               0 :                 return FALSE;
     312                 :             }
     313                 :         }
     314                 :         else
     315                 :         {
     316            2136 :             nNotCSVCount++;
     317            2136 :             continue;
     318                 :         }
     319                 :     }
     320                 : 
     321              48 :     CSLDestroy( papszNames );
     322                 : 
     323                 : /* -------------------------------------------------------------------- */
     324                 : /*      We presume that this is indeed intended to be a CSV             */
     325                 : /*      datasource if over half the files were .csv files.              */
     326                 : /* -------------------------------------------------------------------- */
     327              48 :     return bForceOpen || nNotCSVCount < nLayers;
     328                 : }
     329                 : 
     330                 : /************************************************************************/
     331                 : /*                              OpenTable()                             */
     332                 : /************************************************************************/
     333                 : 
     334             192 : int OGRCSVDataSource::OpenTable( const char * pszFilename,
     335                 :                                  const char* pszNfdcRunwaysGeomField,
     336                 :                                  const char* pszGeonamesGeomFieldPrefix)
     337                 : 
     338                 : {
     339                 : /* -------------------------------------------------------------------- */
     340                 : /*      Open the file.                                                  */
     341                 : /* -------------------------------------------------------------------- */
     342                 :     VSILFILE       * fp;
     343                 : 
     344             192 :     if( bUpdate )
     345              28 :         fp = VSIFOpenL( pszFilename, "rb+" );
     346                 :     else
     347             164 :         fp = VSIFOpenL( pszFilename, "rb" );
     348             192 :     if( fp == NULL )
     349                 :     {
     350                 :         CPLError( CE_Warning, CPLE_OpenFailed, 
     351                 :                   "Failed to open %s, %s.", 
     352               0 :                   pszFilename, VSIStrerror( errno ) );
     353               0 :         return FALSE;
     354                 :     }
     355                 : 
     356             192 :     if( !bUpdate && strstr(pszFilename, "/vsigzip/") == NULL &&
     357                 :         strstr(pszFilename, "/vsizip/") == NULL )
     358             164 :         fp = (VSILFILE*) VSICreateBufferedReaderHandle((VSIVirtualHandle*)fp);
     359                 : 
     360                 : /* -------------------------------------------------------------------- */
     361                 : /*      Read and parse a line.  Did we get multiple fields?             */
     362                 : /* -------------------------------------------------------------------- */
     363                 : 
     364             192 :     const char* pszLine = CPLReadLineL( fp );
     365             192 :     if (pszLine == NULL)
     366                 :     {
     367               0 :         VSIFCloseL( fp );
     368               0 :         return FALSE;
     369                 :     }
     370             192 :     char chDelimiter = CSVDetectSeperator(pszLine);
     371             192 :     VSIRewindL( fp );
     372                 : 
     373                 :     /* GNIS specific */
     374             192 :     if (pszGeonamesGeomFieldPrefix != NULL &&
     375                 :         strchr(pszLine, '|') != NULL)
     376               0 :         chDelimiter = '|';
     377                 : 
     378             192 :     char **papszFields = OGRCSVReadParseLineL( fp, chDelimiter, FALSE );
     379                 :             
     380             192 :     if( CSLCount(papszFields) < 2 )
     381                 :     {
     382               0 :         VSIFCloseL( fp );
     383               0 :         CSLDestroy( papszFields );
     384               0 :         return FALSE;
     385                 :     }
     386                 : 
     387             192 :     VSIRewindL( fp );
     388             192 :     CSLDestroy( papszFields );
     389                 : 
     390                 : /* -------------------------------------------------------------------- */
     391                 : /*      Create a layer.                                                 */
     392                 : /* -------------------------------------------------------------------- */
     393             192 :     nLayers++;
     394                 :     papoLayers = (OGRCSVLayer **) CPLRealloc(papoLayers, 
     395             192 :                                              sizeof(void*) * nLayers);
     396                 : 
     397             192 :     CPLString osLayerName = CPLGetBasename(pszFilename);
     398             192 :     if (pszNfdcRunwaysGeomField != NULL)
     399                 :     {
     400               0 :         osLayerName += "_";
     401               0 :         osLayerName += pszNfdcRunwaysGeomField;
     402                 :     }
     403             192 :     else if (pszGeonamesGeomFieldPrefix != NULL &&
     404                 :              !EQUAL(pszGeonamesGeomFieldPrefix, ""))
     405                 :     {
     406               0 :         osLayerName += "_";
     407               0 :         osLayerName += pszGeonamesGeomFieldPrefix;
     408                 :     }
     409             192 :     if (EQUAL(pszFilename, "/vsistdin/"))
     410               0 :         osLayerName = "layer";
     411             192 :     papoLayers[nLayers-1] = 
     412                 :         new OGRCSVLayer( osLayerName, fp, pszFilename, FALSE, bUpdate,
     413             384 :                          chDelimiter, pszNfdcRunwaysGeomField, pszGeonamesGeomFieldPrefix );
     414                 : 
     415             192 :     return TRUE;
     416                 : }
     417                 : 
     418                 : /************************************************************************/
     419                 : /*                            CreateLayer()                             */
     420                 : /************************************************************************/
     421                 : 
     422                 : OGRLayer *
     423              26 : OGRCSVDataSource::CreateLayer( const char *pszLayerName, 
     424                 :                                OGRSpatialReference *poSpatialRef,
     425                 :                                OGRwkbGeometryType eGType,
     426                 :                                char ** papszOptions  )
     427                 : 
     428                 : {
     429                 : /* -------------------------------------------------------------------- */
     430                 : /*      Verify we are in update mode.                                   */
     431                 : /* -------------------------------------------------------------------- */
     432              26 :     if (!bUpdate)
     433                 :     {
     434                 :         CPLError( CE_Failure, CPLE_NoWriteAccess,
     435                 :                   "Data source %s opened read-only.\n"
     436                 :                   "New layer %s cannot be created.\n",
     437               0 :                   pszName, pszLayerName );
     438                 : 
     439               0 :         return NULL;
     440                 :     }
     441                 : 
     442                 : /* -------------------------------------------------------------------- */
     443                 : /*      Verify that the datasource is a directory.                      */
     444                 : /* -------------------------------------------------------------------- */
     445                 :     VSIStatBufL sStatBuf;
     446                 : 
     447              26 :     if( strncmp(pszName, "/vsizip/", 8) == 0)
     448                 :     {
     449                 :         /* Do nothing */
     450                 :     }
     451              26 :     else if( !EQUAL(pszName, "/vsistdout/") &&
     452                 :         (VSIStatL( pszName, &sStatBuf ) != 0
     453                 :         || !VSI_ISDIR( sStatBuf.st_mode )) )
     454                 :     {
     455                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     456               0 :                   "Attempt to create csv layer (file) against a non-directory datasource." );
     457               0 :         return NULL;
     458                 :     }
     459                 : 
     460                 : /* -------------------------------------------------------------------- */
     461                 : /*      What filename would we use?                                     */
     462                 : /* -------------------------------------------------------------------- */
     463              26 :     CPLString osFilename;
     464                 : 
     465              26 :     if( osDefaultCSVName != "" )
     466                 :     {
     467               2 :         osFilename = CPLFormFilename( pszName, osDefaultCSVName, NULL );
     468               2 :         osDefaultCSVName = "";
     469                 :     }
     470                 :     else
     471                 :     {
     472              24 :         osFilename = CPLFormFilename( pszName, pszLayerName, "csv" );
     473                 :     }
     474                 : 
     475                 : /* -------------------------------------------------------------------- */
     476                 : /*      Does this directory/file already exist?                         */
     477                 : /* -------------------------------------------------------------------- */
     478              26 :     if( VSIStatL( osFilename, &sStatBuf ) == 0 )
     479                 :     {
     480                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     481                 :                   "Attempt to create layer %s, but %s already exists.",
     482               0 :                   pszLayerName, osFilename.c_str() );
     483               0 :         return NULL;
     484                 :     }
     485                 : 
     486                 : /* -------------------------------------------------------------------- */
     487                 : /*      Create the empty file.                                          */
     488                 : /* -------------------------------------------------------------------- */
     489                 : 
     490              26 :     const char *pszDelimiter = CSLFetchNameValue( papszOptions, "SEPARATOR");
     491              26 :     char chDelimiter = ',';
     492              26 :     if (pszDelimiter != NULL)
     493                 :     {
     494               2 :         if (EQUAL(pszDelimiter, "COMMA"))
     495               0 :             chDelimiter = ',';
     496               2 :         else if (EQUAL(pszDelimiter, "SEMICOLON"))
     497               2 :             chDelimiter = ';';
     498               0 :         else if (EQUAL(pszDelimiter, "TAB"))
     499               0 :             chDelimiter = '\t';
     500                 :         else
     501                 :         {
     502                 :             CPLError( CE_Warning, CPLE_AppDefined, 
     503                 :                   "SEPARATOR=%s not understood, use one of COMMA, SEMICOLON or TAB.",
     504               0 :                   pszDelimiter );
     505                 :         }
     506                 :     }
     507                 : 
     508                 : /* -------------------------------------------------------------------- */
     509                 : /*      Create a layer.                                                 */
     510                 : /* -------------------------------------------------------------------- */
     511              26 :     nLayers++;
     512                 :     papoLayers = (OGRCSVLayer **) CPLRealloc(papoLayers, 
     513              26 :                                              sizeof(void*) * nLayers);
     514                 :     
     515              26 :     papoLayers[nLayers-1] = new OGRCSVLayer( pszLayerName, NULL, osFilename,
     516              52 :                                              TRUE, TRUE, chDelimiter, NULL, NULL );
     517                 : 
     518                 : /* -------------------------------------------------------------------- */
     519                 : /*      Was a partiuclar CRLF order requested?                          */
     520                 : /* -------------------------------------------------------------------- */
     521              52 :     const char *pszCRLFFormat = CSLFetchNameValue( papszOptions, "LINEFORMAT");
     522                 :     int bUseCRLF;
     523                 : 
     524              26 :     if( pszCRLFFormat == NULL )
     525                 :     {
     526                 : #ifdef WIN32
     527                 :         bUseCRLF = TRUE;
     528                 : #else
     529              24 :         bUseCRLF = FALSE;
     530                 : #endif
     531                 :     }
     532               2 :     else if( EQUAL(pszCRLFFormat,"CRLF") )
     533               2 :         bUseCRLF = TRUE;
     534               0 :     else if( EQUAL(pszCRLFFormat,"LF") )
     535               0 :         bUseCRLF = FALSE;
     536                 :     else
     537                 :     {
     538                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     539                 :                   "LINEFORMAT=%s not understood, use one of CRLF or LF.",
     540               0 :                   pszCRLFFormat );
     541                 : #ifdef WIN32
     542                 :         bUseCRLF = TRUE;
     543                 : #else
     544               0 :         bUseCRLF = FALSE;
     545                 : #endif
     546                 :     }
     547                 :     
     548              26 :     papoLayers[nLayers-1]->SetCRLF( bUseCRLF );
     549                 : 
     550                 : /* -------------------------------------------------------------------- */
     551                 : /*      Should we write the geometry ?                                  */
     552                 : /* -------------------------------------------------------------------- */
     553              26 :     const char *pszGeometry = CSLFetchNameValue( papszOptions, "GEOMETRY");
     554              26 :     if (pszGeometry != NULL)
     555                 :     {
     556              10 :         if (EQUAL(pszGeometry, "AS_WKT"))
     557                 :         {
     558               4 :             papoLayers[nLayers-1]->SetWriteGeometry(OGR_CSV_GEOM_AS_WKT);
     559                 :         }
     560              12 :         else if (EQUAL(pszGeometry, "AS_XYZ") ||
     561                 :                  EQUAL(pszGeometry, "AS_XY") ||
     562                 :                  EQUAL(pszGeometry, "AS_YX"))
     563                 :         {
     564              12 :             if (eGType == wkbUnknown || wkbFlatten(eGType) == wkbPoint)
     565                 :             {
     566               6 :                 papoLayers[nLayers-1]->SetWriteGeometry(EQUAL(pszGeometry, "AS_XYZ") ? OGR_CSV_GEOM_AS_XYZ :
     567                 :                                                         EQUAL(pszGeometry, "AS_XY") ?  OGR_CSV_GEOM_AS_XY :
     568              12 :                                                                                        OGR_CSV_GEOM_AS_YX);
     569                 :             }
     570                 :             else
     571                 :             {
     572                 :                 CPLError( CE_Warning, CPLE_AppDefined, 
     573                 :                           "Geometry type %s is not compatible with GEOMETRY=AS_XYZ.",
     574               0 :                           OGRGeometryTypeToName(eGType) );
     575                 :             }
     576                 :         }
     577                 :         else
     578                 :         {
     579                 :             CPLError( CE_Warning, CPLE_AppDefined, 
     580                 :                       "Unsupported value %s for creation option GEOMETRY",
     581               0 :                        pszGeometry );
     582                 :         }
     583                 :     }
     584                 : 
     585                 : /* -------------------------------------------------------------------- */
     586                 : /*      Should we create a CSVT file ?                                  */
     587                 : /* -------------------------------------------------------------------- */
     588                 : 
     589              26 :     const char *pszCreateCSVT = CSLFetchNameValue( papszOptions, "CREATE_CSVT");
     590              26 :     if (pszCreateCSVT)
     591               8 :         papoLayers[nLayers-1]->SetCreateCSVT(CSLTestBoolean(pszCreateCSVT));
     592                 : 
     593              26 :     return papoLayers[nLayers-1];
     594                 : }
     595                 : 
     596                 : /************************************************************************/
     597                 : /*                            DeleteLayer()                             */
     598                 : /************************************************************************/
     599                 : 
     600               2 : OGRErr OGRCSVDataSource::DeleteLayer( int iLayer )
     601                 : 
     602                 : {
     603                 :     char *pszFilename;
     604                 :     char *pszFilenameCSVT;
     605                 : 
     606                 : /* -------------------------------------------------------------------- */
     607                 : /*      Verify we are in update mode.                                   */
     608                 : /* -------------------------------------------------------------------- */
     609               2 :     if( !bUpdate )
     610                 :     {
     611                 :         CPLError( CE_Failure, CPLE_NoWriteAccess,
     612                 :                   "Data source %s opened read-only.\n"
     613                 :                   "Layer %d cannot be deleted.\n",
     614               0 :                   pszName, iLayer );
     615                 : 
     616               0 :         return OGRERR_FAILURE;
     617                 :     }
     618                 : 
     619               2 :     if( iLayer < 0 || iLayer >= nLayers )
     620                 :     {
     621                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     622                 :                   "Layer %d not in legal range of 0 to %d.", 
     623               0 :                   iLayer, nLayers-1 );
     624               0 :         return OGRERR_FAILURE;
     625                 :     }
     626                 : 
     627                 :     pszFilename = 
     628               2 :         CPLStrdup(CPLFormFilename(pszName,papoLayers[iLayer]->GetLayerDefn()->GetName(),"csv"));
     629                 :     pszFilenameCSVT = 
     630               2 :         CPLStrdup(CPLFormFilename(pszName,papoLayers[iLayer]->GetLayerDefn()->GetName(),"csvt"));
     631                 : 
     632               2 :     delete papoLayers[iLayer];
     633                 : 
     634               6 :     while( iLayer < nLayers - 1 )
     635                 :     {
     636               2 :         papoLayers[iLayer] = papoLayers[iLayer+1];
     637               2 :         iLayer++;
     638                 :     }
     639                 : 
     640               2 :     nLayers--;
     641                 : 
     642               2 :     VSIUnlink( pszFilename );
     643               2 :     CPLFree( pszFilename );
     644               2 :     VSIUnlink( pszFilenameCSVT );
     645               2 :     CPLFree( pszFilenameCSVT );
     646                 : 
     647               2 :     return OGRERR_NONE;
     648                 : }

Generated by: LCOV version 1.7