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 : * 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 "cpl_port.h"
31 : #include "gmlreader.h"
32 :
33 : #include <cstring>
34 :
35 : #include "cpl_conv.h"
36 : #include "cpl_string.h"
37 :
38 : /************************************************************************/
39 : /* GMLPropertyDefn */
40 : /************************************************************************/
41 :
42 2641 : GMLPropertyDefn::GMLPropertyDefn(const char *pszName, const char *pszSrcElement)
43 2641 : : m_pszName(CPLStrdup(pszName)), m_eType(GMLPT_Untyped), m_nWidth(0),
44 : m_nPrecision(0),
45 2641 : m_pszSrcElement(pszSrcElement ? CPLStrdup(pszSrcElement) : nullptr),
46 2641 : m_nSrcElementLen(pszSrcElement ? strlen(pszSrcElement) : 0),
47 7923 : m_pszCondition(nullptr), m_bNullable(true)
48 : {
49 2641 : }
50 :
51 : /************************************************************************/
52 : /* ~GMLPropertyDefn() */
53 : /************************************************************************/
54 :
55 2641 : GMLPropertyDefn::~GMLPropertyDefn()
56 :
57 : {
58 2641 : CPLFree(m_pszName);
59 2641 : CPLFree(m_pszSrcElement);
60 2641 : CPLFree(m_pszCondition);
61 2641 : }
62 :
63 : /************************************************************************/
64 : /* SetSrcElement() */
65 : /************************************************************************/
66 :
67 200 : void GMLPropertyDefn::SetSrcElement(const char *pszSrcElement)
68 :
69 : {
70 200 : CPLFree(m_pszSrcElement);
71 200 : if (pszSrcElement != nullptr)
72 : {
73 200 : m_nSrcElementLen = strlen(pszSrcElement);
74 200 : m_pszSrcElement = CPLStrdup(pszSrcElement);
75 : }
76 : else
77 : {
78 0 : m_nSrcElementLen = 0;
79 0 : m_pszSrcElement = nullptr;
80 : }
81 200 : }
82 :
83 : /************************************************************************/
84 : /* SetCondition() */
85 : /************************************************************************/
86 :
87 4 : void GMLPropertyDefn::SetCondition(const char *pszCondition)
88 : {
89 4 : CPLFree(m_pszCondition);
90 4 : m_pszCondition =
91 4 : pszCondition != nullptr ? CPLStrdup(pszCondition) : nullptr;
92 4 : }
93 :
94 : /************************************************************************/
95 : /* AnalysePropertyValue() */
96 : /* */
97 : /* Examine the passed property value, and see if we need to */
98 : /* make the field type more specific, or more general. */
99 : /************************************************************************/
100 :
101 3719 : void GMLPropertyDefn::AnalysePropertyValue(const GMLProperty *psGMLProperty,
102 : bool bSetWidth)
103 :
104 : {
105 : /* -------------------------------------------------------------------- */
106 : /* Does the string consist entirely of numeric values? */
107 : /* -------------------------------------------------------------------- */
108 3719 : bool bIsReal = false;
109 :
110 7603 : for (int j = 0; j < psGMLProperty->nSubProperties; j++)
111 : {
112 3884 : if (j > 0)
113 : {
114 165 : if (m_eType == GMLPT_Integer)
115 : {
116 3 : m_eType = GMLPT_IntegerList;
117 : }
118 162 : else if (m_eType == GMLPT_Integer64)
119 : {
120 0 : m_eType = GMLPT_Integer64List;
121 : }
122 162 : else if (m_eType == GMLPT_Real)
123 : {
124 2 : m_eType = GMLPT_RealList;
125 : }
126 160 : else if (m_eType == GMLPT_String)
127 : {
128 34 : m_eType = GMLPT_StringList;
129 34 : m_nWidth = 0;
130 : }
131 126 : else if (m_eType == GMLPT_Boolean)
132 1 : m_eType = GMLPT_BooleanList;
133 : }
134 3884 : const char *pszValue = psGMLProperty->papszSubProperties[j];
135 : /* --------------------------------------------------------------------
136 : */
137 : /* If it is a zero length string, just return. We can't deduce */
138 : /* much from this. */
139 : /* --------------------------------------------------------------------
140 : */
141 3884 : if (*pszValue == '\0')
142 8 : continue;
143 :
144 3876 : const CPLValueType valueType = CPLGetValueType(pszValue);
145 :
146 3876 : if (valueType == CPL_VALUE_STRING && m_eType != GMLPT_String &&
147 634 : m_eType != GMLPT_StringList)
148 : {
149 261 : if ((m_eType == GMLPT_Untyped || m_eType == GMLPT_Boolean) &&
150 256 : (strcmp(pszValue, "true") == 0 ||
151 246 : strcmp(pszValue, "false") == 0))
152 : {
153 16 : m_eType = GMLPT_Boolean;
154 : }
155 245 : else if (m_eType == GMLPT_BooleanList)
156 : {
157 4 : if (!(strcmp(pszValue, "true") == 0 ||
158 2 : strcmp(pszValue, "false") == 0))
159 0 : m_eType = GMLPT_StringList;
160 : }
161 241 : else if (m_eType == GMLPT_IntegerList ||
162 241 : m_eType == GMLPT_Integer64List ||
163 241 : m_eType == GMLPT_RealList)
164 : {
165 0 : m_eType = GMLPT_StringList;
166 : }
167 : else
168 : {
169 241 : m_eType = GMLPT_String;
170 : }
171 : }
172 : else
173 : {
174 3615 : bIsReal = valueType == CPL_VALUE_REAL;
175 : }
176 :
177 3876 : if (m_eType == GMLPT_String)
178 : {
179 2286 : if (bSetWidth)
180 : {
181 : // Grow the Width to the length of the string passed in.
182 2262 : const int nWidth = static_cast<int>(strlen(pszValue));
183 2262 : if (m_nWidth < nWidth)
184 276 : SetWidth(nWidth);
185 : }
186 : }
187 1590 : else if (m_eType == GMLPT_Untyped || m_eType == GMLPT_Integer ||
188 492 : m_eType == GMLPT_Integer64)
189 : {
190 1100 : if (bIsReal)
191 25 : m_eType = GMLPT_Real;
192 1075 : else if (m_eType != GMLPT_Integer64)
193 : {
194 1073 : const GIntBig nVal = CPLAtoGIntBig(pszValue);
195 1073 : if (!CPL_INT64_FITS_ON_INT32(nVal))
196 1 : m_eType = GMLPT_Integer64;
197 : else
198 1072 : m_eType = GMLPT_Integer;
199 1100 : }
200 : }
201 490 : else if ((m_eType == GMLPT_IntegerList ||
202 490 : m_eType == GMLPT_Integer64List) &&
203 : bIsReal)
204 : {
205 0 : m_eType = GMLPT_RealList;
206 : }
207 490 : else if (m_eType == GMLPT_IntegerList && valueType == CPL_VALUE_INTEGER)
208 : {
209 12 : GIntBig nVal = CPLAtoGIntBig(pszValue);
210 12 : if (!CPL_INT64_FITS_ON_INT32(nVal))
211 1 : m_eType = GMLPT_Integer64List;
212 : }
213 : }
214 3719 : }
215 :
216 : /************************************************************************/
217 : /* GMLGeometryPropertyDefn */
218 : /************************************************************************/
219 :
220 845 : GMLGeometryPropertyDefn::GMLGeometryPropertyDefn(
221 : const char *pszName, const char *pszSrcElement, OGRwkbGeometryType nType,
222 : int nAttributeIndex, bool bNullable,
223 845 : const OGRGeomCoordinatePrecision &oCoordPrec)
224 836 : : m_pszName((pszName == nullptr || pszName[0] == '\0')
225 890 : ? CPLStrdup(pszSrcElement)
226 791 : : CPLStrdup(pszName)),
227 1690 : m_pszSrcElement(CPLStrdup(pszSrcElement)), m_nGeometryType(nType),
228 : m_nAttributeIndex(nAttributeIndex), m_bNullable(bNullable),
229 845 : m_oCoordPrecision(oCoordPrec)
230 : {
231 845 : }
232 :
233 : /************************************************************************/
234 : /* ~GMLGeometryPropertyDefn */
235 : /************************************************************************/
236 :
237 845 : GMLGeometryPropertyDefn::~GMLGeometryPropertyDefn()
238 : {
239 845 : CPLFree(m_pszName);
240 845 : CPLFree(m_pszSrcElement);
241 845 : }
242 :
243 : /************************************************************************/
244 : /* MergeSRSName() */
245 : /************************************************************************/
246 :
247 9 : void GMLGeometryPropertyDefn::MergeSRSName(const std::string &osSRSName)
248 :
249 : {
250 9 : if (!m_bSRSNameConsistent)
251 0 : return;
252 :
253 9 : if (m_osSRSName.empty())
254 : {
255 7 : m_osSRSName = osSRSName;
256 : }
257 : else
258 : {
259 2 : m_bSRSNameConsistent = osSRSName == m_osSRSName;
260 2 : if (!m_bSRSNameConsistent)
261 : {
262 1 : m_osSRSName.clear();
263 : }
264 : }
265 : }
|