LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/gml - gmlhandler.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 189
Code covered: 77.8 % Executed lines: 147

       1                 : /**********************************************************************
       2                 :  * $Id: gmlhandler.cpp 20021 2010-07-11 11:56:20Z rouault $
       3                 :  *
       4                 :  * Project:  GML Reader
       5                 :  * Purpose:  Implementation of GMLHandler class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  **********************************************************************
       9                 :  * Copyright (c) 2002, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  * 
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  * 
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      22                 :  * 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 <ctype.h>
      31                 : #include "gmlreaderp.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35                 : #if HAVE_XERCES == 1
      36                 : 
      37                 : /* Must be a multiple of 4 */
      38                 : #define MAX_TOKEN_SIZE  1000
      39                 : 
      40                 : /************************************************************************/
      41                 : /*                        GMLXercesHandler()                            */
      42                 : /************************************************************************/
      43                 : 
      44              27 : GMLXercesHandler::GMLXercesHandler( GMLReader *poReader ) : GMLHandler(poReader)
      45                 : {
      46              27 :     m_nEntityCounter = 0;
      47              27 : }
      48                 : 
      49                 : /************************************************************************/
      50                 : /*                            startElement()                            */
      51                 : /************************************************************************/
      52                 : 
      53                 : void GMLXercesHandler::startElement(const XMLCh* const    uri,
      54                 :                                     const XMLCh* const    localname,
      55                 :                                     const XMLCh* const    qname,
      56             780 :                                     const Attributes& attrs )
      57                 : 
      58                 : {
      59                 :     char        szElementName[MAX_TOKEN_SIZE];
      60                 : 
      61             780 :     m_nEntityCounter = 0;
      62                 : 
      63                 :     /* A XMLCh character can expand to 4 bytes in UTF-8 */
      64             780 :     if (4 * tr_strlen( localname ) >= MAX_TOKEN_SIZE)
      65                 :     {
      66                 :         static int bWarnOnce = FALSE;
      67               0 :         XMLCh* tempBuffer = (XMLCh*) CPLMalloc(sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4 + 1));
      68               0 :         memcpy(tempBuffer, localname, sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4));
      69               0 :         tempBuffer[MAX_TOKEN_SIZE / 4] = 0;
      70               0 :         tr_strcpy( szElementName, tempBuffer );
      71               0 :         CPLFree(tempBuffer);
      72               0 :         if (!bWarnOnce)
      73                 :         {
      74               0 :             bWarnOnce = TRUE;
      75               0 :             CPLError(CE_Warning, CPLE_AppDefined, "A too big element name has been truncated");
      76                 :         }
      77                 :     }
      78                 :     else
      79             780 :         tr_strcpy( szElementName, localname );
      80                 : 
      81             780 :     if (GMLHandler::startElement(szElementName, (void*) &attrs) == CE_Failure)
      82                 :     {
      83               0 :         throw SAXNotSupportedException("Out of memory");
      84                 :     }
      85             780 : }
      86                 : 
      87                 : /************************************************************************/
      88                 : /*                             endElement()                             */
      89                 : /************************************************************************/
      90                 : void GMLXercesHandler::endElement(const   XMLCh* const    uri,
      91                 :                                   const   XMLCh* const    localname,
      92             768 :                                   const   XMLCh* const    qname )
      93                 : 
      94                 : {
      95                 :     char        szElementName[MAX_TOKEN_SIZE];
      96                 : 
      97             768 :     m_nEntityCounter = 0;
      98                 : 
      99                 :     /* A XMLCh character can expand to 4 bytes in UTF-8 */
     100             768 :     if (4 * tr_strlen( localname ) >= MAX_TOKEN_SIZE)
     101                 :     {
     102               0 :         XMLCh* tempBuffer = (XMLCh*) CPLMalloc(sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4 + 1));
     103               0 :         memcpy(tempBuffer, localname, sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4));
     104               0 :         tempBuffer[MAX_TOKEN_SIZE / 4] = 0;
     105               0 :         tr_strcpy( szElementName, tempBuffer );
     106               0 :         CPLFree(tempBuffer);
     107                 :     }
     108                 :     else
     109             768 :         tr_strcpy( szElementName, localname );
     110                 : 
     111             768 :     if (GMLHandler::endElement(szElementName) == CE_Failure)
     112                 :     {
     113               0 :         throw SAXNotSupportedException("Out of memory");
     114                 :     }
     115             768 : }
     116                 : 
     117                 : #if XERCES_VERSION_MAJOR >= 3
     118                 : /************************************************************************/
     119                 : /*                             characters() (xerces 3 version)          */
     120                 : /************************************************************************/
     121                 : 
     122                 : void GMLXercesHandler::characters(const XMLCh* const chars_in,
     123                 :                                   const XMLSize_t length )
     124                 : {
     125                 :     char* utf8String = tr_strdup(chars_in);
     126                 :     int nLen = strlen(utf8String);
     127                 :     OGRErr eErr = GMLHandler::dataHandler(utf8String, nLen);
     128                 :     CPLFree(utf8String);
     129                 :     if (eErr == CE_Failure)
     130                 :     {
     131                 :         throw SAXNotSupportedException("Out of memory");
     132                 :     }
     133                 : }
     134                 : 
     135                 : #else
     136                 : /************************************************************************/
     137                 : /*                             characters() (xerces 2 version)          */
     138                 : /************************************************************************/
     139                 : 
     140                 : void GMLXercesHandler::characters(const XMLCh* const chars_in,
     141            1523 :                                   const unsigned int length )
     142                 : 
     143                 : {
     144            1523 :     char* utf8String = tr_strdup(chars_in);
     145            1523 :     int nLen = strlen(utf8String);
     146            1523 :     OGRErr eErr = GMLHandler::dataHandler(utf8String, nLen);
     147            1523 :     CPLFree(utf8String);
     148            1523 :     if (eErr == CE_Failure)
     149                 :     {
     150               0 :         throw SAXNotSupportedException("Out of memory");
     151                 :     }
     152            1523 : }
     153                 : #endif
     154                 : 
     155                 : /************************************************************************/
     156                 : /*                             fatalError()                             */
     157                 : /************************************************************************/
     158                 : 
     159               0 : void GMLXercesHandler::fatalError( const SAXParseException &exception)
     160                 : 
     161                 : {
     162                 :     char *pszErrorMessage;
     163                 : 
     164               0 :     pszErrorMessage = tr_strdup( exception.getMessage() );
     165                 :     CPLError( CE_Failure, CPLE_AppDefined, 
     166                 :               "XML Parsing Error: %s\n", 
     167               0 :               pszErrorMessage );
     168                 : 
     169               0 :     CPLFree( pszErrorMessage );
     170               0 : }
     171                 : 
     172                 : /************************************************************************/
     173                 : /*                             startEntity()                            */
     174                 : /************************************************************************/
     175                 : 
     176               0 : void GMLXercesHandler::startEntity (const XMLCh *const name)
     177                 : {
     178               0 :     m_nEntityCounter ++;
     179               0 :     if (m_nEntityCounter > 1000 && !m_poReader->HasStoppedParsing())
     180                 :     {
     181               0 :         throw SAXNotSupportedException("File probably corrupted (million laugh pattern)");
     182                 :     }
     183               0 : }
     184                 : 
     185                 : /************************************************************************/
     186                 : /*                               GetFID()                               */
     187                 : /************************************************************************/
     188                 : 
     189              60 : char* GMLXercesHandler::GetFID(void* attr)
     190                 : {
     191              60 :     const Attributes* attrs = (const Attributes*) attr;
     192                 :     int nFIDIndex;
     193                 :     XMLCh   anFID[100];
     194                 : 
     195              60 :     tr_strcpy( anFID, "fid" );
     196              60 :     nFIDIndex = attrs->getIndex( anFID );
     197              60 :     if( nFIDIndex != -1 )
     198              54 :         return tr_strdup( attrs->getValue( nFIDIndex ) );
     199                 : 
     200               6 :     return NULL;
     201                 : }
     202                 : 
     203                 : /************************************************************************/
     204                 : /*                        GetAttributes()                               */
     205                 : /************************************************************************/
     206                 : 
     207             144 : char* GMLXercesHandler::GetAttributes(void* attr)
     208                 : {
     209             144 :     const Attributes* attrs = (const Attributes*) attr;
     210             144 :     CPLString osRes;
     211                 :     char *pszString;
     212                 : 
     213             159 :     for(unsigned int i=0; i < attrs->getLength(); i++)
     214                 :     {
     215              15 :         osRes += " ";
     216              15 :         pszString = tr_strdup(attrs->getQName(i));
     217              15 :         osRes += pszString;
     218              15 :         CPLFree( pszString );
     219              15 :         osRes += "=\"";
     220              15 :         pszString = tr_strdup(attrs->getValue(i));
     221              15 :         osRes += pszString;
     222              15 :         CPLFree( pszString );
     223              15 :         osRes += "\"";
     224                 :     }
     225             144 :     return CPLStrdup(osRes);
     226                 : }
     227                 : 
     228                 : #else
     229                 : 
     230                 : 
     231                 : /************************************************************************/
     232                 : /*                            GMLExpatHandler()                         */
     233                 : /************************************************************************/
     234                 : 
     235                 : GMLExpatHandler::GMLExpatHandler( GMLReader *poReader, XML_Parser oParser ) : GMLHandler(poReader)
     236                 : 
     237                 : {
     238                 :     m_oParser = oParser;
     239                 :     m_bStopParsing = FALSE;
     240                 :     m_nDataHandlerCounter = 0;
     241                 : }
     242                 : 
     243                 : /************************************************************************/
     244                 : /*                            startElement()                            */
     245                 : /************************************************************************/
     246                 : 
     247                 : OGRErr GMLExpatHandler::startElement(const char *pszName, void* attr )
     248                 : 
     249                 : {
     250                 :     if (m_bStopParsing)
     251                 :         return CE_Failure;
     252                 : 
     253                 :     const char* pszColon = strchr(pszName, ':');
     254                 :     if (pszColon)
     255                 :         pszName = pszColon + 1;
     256                 : 
     257                 :     if (GMLHandler::startElement(pszName, attr) == CE_Failure)
     258                 :     {
     259                 :         CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
     260                 :         m_bStopParsing = TRUE;
     261                 :         XML_StopParser(m_oParser, XML_FALSE);
     262                 :         return CE_Failure;
     263                 :     }
     264                 : 
     265                 :     return CE_None;
     266                 : }
     267                 : 
     268                 : /************************************************************************/
     269                 : /*                             endElement()                             */
     270                 : /************************************************************************/
     271                 : OGRErr GMLExpatHandler::endElement(const char* pszName )
     272                 : 
     273                 : {
     274                 :     if (m_bStopParsing)
     275                 :         return CE_Failure;
     276                 : 
     277                 :     const char* pszColon = strchr(pszName, ':');
     278                 :     if (pszColon)
     279                 :         pszName = pszColon + 1;
     280                 : 
     281                 :     if (GMLHandler::endElement(pszName) == CE_Failure)
     282                 :     {
     283                 :         CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
     284                 :         m_bStopParsing = TRUE;
     285                 :         XML_StopParser(m_oParser, XML_FALSE);
     286                 :         return CE_Failure;
     287                 :     }
     288                 : 
     289                 :     return CE_None;
     290                 : }
     291                 : 
     292                 : /************************************************************************/
     293                 : /*                             characters()                             */
     294                 : /************************************************************************/
     295                 : 
     296                 : OGRErr GMLExpatHandler::dataHandler(const char *data, int nLen)
     297                 : 
     298                 : {
     299                 :     if (m_bStopParsing)
     300                 :         return CE_Failure;
     301                 : 
     302                 :     m_nDataHandlerCounter ++;
     303                 :     if (m_nDataHandlerCounter >= BUFSIZ)
     304                 :     {
     305                 :         CPLError(CE_Failure, CPLE_AppDefined, "File probably corrupted (million laugh pattern)");
     306                 :         m_bStopParsing = TRUE;
     307                 :         XML_StopParser(m_oParser, XML_FALSE);
     308                 :         return CE_Failure;
     309                 :     }
     310                 : 
     311                 :     if (GMLHandler::dataHandler(data, nLen) == CE_Failure)
     312                 :     {
     313                 :         CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
     314                 :         m_bStopParsing = TRUE;
     315                 :         XML_StopParser(m_oParser, XML_FALSE);
     316                 :         return CE_Failure;
     317                 :     }
     318                 : 
     319                 :     return CE_None;
     320                 : }
     321                 : 
     322                 : /************************************************************************/
     323                 : /*                               GetFID()                               */
     324                 : /************************************************************************/
     325                 : 
     326                 : char* GMLExpatHandler::GetFID(void* attr)
     327                 : {
     328                 :     const char** papszIter = (const char** )attr;
     329                 :     while(*papszIter)
     330                 :     {
     331                 :         if (strcmp(*papszIter, "fid") == 0)
     332                 :         {
     333                 :             return CPLStrdup(papszIter[1]);
     334                 :         }
     335                 :         
     336                 :         papszIter += 2;
     337                 :     }
     338                 :     return NULL;
     339                 : }
     340                 : 
     341                 : /************************************************************************/
     342                 : /*                        GetAttributes()                               */
     343                 : /************************************************************************/
     344                 : 
     345                 : char* GMLExpatHandler::GetAttributes(void* attr)
     346                 : {
     347                 :     const char** papszIter = (const char** )attr;
     348                 :     CPLString osRes;
     349                 :     while(*papszIter)
     350                 :     {
     351                 :         osRes += " ";
     352                 :         osRes += *papszIter;
     353                 :         osRes += "=\"";
     354                 :         osRes += papszIter[1];
     355                 :         osRes += "\"";
     356                 : 
     357                 :         papszIter += 2;
     358                 :     }
     359                 :     return CPLStrdup( osRes );
     360                 : }
     361                 : 
     362                 : #endif
     363                 : 
     364                 : 
     365                 : 
     366                 : /************************************************************************/
     367                 : /*                            GMLHandler()                              */
     368                 : /************************************************************************/
     369                 : 
     370              27 : GMLHandler::GMLHandler( GMLReader *poReader )
     371                 : 
     372                 : {
     373              27 :     m_poReader = poReader;
     374              27 :     m_pszCurField = NULL;
     375              27 :     m_pszGeometry = NULL;
     376              27 :     m_nGeomAlloc = m_nGeomLen = 0;
     377              27 :     m_nDepthFeature = m_nDepth = 0;
     378              27 : }
     379                 : 
     380                 : /************************************************************************/
     381                 : /*                            ~GMLHandler()                             */
     382                 : /************************************************************************/
     383                 : 
     384              27 : GMLHandler::~GMLHandler()
     385                 : 
     386                 : {
     387              27 :     CPLFree( m_pszCurField );
     388              27 :     CPLFree( m_pszGeometry );
     389              27 : }
     390                 : 
     391                 : 
     392                 : /************************************************************************/
     393                 : /*                            startElement()                            */
     394                 : /************************************************************************/
     395                 : 
     396             780 : OGRErr GMLHandler::startElement(const char *pszName, void* attr )
     397                 : 
     398                 : {
     399             780 :     GMLReadState *poState = m_poReader->GetState();
     400                 : 
     401             780 :     int nLNLenBytes = strlen(pszName);
     402                 : 
     403                 : /* -------------------------------------------------------------------- */
     404                 : /*      If we are in the midst of collecting a feature attribute        */
     405                 : /*      value, then this must be a complex attribute which we don't     */
     406                 : /*      try to collect for now, so just terminate the field             */
     407                 : /*      collection.                                                     */
     408                 : /* -------------------------------------------------------------------- */
     409             780 :     if( m_pszCurField != NULL )
     410                 :     {
     411              56 :         CPLFree( m_pszCurField );
     412              56 :         m_pszCurField = NULL;
     413                 :     }
     414                 : 
     415                 : /* -------------------------------------------------------------------- */
     416                 : /*      If we are collecting geometry, or if we determine this is a     */
     417                 : /*      geometry element then append to the geometry info.              */
     418                 : /* -------------------------------------------------------------------- */
     419             780 :     if( m_pszGeometry != NULL 
     420                 :         || IsGeometryElement( pszName ) )
     421                 :     {
     422                 :         /* should save attributes too! */
     423                 : 
     424                 :         int bReadGeometry;
     425                 : 
     426             146 :         if( m_pszGeometry == NULL )
     427                 :         {
     428                 :             /* If the <GeometryElementPath> is defined in the .gfs, use it */
     429                 :             /* to read the appropriate geometry element */
     430                 :             const char* pszGeometryElement = (poState->m_poFeature) ?
     431              68 :                     poState->m_poFeature->GetClass()->GetGeometryElement() : NULL;
     432              68 :             if (pszGeometryElement != NULL)
     433               4 :                 bReadGeometry = strcmp(poState->m_pszPath, pszGeometryElement) == 0;
     434                 :             else
     435              64 :                 bReadGeometry = TRUE;
     436              68 :             if (bReadGeometry)
     437              66 :                 m_nGeometryDepth = poState->m_nPathLength;
     438                 :         }
     439                 :         else
     440              78 :             bReadGeometry = TRUE;
     441                 : 
     442             146 :         if (bReadGeometry)
     443                 :         {
     444             144 :             char* pszAttributes = GetAttributes(attr);
     445                 : 
     446             144 :             if( m_nGeomLen + nLNLenBytes + 4 + strlen( pszAttributes ) >
     447                 :                 m_nGeomAlloc )
     448                 :             {
     449                 :                 m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLenBytes + 1000 +
     450              66 :                                     strlen( pszAttributes ));
     451                 :                 char* pszNewGeometry = (char *) 
     452              66 :                     VSIRealloc( m_pszGeometry, m_nGeomAlloc);
     453              66 :                 if (pszNewGeometry == NULL)
     454                 :                 {
     455               0 :                     CPLFree(pszAttributes);
     456               0 :                     return CE_Failure;
     457                 :                 }
     458              66 :                 m_pszGeometry = pszNewGeometry;
     459                 :             }
     460                 : 
     461             144 :             strcpy( m_pszGeometry+m_nGeomLen++, "<" );
     462             144 :             strcpy( m_pszGeometry+m_nGeomLen, pszName );
     463             144 :             m_nGeomLen += nLNLenBytes;
     464                 :             /* saving attributes */
     465             144 :             strcat( m_pszGeometry + m_nGeomLen, pszAttributes );
     466             144 :             m_nGeomLen += strlen( pszAttributes );
     467             144 :             CPLFree(pszAttributes);
     468             144 :             strcat( m_pszGeometry + (m_nGeomLen++), ">" );
     469                 :         }
     470                 :     }
     471                 :     
     472                 : /* -------------------------------------------------------------------- */
     473                 : /*      Is it a feature?  If so push a whole new state, and return.     */
     474                 : /* -------------------------------------------------------------------- */
     475             634 :     else if( m_nDepthFeature == 0 &&
     476                 :              m_poReader->IsFeatureElement( pszName ) )
     477                 :     {
     478              60 :         char* pszFID = GetFID(attr);
     479                 : 
     480              60 :         m_poReader->PushFeature( pszName, pszFID);
     481                 : 
     482              60 :         CPLFree(pszFID);
     483                 : 
     484              60 :         m_nDepthFeature = m_nDepth;
     485              60 :         m_nDepth ++;
     486                 : 
     487              60 :         return CE_None;
     488                 :     }
     489                 : 
     490                 : /* -------------------------------------------------------------------- */
     491                 : /*      If it is (or at least potentially is) a simple attribute,       */
     492                 : /*      then start collecting it.                                       */
     493                 : /* -------------------------------------------------------------------- */
     494             574 :     else if( m_poReader->IsAttributeElement( pszName ) )
     495                 :     {
     496             274 :         CPLFree( m_pszCurField );
     497             274 :         m_pszCurField = CPLStrdup("");
     498                 :     }
     499                 : 
     500                 : /* -------------------------------------------------------------------- */
     501                 : /*      Push the element onto the current state's path.                 */
     502                 : /* -------------------------------------------------------------------- */
     503             720 :     poState->PushPath( pszName );
     504                 : 
     505             720 :     m_nDepth ++;
     506                 : 
     507             720 :     return CE_None;
     508                 : }
     509                 : 
     510                 : /************************************************************************/
     511                 : /*                             endElement()                             */
     512                 : /************************************************************************/
     513             768 : OGRErr GMLHandler::endElement(const char* pszName )
     514                 : 
     515                 : {
     516             768 :     m_nDepth --;
     517                 : 
     518             768 :     GMLReadState *poState = m_poReader->GetState();
     519                 : 
     520             768 :     int nLNLenBytes = strlen(pszName);
     521                 : 
     522                 : /* -------------------------------------------------------------------- */
     523                 : /*      Is this closing off an attribute value?  We assume so if        */
     524                 : /*      we are collecting an attribute value and got to this point.     */
     525                 : /*      We don't bother validating that the closing tag matches the     */
     526                 : /*      opening tag.                                                    */
     527                 : /* -------------------------------------------------------------------- */
     528             768 :     if( m_pszCurField != NULL )
     529                 :     {
     530             218 :         CPLAssert( poState->m_poFeature != NULL );
     531                 :         
     532             218 :         m_poReader->SetFeatureProperty( poState->m_pszPath, m_pszCurField );
     533             218 :         CPLFree( m_pszCurField );
     534             218 :         m_pszCurField = NULL;
     535                 :     }
     536                 : 
     537                 : /* -------------------------------------------------------------------- */
     538                 : /*      If we are collecting Geometry than store it, and consider if    */
     539                 : /*      this is the end of the geometry.                                */
     540                 : /* -------------------------------------------------------------------- */
     541             768 :     if( m_pszGeometry != NULL )
     542                 :     {
     543                 :         /* should save attributes too! */
     544                 : 
     545             144 :         if( m_nGeomLen + nLNLenBytes + 4 > m_nGeomAlloc )
     546                 :         {
     547               0 :             m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLenBytes + 1000);
     548                 :             char* pszNewGeometry = (char *) 
     549               0 :                 VSIRealloc( m_pszGeometry, m_nGeomAlloc);
     550               0 :             if (pszNewGeometry == NULL)
     551                 :             {
     552               0 :                 return CE_Failure;
     553                 :             }
     554               0 :             m_pszGeometry = pszNewGeometry;
     555                 :         }
     556                 : 
     557             144 :         strcat( m_pszGeometry+m_nGeomLen, "</" );
     558             144 :         strcpy( m_pszGeometry+m_nGeomLen+2, pszName );
     559             144 :         strcat( m_pszGeometry+m_nGeomLen+nLNLenBytes+2, ">" );
     560             144 :         m_nGeomLen += nLNLenBytes + 3;
     561                 : 
     562             144 :         if( poState->m_nPathLength == m_nGeometryDepth+1 )
     563                 :         {
     564              66 :             if( poState->m_poFeature != NULL )
     565              58 :                 poState->m_poFeature->SetGeometryDirectly( m_pszGeometry );
     566                 :             else
     567               8 :                 CPLFree( m_pszGeometry );
     568                 : 
     569              66 :             m_pszGeometry = NULL;
     570              66 :             m_nGeomAlloc = m_nGeomLen = 0;
     571                 :         }
     572                 :     }
     573                 : 
     574                 : /* -------------------------------------------------------------------- */
     575                 : /*      If we are collecting a feature, and this element tag matches    */
     576                 : /*      element name for the class, then we have finished the           */
     577                 : /*      feature, and we pop the feature read state.                     */
     578                 : /* -------------------------------------------------------------------- */
     579             768 :     if( m_nDepth == m_nDepthFeature && poState->m_poFeature != NULL
     580                 :         && strcmp(pszName,
     581                 :                  poState->m_poFeature->GetClass()->GetElementName()) == 0 )
     582                 :     {
     583              60 :         m_nDepthFeature = 0;
     584              60 :         m_poReader->PopState();
     585                 :     }
     586                 : 
     587                 : /* -------------------------------------------------------------------- */
     588                 : /*      Otherwise, we just pop the element off the local read states    */
     589                 : /*      element stack.                                                  */
     590                 : /* -------------------------------------------------------------------- */
     591                 :     else
     592                 :     {
     593             708 :         if( strcmp(pszName,poState->GetLastComponent()) == 0 )
     594             708 :             poState->PopPath();
     595                 :         else
     596                 :         {
     597               0 :             CPLAssert( FALSE );
     598                 :         }
     599                 :     }
     600                 : 
     601             768 :     return CE_None;
     602                 : }
     603                 : 
     604                 : /************************************************************************/
     605                 : /*                             characters()                             */
     606                 : /************************************************************************/
     607                 : 
     608            1523 : OGRErr GMLHandler::dataHandler(const char *data, int nLen)
     609                 : 
     610                 : {
     611            1523 :     int nIter = 0;
     612                 : 
     613            1523 :     if( m_pszCurField != NULL )
     614                 :     {
     615             274 :         int     nCurFieldLength = strlen(m_pszCurField);
     616                 : 
     617                 :         // Ignore white space
     618             274 :         if (nCurFieldLength == 0)
     619                 :         {
     620            1056 :             while (nIter < nLen &&
     621                 :                    ( data[nIter] == ' ' || data[nIter] == 10 || data[nIter]== 13 || data[nIter] == '\t') )
     622             508 :                 nIter ++;
     623                 :         }
     624                 : 
     625             274 :         int nCharsLen = nLen - nIter;
     626                 : 
     627                 :         char *pszNewCurField = (char *) 
     628                 :             VSIRealloc( m_pszCurField, 
     629             274 :                         nCurFieldLength+ nCharsLen +1 );
     630             274 :         if (pszNewCurField == NULL)
     631                 :         {
     632               0 :             return CE_Failure;
     633                 :         }
     634             274 :         m_pszCurField = pszNewCurField;
     635             274 :         memcpy( m_pszCurField + nCurFieldLength, data + nIter, nCharsLen);
     636             274 :         nCurFieldLength += nCharsLen;
     637                 : 
     638             274 :         m_pszCurField[nCurFieldLength] = '\0';
     639                 :     }
     640            1249 :     else if( m_pszGeometry != NULL )
     641                 :     {
     642                 :         // Ignore white space
     643             222 :         if (m_nGeomLen == 0)
     644                 :         {
     645               0 :             while (nIter < nLen &&
     646                 :                    ( data[nIter] == ' ' || data[nIter] == 10 || data[nIter]== 13 || data[nIter] == '\t') )
     647               0 :                 nIter ++;
     648                 :         }
     649                 : 
     650             222 :         int nCharsLen = nLen - nIter;
     651                 : 
     652             222 :         if( m_nGeomLen + nCharsLen + 4 > m_nGeomAlloc )
     653                 :         {
     654               0 :             m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nCharsLen + 1000);
     655                 :             char* pszNewGeometry = (char *) 
     656               0 :                 VSIRealloc( m_pszGeometry, m_nGeomAlloc);
     657               0 :             if (pszNewGeometry == NULL)
     658                 :             {
     659               0 :                 return CE_Failure;
     660                 :             }
     661               0 :             m_pszGeometry = pszNewGeometry;
     662                 :         }
     663                 : 
     664             222 :         memcpy( m_pszGeometry+m_nGeomLen, data + nIter, nCharsLen);
     665             222 :         m_nGeomLen += nCharsLen;
     666             222 :         m_pszGeometry[m_nGeomLen] = '\0';
     667                 :     }
     668                 : 
     669            1523 :     return CE_None;
     670                 : }
     671                 : 
     672                 : 
     673                 : /************************************************************************/
     674                 : /*                         IsGeometryElement()                          */
     675                 : /************************************************************************/
     676                 : 
     677             702 : int GMLHandler::IsGeometryElement( const char *pszElement )
     678                 : 
     679                 : {
     680                 :     return strcmp(pszElement,"Polygon") == 0
     681                 :         || strcmp(pszElement,"MultiPolygon") == 0
     682                 :         || strcmp(pszElement,"MultiPoint") == 0
     683                 :         || strcmp(pszElement,"MultiLineString") == 0
     684                 :         || strcmp(pszElement,"MultiSurface") == 0
     685                 :         || strcmp(pszElement,"GeometryCollection") == 0
     686                 :         || strcmp(pszElement,"Point") == 0
     687                 :         || strcmp(pszElement,"Curve") == 0
     688                 :         || strcmp(pszElement,"MultiCurve") == 0
     689                 :         || strcmp(pszElement,"TopoCurve") == 0
     690                 :         || strcmp(pszElement,"Surface") == 0
     691                 :         || strcmp(pszElement,"TopoSurface") == 0
     692                 :         || strcmp(pszElement,"PolygonPatch") == 0
     693             702 :         || strcmp(pszElement,"LineString") == 0;
     694                 : }

Generated by: LTP GCOV extension version 1.5