Coverage Report

Created: 2025-06-09 08:44

/src/gdal/ogr/ogrsf_frmts/gmlutils/gmlpropertydefn.cpp
Line
Count
Source (jump to first uncovered line)
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
GMLPropertyDefn::GMLPropertyDefn(const char *pszName, const char *pszSrcElement)
27
206k
    : m_pszName(CPLStrdup(pszName)),
28
206k
      m_pszSrcElement(pszSrcElement ? CPLStrdup(pszSrcElement) : nullptr),
29
206k
      m_nSrcElementLen(pszSrcElement ? strlen(pszSrcElement) : 0)
30
206k
{
31
206k
}
32
33
/************************************************************************/
34
/*                          ~GMLPropertyDefn()                          */
35
/************************************************************************/
36
37
GMLPropertyDefn::~GMLPropertyDefn()
38
39
206k
{
40
206k
    CPLFree(m_pszName);
41
206k
    CPLFree(m_pszSrcElement);
42
206k
    CPLFree(m_pszCondition);
43
206k
}
44
45
/************************************************************************/
46
/*                           SetSrcElement()                            */
47
/************************************************************************/
48
49
void GMLPropertyDefn::SetSrcElement(const char *pszSrcElement)
50
51
3.56k
{
52
3.56k
    CPLFree(m_pszSrcElement);
53
3.56k
    if (pszSrcElement != nullptr)
54
3.56k
    {
55
3.56k
        m_nSrcElementLen = strlen(pszSrcElement);
56
3.56k
        m_pszSrcElement = CPLStrdup(pszSrcElement);
57
3.56k
    }
58
0
    else
59
0
    {
60
0
        m_nSrcElementLen = 0;
61
0
        m_pszSrcElement = nullptr;
62
0
    }
63
3.56k
}
64
65
/************************************************************************/
66
/*                           SetCondition()                             */
67
/************************************************************************/
68
69
void GMLPropertyDefn::SetCondition(const char *pszCondition)
70
0
{
71
0
    CPLFree(m_pszCondition);
72
0
    m_pszCondition =
73
0
        pszCondition != nullptr ? CPLStrdup(pszCondition) : nullptr;
74
0
}
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
void GMLPropertyDefn::AnalysePropertyValue(const GMLProperty *psGMLProperty,
84
                                           bool bSetWidth)
