LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gft - ogrgftdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 259 167 64.5 %
Date: 2011-12-18 Functions: 20 15 75.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgftdatasource.cpp 22871 2011-08-06 20:29:35Z rouault $
       3                 :  *
       4                 :  * Project:  GFT Translator
       5                 :  * Purpose:  Implements OGRGFTDataSource class
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
      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_gft.h"
      31                 : 
      32                 : CPL_CVSID("$Id: ogrgftdatasource.cpp 22871 2011-08-06 20:29:35Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /*                          OGRGFTDataSource()                          */
      36                 : /************************************************************************/
      37                 : 
      38              61 : OGRGFTDataSource::OGRGFTDataSource()
      39                 : 
      40                 : {
      41              61 :     papoLayers = NULL;
      42              61 :     nLayers = 0;
      43                 : 
      44              61 :     pszName = NULL;
      45                 : 
      46              61 :     bReadWrite = FALSE;
      47              61 :     bUseHTTPS = FALSE;
      48                 : 
      49              61 :     bMustCleanPersistant = FALSE;
      50              61 : }
      51                 : 
      52                 : /************************************************************************/
      53                 : /*                         ~OGRGFTDataSource()                          */
      54                 : /************************************************************************/
      55                 : 
      56              61 : OGRGFTDataSource::~OGRGFTDataSource()
      57                 : 
      58                 : {
      59             151 :     for( int i = 0; i < nLayers; i++ )
      60              90 :         delete papoLayers[i];
      61              61 :     CPLFree( papoLayers );
      62                 : 
      63              61 :     if (bMustCleanPersistant)
      64                 :     {
      65               8 :         char** papszOptions = CSLAddString(NULL, CPLSPrintf("CLOSE_PERSISTENT=GFT:%p", this));
      66               8 :         CPLHTTPFetch( GetAPIURL(), papszOptions);
      67               8 :         CSLDestroy(papszOptions);
      68                 :     }
      69                 : 
      70              61 :     CPLFree( pszName );
      71              61 : }
      72                 : 
      73                 : /************************************************************************/
      74                 : /*                           TestCapability()                           */
      75                 : /************************************************************************/
      76                 : 
      77               3 : int OGRGFTDataSource::TestCapability( const char * pszCap )
      78                 : 
      79                 : {
      80               3 :     if( bReadWrite && EQUAL(pszCap,ODsCCreateLayer) )
      81               3 :         return TRUE;
      82               0 :     else if( bReadWrite && EQUAL(pszCap,ODsCDeleteLayer) )
      83               0 :         return TRUE;
      84                 :     else
      85               0 :         return FALSE;
      86                 : }
      87                 : 
      88                 : /************************************************************************/
      89                 : /*                              GetLayer()                              */
      90                 : /************************************************************************/
      91                 : 
      92              84 : OGRLayer *OGRGFTDataSource::GetLayer( int iLayer )
      93                 : 
      94                 : {
      95              84 :     if( iLayer < 0 || iLayer >= nLayers )
      96               0 :         return NULL;
      97                 :     else
      98              84 :         return papoLayers[iLayer];
      99                 : }
     100                 : 
     101                 : /************************************************************************/
     102                 : /*                          GetLayerByName()                            */
     103                 : /************************************************************************/
     104                 : 
     105               7 : OGRLayer *OGRGFTDataSource::GetLayerByName(const char * pszLayerName)
     106                 : {
     107               7 :     OGRLayer* poLayer = OGRDataSource::GetLayerByName(pszLayerName);
     108               7 :     if (poLayer)
     109               4 :         return poLayer;
     110                 :         
     111               3 :     char* pszGeomColumnName = NULL;
     112               3 :     char* pszName = CPLStrdup(pszLayerName);
     113               3 :     char *pszLeftParenthesis = strchr(pszName, '(');
     114               3 :     if( pszLeftParenthesis != NULL )
     115                 :     {
     116               0 :         *pszLeftParenthesis = '\0';
     117               0 :         pszGeomColumnName = CPLStrdup(pszLeftParenthesis+1);
     118               0 :         int len = strlen(pszGeomColumnName);
     119               0 :         if (len > 0 && pszGeomColumnName[len - 1] == ')')
     120               0 :             pszGeomColumnName[len - 1] = '\0';
     121                 :     }
     122                 :     
     123               3 :     CPLString osTableId(pszName);
     124              40 :     for(int i=0;i<nLayers;i++)
     125                 :     {
     126              37 :         if( strcmp(papoLayers[i]->GetName(), pszName) == 0)
     127                 :         {
     128               0 :             osTableId = ((OGRGFTTableLayer*)papoLayers[i])->GetTableId();
     129               0 :             break;
     130                 :         }
     131                 :     }
     132                 : 
     133                 :     poLayer = new OGRGFTTableLayer(this, pszLayerName, osTableId,
     134               3 :                                    pszGeomColumnName);
     135               3 :     CPLFree(pszName);
     136               3 :     CPLFree(pszGeomColumnName);
     137               3 :     if (poLayer->GetLayerDefn()->GetFieldCount() == 0)
     138                 :     {
     139               3 :         delete poLayer;
     140               3 :         return NULL;
     141                 :     }
     142               0 :     papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     143               0 :     papoLayers[nLayers ++] = poLayer;
     144               0 :     return poLayer;
     145                 : }
     146                 : 
     147                 : /************************************************************************/
     148                 : /*                             FetchAuth()                              */
     149                 : /************************************************************************/
     150                 : 
     151               0 : int OGRGFTDataSource::FetchAuth(const char* pszEmail, const char* pszPassword)
     152                 : {
     153                 : 
     154               0 :     char** papszOptions = NULL;
     155                 : 
     156               0 :     const char* pszAuthURL = CPLGetConfigOption("GFT_AUTH_URL", NULL);
     157               0 :     if (pszAuthURL == NULL)
     158               0 :         pszAuthURL = "https://www.google.com/accounts/ClientLogin";
     159                 : 
     160               0 :     papszOptions = CSLAddString(papszOptions, "HEADERS=Content-Type: application/x-www-form-urlencoded");
     161               0 :     papszOptions = CSLAddString(papszOptions, CPLSPrintf("POSTFIELDS=Email=%s&Passwd=%s&service=fusiontables", pszEmail, pszPassword));
     162               0 :     CPLHTTPResult * psResult = CPLHTTPFetch( pszAuthURL, papszOptions);
     163               0 :     CSLDestroy(papszOptions);
     164               0 :     papszOptions = NULL;
     165                 : 
     166               0 :     if (psResult == NULL)
     167               0 :         return FALSE;
     168                 : 
     169               0 :     const char* pszAuth = NULL;
     170               0 :     if (psResult->pabyData == NULL ||
     171                 :         psResult->pszErrBuf != NULL ||
     172                 :         (pszAuth = strstr((const char*)psResult->pabyData, "Auth=")) == NULL)
     173                 :     {
     174               0 :         CPLHTTPDestroyResult(psResult);
     175               0 :         return FALSE;
     176                 :     }
     177               0 :     osAuth = pszAuth + 5;
     178               0 :     pszAuth = NULL;
     179                 : 
     180               0 :     while(osAuth.size() &&
     181                 :           (osAuth[osAuth.size()-1] == 13 || osAuth[osAuth.size()-1] == 10))
     182               0 :         osAuth.resize(osAuth.size()-1);
     183                 : 
     184               0 :     CPLDebug("GFT", "Auth key : %s", osAuth.c_str());
     185                 : 
     186               0 :     CPLHTTPDestroyResult(psResult);
     187                 : 
     188               0 :     return TRUE;
     189                 : }
     190                 : 
     191                 : /************************************************************************/
     192                 : /*                      OGRGFTGetOptionValue()                          */
     193                 : /************************************************************************/
     194                 : 
     195              32 : CPLString OGRGFTGetOptionValue(const char* pszFilename,
     196                 :                                const char* pszOptionName)
     197                 : {
     198              32 :     CPLString osOptionName(pszOptionName);
     199              32 :     osOptionName += "=";
     200              32 :     const char* pszOptionValue = strstr(pszFilename, osOptionName);
     201              32 :     if (!pszOptionValue)
     202              24 :         return "";
     203                 : 
     204               8 :     CPLString osOptionValue(pszOptionValue + strlen(osOptionName));
     205               8 :     const char* pszSpace = strchr(osOptionValue.c_str(), ' ');
     206               8 :     if (pszSpace)
     207               0 :         osOptionValue.resize(pszSpace - osOptionValue.c_str());
     208               8 :     return osOptionValue;
     209                 : }
     210                 : 
     211                 : /************************************************************************/
     212                 : /*                                Open()                                */
     213                 : /************************************************************************/
     214                 : 
     215              61 : int OGRGFTDataSource::Open( const char * pszFilename, int bUpdateIn)
     216                 : 
     217                 : {
     218              61 :     if (!EQUALN(pszFilename, "GFT:", 4))
     219              53 :         return FALSE;
     220                 : 
     221               8 :     bReadWrite = bUpdateIn;
     222                 : 
     223               8 :     pszName = CPLStrdup( pszFilename );
     224                 : 
     225               8 :     const char* pszEmail = CPLGetConfigOption("GFT_EMAIL", NULL);
     226               8 :     CPLString osEmail = OGRGFTGetOptionValue(pszFilename, "email");
     227               8 :     if (osEmail.size() != 0)
     228               0 :         pszEmail = osEmail.c_str();
     229                 : 
     230               8 :     const char* pszPassword = CPLGetConfigOption("GFT_PASSWORD", NULL);
     231               8 :     CPLString osPassword = OGRGFTGetOptionValue(pszFilename, "password");
     232               8 :     if (osPassword.size() != 0)
     233               0 :         pszPassword = osPassword.c_str();
     234                 : 
     235               8 :     const char* pszAuth = CPLGetConfigOption("GFT_AUTH", NULL);
     236               8 :     osAuth = OGRGFTGetOptionValue(pszFilename, "auth");
     237               8 :     if (osAuth.size() == 0 && pszAuth != NULL)
     238               0 :         osAuth = pszAuth;
     239                 : 
     240               8 :     CPLString osTables = OGRGFTGetOptionValue(pszFilename, "tables");
     241                 : 
     242               8 :     bUseHTTPS = strstr(pszFilename, "protocol=https") != NULL;
     243                 : 
     244               8 :     if (osAuth.size() == 0 && (pszEmail == NULL || pszPassword == NULL))
     245                 :     {
     246               1 :         if (osTables.size() == 0)
     247                 :         {
     248                 :             CPLError(CE_Failure, CPLE_AppDefined,
     249               0 :                     "Unauthenticated access requires explicit tables= parameter");
     250               0 :             return FALSE;
     251                 :         }
     252                 :     }
     253               7 :     else if (osAuth.size() == 0 && !FetchAuth(pszEmail, pszPassword))
     254                 :     {
     255               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Authentication failed");
     256               0 :         return FALSE;
     257                 :     }
     258                 : 
     259               8 :     if (osTables.size() != 0)
     260                 :     {
     261               1 :         char** papszTables = CSLTokenizeString2(osTables, ",", 0);
     262               4 :         for(int i=0;papszTables && papszTables[i];i++)
     263                 :         {
     264               1 :             papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     265               1 :             papoLayers[nLayers ++] = new OGRGFTTableLayer(this, papszTables[i], papszTables[i]);
     266                 :         }
     267               1 :         CSLDestroy(papszTables);
     268               1 :         return TRUE;
     269                 :     }
     270                 : 
     271                 :     /* Get list of tables */
     272               7 :     CPLHTTPResult * psResult = RunSQL("SHOW TABLES");
     273                 : 
     274               7 :     if (psResult == NULL)
     275               0 :         return FALSE;
     276                 : 
     277               7 :     char* pszLine = (char*) psResult->pabyData;
     278               7 :     if (pszLine == NULL ||
     279                 :         psResult->pszErrBuf != NULL ||
     280                 :         strncmp(pszLine, "table id,name", strlen("table id,name")) != 0)
     281                 :     {
     282               0 :         CPLHTTPDestroyResult(psResult);
     283               0 :         return FALSE;
     284                 :     }
     285                 : 
     286               7 :     pszLine = OGRGFTGotoNextLine(pszLine);
     287             117 :     while(pszLine != NULL && *pszLine != 0)
     288                 :     {
     289             103 :         char* pszNextLine = OGRGFTGotoNextLine(pszLine);
     290             103 :         if (pszNextLine)
     291             103 :             pszNextLine[-1] = 0;
     292                 : 
     293             103 :         char** papszTokens = CSLTokenizeString2(pszLine, ",", 0);
     294             103 :         if (CSLCount(papszTokens) == 2)
     295                 :         {
     296              89 :             CPLString osTableId(papszTokens[0]);
     297              89 :             CPLString osLayerName(papszTokens[1]);
     298             612 :             for(int i=0;i<nLayers;i++)
     299                 :             {
     300             523 :                 if (strcmp(papoLayers[i]->GetName(), osLayerName) == 0)
     301                 :                 {
     302               0 :                     osLayerName += " (";
     303               0 :                     osLayerName += osTableId;
     304               0 :                     osLayerName += ")";
     305               0 :                     break;
     306                 :                 }
     307                 :             }
     308              89 :             papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     309              89 :             papoLayers[nLayers ++] = new OGRGFTTableLayer(this, osLayerName, osTableId);
     310                 :         }
     311             103 :         CSLDestroy(papszTokens);
     312                 : 
     313             103 :         pszLine = pszNextLine;
     314                 :     }
     315                 : 
     316               7 :     CPLHTTPDestroyResult(psResult);
     317                 : 
     318               7 :     return TRUE;
     319                 : }
     320                 : 
     321                 : /************************************************************************/
     322                 : /*                            GetAPIURL()                               */
     323                 : /************************************************************************/
     324                 : 
     325              47 : const char*  OGRGFTDataSource::GetAPIURL() const
     326                 : {
     327              47 :     const char* pszAPIURL = CPLGetConfigOption("GFT_API_URL", NULL);
     328              47 :     if (pszAPIURL)
     329               0 :         return pszAPIURL;
     330              47 :     else if (bUseHTTPS)
     331               0 :         return "https://www.google.com/fusiontables/api/query";
     332                 :     else
     333              47 :         return "http://www.google.com/fusiontables/api/query";
     334                 : }
     335                 : 
     336                 : /************************************************************************/
     337                 : /*                           CreateLayer()                              */
     338                 : /************************************************************************/
     339                 : 
     340               4 : OGRLayer   *OGRGFTDataSource::CreateLayer( const char *pszName,
     341                 :                                            OGRSpatialReference *poSpatialRef,
     342                 :                                            OGRwkbGeometryType eGType,
     343                 :                                            char ** papszOptions )
     344                 : {
     345               4 :     if (!bReadWrite)
     346                 :     {
     347               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode");
     348               0 :         return NULL;
     349                 :     }
     350                 : 
     351               4 :     if (osAuth.size() == 0)
     352                 :     {
     353               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in unauthenticated mode");
     354               0 :         return NULL;
     355                 :     }
     356                 : 
     357                 : /* -------------------------------------------------------------------- */
     358                 : /*      Do we already have this layer?  If so, should we blow it        */
     359                 : /*      away?                                                           */
     360                 : /* -------------------------------------------------------------------- */
     361                 :     int iLayer;
     362                 : 
     363              53 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
     364                 :     {
     365              49 :         if( EQUAL(pszName,papoLayers[iLayer]->GetName()) )
     366                 :         {
     367               0 :             if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL
     368                 :                 && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") )
     369                 :             {
     370               0 :                 DeleteLayer( pszName );
     371               0 :                 break;
     372                 :             }
     373                 :             else
     374                 :             {
     375                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     376                 :                           "Layer %s already exists, CreateLayer failed.\n"
     377                 :                           "Use the layer creation option OVERWRITE=YES to "
     378                 :                           "replace it.",
     379               0 :                           pszName );
     380               0 :                 return NULL;
     381                 :             }
     382                 :         }
     383                 :     }
     384                 : 
     385               4 :     OGRGFTTableLayer* poLayer = new OGRGFTTableLayer(this, pszName);
     386               4 :     poLayer->SetGeometryType(eGType);
     387               4 :     papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     388               4 :     papoLayers[nLayers ++] = poLayer;
     389               4 :     return poLayer;
     390                 : }
     391                 : 
     392                 : /************************************************************************/
     393                 : /*                            DeleteLayer()                             */
     394                 : /************************************************************************/
     395                 : 
     396               4 : void OGRGFTDataSource::DeleteLayer( const char *pszLayerName )
     397                 : 
     398                 : {
     399                 :     int iLayer;
     400                 : 
     401                 : /* -------------------------------------------------------------------- */
     402                 : /*      Try to find layer.                                              */
     403                 : /* -------------------------------------------------------------------- */
     404              17 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
     405                 :     {
     406              17 :         if( EQUAL(pszLayerName,papoLayers[iLayer]->GetName()) )
     407               4 :             break;
     408                 :     }
     409                 : 
     410               4 :     if( iLayer == nLayers )
     411                 :     {
     412                 :         CPLError( CE_Failure, CPLE_AppDefined,
     413                 :                   "Attempt to delete layer '%s', but this layer is not known to OGR.",
     414               0 :                   pszLayerName );
     415               0 :         return;
     416                 :     }
     417                 : 
     418               4 :     DeleteLayer(iLayer);
     419                 : }
     420                 : 
     421                 : /************************************************************************/
     422                 : /*                            DeleteLayer()                             */
     423                 : /************************************************************************/
     424                 : 
     425               4 : OGRErr OGRGFTDataSource::DeleteLayer(int iLayer)
     426                 : {
     427               4 :     if (!bReadWrite)
     428                 :     {
     429                 :         CPLError(CE_Failure, CPLE_AppDefined,
     430               0 :                  "Operation not available in read-only mode");
     431               0 :         return OGRERR_FAILURE;
     432                 :     }
     433                 : 
     434               4 :     if (osAuth.size() == 0)
     435                 :     {
     436                 :         CPLError(CE_Failure, CPLE_AppDefined,
     437               0 :                  "Operation not available in unauthenticated mode");
     438               0 :         return OGRERR_FAILURE;
     439                 :     }
     440                 : 
     441               4 :     if( iLayer < 0 || iLayer >= nLayers )
     442                 :     {
     443                 :         CPLError( CE_Failure, CPLE_AppDefined,
     444                 :                   "Layer %d not in legal range of 0 to %d.",
     445               0 :                   iLayer, nLayers-1 );
     446               0 :         return OGRERR_FAILURE;
     447                 :     }
     448                 : 
     449               4 :     CPLString osTableId = ((OGRGFTTableLayer*)papoLayers[iLayer])->GetTableId();
     450               4 :     CPLString osLayerName = GetLayer(iLayer)->GetName();
     451                 : 
     452                 : /* -------------------------------------------------------------------- */
     453                 : /*      Blow away our OGR structures related to the layer.  This is     */
     454                 : /*      pretty dangerous if anything has a reference to this layer!     */
     455                 : /* -------------------------------------------------------------------- */
     456               4 :     CPLDebug( "GFT", "DeleteLayer(%s)", osLayerName.c_str() );
     457                 : 
     458               4 :     delete papoLayers[iLayer];
     459                 :     memmove( papoLayers + iLayer, papoLayers + iLayer + 1,
     460               4 :              sizeof(void *) * (nLayers - iLayer - 1) );
     461               4 :     nLayers--;
     462                 : 
     463                 : /* -------------------------------------------------------------------- */
     464                 : /*      Remove from the database.                                       */
     465                 : /* -------------------------------------------------------------------- */
     466                 : 
     467               4 :     CPLString osSQL("DROP TABLE ");
     468               4 :     osSQL += osTableId;
     469                 : 
     470               4 :     CPLHTTPResult* psResult = RunSQL( osSQL );
     471                 : 
     472               4 :     if (psResult == NULL)
     473                 :     {
     474               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Table deletion failed");
     475               0 :         return OGRERR_FAILURE;
     476                 :     }
     477                 : 
     478               4 :     char* pszLine = (char*) psResult->pabyData;
     479               4 :     if (pszLine == NULL ||
     480                 :         !EQUALN(pszLine, "OK", 2) ||
     481                 :         psResult->pszErrBuf != NULL)
     482                 :     {
     483               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Table deletion failed");
     484               0 :         CPLHTTPDestroyResult(psResult);
     485               0 :         return OGRERR_FAILURE;
     486                 :     }
     487                 : 
     488               4 :     CPLHTTPDestroyResult(psResult);
     489                 : 
     490               4 :     return OGRERR_NONE;
     491                 : }
     492                 : 
     493                 : /************************************************************************/
     494                 : /*                          AddHTTPOptions()                            */
     495                 : /************************************************************************/
     496                 : 
     497              39 : char** OGRGFTDataSource::AddHTTPOptions(char** papszOptions)
     498                 : {
     499              39 :     bMustCleanPersistant = TRUE;
     500                 :     papszOptions = CSLAddString(papszOptions,
     501              39 :         CPLSPrintf("HEADERS=Authorization: GoogleLogin auth=%s", osAuth.c_str()));
     502              39 :     return CSLAddString(papszOptions, CPLSPrintf("PERSISTENT=GFT:%p", this));
     503                 : }
     504                 : 
     505                 : /************************************************************************/
     506                 : /*                               RunSQL()                               */
     507                 : /************************************************************************/
     508                 : 
     509              39 : CPLHTTPResult * OGRGFTDataSource::RunSQL(const char* pszUnescapedSQL)
     510                 : {
     511              39 :     CPLString osSQL("POSTFIELDS=sql=");
     512                 :     /* Do post escaping */
     513            2927 :     for(int i=0;pszUnescapedSQL[i] != 0;i++)
     514                 :     {
     515            2888 :         const int ch = ((unsigned char*)pszUnescapedSQL)[i];
     516            5776 :         if (ch != '&' && ch >= 32 && ch < 128)
     517            2888 :             osSQL += (char)ch;
     518                 :         else
     519               0 :             osSQL += CPLSPrintf("%%%02X", ch);
     520                 :     }
     521              39 :     char** papszOptions = CSLAddString(AddHTTPOptions(), osSQL);
     522              39 :     CPLDebug("GFT", "Run %s", pszUnescapedSQL);
     523              39 :     CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions);
     524              39 :     CSLDestroy(papszOptions);
     525              39 :     if (psResult && psResult->pszContentType &&
     526                 :         strncmp(psResult->pszContentType, "text/html", 9) == 0)
     527                 :     {
     528               3 :         CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server");
     529               3 :         CPLHTTPDestroyResult(psResult);
     530               3 :         psResult = NULL;
     531                 :     }
     532              39 :     return psResult;
     533                 : }
     534                 : 
     535                 : /************************************************************************/
     536                 : /*                             ExecuteSQL()                             */
     537                 : /************************************************************************/
     538                 : 
     539               4 : OGRLayer * OGRGFTDataSource::ExecuteSQL( const char *pszSQLCommand,
     540                 :                                           OGRGeometry *poSpatialFilter,
     541                 :                                           const char *pszDialect )
     542                 : 
     543                 : {
     544               4 :     if( pszDialect != NULL && EQUAL(pszDialect,"OGRSQL") )
     545                 :         return OGRDataSource::ExecuteSQL( pszSQLCommand,
     546                 :                                           poSpatialFilter,
     547               0 :                                           pszDialect );
     548                 : 
     549                 : /* -------------------------------------------------------------------- */
     550                 : /*      Special case DELLAYER: command.                                 */
     551                 : /* -------------------------------------------------------------------- */
     552               4 :     if( EQUALN(pszSQLCommand,"DELLAYER:",9) )
     553                 :     {
     554               4 :         const char *pszLayerName = pszSQLCommand + 9;
     555                 : 
     556               8 :         while( *pszLayerName == ' ' )
     557               0 :             pszLayerName++;
     558                 : 
     559               4 :         DeleteLayer( pszLayerName );
     560               4 :         return NULL;
     561                 :     }
     562                 : 
     563                 : /* -------------------------------------------------------------------- */
     564                 : /*      Create layer.                                                   */
     565                 : /* -------------------------------------------------------------------- */
     566               0 :     OGRGFTResultLayer *poLayer = NULL;
     567                 : 
     568               0 :     CPLString osSQL = pszSQLCommand;
     569               0 :     poLayer = new OGRGFTResultLayer( this, osSQL );
     570               0 :     if (!poLayer->RunSQL())
     571                 :     {
     572               0 :         delete poLayer;
     573               0 :         return NULL;
     574                 :     }
     575                 : 
     576               0 :     if( poSpatialFilter != NULL )
     577               0 :         poLayer->SetSpatialFilter( poSpatialFilter );
     578                 : 
     579               0 :     return poLayer;
     580                 : }
     581                 : 
     582                 : /************************************************************************/
     583                 : /*                          ReleaseResultSet()                          */
     584                 : /************************************************************************/
     585                 : 
     586               0 : void OGRGFTDataSource::ReleaseResultSet( OGRLayer * poLayer )
     587                 : 
     588                 : {
     589               0 :     delete poLayer;
     590               0 : }
     591                 : 
     592                 : /************************************************************************/
     593                 : /*                      OGRGFTGotoNextLine()                            */
     594                 : /************************************************************************/
     595                 : 
     596             174 : char* OGRGFTGotoNextLine(char* pszData)
     597                 : {
     598             174 :     char* pszNextLine = strchr(pszData, '\n');
     599             174 :     if (pszNextLine)
     600             174 :         return pszNextLine + 1;
     601               0 :     return NULL;
     602                 : }

Generated by: LCOV version 1.7