LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gmlutils - gmlfeature.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 97 134 72.4 %
Date: 2024-11-21 22:18:42 Functions: 8 10 80.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Project:  GML Reader
       4             :  * Purpose:  Implementation of GMLFeature.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  **********************************************************************
       8             :  * Copyright (c) 2002, Frank Warmerdam
       9             :  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_port.h"
      15             : #include "gmlfeature.h"
      16             : 
      17             : #include <cstdio>
      18             : 
      19             : #include "cpl_conv.h"
      20             : #include "cpl_error.h"
      21             : #include "cpl_minixml.h"
      22             : #include "cpl_string.h"
      23             : 
      24             : /************************************************************************/
      25             : /*                             GMLFeature()                             */
      26             : /************************************************************************/
      27             : 
      28        2487 : GMLFeature::GMLFeature(GMLFeatureClass *poClass)
      29             :     : m_poClass(poClass), m_pszFID(nullptr), m_nPropertyCount(0),
      30             :       m_pasProperties(nullptr), m_nGeometryCount(0),
      31        2487 :       m_papsGeometry(m_apsGeometry)  // TODO(schwehr): Allowed in init list?
      32             : {
      33        2487 :     m_apsGeometry[0] = nullptr;
      34        2487 :     m_apsGeometry[1] = nullptr;
      35        2487 : }
      36             : 
      37             : /************************************************************************/
      38             : /*                            ~GMLFeature()                             */
      39             : /************************************************************************/
      40             : 
      41        4974 : GMLFeature::~GMLFeature()
      42             : 
      43             : {
      44        2487 :     CPLFree(m_pszFID);
      45             : 
      46        9310 :     for (int i = 0; i < m_nPropertyCount; i++)
      47             :     {
      48        6823 :         const int nSubProperties = m_pasProperties[i].nSubProperties;
      49        6823 :         if (nSubProperties == 1)
      50             :         {
      51        6128 :             CPLFree(m_pasProperties[i].aszSubProperties[0]);
      52             :         }
      53         695 :         else if (nSubProperties > 1)
      54             :         {
      55         710 :             for (int j = 0; j < nSubProperties; j++)
      56         479 :                 CPLFree(m_pasProperties[i].papszSubProperties[j]);
      57         231 :             CPLFree(m_pasProperties[i].papszSubProperties);
      58             :         }
      59             :     }
      60             : 
      61        2487 :     if (m_nGeometryCount == 1)
      62             :     {
      63        2242 :         CPLDestroyXMLNode(m_apsGeometry[0]);
      64             :     }
      65         245 :     else if (m_nGeometryCount > 1)
      66             :     {
      67         281 :         for (int i = 0; i < m_nGeometryCount; i++)
      68         192 :             CPLDestroyXMLNode(m_papsGeometry[i]);
      69          89 :         CPLFree(m_papsGeometry);
      70             :     }
      71             : 
      72        2487 :     if (m_psBoundedByGeometry)
      73          20 :         CPLDestroyXMLNode(m_psBoundedByGeometry);
      74             : 
      75        2487 :     CPLFree(m_pasProperties);
      76        2487 : }
      77             : 
      78             : /************************************************************************/
      79             : /*                               SetFID()                               */
      80             : /************************************************************************/
      81             : 
      82        1453 : void GMLFeature::SetFID(const char *pszFID)
      83             : 
      84             : {
      85        1453 :     CPLFree(m_pszFID);
      86        1453 :     if (pszFID != nullptr)
      87        1453 :         m_pszFID = CPLStrdup(pszFID);
      88             :     else
      89           0 :         m_pszFID = nullptr;
      90        1453 : }
      91             : 
      92             : /************************************************************************/
      93             : /*                        SetPropertyDirectly()                         */
      94             : /************************************************************************/
      95             : 
      96        6607 : void GMLFeature::SetPropertyDirectly(int iIndex, char *pszValue)
      97             : 
      98             : {
      99        6607 :     CPLAssert(pszValue);
     100        6607 :     if (iIndex >= m_nPropertyCount)
     101             :     {
     102        2582 :         const int nClassPropertyCount = m_poClass->GetPropertyCount();
     103        5164 :         m_pasProperties = static_cast<GMLProperty *>(CPLRealloc(
     104        2582 :             m_pasProperties, sizeof(GMLProperty) * nClassPropertyCount));
     105        4182 :         for (int i = 0; i < m_nPropertyCount; i++)
     106             :         {
     107             :             // Make sure papszSubProperties point to the right address in case
     108             :             // m_pasProperties has been relocated.
     109        1600 :             if (m_pasProperties[i].nSubProperties <= 1)
     110        1372 :                 m_pasProperties[i].papszSubProperties =
     111        1372 :                     m_pasProperties[i].aszSubProperties;
     112             :         }
     113        9405 :         for (int i = m_nPropertyCount; i < nClassPropertyCount; i++)
     114             :         {
     115        6823 :             m_pasProperties[i].nSubProperties = 0;
     116        6823 :             m_pasProperties[i].papszSubProperties =
     117        6823 :                 m_pasProperties[i].aszSubProperties;
     118        6823 :             m_pasProperties[i].aszSubProperties[0] = nullptr;
     119        6823 :             m_pasProperties[i].aszSubProperties[1] = nullptr;
     120             :         }
     121        2582 :         m_nPropertyCount = nClassPropertyCount;
     122             :     }
     123             : 
     124        6607 :     GMLProperty *psProperty = &m_pasProperties[iIndex];
     125        6607 :     const int nSubProperties = psProperty->nSubProperties;
     126        6607 :     if (nSubProperties == 0)
     127             :     {
     128        6359 :         psProperty->aszSubProperties[0] = pszValue;
     129             :     }
     130         248 :     else if (nSubProperties == 1)
     131             :     {
     132         231 :         psProperty->papszSubProperties = static_cast<char **>(
     133         231 :             CPLMalloc(sizeof(char *) * (nSubProperties + 2)));
     134         231 :         psProperty->papszSubProperties[0] = psProperty->aszSubProperties[0];
     135         231 :         psProperty->aszSubProperties[0] = nullptr;
     136         231 :         psProperty->papszSubProperties[nSubProperties] = pszValue;
     137         231 :         psProperty->papszSubProperties[nSubProperties + 1] = nullptr;
     138             :     }
     139             :     else
     140             :     {
     141          17 :         psProperty->papszSubProperties = static_cast<char **>(
     142          34 :             CPLRealloc(psProperty->papszSubProperties,
     143          17 :                        sizeof(char *) * (nSubProperties + 2)));
     144          17 :         psProperty->papszSubProperties[nSubProperties] = pszValue;
     145          17 :         psProperty->papszSubProperties[nSubProperties + 1] = nullptr;
     146             :     }
     147        6607 :     psProperty->nSubProperties++;
     148        6607 : }
     149             : 
     150             : /************************************************************************/
     151             : /*                                Dump()                                */
     152             : /************************************************************************/
     153             : 
     154           0 : void GMLFeature::Dump(CPL_UNUSED FILE *fp)
     155             : {
     156           0 :     printf("GMLFeature(%s):\n", m_poClass->GetName()); /*ok*/
     157             : 
     158           0 :     if (m_pszFID != nullptr)
     159           0 :         printf("  FID = %s\n", m_pszFID); /*ok*/
     160             : 
     161           0 :     for (int i = 0; i < m_nPropertyCount; i++)
     162             :     {
     163           0 :         const GMLProperty *psGMLProperty = GetProperty(i);
     164           0 :         printf("  %s = ", m_poClass->GetProperty(i)->GetName()); /*ok*/
     165           0 :         if (psGMLProperty != nullptr)
     166             :         {
     167           0 :             for (int j = 0; j < psGMLProperty->nSubProperties; j++)
     168             :             {
     169           0 :                 if (j > 0)
     170           0 :                     printf(", ");                                   /*ok*/
     171           0 :                 printf("%s", psGMLProperty->papszSubProperties[j]); /*ok*/
     172             :             }
     173           0 :             printf("\n"); /*ok*/
     174             :         }
     175             :     }
     176             : 
     177           0 :     for (int i = 0; i < m_nGeometryCount; i++)
     178             :     {
     179           0 :         char *pszXML = CPLSerializeXMLTree(m_papsGeometry[i]);
     180           0 :         printf("  %s\n", pszXML); /*ok*/
     181           0 :         CPLFree(pszXML);
     182             :     }
     183           0 : }
     184             : 
     185             : /************************************************************************/
     186             : /*                        SetGeometryDirectly()                         */
     187             : /************************************************************************/
     188             : 
     189        2327 : void GMLFeature::SetGeometryDirectly(CPLXMLNode *psGeom)
     190             : 
     191             : {
     192        2327 :     if (m_apsGeometry[0] != nullptr)
     193          16 :         CPLDestroyXMLNode(m_apsGeometry[0]);
     194        2327 :     m_nGeometryCount = 1;
     195        2327 :     m_apsGeometry[0] = psGeom;
     196        2327 : }
     197             : 
     198             : /************************************************************************/
     199             : /*                        SetGeometryDirectly()                         */
     200             : /************************************************************************/
     201             : 
     202         172 : void GMLFeature::SetGeometryDirectly(int nIdx, CPLXMLNode *psGeom)
     203             : 
     204             : {
     205         172 :     if (nIdx == 0 && m_nGeometryCount <= 1)
     206             :     {
     207          78 :         SetGeometryDirectly(psGeom);
     208          78 :         return;
     209             :     }
     210          94 :     else if (nIdx > 0 && m_nGeometryCount <= 1)
     211             :     {
     212          89 :         m_papsGeometry =
     213          89 :             static_cast<CPLXMLNode **>(CPLMalloc(2 * sizeof(CPLXMLNode *)));
     214          89 :         m_papsGeometry[0] = m_apsGeometry[0];
     215          89 :         m_papsGeometry[1] = nullptr;
     216          89 :         m_apsGeometry[0] = nullptr;
     217             :     }
     218             : 
     219          94 :     if (nIdx >= m_nGeometryCount)
     220             :     {
     221          92 :         m_papsGeometry = static_cast<CPLXMLNode **>(
     222          92 :             CPLRealloc(m_papsGeometry, (nIdx + 2) * sizeof(CPLXMLNode *)));
     223         307 :         for (int i = m_nGeometryCount; i <= nIdx + 1; i++)
     224         215 :             m_papsGeometry[i] = nullptr;
     225          92 :         m_nGeometryCount = nIdx + 1;
     226             :     }
     227          94 :     if (m_papsGeometry[nIdx] != nullptr)
     228           0 :         CPLDestroyXMLNode(m_papsGeometry[nIdx]);
     229          94 :     m_papsGeometry[nIdx] = psGeom;
     230             : }
     231             : 
     232             : /************************************************************************/
     233             : /*                          GetGeometryRef()                            */
     234             : /************************************************************************/
     235             : 
     236        2625 : const CPLXMLNode *GMLFeature::GetGeometryRef(int nIdx) const
     237             : {
     238        2625 :     if (nIdx < 0 || nIdx >= m_nGeometryCount)
     239        2420 :         return nullptr;
     240         205 :     return m_papsGeometry[nIdx];
     241             : }
     242             : 
     243             : /************************************************************************/
     244             : /*                             AddGeometry()                            */
     245             : /************************************************************************/
     246             : 
     247           0 : void GMLFeature::AddGeometry(CPLXMLNode *psGeom)
     248             : 
     249             : {
     250           0 :     if (m_nGeometryCount == 0)
     251             :     {
     252           0 :         m_apsGeometry[0] = psGeom;
     253             :     }
     254           0 :     else if (m_nGeometryCount == 1)
     255             :     {
     256           0 :         m_papsGeometry = static_cast<CPLXMLNode **>(
     257           0 :             CPLMalloc((m_nGeometryCount + 2) * sizeof(CPLXMLNode *)));
     258           0 :         m_papsGeometry[0] = m_apsGeometry[0];
     259           0 :         m_apsGeometry[0] = nullptr;
     260           0 :         m_papsGeometry[m_nGeometryCount] = psGeom;
     261           0 :         m_papsGeometry[m_nGeometryCount + 1] = nullptr;
     262             :     }
     263             :     else
     264             :     {
     265           0 :         m_papsGeometry = static_cast<CPLXMLNode **>(CPLRealloc(
     266           0 :             m_papsGeometry, (m_nGeometryCount + 2) * sizeof(CPLXMLNode *)));
     267           0 :         m_papsGeometry[m_nGeometryCount] = psGeom;
     268           0 :         m_papsGeometry[m_nGeometryCount + 1] = nullptr;
     269             :     }
     270           0 :     m_nGeometryCount++;
     271           0 : }
     272             : 
     273             : /************************************************************************/
     274             : /*                         SetBoundedByGeometry()                       */
     275             : /************************************************************************/
     276             : 
     277          20 : void GMLFeature::SetBoundedByGeometry(CPLXMLNode *psGeom)
     278             : 
     279             : {
     280          20 :     if (m_psBoundedByGeometry)
     281           0 :         CPLDestroyXMLNode(m_psBoundedByGeometry);
     282          20 :     m_psBoundedByGeometry = psGeom;
     283          20 : }

Generated by: LCOV version 1.14