85
86
102k
{
87
    /* -------------------------------------------------------------------- */
88
    /*      Does the string consist entirely of numeric values?             */
89
    /* -------------------------------------------------------------------- */
90
102k
    bool bIsReal = false;
91
92
4.77M
    for (int j = 0; j < psGMLProperty->nSubProperties; j++)
93
4.67M
    {
94
4.67M
        if (j > 0)
95
4.56M
        {
96
4.56M
            if (m_eType == GMLPT_Integer)
97
1.94k
            {
98
1.94k
                m_eType = GMLPT_IntegerList;
99
1.94k
            }
100
4.56M
            else if (m_eType == GMLPT_Integer64)
101
770
            {
102
770
                m_eType = GMLPT_Integer64List;
103
770
            }
104
4.56M
            else if (m_eType == GMLPT_Real)
105
869
            {
106
869
                m_eType = GMLPT_RealList;
107
869
            }
108
4.56M
            else if (m_eType == GMLPT_String)
109
2.77k
            {
110
2.77k
                m_eType = GMLPT_StringList;
111
2.77k
                m_nWidth = 0;
112
2.77k
            }
113
4.56M
            else if (m_eType == GMLPT_Boolean)
114
120
                m_eType = GMLPT_BooleanList;
115
4.56M
        }
116
4.67M
        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
4.67M
        if (*pszValue == '\0')
124
20.4k
            continue;
125
126
4.64M
        const CPLValueType valueType = CPLGetValueType(pszValue);
127
128
4.64M
        if (valueType == CPL_VALUE_STRING && m_eType != GMLPT_String &&
129
4.64M
            m_eType != GMLPT_StringList)
130
25.2k
        {
131
25.2k
            if ((m_eType == GMLPT_Untyped || m_eType == GMLPT_Boolean) &&
132
25.2k
                (strcmp(pszValue, "true") == 0 ||
133
10.8k
                 strcmp(pszValue, "false") == 0))
134
1.41k
            {
135
1.41k
                m_eType = GMLPT_Boolean;
136
1.41k
            }
137
23.8k
            else if (m_eType == GMLPT_BooleanList)
138
12.3k
            {
139
12.3k
                if (!(strcmp(pszValue, "true") == 0 ||
140
12.3k
                      strcmp(pszValue, "false") == 0))
141
41
                    m_eType = GMLPT_StringList;
142
12.3k
            }
143
11.4k
            else if (m_eType == GMLPT_IntegerList ||
144
11.4k
                     m_eType == GMLPT_Integer64List ||
145
11.4k
                     m_eType == GMLPT_RealList)
146
1.88k
            {
147
1.88k
                m_eType = GMLPT_StringList;
148
1.88k
            }
149
9.58k
            else
150
9.58k
            {
151
9.58k
                m_eType = GMLPT_String;
152
9.58k
            }
153
25.2k
        }
154
4.62M
        else
155
4.62M
        {
156
4.62M
            bIsReal = valueType == CPL_VALUE_REAL;
157
4.62M
        }
158
159
4.64M
        if (m_eType == GMLPT_String)
160
20.7k
        {
161
20.7k
            if (bSetWidth)
162
16.9k
            {
163
                // Grow the Width to the length of the string passed in.
164
16.9k
                const int nWidth = static_cast<int>(strlen(pszValue));
165
16.9k
                if (m_nWidth < nWidth)
166
8.12k
                    SetWidth(nWidth);
167
16.9k
            }
168
20.7k
        }
169
4.62M
        else if (m_eType == GMLPT_Untyped || m_eType == GMLPT_Integer ||
170
4.62M
                 m_eType == GMLPT_Integer64)
171
10.1k
        {
172
10.1k
            if (bIsReal)
173
1.81k
                m_eType = GMLPT_Real;
174
8.38k
            else if (m_eType != GMLPT_Integer64)
175
7.13k
            {
176
7.13k
                const GIntBig nVal = CPLAtoGIntBig(pszValue);
177
7.13k
                if (!CPL_INT64_FITS_ON_INT32(nVal))
178
1.41k
                    m_eType = GMLPT_Integer64;
179
5.72k
                else
180
5.72k
                    m_eType = GMLPT_Integer;
181
7.13k
            }
182
10.1k
        }
183
4.61M
        else if ((m_eType == GMLPT_IntegerList ||
184
4.61M
                  m_eType == GMLPT_Integer64List) &&
185
4.61M
                 bIsReal)
186
173
        {
187
173
            m_eType = GMLPT_RealList;
188
173
        }
189
4.61M
        else if (m_eType == GMLPT_IntegerList && valueType == CPL_VALUE_INTEGER)
190
16.7k
        {
191
16.7k
            GIntBig nVal = CPLAtoGIntBig(pszValue);
192
16.7k
            if (!CPL_INT64_FITS_ON_INT32(nVal))
193
316
                m_eType = GMLPT_Integer64List;
194
16.7k
        }
195
4.64M
    }
196
102k
}
197
198
/************************************************************************/
199
/*                       GMLGeometryPropertyDefn                        */
200
/************************************************************************/
201
202
GMLGeometryPropertyDefn::GMLGeometryPropertyDefn(
203
    const char *pszName, const char *pszSrcElement, OGRwkbGeometryType nType,
204
    int nAttributeIndex, bool bNullable,
205
    const OGRGeomCoordinatePrecision &oCoordPrec)
206
117k
    : m_pszName((pszName == nullptr || pszName[0] == '\0')
207
117k
                    ? CPLStrdup(pszSrcElement)
208
117k
                    : CPLStrdup(pszName)),
209
117k
      m_pszSrcElement(CPLStrdup(pszSrcElement)), m_nGeometryType(nType),
210
117k
      m_nAttributeIndex(nAttributeIndex), m_bNullable(bNullable),
211
117k
      m_oCoordPrecision(oCoordPrec)
212
117k
{
213
117k
}
214
215
/************************************************************************/
216
/*                       ~GMLGeometryPropertyDefn                       */
217
/************************************************************************/
218
219
GMLGeometryPropertyDefn::~GMLGeometryPropertyDefn()
220
117k
{
221
117k
    CPLFree(m_pszName);
222
117k
    CPLFree(m_pszSrcElement);
223
117k
}
224
225
/************************************************************************/
226
/*                           MergeSRSName()                             */
227
/************************************************************************/
228
229
void GMLGeometryPropertyDefn::MergeSRSName(const std::string &osSRSName)
230
231
757
{
232
757
    if (!m_bSRSNameConsistent)
233
509
        return;
234
235
248
    if (m_osSRSName.empty())
236
61
    {
237
61
        m_osSRSName = osSRSName;
238
61
    }
239
187
    else
240
187
    {
241
187
        m_bSRSNameConsistent = osSRSName == m_osSRSName;
242
187
        if (!m_bSRSNameConsistent)
243
30
        {
244
30
            m_osSRSName.clear();
245
30
        }
246
187
    }
247
248
}