LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/svg - ogrsvgdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 91 76 83.5 %
Date: 2011-12-18 Functions: 12 8 66.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsvgdatasource.cpp 23557 2011-12-12 22:08:17Z rouault $
       3                 :  *
       4                 :  * Project:  SVG Translator
       5                 :  * Purpose:  Implements OGRSVGDataSource class
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault
      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_svg.h"
      31                 : #include "cpl_conv.h"
      32                 : 
      33                 : CPL_CVSID("$Id: ogrsvgdatasource.cpp 23557 2011-12-12 22:08:17Z rouault $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                          OGRSVGDataSource()                          */
      37                 : /************************************************************************/
      38                 : 
      39              48 : OGRSVGDataSource::OGRSVGDataSource()
      40                 : 
      41                 : {
      42              48 :     papoLayers = NULL;
      43              48 :     nLayers = 0;
      44                 : 
      45              48 :     bIsCloudmade = FALSE;
      46                 : 
      47              48 :     pszName = NULL;
      48              48 : }
      49                 : 
      50                 : /************************************************************************/
      51                 : /*                         ~OGRSVGDataSource()                          */
      52                 : /************************************************************************/
      53                 : 
      54              48 : OGRSVGDataSource::~OGRSVGDataSource()
      55                 : 
      56                 : {
      57              51 :     for( int i = 0; i < nLayers; i++ )
      58               3 :         delete papoLayers[i];
      59              48 :     CPLFree( papoLayers );
      60              48 :     CPLFree( pszName );
      61              48 : }
      62                 : 
      63                 : /************************************************************************/
      64                 : /*                              GetLayer()                              */
      65                 : /************************************************************************/
      66                 : 
      67              12 : OGRLayer *OGRSVGDataSource::GetLayer( int iLayer )
      68                 : 
      69                 : {
      70              12 :     if( iLayer < 0 || iLayer >= nLayers )
      71               0 :         return NULL;
      72                 :     else
      73              12 :         return papoLayers[iLayer];
      74                 : }
      75                 : 
      76                 : #ifdef HAVE_EXPAT
      77                 : 
      78                 : /************************************************************************/
      79                 : /*                startElementValidateCbk()                             */
      80                 : /************************************************************************/
      81                 : 
      82             378 : void OGRSVGDataSource::startElementValidateCbk(const char *pszName,
      83                 :                                                const char **ppszAttr)
      84                 : {
      85             378 :     if (eValidity == SVG_VALIDITY_UNKNOWN)
      86                 :     {
      87               6 :         if (strcmp(pszName, "svg") == 0)
      88                 :         {
      89                 :             int i;
      90               1 :             eValidity = SVG_VALIDITY_VALID;
      91               2 :             for(i=0; ppszAttr[i] != NULL; i+= 2)
      92                 :             {
      93               2 :                 if (strcmp(ppszAttr[i], "xmlns:cm") == 0 &&
      94                 :                     strcmp(ppszAttr[i+1], "http://cloudmade.com/") == 0)
      95                 :                 {
      96               1 :                     bIsCloudmade = TRUE;
      97               1 :                     break;
      98                 :                 }
      99                 :             }
     100                 :         }
     101                 :         else
     102                 :         {
     103               5 :             eValidity = SVG_VALIDITY_INVALID;
     104                 :         }
     105                 :     }
     106             378 : }
     107                 : 
     108                 : 
     109                 : /************************************************************************/
     110                 : /*                      dataHandlerValidateCbk()                        */
     111                 : /************************************************************************/
     112                 : 
     113             967 : void OGRSVGDataSource::dataHandlerValidateCbk(const char *data, int nLen)
     114                 : {
     115             967 :     nDataHandlerCounter ++;
     116             967 :     if (nDataHandlerCounter >= BUFSIZ)
     117                 :     {
     118                 :         CPLError(CE_Failure, CPLE_AppDefined,
     119               0 :                  "File probably corrupted (million laugh pattern)");
     120               0 :         XML_StopParser(oCurrentParser, XML_FALSE);
     121                 :     }
     122             967 : }
     123                 : 
     124                 : 
     125             378 : static void XMLCALL startElementValidateCbk(void *pUserData,
     126                 :                                             const char *pszName, const char **ppszAttr)
     127                 : {
     128             378 :     OGRSVGDataSource* poDS = (OGRSVGDataSource*) pUserData;
     129             378 :     poDS->startElementValidateCbk(pszName, ppszAttr);
     130             378 : }
     131                 : 
     132             967 : static void XMLCALL dataHandlerValidateCbk(void *pUserData, const char *data, int nLen)
     133                 : {
     134             967 :     OGRSVGDataSource* poDS = (OGRSVGDataSource*) pUserData;
     135             967 :     poDS->dataHandlerValidateCbk(data, nLen);
     136             967 : }
     137                 : #endif
     138                 : 
     139                 : /************************************************************************/
     140                 : /*                                Open()                                */
     141                 : /************************************************************************/
     142                 : 
     143              48 : int OGRSVGDataSource::Open( const char * pszFilename, int bUpdateIn)
     144                 : 
     145                 : {
     146              48 :     if (bUpdateIn)
     147                 :     {
     148                 :         CPLError(CE_Failure, CPLE_NotSupported,
     149               0 :                     "OGR/SVG driver does not support opening a file in update mode");
     150               0 :         return FALSE;
     151                 :     }
     152                 : #ifdef HAVE_EXPAT
     153              48 :     pszName = CPLStrdup( pszFilename );
     154                 : 
     155                 : /* -------------------------------------------------------------------- */
     156                 : /*      Try to open the file.                                           */
     157                 : /* -------------------------------------------------------------------- */
     158              48 :     CPLString osFilename(pszFilename);
     159              48 :     if (EQUAL(CPLGetExtension(pszFilename), "svgz") &&
     160                 :         strstr(pszFilename, "/vsigzip/") == NULL)
     161                 :     {
     162               0 :         osFilename = CPLString("/vsigzip/") + pszFilename;
     163               0 :         pszFilename = osFilename.c_str();
     164                 :     }
     165                 : 
     166              48 :     VSILFILE* fp = VSIFOpenL(pszFilename, "r");
     167              48 :     if (fp == NULL)
     168              21 :         return FALSE;
     169                 :     
     170              27 :     eValidity = SVG_VALIDITY_UNKNOWN;
     171                 : 
     172              27 :     XML_Parser oParser = OGRCreateExpatXMLParser();
     173              27 :     oCurrentParser = oParser;
     174              27 :     XML_SetUserData(oParser, this);
     175              27 :     XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
     176              27 :     XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
     177                 :     
     178                 :     char aBuf[BUFSIZ];
     179                 :     int nDone;
     180                 :     unsigned int nLen;
     181              27 :     int nCount = 0;
     182                 :     
     183                 :     /* Begin to parse the file and look for the <svg> element */
     184                 :     /* It *MUST* be the first element of an XML file */
     185                 :     /* So once we have read the first element, we know if we can */
     186                 :     /* handle the file or not with that driver */
     187               0 :     do
     188                 :     {
     189              27 :         nDataHandlerCounter = 0;
     190              27 :         nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
     191              27 :         nDone = VSIFEofL(fp);
     192              27 :         if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
     193                 :         {
     194              21 :             if (nLen <= BUFSIZ-1)
     195              19 :                 aBuf[nLen] = 0;
     196                 :             else
     197               2 :                 aBuf[BUFSIZ-1] = 0;
     198              21 :             if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg"))
     199                 :             {
     200                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     201                 :                         "XML parsing of SVG file failed : %s at line %d, column %d",
     202                 :                         XML_ErrorString(XML_GetErrorCode(oParser)),
     203                 :                         (int)XML_GetCurrentLineNumber(oParser),
     204               0 :                         (int)XML_GetCurrentColumnNumber(oParser));
     205                 :             }
     206              21 :             eValidity = SVG_VALIDITY_INVALID;
     207              21 :             break;
     208                 :         }
     209               6 :         if (eValidity == SVG_VALIDITY_INVALID)
     210                 :         {
     211               5 :             break;
     212                 :         }
     213               1 :         else if (eValidity == SVG_VALIDITY_VALID)
     214                 :         {
     215               1 :             break;
     216                 :         }
     217                 :         else
     218                 :         {
     219                 :             /* After reading 50 * BUFSIZE bytes, and not finding whether the file */
     220                 :             /* is SVG or not, we give up and fail silently */
     221               0 :             nCount ++;
     222               0 :             if (nCount == 50)
     223               0 :                 break;
     224                 :         }
     225                 :     } while (!nDone && nLen > 0 );
     226                 : 
     227              27 :     XML_ParserFree(oParser);
     228                 : 
     229              27 :     VSIFCloseL(fp);
     230                 : 
     231              27 :     if (eValidity == SVG_VALIDITY_VALID)
     232                 :     {
     233               1 :         if (bIsCloudmade)
     234                 :         {
     235               1 :             nLayers = 3;
     236                 :             papoLayers =(OGRSVGLayer **) CPLRealloc(papoLayers,
     237               1 :                                             nLayers * sizeof(OGRSVGLayer*));
     238               1 :             papoLayers[0] = new OGRSVGLayer( pszFilename, "points", SVG_POINTS, this );
     239               2 :             papoLayers[1] = new OGRSVGLayer( pszFilename, "lines", SVG_LINES, this );
     240               2 :             papoLayers[2] = new OGRSVGLayer( pszFilename, "polygons", SVG_POLYGONS, this );
     241                 :         }
     242                 :         else
     243                 :         {
     244                 :             CPLDebug("SVG",
     245                 :                      "%s seems to be a SVG file, but not a Cloudmade vector one.",
     246               0 :                      pszFilename);
     247                 :         }
     248                 :     }
     249                 : 
     250              27 :     return (nLayers > 0);
     251                 : #else
     252                 :     char aBuf[256];
     253                 :     VSILFILE* fp = VSIFOpenL(pszFilename, "r");
     254                 :     if (fp)
     255                 :     {
     256                 :         unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
     257                 :         aBuf[nLen] = 0;
     258                 :         if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg") &&
     259                 :             strstr(aBuf, "http://cloudmade.com/"))
     260                 :         {
     261                 :             CPLError(CE_Failure, CPLE_NotSupported,
     262                 :                     "OGR/SVG driver has not been built with read support. "
     263                 :                     "Expat library required");
     264                 :         }
     265                 :         VSIFCloseL(fp);
     266                 :     }
     267                 :     return FALSE;
     268                 : #endif
     269                 : }
     270                 : 
     271                 : /************************************************************************/
     272                 : /*                            TestCapability()                          */
     273                 : /************************************************************************/
     274                 : 
     275               0 : int OGRSVGDataSource::TestCapability( const char *pszCap )
     276                 : {
     277               0 :     return FALSE;
     278                 : }

Generated by: LCOV version 1.7