LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/nas - nashandler.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 192 172 89.6 %
Date: 2012-04-28 Functions: 11 7 63.6 %

       1                 : /**********************************************************************
       2                 :  * $Id: nashandler.cpp 24105 2012-03-10 12:08:04Z rouault $
       3                 :  *
       4                 :  * Project:  NAS Reader
       5                 :  * Purpose:  Implementation of NASHandler 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 "nasreaderp.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35                 : #define MAX_TOKEN_SIZE  1000
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                             NASHandler()                             */
      39                 : /************************************************************************/
      40                 : 
      41              18 : NASHandler::NASHandler( NASReader *poReader )
      42                 : 
      43                 : {
      44              18 :     m_poReader = poReader;
      45              18 :     m_pszCurField = NULL;
      46              18 :     m_pszGeometry = NULL;
      47              18 :     m_nGeomAlloc = m_nGeomLen = 0;
      48              18 :     m_nDepthFeature = m_nDepth = 0;
      49              18 :     m_bIgnoreFeature = FALSE;
      50              18 : }
      51                 : 
      52                 : /************************************************************************/
      53                 : /*                            ~NASHandler()                             */
      54                 : /************************************************************************/
      55                 : 
      56              18 : NASHandler::~NASHandler()
      57                 : 
      58                 : {
      59              18 :     CPLFree( m_pszCurField );
      60              18 :     CPLFree( m_pszGeometry );
      61              18 : }
      62                 : 
      63                 : /************************************************************************/
      64                 : /*                        GetAttributes()                               */
      65                 : /************************************************************************/
      66                 : 
      67          899488 : CPLString NASHandler::GetAttributes(const Attributes* attrs)
      68                 : {
      69          899488 :     CPLString osRes;
      70                 :     char *pszString;
      71                 : 
      72          919298 :     for(unsigned int i=0; i < attrs->getLength(); i++)
      73                 :     {
      74           19810 :         osRes += " ";
      75           19810 :         pszString = tr_strdup(attrs->getQName(i));
      76           19810 :         osRes += pszString;
      77           19810 :         CPLFree( pszString );
      78           19810 :         osRes += "=\"";
      79           19810 :         pszString = tr_strdup(attrs->getValue(i));
      80           19810 :         osRes += pszString;
      81           19810 :         CPLFree( pszString );
      82           19810 :         osRes += "\"";
      83                 :     }
      84               0 :     return osRes;
      85                 : }
      86                 : 
      87                 : 
      88                 : /************************************************************************/
      89                 : /*                            startElement()                            */
      90                 : /************************************************************************/
      91                 : 
      92         4470626 : void NASHandler::startElement(const XMLCh* const    uri,
      93                 :                               const XMLCh* const    localname,
      94                 :                               const XMLCh* const    qname,
      95                 :                               const Attributes& attrs )
      96                 : 
      97                 : {
      98                 :     char        szElementName[MAX_TOKEN_SIZE];
      99         4470626 :     GMLReadState *poState = m_poReader->GetState();
     100         4470626 :     const char *pszLast = NULL;
     101                 : 
     102         4470626 :     tr_strcpy( szElementName, localname );
     103                 : 
     104         4470626 :     if (m_bIgnoreFeature && m_nDepth >= m_nDepthFeature)
     105                 :     {
     106         3123872 :         m_nDepth ++;
     107         3123872 :         return;
     108                 :     }
     109                 : 
     110                 : #ifdef DEBUG_VERBOSE
     111                 :     CPLDebug("NAS",
     112                 :               "%*sstartElement %s m_bIgnoreFeature:%d depth:%d depthFeature:%d featureClass:%s",
     113                 :               m_nDepth, "", szElementName,
     114                 :               m_bIgnoreFeature, m_nDepth, m_nDepthFeature,
     115                 :               poState->m_poFeature ? poState->m_poFeature->GetClass()->GetElementName() : "(no feature)"
     116                 :             );
     117                 : #endif
     118                 : 
     119                 : /* -------------------------------------------------------------------- */
     120                 : /*      If we are in the midst of collecting a feature attribute        */
     121                 : /*      value, then this must be a complex attribute which we don't     */
     122                 : /*      try to collect for now, so just terminate the field             */
     123                 : /*      collection.                                                     */
     124                 : /* -------------------------------------------------------------------- */
     125         1346754 :     if( m_pszCurField != NULL )
     126                 :     {
     127             100 :         CPLFree( m_pszCurField );
     128             100 :         m_pszCurField = NULL;
     129                 :     }
     130                 : 
     131                 : /* -------------------------------------------------------------------- */
     132                 : /*      If we are collecting geometry, or if we determine this is a     */
     133                 : /*      geometry element then append to the geometry info.              */
     134                 : /* -------------------------------------------------------------------- */
     135         1346754 :     if( m_pszGeometry != NULL 
     136                 :         || IsGeometryElement( szElementName ) )
     137                 :     {
     138          899488 :         int nLNLen = tr_strlen( localname );
     139          899488 :         CPLString osAttributes = GetAttributes( &attrs );
     140                 : 
     141                 :         /* should save attributes too! */
     142                 : 
     143          899488 :         if( m_pszGeometry == NULL )
     144           13368 :             m_nGeometryDepth = poState->m_nPathLength;
     145                 :         
     146          899488 :         if( m_nGeomLen + nLNLen + 4 + (int)osAttributes.size() > m_nGeomAlloc )
     147                 :         {
     148           13368 :             m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLen + osAttributes.size() + 1000);
     149                 :             m_pszGeometry = (char *) 
     150           13368 :                 CPLRealloc( m_pszGeometry, m_nGeomAlloc);
     151                 :         }
     152                 : 
     153          899488 :         strcpy( m_pszGeometry+m_nGeomLen, "<" );
     154          899488 :         tr_strcpy( m_pszGeometry+m_nGeomLen+1, localname );
     155                 :         
     156          899488 :         if( osAttributes.size() > 0 )
     157                 :         {
     158           19144 :             strcat( m_pszGeometry+m_nGeomLen, " " );
     159           19144 :             strcat( m_pszGeometry+m_nGeomLen, osAttributes );
     160                 :         }
     161                 : 
     162          899488 :         strcat( m_pszGeometry+m_nGeomLen, ">" );
     163          899488 :         m_nGeomLen += strlen(m_pszGeometry+m_nGeomLen);
     164                 :     }
     165                 :     
     166                 : /* -------------------------------------------------------------------- */
     167                 : /*      Is this the ogc:Filter element in a wfs:Delete or               */
     168                 : /*      wfsext:Replace operation?  If so we translate it as a           */
     169                 : /*      specialized sort of feature.                                    */
     170                 : /* -------------------------------------------------------------------- */
     171          447266 :     else if( EQUAL(szElementName,"Filter") 
     172                 :              && (pszLast = m_poReader->GetState()->GetLastComponent()) != NULL
     173                 :              && (EQUAL(pszLast,"Delete") || EQUAL(pszLast,"Replace")) )
     174                 :     {
     175              12 :         const char* pszFilteredClassName = m_poReader->GetFilteredClassName();
     176              12 :         if ( pszFilteredClassName != NULL &&
     177                 :              strcmp("Delete", pszFilteredClassName) != 0 )
     178                 :         {
     179               0 :             m_bIgnoreFeature = TRUE;
     180               0 :             m_nDepthFeature = m_nDepth;
     181               0 :             m_nDepth ++;
     182                 : 
     183               0 :             return;
     184                 :         }
     185                 : 
     186              12 :         m_bIgnoreFeature = FALSE;
     187                 : 
     188              12 :         m_poReader->PushFeature( "Delete", attrs );
     189                 : 
     190              12 :         m_nDepthFeature = m_nDepth;
     191              12 :         m_nDepth ++;
     192                 : 
     193              12 :         CPLAssert( m_osLastTypeName != "" );
     194              12 :         m_poReader->SetFeaturePropertyDirectly( "typeName", CPLStrdup(m_osLastTypeName) );
     195              12 :         m_poReader->SetFeaturePropertyDirectly( "context", CPLStrdup(pszLast) );
     196                 : 
     197              12 :         if( EQUAL( pszLast, "Replace" ) )
     198                 :         {
     199               4 :             CPLAssert( m_osLastReplacingFID != "" );
     200               4 :             CPLAssert( m_osLastSafeToIgnore != "" );
     201               4 :             m_poReader->SetFeaturePropertyDirectly( "replacedBy", CPLStrdup(m_osLastReplacingFID) );
     202               4 :             m_poReader->SetFeaturePropertyDirectly( "safeToIgnore", CPLStrdup(m_osLastSafeToIgnore) );
     203                 :         }
     204                 : 
     205              12 :         return;
     206                 :     }
     207                 : 
     208                 : /* -------------------------------------------------------------------- */
     209                 : /*      Is it a feature?  If so push a whole new state, and return.     */
     210                 : /* -------------------------------------------------------------------- */
     211          447254 :     else if( m_poReader->IsFeatureElement( szElementName ) )
     212                 :     {
     213          139292 :         m_osLastTypeName = szElementName;
     214                 : 
     215          139292 :         const char* pszFilteredClassName = m_poReader->GetFilteredClassName();
     216                 : 
     217          139292 :         pszLast = m_poReader->GetState()->GetLastComponent();
     218          278584 :         if( pszLast != NULL && EQUAL(pszLast,"Replace") )
     219                 :         {
     220                 :             int nIndex;
     221                 :             XMLCh  Name[100];
     222                 : 
     223               6 :             tr_strcpy( Name, "gml:id" );
     224               6 :             nIndex = attrs.getIndex( Name );
     225                 : 
     226               6 :             CPLAssert( nIndex!=-1 );
     227               6 :             CPLAssert( m_osLastReplacingFID=="" );
     228                 : 
     229                 :             // Capture "gml:id" attribute as part of the property value -
     230                 :             // primarily this is for the wfsext:Replace operation's attribute.
     231               6 :             char *pszReplacingFID = tr_strdup( attrs.getValue( nIndex ) );
     232               6 :             m_osLastReplacingFID = pszReplacingFID;
     233               6 :             CPLFree( pszReplacingFID );
     234                 : 
     235                 : #ifdef DEBUG_VERBOSE
     236                 :           CPLDebug("NAS", "%*s### Replace typeName=%s replacedBy=%s", m_nDepth, "", m_osLastTypeName.c_str(), m_osLastReplacingFID.c_str() );
     237                 : #endif
     238                 :         }
     239                 : 
     240          139292 :         if ( pszFilteredClassName != NULL &&
     241                 :              strcmp(szElementName, pszFilteredClassName) != 0 )
     242                 :         {
     243          121836 :             m_bIgnoreFeature = TRUE;
     244          121836 :             m_nDepthFeature = m_nDepth;
     245          121836 :             m_nDepth ++;
     246                 : 
     247          121836 :             return;
     248                 :         }
     249                 : 
     250           17456 :         m_bIgnoreFeature = FALSE;
     251                 : 
     252           17456 :         m_poReader->PushFeature( szElementName, attrs );
     253                 : 
     254           17456 :         m_nDepthFeature = m_nDepth;
     255           17456 :         m_nDepth ++;
     256                 : 
     257           17456 :         return;
     258                 :     }
     259                 : 
     260                 : /* -------------------------------------------------------------------- */
     261                 : /*      If it is the wfs:Delete element, then remember the typeName     */
     262                 : /*      attribute so we can assign it to the feature that will be       */
     263                 : /*      produced when we process the Filter element.                    */
     264                 : /* -------------------------------------------------------------------- */
     265          307962 :     else if( EQUAL(szElementName,"Delete") )
     266                 :     {
     267                 :         int nIndex;
     268                 :         XMLCh  Name[100];
     269                 : 
     270               8 :         tr_strcpy( Name, "typeName" );
     271               8 :         nIndex = attrs.getIndex( Name );
     272                 :         
     273               8 :         if( nIndex != -1 )
     274                 :         {
     275               8 :             char *pszTypeName = tr_strdup( attrs.getValue( nIndex ) );
     276               8 :             m_osLastTypeName = pszTypeName;
     277               8 :             CPLFree( pszTypeName );
     278                 :         }
     279                 : 
     280               8 :         m_osLastSafeToIgnore = "";
     281              16 :         m_osLastReplacingFID = "";
     282                 :     }
     283                 : 
     284                 : /* -------------------------------------------------------------------- */
     285                 : /*      If it is the wfsext:Replace element, then remember the          */
     286                 : /*      safeToIgnore attribute so we can assign it to the feature       */
     287                 : /*      that will be produced when we process the Filter element.       */
     288                 : /* -------------------------------------------------------------------- */
     289          307954 :     else if( EQUAL(szElementName,"Replace") )
     290                 :     {
     291                 :         int nIndex;
     292                 :         XMLCh  Name[100];
     293                 : 
     294               6 :         tr_strcpy( Name, "safeToIgnore" );
     295               6 :         nIndex = attrs.getIndex( Name );
     296                 : 
     297               6 :         if( nIndex != -1 )
     298                 :         {
     299               6 :             char *pszSafeToIgnore = tr_strdup( attrs.getValue( nIndex ) );
     300               6 :             m_osLastSafeToIgnore = pszSafeToIgnore;
     301               6 :             CPLFree( pszSafeToIgnore );
     302                 :         }
     303                 :         else
     304                 :         {
     305               0 :       CPLError( CE_Warning, CPLE_AppDefined, "NAS: safeToIgnore attribute missing" );
     306               0 :             m_osLastSafeToIgnore = "false";
     307                 :         }
     308                 : 
     309               6 :         m_osLastReplacingFID = "";
     310                 :     }
     311                 : 
     312                 : /* -------------------------------------------------------------------- */
     313                 : /*      If it is (or at least potentially is) a simple attribute,       */
     314                 : /*      then start collecting it.                                       */
     315                 : /* -------------------------------------------------------------------- */
     316          307948 :     else if( m_poReader->IsAttributeElement( szElementName ) )
     317                 :     {
     318           77158 :         CPLFree( m_pszCurField );
     319           77158 :         m_pszCurField = CPLStrdup("");
     320                 : 
     321                 :         // Capture href as OB property.
     322           77158 :         m_poReader->CheckForRelations( szElementName, attrs );
     323                 : 
     324                 :         // Capture "fid" attribute as part of the property value - 
     325                 :         // primarily this is for wfs:Delete operation's FeatureId attribute.
     326           77158 :         if( EQUAL(szElementName,"FeatureId") )
     327              12 :             m_poReader->CheckForFID( attrs, &m_pszCurField );
     328                 :     }
     329                 : 
     330                 : /* -------------------------------------------------------------------- */
     331                 : /*      Push the element onto the current state's path.                 */
     332                 : /* -------------------------------------------------------------------- */
     333         1207450 :     poState->PushPath( szElementName );
     334                 : 
     335         1207450 :     m_nDepth ++;
     336                 : }
     337                 : 
     338                 : /************************************************************************/
     339                 : /*                             endElement()                             */
     340                 : /************************************************************************/
     341         4470588 : void NASHandler::endElement(const   XMLCh* const    uri,
     342                 :                             const   XMLCh* const    localname,
     343                 :                             const   XMLCh* const    qname )
     344                 : 
     345                 : {
     346                 :     char        szElementName[MAX_TOKEN_SIZE];
     347         4470588 :     GMLReadState *poState = m_poReader->GetState();
     348                 : 
     349         4470588 :     tr_strcpy( szElementName, localname );
     350                 : 
     351                 : 
     352         4470588 :     m_nDepth --;
     353                 : 
     354         4470588 :     if (m_bIgnoreFeature && m_nDepth >= m_nDepthFeature)
     355                 :     {
     356         3245708 :         if (m_nDepth == m_nDepthFeature)
     357                 :         {
     358          121836 :              m_bIgnoreFeature = FALSE;
     359          121836 :              m_nDepthFeature = 0;
     360                 :         }
     361         3245708 :         return;
     362                 :     }
     363                 : 
     364                 : #ifdef DEBUG_VERBOSE
     365                 :    CPLDebug("NAS",
     366                 :               "%*sendElement %s m_bIgnoreFeature:%d depth:%d depthFeature:%d featureClass:%s",
     367                 :               m_nDepth, "", szElementName,
     368                 :               m_bIgnoreFeature, m_nDepth, m_nDepthFeature,
     369                 :               poState->m_poFeature ? poState->m_poFeature->GetClass()->GetElementName() : "(no feature)"
     370                 :             );
     371                 : #endif
     372                 : 
     373                 : /* -------------------------------------------------------------------- */
     374                 : /*      Is this closing off an attribute value?  We assume so if        */
     375                 : /*      we are collecting an attribute value and got to this point.     */
     376                 : /*      We don't bother validating that the closing tag matches the     */
     377                 : /*      opening tag.                                                    */
     378                 : /* -------------------------------------------------------------------- */
     379         1224880 :     if( m_pszCurField != NULL )
     380                 :     {
     381           77058 :         CPLAssert( poState->m_poFeature != NULL );
     382                 :         
     383           77058 :         m_poReader->SetFeaturePropertyDirectly( poState->osPath.c_str(), m_pszCurField );
     384           77058 :         m_pszCurField = NULL;
     385                 :     }
     386                 : 
     387                 : /* -------------------------------------------------------------------- */
     388                 : /*      If we are collecting Geometry than store it, and consider if    */
     389                 : /*      this is the end of the geometry.                                */
     390                 : /* -------------------------------------------------------------------- */
     391         1224880 :     if( m_pszGeometry != NULL )
     392                 :     {
     393          899488 :         int nLNLen = tr_strlen( localname );
     394                 : 
     395                 :         /* should save attributes too! */
     396                 : 
     397          899488 :         if( m_nGeomLen + nLNLen + 4 > m_nGeomAlloc )
     398                 :         {
     399               0 :             m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLen + 1000);
     400                 :             m_pszGeometry = (char *) 
     401               0 :                 CPLRealloc( m_pszGeometry, m_nGeomAlloc);
     402                 :         }
     403                 : 
     404          899488 :         strcat( m_pszGeometry+m_nGeomLen, "</" );
     405          899488 :         tr_strcpy( m_pszGeometry+m_nGeomLen+2, localname );
     406          899488 :         strcat( m_pszGeometry+m_nGeomLen+nLNLen+2, ">" );
     407          899488 :         m_nGeomLen += strlen(m_pszGeometry+m_nGeomLen);
     408                 : 
     409          899488 :         if( poState->m_nPathLength == m_nGeometryDepth+1 )
     410                 :         {
     411           13368 :             if( poState->m_poFeature != NULL )
     412                 :             {
     413           13368 :                 CPLXMLNode* psNode = CPLParseXMLString(m_pszGeometry);
     414           13368 :                 if (psNode)
     415                 :                 {
     416                 :                     /* workaround common malformed gml:pos with just a
     417                 :                      * elevation value instead of a full 3D coordinate:
     418                 :                      *
     419                 :                      * <gml:Point gml:id="BII2H">
     420                 :                      *    <gml:pos srsName="urn:adv:crs:ETRS89_h">41.394</gml:pos>
     421                 :                      * </gml:Point>
     422                 :                      *
     423                 :                      */
     424                 :                     const char *pszPos;
     425           13368 :                     if( (pszPos = CPLGetXMLValue( psNode, "=Point.pos", NULL ) ) != NULL
     426                 :                         && strstr(pszPos, " ") == NULL )
     427                 :                     {
     428               0 :                         CPLSetXMLValue( psNode, "pos", CPLSPrintf("0 0 %s", pszPos) );
     429                 :                     }
     430                 : 
     431           13368 :                     poState->m_poFeature->SetGeometryDirectly( psNode );
     432                 :                 }
     433                 :             }
     434                 : 
     435           13368 :             CPLFree( m_pszGeometry );
     436           13368 :             m_pszGeometry = NULL;
     437           13368 :             m_nGeomAlloc = m_nGeomLen = 0;
     438                 :         }
     439                 :     }
     440                 : 
     441                 : /* -------------------------------------------------------------------- */
     442                 : /*      If we are collecting a feature, and this element tag matches    */
     443                 : /*      element name for the class, then we have finished the           */
     444                 : /*      feature, and we pop the feature read state.                     */
     445                 : /* -------------------------------------------------------------------- */
     446         1224880 :     if( m_nDepth == m_nDepthFeature && poState->m_poFeature != NULL
     447                 :         && EQUAL(szElementName,
     448                 :                  poState->m_poFeature->GetClass()->GetElementName()) )
     449                 :     {
     450           17456 :         m_nDepthFeature = 0;
     451           17456 :         m_poReader->PopState();
     452                 :     }
     453                 : 
     454                 : /* -------------------------------------------------------------------- */
     455                 : /*      Ends of a wfs:Delete should be triggered on the close of the    */
     456                 : /*      <Filter> element.                                               */
     457                 : /* -------------------------------------------------------------------- */
     458         1207424 :     else if( m_nDepth == m_nDepthFeature 
     459                 :              && poState->m_poFeature != NULL
     460                 :              && EQUAL(szElementName,"Filter") 
     461                 :              && EQUAL(poState->m_poFeature->GetClass()->GetElementName(),
     462                 :                       "Delete") )
     463                 :     {
     464              12 :         m_nDepthFeature = 0;
     465              12 :         m_poReader->PopState();
     466                 :     }
     467                 : 
     468                 : /* -------------------------------------------------------------------- */
     469                 : /*      Otherwise, we just pop the element off the local read states    */
     470                 : /*      element stack.                                                  */
     471                 : /* -------------------------------------------------------------------- */
     472                 :     else
     473                 :     {
     474         1207412 :         if( EQUAL(szElementName,poState->GetLastComponent()) )
     475         1207412 :             poState->PopPath();
     476                 :         else
     477                 :         {
     478               0 :             CPLAssert( FALSE );
     479                 :         }
     480                 :     }
     481                 : }
     482                 : 
     483                 : /************************************************************************/
     484                 : /*                             characters()                             */
     485                 : /************************************************************************/
     486                 : 
     487                 : #if XERCES_VERSION_MAJOR >= 3
     488                 : void NASHandler::characters( const XMLCh *const chars_in,
     489                 :                              const XMLSize_t length )
     490                 : #else
     491         8834374 : void NASHandler::characters(const XMLCh* const chars_in,
     492                 :                             const unsigned int length )
     493                 : #endif
     494                 : 
     495                 : {
     496         8834374 :     const XMLCh *chars = chars_in;
     497                 : 
     498         8834374 :     if( m_pszCurField != NULL )
     499                 :     {
     500           72130 :         int     nCurFieldLength = strlen(m_pszCurField);
     501                 : 
     502           72130 :         if (nCurFieldLength == 0)
     503                 :         {
     504                 :             // Ignore white space
     505          145056 :             while( *chars == ' ' || *chars == 10 || *chars == 13 || *chars == '\t')
     506             796 :                 chars++;
     507                 :         }
     508                 : 
     509           72130 :         char *pszTranslated = tr_strdup(chars);
     510                 :         
     511           72130 :         if( m_pszCurField == NULL )
     512                 :         {
     513               0 :             m_pszCurField = pszTranslated;
     514               0 :             nCurFieldLength = strlen(m_pszCurField);
     515                 :         }
     516                 :         else
     517                 :         {
     518                 :             m_pszCurField = (char *) 
     519                 :                 CPLRealloc( m_pszCurField, 
     520           72130 :                             nCurFieldLength+strlen(pszTranslated)+1 );
     521           72130 :             strcpy( m_pszCurField + nCurFieldLength, pszTranslated );
     522           72130 :             CPLFree( pszTranslated );
     523                 :         }
     524                 :     }
     525         8762244 :     else if( m_pszGeometry != NULL )
     526                 :     {
     527         1785608 :         if (m_nGeomLen == 0)
     528                 :         {
     529                 :             // Ignore white space
     530               0 :             while( *chars == ' ' || *chars == 10 || *chars == 13 || *chars == '\t')
     531               0 :                 chars++;
     532                 :         }
     533                 :         
     534         1785608 :         int nCharsLen = tr_strlen(chars);
     535                 : 
     536         1785608 :         if( m_nGeomLen + nCharsLen*4 + 4 > m_nGeomAlloc )
     537                 :         {
     538           23932 :             m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nCharsLen*4 + 1000);
     539                 :             m_pszGeometry = (char *) 
     540           23932 :                 CPLRealloc( m_pszGeometry, m_nGeomAlloc);
     541                 :         }
     542                 : 
     543         1785608 :         tr_strcpy( m_pszGeometry+m_nGeomLen, chars );
     544         1785608 :         m_nGeomLen += strlen(m_pszGeometry+m_nGeomLen);
     545                 :     }
     546         8834374 : }
     547                 : 
     548                 : /************************************************************************/
     549                 : /*                             fatalError()                             */
     550                 : /************************************************************************/
     551                 : 
     552               0 : void NASHandler::fatalError( const SAXParseException &exception)
     553                 : 
     554                 : {
     555                 :     char *pszErrorMessage;
     556                 : 
     557               0 :     pszErrorMessage = tr_strdup( exception.getMessage() );
     558                 :     CPLError( CE_Failure, CPLE_AppDefined, 
     559                 :               "XML Parsing Error: %s\n", 
     560               0 :               pszErrorMessage );
     561                 : 
     562               0 :     CPLFree( pszErrorMessage );
     563               0 : }
     564                 : 
     565                 : /************************************************************************/
     566                 : /*                         IsGeometryElement()                          */
     567                 : /************************************************************************/
     568                 : 
     569          460634 : int NASHandler::IsGeometryElement( const char *pszElement )
     570                 : 
     571                 : {
     572                 :     return strcmp(pszElement,"Polygon") == 0
     573                 :         || strcmp(pszElement,"MultiPolygon") == 0 
     574                 :         || strcmp(pszElement,"MultiPoint") == 0 
     575                 :         || strcmp(pszElement,"MultiLineString") == 0 
     576                 :         || strcmp(pszElement,"MultiSurface") == 0 
     577                 :         || strcmp(pszElement,"GeometryCollection") == 0
     578                 :         || strcmp(pszElement,"Point") == 0 
     579                 :         || strcmp(pszElement,"Curve") == 0 
     580                 :         || strcmp(pszElement,"Surface") == 0 
     581                 :         || strcmp(pszElement,"PolygonPatch") == 0 
     582          460634 :         || strcmp(pszElement,"LineString") == 0;
     583                 : }

Generated by: LCOV version 1.7