LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gmlutils - gmlpropertydefn.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 134 142 94.4 %
Date: 2025-10-27 00:14:23 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Project:  GML Reader
       4             :  * Purpose:  Implementation of GMLPropertyDefn
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  **********************************************************************
       8             :  * Copyright (c) 2002, Frank Warmerdam
       9             :  * Copyright (c) 2008-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 <cstring>
      18             : 
      19             : #include "cpl_conv.h"
      20             : #include "cpl_string.h"
      21             : 
      22             : /************************************************************************/
      23             : /*                           GMLPropertyDefn                            */
      24             : /************************************************************************/
      25             : 
      26        3079 : GMLPropertyDefn::GMLPropertyDefn(const char *pszName, const char *pszSrcElement)
      27        3079 :     : m_pszName(CPLStrdup(pszName)),
      28        3079 :       m_pszSrcElement(pszSrcElement ? CPLStrdup(pszSrcElement) : nullptr),
      29        6158 :       m_nSrcElementLen(pszSrcElement ? strlen(pszSrcElement) : 0)
      30             : {
      31        3079 : }
      32             : 
      33             : /************************************************************************/
      34             : /*                          ~GMLPropertyDefn()                          */
      35             : /************************************************************************/
      36             : 
      37        3079 : GMLPropertyDefn::~GMLPropertyDefn()
      38             : 
      39             : {
      40        3079 :     CPLFree(m_pszName);
      41        3079 :     CPLFree(m_pszSrcElement);
      42        3079 :     CPLFree(m_pszCondition);
      43        3079 : }
      44             : 
      45             : /************************************************************************/
      46             : /*                           SetSrcElement()                            */
      47             : /************************************************************************/
      48             : 
      49         200 : void GMLPropertyDefn::SetSrcElement(const char *pszSrcElement)
      50             : 
      51             : {
      52         200 :     CPLFree(m_pszSrcElement);
      53         200 :     if (pszSrcElement != nullptr)
      54             :     {
      55         200 :         m_nSrcElementLen = strlen(pszSrcElement);
      56         200 :         m_pszSrcElement = CPLStrdup(pszSrcElement);
      57             :     }
      58             :     else
      59             :     {
      60           0 :         m_nSrcElementLen = 0;
      61           0 :         m_pszSrcElement = nullptr;
      62             :     }
      63         200 : }
      64             : 
      65             : /************************************************************************/
      66             : /*                           SetCondition()                             */
      67             : /************************************************************************/
      68             : 
      69           4 : void GMLPropertyDefn::SetCondition(const char *pszCondition)
      70             : {
      71           4 :     CPLFree(m_pszCondition);
      72           4 :     m_pszCondition =
      73           4 :         pszCondition != nullptr ? CPLStrdup(pszCondition) : nullptr;
      74           4 : }
      75             : 
      76             : /************************************************************************/
      77             : /*                        AnalysePropertyValue()                        */
      78             : /*                                                                      */
      79             : /*      Examine the passed property value, and see if we need to        */
      80             : /*      make the field type more specific, or more general.             */
      81             : /************************************************************************/
      82             : 
      83        5131 : void GMLPropertyDefn::AnalysePropertyValue(const GMLProperty *psGMLProperty,
      84             :                                            bool bSetWidth)
      85             : 
      86             : {
      87             :     /* -------------------------------------------------------------------- */
      88             :     /*      Does the string consist entirely of numeric values?             */
      89             :     /* -------------------------------------------------------------------- */
      90        5131 :     bool bIsReal = false;
      91             : 
      92       10432 :     for (int j = 0; j < psGMLProperty->nSubProperties; j++)
      93             :     {
      94        5301 :         if (j > 0)
      95             :         {
      96         170 :             if (m_eType == GMLPT_Integer)
      97             :             {
      98           3 :                 m_eType = GMLPT_IntegerList;
      99             :             }
     100         167 :             else if (m_eType == GMLPT_Integer64)
     101             :             {
     102           0 :                 m_eType = GMLPT_Integer64List;
     103             :             }
     104         167 :             else if (m_eType == GMLPT_Real)
     105             :             {
     106           2 :                 m_eType = GMLPT_RealList;
     107             :             }
     108         165 :             else if (m_eType == GMLPT_String)
     109             :             {
     110          36 :                 m_eType = GMLPT_StringList;
     111          36 :                 m_nWidth = 0;
     112             :             }
     113         129 :             else if (m_eType == GMLPT_Boolean)
     114           1 :                 m_eType = GMLPT_BooleanList;
     115             :         }
     116        5301 :         const char *pszValue = psGMLProperty->papszSubProperties[j];
     117             :         /* --------------------------------------------------------------------
     118             :          */
     119             :         /*      If it is a zero length string, just return.  We can't deduce */
     120             :         /*      much from this. */
     121             :         /* --------------------------------------------------------------------
     122             :          */
     123        5301 :         if (*pszValue == '\0')
     124          12 :             continue;
     125             : 
     126        5289 :         const CPLValueType valueType = CPLGetValueType(pszValue);
     127             : 
     128        5289 :         if (valueType == CPL_VALUE_STRING && m_eType != GMLPT_String &&
     129         801 :             m_eType != GMLPT_StringList)
     130             :         {
     131         423 :             if ((m_eType == GMLPT_Untyped || m_eType == GMLPT_Boolean) &&
     132         354 :                 (strcmp(pszValue, "true") == 0 ||
     133         344 :                  strcmp(pszValue, "false") == 0))
     134             :             {
     135          18 :                 m_eType = GMLPT_Boolean;
     136             :             }
     137         405 :             else if (m_eType == GMLPT_BooleanList)
     138             :             {
     139           4 :                 if (!(strcmp(pszValue, "true") == 0 ||
     140           2 :                       strcmp(pszValue, "false") == 0))
     141           0 :                     m_eType = GMLPT_StringList;
     142             :             }
     143         401 :             else if (m_eType == GMLPT_IntegerList ||
     144         401 :                      m_eType == GMLPT_Integer64List ||
     145         401 :                      m_eType == GMLPT_RealList)
     146             :             {
     147           0 :                 m_eType = GMLPT_StringList;
     148             :             }
     149             :             else
     150             :             {
     151        1856 :                 const auto IsDigitLowerOrEqual = [](char c, int max)
     152        1856 :                 { return c >= '0' && c <= '0' + max; };
     153             : 
     154          65 :                 if ((m_eType == GMLPT_Untyped || m_eType == GMLPT_DateTime ||
     155         439 :                      m_eType == GMLPT_Date) &&
     156         573 :                     IsDigitLowerOrEqual(pszValue[0], 9) &&
     157         326 :                     IsDigitLowerOrEqual(pszValue[1], 9) &&
     158         279 :                     IsDigitLowerOrEqual(pszValue[2], 9) &&
     159         357 :                     IsDigitLowerOrEqual(pszValue[3], 9) && pszValue[4] == '-' &&
     160         202 :                     IsDigitLowerOrEqual(pszValue[5], 1) &&
     161         303 :                     IsDigitLowerOrEqual(pszValue[6], 9) && pszValue[7] == '-' &&
     162         903 :                     IsDigitLowerOrEqual(pszValue[8], 3) &&
     163         101 :                     IsDigitLowerOrEqual(pszValue[9], 9))
     164             :                 {
     165          37 :                     if (pszValue[10] == 'T' &&
     166          74 :                         IsDigitLowerOrEqual(pszValue[11], 2) &&
     167          37 :                         IsDigitLowerOrEqual(pszValue[12], 9) &&
     168          74 :                         pszValue[13] == ':' &&
     169          74 :                         IsDigitLowerOrEqual(pszValue[14], 5) &&
     170          37 :                         IsDigitLowerOrEqual(pszValue[15], 9) &&
     171          74 :                         pszValue[16] == ':' &&
     172          74 :                         IsDigitLowerOrEqual(pszValue[17], 6) &&
     173         175 :                         IsDigitLowerOrEqual(pszValue[18], 9) &&
     174          37 :                         (pszValue[19] == '\0' || pszValue[19] == '.' ||
     175          25 :                          pszValue[19] == 'Z' || pszValue[19] == '+' ||
     176           0 :                          pszValue[19] == '-'))
     177             :                     {
     178          37 :                         m_eType = GMLPT_DateTime;
     179             :                     }
     180          64 :                     else if (pszValue[10] == '\0')
     181             :                     {
     182          63 :                         if (m_eType != GMLPT_DateTime)
     183          63 :                             m_eType = GMLPT_Date;
     184             :                     }
     185             :                     else
     186             :                     {
     187           1 :                         m_eType = GMLPT_String;
     188             :                     }
     189             :                 }
     190         303 :                 else if ((m_eType == GMLPT_Untyped || m_eType == GMLPT_Time) &&
     191         362 :                          IsDigitLowerOrEqual(pszValue[0], 2) &&
     192          63 :                          IsDigitLowerOrEqual(pszValue[1], 9) &&
     193          41 :                          pszValue[2] == ':' &&
     194           8 :                          IsDigitLowerOrEqual(pszValue[3], 5) &&
     195           4 :                          IsDigitLowerOrEqual(pszValue[4], 9) &&
     196           8 :                          pszValue[5] == ':' &&
     197           8 :                          IsDigitLowerOrEqual(pszValue[6], 6) &&
     198         604 :                          IsDigitLowerOrEqual(pszValue[7], 9) &&
     199           4 :                          (pszValue[8] == '\0' || pszValue[8] == '.'))
     200             :                 {
     201           4 :                     m_eType = GMLPT_Time;
     202             :                 }
     203             :                 else
     204             :                 {
     205         296 :                     m_eType = GMLPT_String;
     206             :                 }
     207         423 :             }
     208             :         }
     209             :         else
     210             :         {
     211        4866 :             bIsReal = valueType == CPL_VALUE_REAL;
     212             :         }
     213             : 
     214        5289 :         if (m_eType == GMLPT_String)
     215             :         {
     216        3238 :             if (bSetWidth)
     217             :             {
     218             :                 // Grow the Width to the length of the string passed in.
     219        3214 :                 const int nWidth = static_cast<int>(strlen(pszValue));
     220        3214 :                 if (m_nWidth < nWidth)
     221         352 :                     SetWidth(nWidth);
     222             :             }
     223             :         }
     224        2051 :         else if (m_eType == GMLPT_Untyped || m_eType == GMLPT_Integer ||
     225         678 :                  m_eType == GMLPT_Integer64)
     226             :         {
     227        1375 :             if (bIsReal)
     228          33 :                 m_eType = GMLPT_Real;
     229        1342 :             else if (m_eType != GMLPT_Integer64)
     230             :             {
     231        1340 :                 const GIntBig nVal = CPLAtoGIntBig(pszValue);
     232        1340 :                 if (!CPL_INT64_FITS_ON_INT32(nVal))
     233           1 :                     m_eType = GMLPT_Integer64;
     234             :                 else
     235        1339 :                     m_eType = GMLPT_Integer;
     236        1375 :             }
     237             :         }
     238         676 :         else if ((m_eType == GMLPT_IntegerList ||
     239         676 :                   m_eType == GMLPT_Integer64List) &&
     240             :                  bIsReal)
     241             :         {
     242           0 :             m_eType = GMLPT_RealList;
     243             :         }
     244         676 :         else if (m_eType == GMLPT_IntegerList && valueType == CPL_VALUE_INTEGER)
     245             :         {
     246          12 :             GIntBig nVal = CPLAtoGIntBig(pszValue);
     247          12 :             if (!CPL_INT64_FITS_ON_INT32(nVal))
     248           1 :                 m_eType = GMLPT_Integer64List;
     249             :         }
     250             :     }
     251        5131 : }
     252             : 
     253             : /************************************************************************/
     254             : /*                       GMLGeometryPropertyDefn                        */
     255             : /************************************************************************/
     256             : 
     257         931 : GMLGeometryPropertyDefn::GMLGeometryPropertyDefn(
     258             :     const char *pszName, const char *pszSrcElement, OGRwkbGeometryType nType,
     259             :     int nAttributeIndex, bool bNullable,
     260         931 :     const OGRGeomCoordinatePrecision &oCoordPrec)
     261         922 :     : m_pszName((pszName == nullptr || pszName[0] == '\0')
     262         993 :                     ? CPLStrdup(pszSrcElement)
     263         860 :                     : CPLStrdup(pszName)),
     264        1862 :       m_pszSrcElement(CPLStrdup(pszSrcElement)), m_nGeometryType(nType),
     265             :       m_nAttributeIndex(nAttributeIndex), m_bNullable(bNullable),
     266         931 :       m_oCoordPrecision(oCoordPrec)
     267             : {
     268         931 : }
     269             : 
     270             : /************************************************************************/
     271             : /*                       ~GMLGeometryPropertyDefn                       */
     272             : /************************************************************************/
     273             : 
     274         931 : GMLGeometryPropertyDefn::~GMLGeometryPropertyDefn()
     275             : {
     276         931 :     CPLFree(m_pszName);
     277         931 :     CPLFree(m_pszSrcElement);
     278         931 : }
     279             : 
     280             : /************************************************************************/
     281             : /*                           MergeSRSName()                             */
     282             : /************************************************************************/
     283             : 
     284           9 : void GMLGeometryPropertyDefn::MergeSRSName(const std::string &osSRSName)
     285             : 
     286             : {
     287           9 :     if (!m_bSRSNameConsistent)
     288           0 :         return;
     289             : 
     290           9 :     if (m_osSRSName.empty())
     291             :     {
     292           7 :         m_osSRSName = osSRSName;
     293             :     }
     294             :     else
     295             :     {
     296           2 :         m_bSRSNameConsistent = osSRSName == m_osSRSName;
     297           2 :         if (!m_bSRSNameConsistent)
     298             :         {
     299           1 :             m_osSRSName.clear();
     300             :         }
     301             :     }
     302             : }

Generated by: LCOV version 1.14