/src/gdal/ogr/ogrfeature.cpp
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /******************************************************************************  | 
2  |  |  *  | 
3  |  |  * Project:  OpenGIS Simple Features Reference Implementation  | 
4  |  |  * Purpose:  The OGRFeature class implementation.  | 
5  |  |  * Author:   Frank Warmerdam, warmerda@home.com  | 
6  |  |  *  | 
7  |  |  ******************************************************************************  | 
8  |  |  * Copyright (c) 1999,  Les Technologies SoftMap Inc.  | 
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 "ogr_api.h"  | 
16  |  | #include "ogr_feature.h"  | 
17  |  |  | 
18  |  | #include <cerrno>  | 
19  |  | #include <cinttypes>  | 
20  |  | #include <climits>  | 
21  |  | #include <cstdio>  | 
22  |  | #include <cstdlib>  | 
23  |  | #include <cstring>  | 
24  |  | #include <cmath>  | 
25  |  | #include <ctime>  | 
26  |  |  | 
27  |  | #include <algorithm>  | 
28  |  | #include <limits>  | 
29  |  | #include <map>  | 
30  |  | #include <new>  | 
31  |  | #include <vector>  | 
32  |  |  | 
33  |  | #include "cpl_conv.h"  | 
34  |  | #include "cpl_error.h"  | 
35  |  | #include "cpl_string.h"  | 
36  |  | #include "cpl_time.h"  | 
37  |  | #include "cpl_vsi.h"  | 
38  |  | #include "ogr_core.h"  | 
39  |  | #include "ogr_featurestyle.h"  | 
40  |  | #include "ogr_geometry.h"  | 
41  |  | #include "ogr_p.h"  | 
42  |  | #include "ogrlibjsonutils.h"  | 
43  |  |  | 
44  |  | #include "cpl_json_header.h"  | 
45  |  |  | 
46  |  | // Too many false positives from gcc 13.2.1 in that file...  | 
47  |  | #if defined(__GNUC__)  | 
48  |  | #pragma GCC diagnostic push  | 
49  |  | #pragma GCC diagnostic ignored "-Wnull-dereference"  | 
50  |  | #endif  | 
51  |  |  | 
52  |  | /************************************************************************/  | 
53  |  | /*                             OGRFeature()                             */  | 
54  |  | /************************************************************************/  | 
55  |  |  | 
56  |  | /**  | 
57  |  |  * \brief Constructor  | 
58  |  |  *  | 
59  |  |  * Note that the OGRFeature will increment the reference count of its  | 
60  |  |  * defining OGRFeatureDefn.  Destruction of the OGRFeatureDefn before  | 
61  |  |  * destruction of all OGRFeatures that depend on it is likely to result in  | 
62  |  |  * a crash.  | 
63  |  |  *  | 
64  |  |  * This method is the same as the C function OGR_F_Create().  | 
65  |  |  *  | 
66  |  |  * @param poDefnIn feature class (layer) definition to which the feature will  | 
67  |  |  * adhere.  | 
68  |  |  */  | 
69  |  |  | 
70  |  | OGRFeature::OGRFeature(OGRFeatureDefn *poDefnIn)  | 
71  | 0  |     : nFID(OGRNullFID), poDefn(poDefnIn), papoGeometries(nullptr),  | 
72  | 0  |       pauFields(nullptr), m_pszNativeData(nullptr),  | 
73  | 0  |       m_pszNativeMediaType(nullptr), m_pszStyleString(nullptr),  | 
74  | 0  |       m_poStyleTable(nullptr), m_pszTmpFieldValue(nullptr)  | 
75  | 0  | { | 
76  | 0  |     poDefnIn->Reference();  | 
77  |  | 
  | 
78  | 0  |     const int nFieldCount = poDefn->GetFieldCount();  | 
79  | 0  |     pauFields = static_cast<OGRField *>(  | 
80  | 0  |         VSI_MALLOC_VERBOSE(nFieldCount * sizeof(OGRField)));  | 
81  |  | 
  | 
82  | 0  |     papoGeometries = static_cast<OGRGeometry **>(  | 
83  | 0  |         VSI_CALLOC_VERBOSE(poDefn->GetGeomFieldCount(), sizeof(OGRGeometry *)));  | 
84  |  |  | 
85  |  |     // Initialize array to the unset special value.  | 
86  | 0  |     if (pauFields != nullptr)  | 
87  | 0  |     { | 
88  | 0  |         for (int i = 0; i < nFieldCount; i++)  | 
89  | 0  |         { | 
90  | 0  |             pauFields[i].Set.nMarker1 = OGRUnsetMarker;  | 
91  | 0  |             pauFields[i].Set.nMarker2 = OGRUnsetMarker;  | 
92  | 0  |             pauFields[i].Set.nMarker3 = OGRUnsetMarker;  | 
93  | 0  |         }  | 
94  | 0  |     }  | 
95  | 0  | }  | 
96  |  |  | 
97  |  | /************************************************************************/  | 
98  |  | /*                            OGR_F_Create()                            */  | 
99  |  | /************************************************************************/  | 
100  |  | /**  | 
101  |  |  * \brief Feature factory.  | 
102  |  |  *  | 
103  |  |  * Note that the OGRFeature will increment the reference count of its  | 
104  |  |  * defining OGRFeatureDefn.  Destruction of the OGRFeatureDefn before  | 
105  |  |  * destruction of all OGRFeatures that depend on it is likely to result in  | 
106  |  |  * a crash.  | 
107  |  |  *  | 
108  |  |  * This function is the same as the C++ method OGRFeature::OGRFeature().  | 
109  |  |  *  | 
110  |  |  * @param hDefn handle to the feature class (layer) definition to  | 
111  |  |  * which the feature will adhere.  | 
112  |  |  *  | 
113  |  |  * @return a handle to the new feature object with null fields and no geometry,  | 
114  |  |  * or, starting with GDAL 2.1, NULL in case out of memory situation.  | 
115  |  |  */  | 
116  |  |  | 
117  |  | OGRFeatureH OGR_F_Create(OGRFeatureDefnH hDefn)  | 
118  |  |  | 
119  | 0  | { | 
120  | 0  |     VALIDATE_POINTER1(hDefn, "OGR_F_Create", nullptr);  | 
121  | 0  |     return OGRFeature::ToHandle(  | 
122  | 0  |         OGRFeature::CreateFeature(OGRFeatureDefn::FromHandle(hDefn)));  | 
123  | 0  | }  | 
124  |  |  | 
125  |  | /************************************************************************/  | 
126  |  | /*                            ~OGRFeature()                             */  | 
127  |  | /************************************************************************/  | 
128  |  |  | 
129  |  | OGRFeature::~OGRFeature()  | 
130  |  |  | 
131  | 0  | { | 
132  | 0  |     if (pauFields != nullptr)  | 
133  | 0  |     { | 
134  |  |         // We can call GetFieldCountUnsafe() as the constructor has called  | 
135  |  |         // the regular GetFieldCount()  | 
136  | 0  |         const int nFieldcount = poDefn->GetFieldCountUnsafe();  | 
137  | 0  |         for (int i = 0; i < nFieldcount; i++)  | 
138  | 0  |         { | 
139  | 0  |             const OGRFieldDefn *poFDefn = poDefn->GetFieldDefnUnsafe(i);  | 
140  |  | 
  | 
141  | 0  |             if (!IsFieldSetAndNotNullUnsafe(i))  | 
142  | 0  |                 continue;  | 
143  |  |  | 
144  | 0  |             switch (poFDefn->GetType())  | 
145  | 0  |             { | 
146  | 0  |                 case OFTString:  | 
147  | 0  |                     if (pauFields[i].String != nullptr)  | 
148  | 0  |                         VSIFree(pauFields[i].String);  | 
149  | 0  |                     break;  | 
150  |  |  | 
151  | 0  |                 case OFTBinary:  | 
152  | 0  |                     if (pauFields[i].Binary.paData != nullptr)  | 
153  | 0  |                         VSIFree(pauFields[i].Binary.paData);  | 
154  | 0  |                     break;  | 
155  |  |  | 
156  | 0  |                 case OFTStringList:  | 
157  | 0  |                     CSLDestroy(pauFields[i].StringList.paList);  | 
158  | 0  |                     break;  | 
159  |  |  | 
160  | 0  |                 case OFTIntegerList:  | 
161  | 0  |                 case OFTInteger64List:  | 
162  | 0  |                 case OFTRealList:  | 
163  | 0  |                     CPLFree(pauFields[i].IntegerList.paList);  | 
164  | 0  |                     break;  | 
165  |  |  | 
166  | 0  |                 default:  | 
167  |  |                     // TODO(schwehr): Add support for wide strings.  | 
168  | 0  |                     break;  | 
169  | 0  |             }  | 
170  | 0  |         }  | 
171  | 0  |     }  | 
172  |  |  | 
173  | 0  |     if (papoGeometries != nullptr)  | 
174  | 0  |     { | 
175  | 0  |         const int nGeomFieldCount = poDefn->GetGeomFieldCount();  | 
176  |  | 
  | 
177  | 0  |         for (int i = 0; i < nGeomFieldCount; i++)  | 
178  | 0  |         { | 
179  | 0  |             delete papoGeometries[i];  | 
180  | 0  |         }  | 
181  | 0  |     }  | 
182  |  | 
  | 
183  | 0  |     if (poDefn)  | 
184  | 0  |         poDefn->Release();  | 
185  |  | 
  | 
186  | 0  |     CPLFree(pauFields);  | 
187  | 0  |     CPLFree(papoGeometries);  | 
188  | 0  |     CPLFree(m_pszStyleString);  | 
189  | 0  |     CPLFree(m_pszTmpFieldValue);  | 
190  | 0  |     CPLFree(m_pszNativeData);  | 
191  | 0  |     CPLFree(m_pszNativeMediaType);  | 
192  | 0  | }  | 
193  |  |  | 
194  |  | /************************************************************************/  | 
195  |  | /*                           OGR_F_Destroy()                            */  | 
196  |  | /************************************************************************/  | 
197  |  | /**  | 
198  |  |  * \brief Destroy feature  | 
199  |  |  *  | 
200  |  |  * The feature is deleted, but within the context of the GDAL/OGR heap.  | 
201  |  |  * This is necessary when higher level applications use GDAL/OGR from a  | 
202  |  |  * DLL and they want to delete a feature created within the DLL.  If the  | 
203  |  |  * delete is done in the calling application the memory will be freed onto  | 
204  |  |  * the application heap which is inappropriate.  | 
205  |  |  *  | 
206  |  |  * This function is the same as the C++ method OGRFeature::DestroyFeature().  | 
207  |  |  *  | 
208  |  |  * @param hFeat handle to the feature to destroy.  | 
209  |  |  */  | 
210  |  |  | 
211  |  | void OGR_F_Destroy(OGRFeatureH hFeat)  | 
212  |  |  | 
213  | 0  | { | 
214  | 0  |     delete OGRFeature::FromHandle(hFeat);  | 
215  | 0  | }  | 
216  |  |  | 
217  |  | /************************************************************************/  | 
218  |  | /*                           CreateFeature()                            */  | 
219  |  | /************************************************************************/  | 
220  |  |  | 
221  |  | /**  | 
222  |  |  * \brief Feature factory.  | 
223  |  |  *  | 
224  |  |  * This is essentially a feature factory, useful for  | 
225  |  |  * applications creating features but wanting to ensure they  | 
226  |  |  * are created out of the OGR/GDAL heap.  | 
227  |  |  *  | 
228  |  |  * This method is the same as the C function OGR_F_Create().  | 
229  |  |  *  | 
230  |  |  * @param poDefn Feature definition defining schema.  | 
231  |  |  *  | 
232  |  |  * @return new feature object with null fields and no geometry, or, starting  | 
233  |  |  * with GDAL 2.1, NULL in case of out of memory situation.  May be deleted with  | 
234  |  |  * DestroyFeature().  | 
235  |  |  */  | 
236  |  |  | 
237  |  | OGRFeature *OGRFeature::CreateFeature(OGRFeatureDefn *poDefn)  | 
238  |  |  | 
239  | 0  | { | 
240  | 0  |     OGRFeature *poFeature = new (std::nothrow) OGRFeature(poDefn);  | 
241  | 0  |     if (poFeature == nullptr)  | 
242  | 0  |         return nullptr;  | 
243  |  |  | 
244  | 0  |     if ((poFeature->pauFields == nullptr &&  | 
245  | 0  |          poDefn->GetFieldCountUnsafe() != 0) ||  | 
246  | 0  |         (poFeature->papoGeometries == nullptr &&  | 
247  | 0  |          poDefn->GetGeomFieldCount() != 0))  | 
248  | 0  |     { | 
249  | 0  |         delete poFeature;  | 
250  | 0  |         return nullptr;  | 
251  | 0  |     }  | 
252  |  |  | 
253  | 0  |     return poFeature;  | 
254  | 0  | }  | 
255  |  |  | 
256  |  | /************************************************************************/  | 
257  |  | /*                           DestroyFeature()                           */  | 
258  |  | /************************************************************************/  | 
259  |  |  | 
260  |  | /**  | 
261  |  |  * \brief Destroy feature  | 
262  |  |  *  | 
263  |  |  * The feature is deleted, but within the context of the GDAL/OGR heap.  | 
264  |  |  * This is necessary when higher level applications use GDAL/OGR from a  | 
265  |  |  * DLL and they want to delete a feature created within the DLL.  If the  | 
266  |  |  * delete is done in the calling application the memory will be freed onto  | 
267  |  |  * the application heap which is inappropriate.  | 
268  |  |  *  | 
269  |  |  * This method is the same as the C function OGR_F_Destroy().  | 
270  |  |  *  | 
271  |  |  * @param poFeature the feature to delete.  | 
272  |  |  */  | 
273  |  |  | 
274  |  | void OGRFeature::DestroyFeature(OGRFeature *poFeature)  | 
275  |  |  | 
276  | 0  | { | 
277  | 0  |     delete poFeature;  | 
278  | 0  | }  | 
279  |  |  | 
280  |  | /************************************************************************/  | 
281  |  | /*                                Reset()                               */  | 
282  |  | /************************************************************************/  | 
283  |  |  | 
284  |  | /** Reset the state of a OGRFeature to its state after construction.  | 
285  |  |  *  | 
286  |  |  * This enables recycling existing OGRFeature instances.  | 
287  |  |  *  | 
288  |  |  * @since GDAL 3.5  | 
289  |  |  */  | 
290  |  | void OGRFeature::Reset()  | 
291  | 0  | { | 
292  | 0  |     nFID = OGRNullFID;  | 
293  |  | 
  | 
294  | 0  |     if (pauFields != nullptr)  | 
295  | 0  |     { | 
296  | 0  |         const int nFieldcount = poDefn->GetFieldCountUnsafe();  | 
297  | 0  |         for (int i = 0; i < nFieldcount; i++)  | 
298  | 0  |         { | 
299  | 0  |             if (!IsFieldSetAndNotNullUnsafe(i))  | 
300  | 0  |                 continue;  | 
301  |  |  | 
302  | 0  |             const OGRFieldDefn *poFDefn = poDefn->GetFieldDefnUnsafe(i);  | 
303  | 0  |             switch (poFDefn->GetType())  | 
304  | 0  |             { | 
305  | 0  |                 case OFTString:  | 
306  | 0  |                     if (pauFields[i].String != nullptr)  | 
307  | 0  |                         VSIFree(pauFields[i].String);  | 
308  | 0  |                     break;  | 
309  |  |  | 
310  | 0  |                 case OFTBinary:  | 
311  | 0  |                     if (pauFields[i].Binary.paData != nullptr)  | 
312  | 0  |                         VSIFree(pauFields[i].Binary.paData);  | 
313  | 0  |                     break;  | 
314  |  |  | 
315  | 0  |                 case OFTStringList:  | 
316  | 0  |                     CSLDestroy(pauFields[i].StringList.paList);  | 
317  | 0  |                     break;  | 
318  |  |  | 
319  | 0  |                 case OFTIntegerList:  | 
320  | 0  |                 case OFTInteger64List:  | 
321  | 0  |                 case OFTRealList:  | 
322  | 0  |                     CPLFree(pauFields[i].IntegerList.paList);  | 
323  | 0  |                     break;  | 
324  |  |  | 
325  | 0  |                 default:  | 
326  |  |                     // TODO(schwehr): Add support for wide strings.  | 
327  | 0  |                     break;  | 
328  | 0  |             }  | 
329  |  |  | 
330  | 0  |             pauFields[i].Set.nMarker1 = OGRUnsetMarker;  | 
331  | 0  |             pauFields[i].Set.nMarker2 = OGRUnsetMarker;  | 
332  | 0  |             pauFields[i].Set.nMarker3 = OGRUnsetMarker;  | 
333  | 0  |         }  | 
334  | 0  |     }  | 
335  |  |  | 
336  | 0  |     if (papoGeometries != nullptr)  | 
337  | 0  |     { | 
338  | 0  |         const int nGeomFieldCount = poDefn->GetGeomFieldCount();  | 
339  |  | 
  | 
340  | 0  |         for (int i = 0; i < nGeomFieldCount; i++)  | 
341  | 0  |         { | 
342  | 0  |             delete papoGeometries[i];  | 
343  | 0  |             papoGeometries[i] = nullptr;  | 
344  | 0  |         }  | 
345  | 0  |     }  | 
346  |  | 
  | 
347  | 0  |     if (m_pszStyleString)  | 
348  | 0  |     { | 
349  | 0  |         CPLFree(m_pszStyleString);  | 
350  | 0  |         m_pszStyleString = nullptr;  | 
351  | 0  |     }  | 
352  |  | 
  | 
353  | 0  |     if (m_pszNativeData)  | 
354  | 0  |     { | 
355  | 0  |         CPLFree(m_pszNativeData);  | 
356  | 0  |         m_pszNativeData = nullptr;  | 
357  | 0  |     }  | 
358  |  | 
  | 
359  | 0  |     if (m_pszNativeMediaType)  | 
360  | 0  |     { | 
361  | 0  |         CPLFree(m_pszNativeMediaType);  | 
362  | 0  |         m_pszNativeMediaType = nullptr;  | 
363  | 0  |     }  | 
364  | 0  | }  | 
365  |  |  | 
366  |  | /************************************************************************/  | 
367  |  | /*                        SetFDefnUnsafe()                              */  | 
368  |  | /************************************************************************/  | 
369  |  |  | 
370  |  | //! @cond Doxygen_Suppress  | 
371  |  | void OGRFeature::SetFDefnUnsafe(OGRFeatureDefn *poNewFDefn)  | 
372  | 0  | { | 
373  | 0  |     poNewFDefn->Reference();  | 
374  | 0  |     poDefn->Release();  | 
375  | 0  |     poDefn = poNewFDefn;  | 
376  | 0  | }  | 
377  |  |  | 
378  |  | //! @endcond  | 
379  |  |  | 
380  |  | /************************************************************************/  | 
381  |  | /*                             GetDefnRef()                             */  | 
382  |  | /************************************************************************/  | 
383  |  |  | 
384  |  | /**  | 
385  |  |  * \fn OGRFeatureDefn *OGRFeature::GetDefnRef();  | 
386  |  |  *  | 
387  |  |  * \brief Fetch feature definition.  | 
388  |  |  *  | 
389  |  |  * This method is the same as the C function OGR_F_GetDefnRef().  | 
390  |  |  *  | 
391  |  |  * @return a reference to the feature definition object.  | 
392  |  |  */  | 
393  |  |  | 
394  |  | /**  | 
395  |  |  * \fn const OGRFeatureDefn *OGRFeature::GetDefnRef() const;  | 
396  |  |  *  | 
397  |  |  * \brief Fetch feature definition.  | 
398  |  |  *  | 
399  |  |  * This method is the same as the C function OGR_F_GetDefnRef().  | 
400  |  |  *  | 
401  |  |  * @return a reference to the feature definition object.  | 
402  |  |  * @since GDAL 2.3  | 
403  |  |  */  | 
404  |  |  | 
405  |  | /************************************************************************/  | 
406  |  | /*                          OGR_F_GetDefnRef()                          */  | 
407  |  | /************************************************************************/  | 
408  |  |  | 
409  |  | /**  | 
410  |  |  * \brief Fetch feature definition.  | 
411  |  |  *  | 
412  |  |  * This function is the same as the C++ method OGRFeature::GetDefnRef().  | 
413  |  |  *  | 
414  |  |  * @param hFeat handle to the feature to get the feature definition from.  | 
415  |  |  *  | 
416  |  |  * @return a handle to the feature definition object on which feature  | 
417  |  |  * depends.  | 
418  |  |  */  | 
419  |  |  | 
420  |  | OGRFeatureDefnH OGR_F_GetDefnRef(OGRFeatureH hFeat)  | 
421  |  |  | 
422  | 0  | { | 
423  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetDefnRef", nullptr);  | 
424  |  |  | 
425  | 0  |     return OGRFeatureDefn::ToHandle(  | 
426  | 0  |         OGRFeature::FromHandle(hFeat)->GetDefnRef());  | 
427  | 0  | }  | 
428  |  |  | 
429  |  | /************************************************************************/  | 
430  |  | /*                        SetGeometryDirectly()                         */  | 
431  |  | /************************************************************************/  | 
432  |  |  | 
433  |  | /**  | 
434  |  |  * \brief Set feature geometry.  | 
435  |  |  *  | 
436  |  |  * This method updates the features geometry, and operates the same as  | 
437  |  |  * SetGeometry(), except that this method assumes ownership of the  | 
438  |  |  * passed geometry (even in case of failure of that function).  | 
439  |  |  *  | 
440  |  |  * This method is the same as the C function OGR_F_SetGeometryDirectly().  | 
441  |  |  *  | 
442  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
443  |  |  * this object comes from a layer and the modifications must be serialized back  | 
444  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
445  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
446  |  |  *  | 
447  |  |  * @param poGeomIn new geometry to apply to feature. Passing NULL value here  | 
448  |  |  * is correct and it will result in deallocation of currently assigned geometry  | 
449  |  |  * without assigning new one.  | 
450  |  |  *  | 
451  |  |  * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if  | 
452  |  |  * the geometry type is illegal for the OGRFeatureDefn (checking not yet  | 
453  |  |  * implemented).  | 
454  |  |  */  | 
455  |  |  | 
456  |  | OGRErr OGRFeature::SetGeometryDirectly(OGRGeometry *poGeomIn)  | 
457  |  |  | 
458  | 0  | { | 
459  | 0  |     if (poGeomIn == GetGeometryRef())  | 
460  | 0  |     { | 
461  | 0  |         return OGRERR_NONE;  | 
462  | 0  |     }  | 
463  |  |  | 
464  | 0  |     return SetGeomField(0, std::unique_ptr<OGRGeometry>(poGeomIn));  | 
465  | 0  | }  | 
466  |  |  | 
467  |  | /************************************************************************/  | 
468  |  | /*                     OGR_F_SetGeometryDirectly()                      */  | 
469  |  | /************************************************************************/  | 
470  |  |  | 
471  |  | /**  | 
472  |  |  * \brief Set feature geometry.  | 
473  |  |  *  | 
474  |  |  * This function updates the features geometry, and operates the same as  | 
475  |  |  * SetGeometry(), except that this function assumes ownership of the  | 
476  |  |  * passed geometry (even in case of failure of that function).  | 
477  |  |  *  | 
478  |  |  * This function is the same as the C++ method  | 
479  |  |  * OGRFeature::SetGeometryDirectly.  | 
480  |  |  *  | 
481  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
482  |  |  * this object comes from a layer and the modifications must be serialized back  | 
483  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
484  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
485  |  |  *  | 
486  |  |  * @param hFeat handle to the feature on which to apply the geometry.  | 
487  |  |  * @param hGeom handle to the new geometry to apply to feature.  | 
488  |  |  *  | 
489  |  |  * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if  | 
490  |  |  * the geometry type is illegal for the OGRFeatureDefn (checking not yet  | 
491  |  |  * implemented).  | 
492  |  |  */  | 
493  |  |  | 
494  |  | OGRErr OGR_F_SetGeometryDirectly(OGRFeatureH hFeat, OGRGeometryH hGeom)  | 
495  |  |  | 
496  | 0  | { | 
497  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_SetGeometryDirectly", OGRERR_FAILURE);  | 
498  |  |  | 
499  | 0  |     return OGRFeature::FromHandle(hFeat)->SetGeometryDirectly(  | 
500  | 0  |         OGRGeometry::FromHandle(hGeom));  | 
501  | 0  | }  | 
502  |  |  | 
503  |  | /************************************************************************/  | 
504  |  | /*                            SetGeometry()                             */  | 
505  |  | /************************************************************************/  | 
506  |  |  | 
507  |  | /**  | 
508  |  |  * \brief Set feature geometry.  | 
509  |  |  *  | 
510  |  |  * This method updates the features geometry, and operates the same as  | 
511  |  |  * SetGeometryDirectly(), except that this method does not assume ownership  | 
512  |  |  * of the passed geometry, but instead makes a copy of it.  | 
513  |  |  *  | 
514  |  |  * This method is the same as the C function OGR_F_SetGeometry().  | 
515  |  |  *  | 
516  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
517  |  |  * this object comes from a layer and the modifications must be serialized back  | 
518  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
519  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
520  |  |  *  | 
521  |  |  * @param poGeomIn new geometry to apply to feature. Passing NULL value here  | 
522  |  |  * is correct and it will result in deallocation of currently assigned geometry  | 
523  |  |  * without assigning new one.  | 
524  |  |  *  | 
525  |  |  * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if  | 
526  |  |  * the geometry type is illegal for the OGRFeatureDefn (checking not yet  | 
527  |  |  * implemented).  | 
528  |  |  */  | 
529  |  |  | 
530  |  | OGRErr OGRFeature::SetGeometry(const OGRGeometry *poGeomIn)  | 
531  |  |  | 
532  | 0  | { | 
533  | 0  |     if (GetGeomFieldCount() < 1)  | 
534  | 0  |         return OGRERR_FAILURE;  | 
535  |  |  | 
536  | 0  |     return SetGeomField(0, poGeomIn);  | 
537  | 0  | }  | 
538  |  |  | 
539  |  | /************************************************************************/  | 
540  |  | /*                         OGR_F_SetGeometry()                          */  | 
541  |  | /************************************************************************/  | 
542  |  |  | 
543  |  | /**  | 
544  |  |  * \brief Set feature geometry.  | 
545  |  |  *  | 
546  |  |  * This function updates the features geometry, and operates the same as  | 
547  |  |  * SetGeometryDirectly(), except that this function does not assume ownership  | 
548  |  |  * of the passed geometry, but instead makes a copy of it.  | 
549  |  |  *  | 
550  |  |  * This function is the same as the C++ OGRFeature::SetGeometry().  | 
551  |  |  *  | 
552  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
553  |  |  * this object comes from a layer and the modifications must be serialized back  | 
554  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
555  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
556  |  |  *  | 
557  |  |  * @param hFeat handle to the feature on which new geometry is applied to.  | 
558  |  |  * @param hGeom handle to the new geometry to apply to feature.  | 
559  |  |  *  | 
560  |  |  * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if  | 
561  |  |  * the geometry type is illegal for the OGRFeatureDefn (checking not yet  | 
562  |  |  * implemented).  | 
563  |  |  */  | 
564  |  |  | 
565  |  | OGRErr OGR_F_SetGeometry(OGRFeatureH hFeat, OGRGeometryH hGeom)  | 
566  |  |  | 
567  | 0  | { | 
568  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_SetGeometry", OGRERR_FAILURE);  | 
569  |  |  | 
570  | 0  |     return OGRFeature::FromHandle(hFeat)->SetGeometry(  | 
571  | 0  |         OGRGeometry::FromHandle(hGeom));  | 
572  | 0  | }  | 
573  |  |  | 
574  |  | /************************************************************************/  | 
575  |  | /*                        SetGeometry()                                 */  | 
576  |  | /************************************************************************/  | 
577  |  |  | 
578  |  | /**  | 
579  |  |  * \brief Set feature geometry.  | 
580  |  |  *  | 
581  |  |  * This method is the same as the C function OGR_F_SetGeometryDirectly().  | 
582  |  |  *  | 
583  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
584  |  |  * this object comes from a layer and the modifications must be serialized back  | 
585  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
586  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
587  |  |  *  | 
588  |  |  * @param poGeomIn new geometry to apply to feature. Passing NULL value here  | 
589  |  |  * is correct and it will result in deallocation of currently assigned geometry  | 
590  |  |  * without assigning new one.  | 
591  |  |  *  | 
592  |  |  * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if  | 
593  |  |  * the geometry type is illegal for the OGRFeatureDefn (checking not yet  | 
594  |  |  * implemented).  | 
595  |  |  *  | 
596  |  |  * @since GDAL 3.11  | 
597  |  |  */  | 
598  |  |  | 
599  |  | OGRErr OGRFeature::SetGeometry(std::unique_ptr<OGRGeometry> poGeomIn)  | 
600  |  |  | 
601  | 0  | { | 
602  | 0  |     return SetGeomField(0, std::move(poGeomIn));  | 
603  | 0  | }  | 
604  |  |  | 
605  |  | /************************************************************************/  | 
606  |  | /*                           StealGeometry()                            */  | 
607  |  | /************************************************************************/  | 
608  |  |  | 
609  |  | /**  | 
610  |  |  * \brief Take away ownership of geometry.  | 
611  |  |  *  | 
612  |  |  * Fetch the geometry from this feature, and clear the reference to the  | 
613  |  |  * geometry on the feature.  This is a mechanism for the application to  | 
614  |  |  * take over ownership of the geometry from the feature without copying.  | 
615  |  |  * Sort of an inverse to SetGeometryDirectly().  | 
616  |  |  *  | 
617  |  |  * After this call the OGRFeature will have a NULL geometry.  | 
618  |  |  *  | 
619  |  |  * @return the pointer to the geometry.  | 
620  |  |  */  | 
621  |  |  | 
622  |  | OGRGeometry *OGRFeature::StealGeometry()  | 
623  |  |  | 
624  | 0  | { | 
625  | 0  |     if (GetGeomFieldCount() > 0)  | 
626  | 0  |     { | 
627  | 0  |         OGRGeometry *poReturn = papoGeometries[0];  | 
628  | 0  |         papoGeometries[0] = nullptr;  | 
629  | 0  |         return poReturn;  | 
630  | 0  |     }  | 
631  |  |  | 
632  | 0  |     return nullptr;  | 
633  | 0  | }  | 
634  |  |  | 
635  |  | /**  | 
636  |  |  * \brief Take away ownership of geometry.  | 
637  |  |  *  | 
638  |  |  * Fetch the geometry from this feature, and clear the reference to the  | 
639  |  |  * geometry on the feature.  This is a mechanism for the application to  | 
640  |  |  * take over ownership of the geometry from the feature without copying.  | 
641  |  |  * Sort of an inverse to SetGeometryDirectly().  | 
642  |  |  *  | 
643  |  |  * After this call the OGRFeature will have a NULL geometry.  | 
644  |  |  *  | 
645  |  |  * @param iGeomField index of the geometry field.  | 
646  |  |  *  | 
647  |  |  * @return the pointer to the geometry.  | 
648  |  |  */  | 
649  |  |  | 
650  |  | OGRGeometry *OGRFeature::StealGeometry(int iGeomField)  | 
651  |  |  | 
652  | 0  | { | 
653  | 0  |     if (iGeomField >= 0 && iGeomField < GetGeomFieldCount())  | 
654  | 0  |     { | 
655  | 0  |         OGRGeometry *poReturn = papoGeometries[iGeomField];  | 
656  | 0  |         papoGeometries[iGeomField] = nullptr;  | 
657  | 0  |         return poReturn;  | 
658  | 0  |     }  | 
659  |  |  | 
660  | 0  |     return nullptr;  | 
661  | 0  | }  | 
662  |  |  | 
663  |  | /************************************************************************/  | 
664  |  | /*                        OGR_F_StealGeometry()                         */  | 
665  |  | /************************************************************************/  | 
666  |  |  | 
667  |  | /**  | 
668  |  |  * \brief Take away ownership of geometry.  | 
669  |  |  *  | 
670  |  |  * Fetch the geometry from this feature, and clear the reference to the  | 
671  |  |  * geometry on the feature.  This is a mechanism for the application to  | 
672  |  |  * take over ownership of the geometry from the feature without copying.  | 
673  |  |  * Sort of an inverse to OGR_FSetGeometryDirectly().  | 
674  |  |  *  | 
675  |  |  * After this call the OGRFeature will have a NULL geometry.  | 
676  |  |  *  | 
677  |  |  * @param hFeat feature from which to steal the first geometry.  | 
678  |  |  * @return the pointer to the stolen geometry.  | 
679  |  |  */  | 
680  |  |  | 
681  |  | OGRGeometryH OGR_F_StealGeometry(OGRFeatureH hFeat)  | 
682  |  |  | 
683  | 0  | { | 
684  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_StealGeometry", nullptr);  | 
685  |  |  | 
686  | 0  |     return OGRGeometry::ToHandle(  | 
687  | 0  |         OGRFeature::FromHandle(hFeat)->StealGeometry());  | 
688  | 0  | }  | 
689  |  |  | 
690  |  | /************************************************************************/  | 
691  |  | /*                       OGR_F_StealGeometryEx()                        */  | 
692  |  | /************************************************************************/  | 
693  |  |  | 
694  |  | /**  | 
695  |  |  * \brief Take away ownership of geometry.  | 
696  |  |  *  | 
697  |  |  * Fetch the geometry from this feature, and clear the reference to the  | 
698  |  |  * geometry on the feature.  This is a mechanism for the application to  | 
699  |  |  * take over ownership of the geometry from the feature without copying.  | 
700  |  |  * This is the functional opposite of OGR_F_SetGeomFieldDirectly.  | 
701  |  |  *  | 
702  |  |  * After this call the OGRFeature will have a NULL geometry for the  | 
703  |  |  * geometry field of index iGeomField.  | 
704  |  |  *  | 
705  |  |  * @param hFeat feature from which to steal a geometry.  | 
706  |  |  * @param iGeomField index of the geometry field to steal.  | 
707  |  |  * @return the pointer to the stolen geometry.  | 
708  |  |  * @since GDAL 3.5  | 
709  |  |  */  | 
710  |  |  | 
711  |  | OGRGeometryH OGR_F_StealGeometryEx(OGRFeatureH hFeat, int iGeomField)  | 
712  |  |  | 
713  | 0  | { | 
714  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_StealGeometryEx", nullptr);  | 
715  |  |  | 
716  | 0  |     return OGRGeometry::ToHandle(  | 
717  | 0  |         OGRFeature::FromHandle(hFeat)->StealGeometry(iGeomField));  | 
718  | 0  | }  | 
719  |  |  | 
720  |  | /************************************************************************/  | 
721  |  | /*                           GetGeometryRef()                           */  | 
722  |  | /************************************************************************/  | 
723  |  |  | 
724  |  | /**  | 
725  |  |  * \fn OGRGeometry *OGRFeature::GetGeometryRef();  | 
726  |  |  *  | 
727  |  |  * \brief Fetch pointer to feature geometry.  | 
728  |  |  *  | 
729  |  |  * This method is essentially the same as the C function OGR_F_GetGeometryRef().  | 
730  |  |  * (the only difference is that the C function honours  | 
731  |  |  * OGRGetNonLinearGeometriesEnabledFlag())  | 
732  |  |  *  | 
733  |  |  * Starting with GDAL 1.11, this is equivalent to calling  | 
734  |  |  * OGRFeature::GetGeomFieldRef(0).  | 
735  |  |  *  | 
736  |  |  * @return pointer to internal feature geometry.  This object should  | 
737  |  |  * not be modified.  | 
738  |  |  */  | 
739  |  | OGRGeometry *OGRFeature::GetGeometryRef()  | 
740  |  |  | 
741  | 0  | { | 
742  | 0  |     if (GetGeomFieldCount() > 0)  | 
743  | 0  |         return GetGeomFieldRef(0);  | 
744  |  |  | 
745  | 0  |     return nullptr;  | 
746  | 0  | }  | 
747  |  |  | 
748  |  | /**  | 
749  |  |  * \fn const OGRGeometry *OGRFeature::GetGeometryRef() const;  | 
750  |  |  *  | 
751  |  |  * \brief Fetch pointer to feature geometry.  | 
752  |  |  *  | 
753  |  |  * This method is essentially the same as the C function OGR_F_GetGeometryRef().  | 
754  |  |  * (the only difference is that the C function honours  | 
755  |  |  * OGRGetNonLinearGeometriesEnabledFlag())  | 
756  |  |  *  | 
757  |  |  * @return pointer to internal feature geometry.  This object should  | 
758  |  |  * not be modified.  | 
759  |  |  * @since GDAL 2.3  | 
760  |  |  */  | 
761  |  | const OGRGeometry *OGRFeature::GetGeometryRef() const  | 
762  |  |  | 
763  | 0  | { | 
764  | 0  |     if (GetGeomFieldCount() > 0)  | 
765  | 0  |         return GetGeomFieldRef(0);  | 
766  |  |  | 
767  | 0  |     return nullptr;  | 
768  | 0  | }  | 
769  |  |  | 
770  |  | /************************************************************************/  | 
771  |  | /*                        OGR_F_GetGeometryRef()                        */  | 
772  |  | /************************************************************************/  | 
773  |  |  | 
774  |  | /**  | 
775  |  |  * \brief Fetch a handle to feature geometry.  | 
776  |  |  *  | 
777  |  |  * This function is essentially the same as the C++ method  | 
778  |  |  * OGRFeature::GetGeometryRef() (the only difference is that this C function  | 
779  |  |  * honours OGRGetNonLinearGeometriesEnabledFlag())  | 
780  |  |  *  | 
781  |  |  * @param hFeat handle to the feature to get geometry from.  | 
782  |  |  * @return a handle to internal feature geometry.  This object should  | 
783  |  |  * not be modified.  | 
784  |  |  */  | 
785  |  |  | 
786  |  | OGRGeometryH OGR_F_GetGeometryRef(OGRFeatureH hFeat)  | 
787  |  |  | 
788  | 0  | { | 
789  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetGeometryRef", nullptr);  | 
790  |  |  | 
791  | 0  |     OGRFeature *poFeature = OGRFeature::FromHandle(hFeat);  | 
792  | 0  |     OGRGeometry *poGeom = poFeature->GetGeometryRef();  | 
793  |  | 
  | 
794  | 0  |     if (!OGRGetNonLinearGeometriesEnabledFlag() && poGeom != nullptr &&  | 
795  | 0  |         OGR_GT_IsNonLinear(poGeom->getGeometryType()))  | 
796  | 0  |     { | 
797  | 0  |         const OGRwkbGeometryType eTargetType =  | 
798  | 0  |             OGR_GT_GetLinear(poGeom->getGeometryType());  | 
799  | 0  |         poGeom = OGRGeometryFactory::forceTo(poFeature->StealGeometry(),  | 
800  | 0  |                                              eTargetType);  | 
801  | 0  |         poFeature->SetGeomFieldDirectly(0, poGeom);  | 
802  | 0  |         poGeom = poFeature->GetGeometryRef();  | 
803  | 0  |     }  | 
804  |  | 
  | 
805  | 0  |     return OGRGeometry::ToHandle(poGeom);  | 
806  | 0  | }  | 
807  |  |  | 
808  |  | /************************************************************************/  | 
809  |  | /*                           GetGeomFieldRef()                          */  | 
810  |  | /************************************************************************/  | 
811  |  |  | 
812  |  | /**  | 
813  |  |  * \brief Fetch pointer to feature geometry.  | 
814  |  |  *  | 
815  |  |  * This method is the same as the C function OGR_F_GetGeomFieldRef().  | 
816  |  |  *  | 
817  |  |  * @param iField geometry field to get.  | 
818  |  |  *  | 
819  |  |  * @return pointer to internal feature geometry.  This object should  | 
820  |  |  * not be modified.  | 
821  |  |  *  | 
822  |  |  * @since GDAL 1.11  | 
823  |  |  */  | 
824  |  | OGRGeometry *OGRFeature::GetGeomFieldRef(int iField)  | 
825  |  |  | 
826  | 0  | { | 
827  | 0  |     if (iField < 0 || iField >= GetGeomFieldCount())  | 
828  | 0  |         return nullptr;  | 
829  | 0  |     else  | 
830  | 0  |         return papoGeometries[iField];  | 
831  | 0  | }  | 
832  |  |  | 
833  |  | /**  | 
834  |  |  * \brief Fetch pointer to feature geometry.  | 
835  |  |  *  | 
836  |  |  * This method is the same as the C function OGR_F_GetGeomFieldRef().  | 
837  |  |  *  | 
838  |  |  * @param iField geometry field to get.  | 
839  |  |  *  | 
840  |  |  * @return pointer to internal feature geometry.  This object should  | 
841  |  |  * not be modified.  | 
842  |  |  * @since GDAL 2.3  | 
843  |  |  */  | 
844  |  | const OGRGeometry *OGRFeature::GetGeomFieldRef(int iField) const  | 
845  |  |  | 
846  | 0  | { | 
847  | 0  |     if (iField < 0 || iField >= GetGeomFieldCount())  | 
848  | 0  |         return nullptr;  | 
849  | 0  |     else  | 
850  | 0  |         return papoGeometries[iField];  | 
851  | 0  | }  | 
852  |  |  | 
853  |  | /************************************************************************/  | 
854  |  | /*                           GetGeomFieldRef()                          */  | 
855  |  | /************************************************************************/  | 
856  |  |  | 
857  |  | /**  | 
858  |  |  * \brief Fetch pointer to feature geometry.  | 
859  |  |  *  | 
860  |  |  * @param pszFName name of geometry field to get.  | 
861  |  |  *  | 
862  |  |  * @return pointer to internal feature geometry.  This object should  | 
863  |  |  * not be modified.  | 
864  |  |  *  | 
865  |  |  * @since GDAL 1.11  | 
866  |  |  */  | 
867  |  | OGRGeometry *OGRFeature::GetGeomFieldRef(const char *pszFName)  | 
868  |  |  | 
869  | 0  | { | 
870  | 0  |     const int iField = GetGeomFieldIndex(pszFName);  | 
871  | 0  |     if (iField < 0)  | 
872  | 0  |         return nullptr;  | 
873  |  |  | 
874  | 0  |     return papoGeometries[iField];  | 
875  | 0  | }  | 
876  |  |  | 
877  |  | /**  | 
878  |  |  * \brief Fetch pointer to feature geometry.  | 
879  |  |  *  | 
880  |  |  * @param pszFName name of geometry field to get.  | 
881  |  |  *  | 
882  |  |  * @return pointer to internal feature geometry.  This object should  | 
883  |  |  * not be modified.  | 
884  |  |  * @since GDAL 2.3  | 
885  |  |  */  | 
886  |  | const OGRGeometry *OGRFeature::GetGeomFieldRef(const char *pszFName) const  | 
887  |  |  | 
888  | 0  | { | 
889  | 0  |     const int iField = GetGeomFieldIndex(pszFName);  | 
890  | 0  |     if (iField < 0)  | 
891  | 0  |         return nullptr;  | 
892  |  |  | 
893  | 0  |     return papoGeometries[iField];  | 
894  | 0  | }  | 
895  |  |  | 
896  |  | /************************************************************************/  | 
897  |  | /*                       OGR_F_GetGeomFieldRef()                        */  | 
898  |  | /************************************************************************/  | 
899  |  |  | 
900  |  | /**  | 
901  |  |  * \brief Fetch a handle to feature geometry.  | 
902  |  |  *  | 
903  |  |  * This function is the same as the C++ method OGRFeature::GetGeomFieldRef().  | 
904  |  |  *  | 
905  |  |  * @param hFeat handle to the feature to get geometry from.  | 
906  |  |  * @param iField geometry field to get.  | 
907  |  |  * @return a handle to internal feature geometry.  This object should  | 
908  |  |  * not be modified.  | 
909  |  |  *  | 
910  |  |  * @since GDAL 1.11  | 
911  |  |  */  | 
912  |  |  | 
913  |  | OGRGeometryH OGR_F_GetGeomFieldRef(OGRFeatureH hFeat, int iField)  | 
914  |  |  | 
915  | 0  | { | 
916  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetGeomFieldRef", nullptr);  | 
917  |  |  | 
918  | 0  |     OGRFeature *poFeature = OGRFeature::FromHandle(hFeat);  | 
919  | 0  |     OGRGeometry *poGeom = poFeature->GetGeomFieldRef(iField);  | 
920  |  | 
  | 
921  | 0  |     if (!OGRGetNonLinearGeometriesEnabledFlag() && poGeom != nullptr &&  | 
922  | 0  |         OGR_GT_IsNonLinear(poGeom->getGeometryType()))  | 
923  | 0  |     { | 
924  | 0  |         const OGRwkbGeometryType eTargetType =  | 
925  | 0  |             OGR_GT_GetLinear(poGeom->getGeometryType());  | 
926  | 0  |         poGeom = OGRGeometryFactory::forceTo(poFeature->StealGeometry(iField),  | 
927  | 0  |                                              eTargetType);  | 
928  | 0  |         poFeature->SetGeomFieldDirectly(iField, poGeom);  | 
929  | 0  |         poGeom = poFeature->GetGeomFieldRef(iField);  | 
930  | 0  |     }  | 
931  |  | 
  | 
932  | 0  |     return OGRGeometry::ToHandle(poGeom);  | 
933  | 0  | }  | 
934  |  |  | 
935  |  | /************************************************************************/  | 
936  |  | /*                       SetGeomFieldDirectly()                         */  | 
937  |  | /************************************************************************/  | 
938  |  |  | 
939  |  | /**  | 
940  |  |  * \brief Set feature geometry of a specified geometry field.  | 
941  |  |  *  | 
942  |  |  * This method updates the features geometry, and operates the same as  | 
943  |  |  * SetGeomField(), except that this method assumes ownership of the  | 
944  |  |  * passed geometry (even in case of failure of that function).  | 
945  |  |  *  | 
946  |  |  * This method is the same as the C function OGR_F_SetGeomFieldDirectly().  | 
947  |  |  *  | 
948  |  |  * @param iField geometry field to set.  | 
949  |  |  * @param poGeomIn new geometry to apply to feature. Passing NULL value here  | 
950  |  |  * is correct and it will result in deallocation of currently assigned geometry  | 
951  |  |  * without assigning new one.  | 
952  |  |  *  | 
953  |  |  * @return OGRERR_NONE if successful, or OGRERR_FAILURE if the index is invalid,  | 
954  |  |  * or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if the geometry type is illegal for the  | 
955  |  |  * OGRFeatureDefn (checking not yet implemented).  | 
956  |  |  *  | 
957  |  |  * @since GDAL 1.11  | 
958  |  |  */  | 
959  |  |  | 
960  |  | OGRErr OGRFeature::SetGeomFieldDirectly(int iField, OGRGeometry *poGeomIn)  | 
961  | 0  | { | 
962  | 0  |     if (poGeomIn && poGeomIn == GetGeomFieldRef(iField))  | 
963  | 0  |     { | 
964  | 0  |         return OGRERR_NONE;  | 
965  | 0  |     }  | 
966  |  |  | 
967  | 0  |     return SetGeomField(iField, std::unique_ptr<OGRGeometry>(poGeomIn));  | 
968  | 0  | }  | 
969  |  |  | 
970  |  | /************************************************************************/  | 
971  |  | /*                     OGR_F_SetGeomFieldDirectly()                     */  | 
972  |  | /************************************************************************/  | 
973  |  |  | 
974  |  | /**  | 
975  |  |  * \brief Set feature geometry of a specified geometry field.  | 
976  |  |  *  | 
977  |  |  * This function updates the features geometry, and operates the same as  | 
978  |  |  * SetGeomField(), except that this function assumes ownership of the  | 
979  |  |  * passed geometry (even in case of failure of that function).  | 
980  |  |  *  | 
981  |  |  * This function is the same as the C++ method  | 
982  |  |  * OGRFeature::SetGeomFieldDirectly.  | 
983  |  |  *  | 
984  |  |  * @param hFeat handle to the feature on which to apply the geometry.  | 
985  |  |  * @param iField geometry field to set.  | 
986  |  |  * @param hGeom handle to the new geometry to apply to feature.  | 
987  |  |  *  | 
988  |  |  * @return OGRERR_NONE if successful, or OGRERR_FAILURE if the index is invalid,  | 
989  |  |  * or OGR_UNSUPPORTED_GEOMETRY_TYPE if the geometry type is illegal for the  | 
990  |  |  * OGRFeatureDefn (checking not yet implemented).  | 
991  |  |  *  | 
992  |  |  * @since GDAL 1.11  | 
993  |  |  */  | 
994  |  |  | 
995  |  | OGRErr OGR_F_SetGeomFieldDirectly(OGRFeatureH hFeat, int iField,  | 
996  |  |                                   OGRGeometryH hGeom)  | 
997  |  |  | 
998  | 0  | { | 
999  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_SetGeomFieldDirectly", OGRERR_FAILURE);  | 
1000  |  |  | 
1001  | 0  |     return OGRFeature::FromHandle(hFeat)->SetGeomFieldDirectly(  | 
1002  | 0  |         iField, OGRGeometry::FromHandle(hGeom));  | 
1003  | 0  | }  | 
1004  |  |  | 
1005  |  | /************************************************************************/  | 
1006  |  | /*                            SetGeomField()                            */  | 
1007  |  | /************************************************************************/  | 
1008  |  |  | 
1009  |  | /**  | 
1010  |  |  * \brief Set feature geometry of a specified geometry field.  | 
1011  |  |  *  | 
1012  |  |  * This method updates the features geometry, and operates the same as  | 
1013  |  |  * SetGeomFieldDirectly(), except that this method does not assume ownership  | 
1014  |  |  * of the passed geometry, but instead makes a copy of it.  | 
1015  |  |  *  | 
1016  |  |  * This method is the same as the C function OGR_F_SetGeomField().  | 
1017  |  |  *  | 
1018  |  |  * @param iField geometry field to set.  | 
1019  |  |  * @param poGeomIn new geometry to apply to feature. Passing NULL value here  | 
1020  |  |  * is correct and it will result in deallocation of currently assigned geometry  | 
1021  |  |  * without assigning new one.  | 
1022  |  |  *  | 
1023  |  |  * @return OGRERR_NONE if successful, or OGRERR_FAILURE if the index is invalid,  | 
1024  |  |  * or OGR_UNSUPPORTED_GEOMETRY_TYPE if the geometry type is illegal for the  | 
1025  |  |  * OGRFeatureDefn (checking not yet implemented).  | 
1026  |  |  *  | 
1027  |  |  * @since GDAL 1.11  | 
1028  |  |  */  | 
1029  |  |  | 
1030  |  | OGRErr OGRFeature::SetGeomField(int iField, const OGRGeometry *poGeomIn)  | 
1031  |  |  | 
1032  | 0  | { | 
1033  | 0  |     if (iField < 0 || iField >= GetGeomFieldCount())  | 
1034  | 0  |         return OGRERR_FAILURE;  | 
1035  |  |  | 
1036  | 0  |     if (papoGeometries[iField] != poGeomIn)  | 
1037  | 0  |     { | 
1038  | 0  |         delete papoGeometries[iField];  | 
1039  |  | 
  | 
1040  | 0  |         if (poGeomIn != nullptr)  | 
1041  | 0  |             papoGeometries[iField] = poGeomIn->clone();  | 
1042  | 0  |         else  | 
1043  | 0  |             papoGeometries[iField] = nullptr;  | 
1044  | 0  |     }  | 
1045  |  |  | 
1046  |  |     // TODO(schwehr): Verify that the geometry matches the defn's type.  | 
1047  |  | 
  | 
1048  | 0  |     return OGRERR_NONE;  | 
1049  | 0  | }  | 
1050  |  |  | 
1051  |  | /************************************************************************/  | 
1052  |  | /*                        OGR_F_SetGeomField()                          */  | 
1053  |  | /************************************************************************/  | 
1054  |  |  | 
1055  |  | /**  | 
1056  |  |  * \brief Set feature geometry of a specified geometry field.  | 
1057  |  |  *  | 
1058  |  |  * This function updates the features geometry, and operates the same as  | 
1059  |  |  * SetGeometryDirectly(), except that this function does not assume ownership  | 
1060  |  |  * of the passed geometry, but instead makes a copy of it.  | 
1061  |  |  *  | 
1062  |  |  * This function is the same as the C++ OGRFeature::SetGeomField().  | 
1063  |  |  *  | 
1064  |  |  * @param hFeat handle to the feature on which new geometry is applied to.  | 
1065  |  |  * @param iField geometry field to set.  | 
1066  |  |  * @param hGeom handle to the new geometry to apply to feature.  | 
1067  |  |  *  | 
1068  |  |  * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if  | 
1069  |  |  * the geometry type is illegal for the OGRFeatureDefn (checking not yet  | 
1070  |  |  * implemented).  | 
1071  |  |  */  | 
1072  |  |  | 
1073  |  | OGRErr OGR_F_SetGeomField(OGRFeatureH hFeat, int iField, OGRGeometryH hGeom)  | 
1074  |  |  | 
1075  | 0  | { | 
1076  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_SetGeomField", OGRERR_FAILURE);  | 
1077  |  |  | 
1078  | 0  |     return OGRFeature::FromHandle(hFeat)->SetGeomField(  | 
1079  | 0  |         iField, OGRGeometry::FromHandle(hGeom));  | 
1080  | 0  | }  | 
1081  |  |  | 
1082  |  | /************************************************************************/  | 
1083  |  | /*                       SetGeomField()                                 */  | 
1084  |  | /************************************************************************/  | 
1085  |  |  | 
1086  |  | /**  | 
1087  |  |  * \brief Set feature geometry of a specified geometry field.  | 
1088  |  |  *  | 
1089  |  |  * This method is the same as the C function OGR_F_SetGeomFieldDirectly().  | 
1090  |  |  *  | 
1091  |  |  * @param iField geometry field to set.  | 
1092  |  |  * @param poGeomIn new geometry to apply to feature. Passing NULL value here  | 
1093  |  |  * is correct and it will result in deallocation of currently assigned geometry  | 
1094  |  |  * without assigning new one.  | 
1095  |  |  *  | 
1096  |  |  * @return OGRERR_NONE if successful, or OGRERR_FAILURE if the index is invalid,  | 
1097  |  |  * or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if the geometry type is illegal for the  | 
1098  |  |  * OGRFeatureDefn (checking not yet implemented).  | 
1099  |  |  *  | 
1100  |  |  * @since GDAL 3.11  | 
1101  |  |  */  | 
1102  |  |  | 
1103  |  | OGRErr OGRFeature::SetGeomField(int iField,  | 
1104  |  |                                 std::unique_ptr<OGRGeometry> poGeomIn)  | 
1105  |  |  | 
1106  | 0  | { | 
1107  | 0  |     if (iField < 0 || iField >= GetGeomFieldCount())  | 
1108  | 0  |     { | 
1109  | 0  |         return OGRERR_FAILURE;  | 
1110  | 0  |     }  | 
1111  |  |  | 
1112  | 0  |     if (papoGeometries[iField] != poGeomIn.get())  | 
1113  | 0  |     { | 
1114  | 0  |         delete papoGeometries[iField];  | 
1115  | 0  |         papoGeometries[iField] = poGeomIn.release();  | 
1116  | 0  |     }  | 
1117  |  | 
  | 
1118  | 0  |     return OGRERR_NONE;  | 
1119  | 0  | }  | 
1120  |  |  | 
1121  |  | /************************************************************************/  | 
1122  |  | /*                               Clone()                                */  | 
1123  |  | /************************************************************************/  | 
1124  |  |  | 
1125  |  | /**  | 
1126  |  |  * \brief Duplicate feature.  | 
1127  |  |  *  | 
1128  |  |  * The newly created feature is owned by the caller, and will have its own  | 
1129  |  |  * reference to the OGRFeatureDefn.  | 
1130  |  |  *  | 
1131  |  |  * This method is the same as the C function OGR_F_Clone().  | 
1132  |  |  *  | 
1133  |  |  * @return new feature, exactly matching this feature. Or, starting with GDAL  | 
1134  |  |  * 2.1, NULL in case of out of memory situation.  | 
1135  |  |  */  | 
1136  |  |  | 
1137  |  | OGRFeature *OGRFeature::Clone() const  | 
1138  |  |  | 
1139  | 0  | { | 
1140  | 0  |     OGRFeature *poNew = CreateFeature(poDefn);  | 
1141  | 0  |     if (poNew == nullptr)  | 
1142  | 0  |         return nullptr;  | 
1143  |  |  | 
1144  | 0  |     if (!CopySelfTo(poNew))  | 
1145  | 0  |     { | 
1146  | 0  |         delete poNew;  | 
1147  | 0  |         return nullptr;  | 
1148  | 0  |     }  | 
1149  |  |  | 
1150  | 0  |     return poNew;  | 
1151  | 0  | }  | 
1152  |  |  | 
1153  |  | /************************************************************************/  | 
1154  |  | /*                            OGR_F_Clone()                             */  | 
1155  |  | /************************************************************************/  | 
1156  |  |  | 
1157  |  | /**  | 
1158  |  |  * \brief Duplicate feature.  | 
1159  |  |  *  | 
1160  |  |  * The newly created feature is owned by the caller, and will have its own  | 
1161  |  |  * reference to the OGRFeatureDefn.  | 
1162  |  |  *  | 
1163  |  |  * This function is the same as the C++ method OGRFeature::Clone().  | 
1164  |  |  *  | 
1165  |  |  * @param hFeat handle to the feature to clone.  | 
1166  |  |  * @return a handle to the new feature, exactly matching this feature.  | 
1167  |  |  */  | 
1168  |  |  | 
1169  |  | OGRFeatureH OGR_F_Clone(OGRFeatureH hFeat)  | 
1170  |  |  | 
1171  | 0  | { | 
1172  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_Clone", nullptr);  | 
1173  |  |  | 
1174  | 0  |     return OGRFeature::ToHandle(OGRFeature::FromHandle(hFeat)->Clone());  | 
1175  | 0  | }  | 
1176  |  |  | 
1177  |  | /************************************************************************/  | 
1178  |  | /*                             CopySelfTo()                             */  | 
1179  |  | /************************************************************************/  | 
1180  |  |  | 
1181  |  | /**  | 
1182  |  |  * \brief Copies the innards of this OGRFeature into the supplied object.  | 
1183  |  |  *  | 
1184  |  |  * This is mainly intended to allow derived classes to implement their own  | 
1185  |  |  * Clone functions.  | 
1186  |  |  *  | 
1187  |  |  * @param poNew The object into which to copy the data of this object.  | 
1188  |  |  * @return True if successful, false if the copy failed.  | 
1189  |  |  */  | 
1190  |  |  | 
1191  |  | bool OGRFeature::CopySelfTo(OGRFeature *poNew) const  | 
1192  | 0  | { | 
1193  | 0  |     const int nFieldCount = poDefn->GetFieldCountUnsafe();  | 
1194  | 0  |     for (int i = 0; i < nFieldCount; i++)  | 
1195  | 0  |     { | 
1196  | 0  |         if (!poNew->SetFieldInternal(i, pauFields + i))  | 
1197  | 0  |         { | 
1198  | 0  |             return false;  | 
1199  | 0  |         }  | 
1200  | 0  |     }  | 
1201  | 0  |     if (poNew->papoGeometries)  | 
1202  | 0  |     { | 
1203  | 0  |         for (int i = 0; i < poDefn->GetGeomFieldCount(); i++)  | 
1204  | 0  |         { | 
1205  | 0  |             if (papoGeometries[i] != nullptr)  | 
1206  | 0  |             { | 
1207  | 0  |                 poNew->papoGeometries[i] = papoGeometries[i]->clone();  | 
1208  | 0  |                 if (poNew->papoGeometries[i] == nullptr)  | 
1209  | 0  |                 { | 
1210  | 0  |                     return false;  | 
1211  | 0  |                 }  | 
1212  | 0  |             }  | 
1213  | 0  |         }  | 
1214  | 0  |     }  | 
1215  |  |  | 
1216  | 0  |     if (m_pszStyleString != nullptr)  | 
1217  | 0  |     { | 
1218  | 0  |         poNew->m_pszStyleString = VSI_STRDUP_VERBOSE(m_pszStyleString);  | 
1219  | 0  |         if (poNew->m_pszStyleString == nullptr)  | 
1220  | 0  |         { | 
1221  | 0  |             return false;  | 
1222  | 0  |         }  | 
1223  | 0  |     }  | 
1224  |  |  | 
1225  | 0  |     poNew->SetFID(GetFID());  | 
1226  |  | 
  | 
1227  | 0  |     if (m_pszNativeData != nullptr)  | 
1228  | 0  |     { | 
1229  | 0  |         poNew->m_pszNativeData = VSI_STRDUP_VERBOSE(m_pszNativeData);  | 
1230  | 0  |         if (poNew->m_pszNativeData == nullptr)  | 
1231  | 0  |         { | 
1232  | 0  |             return false;  | 
1233  | 0  |         }  | 
1234  | 0  |     }  | 
1235  |  |  | 
1236  | 0  |     if (m_pszNativeMediaType != nullptr)  | 
1237  | 0  |     { | 
1238  | 0  |         poNew->m_pszNativeMediaType = VSI_STRDUP_VERBOSE(m_pszNativeMediaType);  | 
1239  | 0  |         if (poNew->m_pszNativeMediaType == nullptr)  | 
1240  | 0  |         { | 
1241  | 0  |             return false;  | 
1242  | 0  |         }  | 
1243  | 0  |     }  | 
1244  |  |  | 
1245  | 0  |     return true;  | 
1246  | 0  | }  | 
1247  |  |  | 
1248  |  | /************************************************************************/  | 
1249  |  | /*                           GetFieldCount()                            */  | 
1250  |  | /************************************************************************/  | 
1251  |  |  | 
1252  |  | /**  | 
1253  |  |  * \fn int OGRFeature::GetFieldCount() const;  | 
1254  |  |  *  | 
1255  |  |  * \brief Fetch number of fields on this feature.  | 
1256  |  |  * This will always be the same  | 
1257  |  |  * as the field count for the OGRFeatureDefn.  | 
1258  |  |  *  | 
1259  |  |  * This method is the same as the C function OGR_F_GetFieldCount().  | 
1260  |  |  *  | 
1261  |  |  * @return count of fields.  | 
1262  |  |  */  | 
1263  |  |  | 
1264  |  | /************************************************************************/  | 
1265  |  | /*                        OGR_F_GetFieldCount()                         */  | 
1266  |  | /************************************************************************/  | 
1267  |  |  | 
1268  |  | /**  | 
1269  |  |  * \brief Fetch number of fields on this feature  | 
1270  |  |  * This will always be the same  | 
1271  |  |  * as the field count for the OGRFeatureDefn.  | 
1272  |  |  *  | 
1273  |  |  * This function is the same as the C++ method OGRFeature::GetFieldCount().  | 
1274  |  |  *  | 
1275  |  |  * @param hFeat handle to the feature to get the fields count from.  | 
1276  |  |  * @return count of fields.  | 
1277  |  |  */  | 
1278  |  |  | 
1279  |  | int OGR_F_GetFieldCount(OGRFeatureH hFeat)  | 
1280  |  |  | 
1281  | 0  | { | 
1282  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldCount", 0);  | 
1283  |  |  | 
1284  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldCount();  | 
1285  | 0  | }  | 
1286  |  |  | 
1287  |  | /************************************************************************/  | 
1288  |  | /*                          GetFieldDefnRef()                           */  | 
1289  |  | /************************************************************************/  | 
1290  |  |  | 
1291  |  | /**  | 
1292  |  |  * \fn OGRFieldDefn *OGRFeature::GetFieldDefnRef( int iField );  | 
1293  |  |  *  | 
1294  |  |  * \brief Fetch definition for this field.  | 
1295  |  |  *  | 
1296  |  |  * This method is the same as the C function OGR_F_GetFieldDefnRef().  | 
1297  |  |  *  | 
1298  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
1299  |  |  *  | 
1300  |  |  * @return the field definition (from the OGRFeatureDefn).  This is an  | 
1301  |  |  * internal reference, and should not be deleted or modified.  | 
1302  |  |  */  | 
1303  |  |  | 
1304  |  | /**  | 
1305  |  |  * \fn const OGRFieldDefn *OGRFeature::GetFieldDefnRef( int iField ) const;  | 
1306  |  |  *  | 
1307  |  |  * \brief Fetch definition for this field.  | 
1308  |  |  *  | 
1309  |  |  * This method is the same as the C function OGR_F_GetFieldDefnRef().  | 
1310  |  |  *  | 
1311  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
1312  |  |  *  | 
1313  |  |  * @return the field definition (from the OGRFeatureDefn).  This is an  | 
1314  |  |  * internal reference, and should not be deleted or modified.  | 
1315  |  |  * @since GDAL 2.3  | 
1316  |  |  */  | 
1317  |  |  | 
1318  |  | /************************************************************************/  | 
1319  |  | /*                       OGR_F_GetFieldDefnRef()                        */  | 
1320  |  | /************************************************************************/  | 
1321  |  |  | 
1322  |  | /**  | 
1323  |  |  * \brief Fetch definition for this field.  | 
1324  |  |  *  | 
1325  |  |  * This function is the same as the C++ method OGRFeature::GetFieldDefnRef().  | 
1326  |  |  *  | 
1327  |  |  * @param hFeat handle to the feature on which the field is found.  | 
1328  |  |  * @param i the field to fetch, from 0 to GetFieldCount()-1.  | 
1329  |  |  *  | 
1330  |  |  * @return a handle to the field definition (from the OGRFeatureDefn).  | 
1331  |  |  * This is an internal reference, and should not be deleted or modified.  | 
1332  |  |  */  | 
1333  |  |  | 
1334  |  | OGRFieldDefnH OGR_F_GetFieldDefnRef(OGRFeatureH hFeat, int i)  | 
1335  |  |  | 
1336  | 0  | { | 
1337  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldDefnRef", nullptr);  | 
1338  |  |  | 
1339  | 0  |     OGRFeature *poFeat = OGRFeature::FromHandle(hFeat);  | 
1340  |  | 
  | 
1341  | 0  |     return OGRFieldDefn::ToHandle(poFeat->GetFieldDefnRef(i));  | 
1342  | 0  | }  | 
1343  |  |  | 
1344  |  | /************************************************************************/  | 
1345  |  | /*                           GetFieldIndex()                            */  | 
1346  |  | /************************************************************************/  | 
1347  |  |  | 
1348  |  | /**  | 
1349  |  |  * \fn int OGRFeature::GetFieldIndex( const char * pszName ) const;  | 
1350  |  |  *  | 
1351  |  |  * \brief Fetch the field index given field name.  | 
1352  |  |  *  | 
1353  |  |  * This is a cover for the OGRFeatureDefn::GetFieldIndex() method.  | 
1354  |  |  *  | 
1355  |  |  * This method is the same as the C function OGR_F_GetFieldIndex().  | 
1356  |  |  *  | 
1357  |  |  * @param pszName the name of the field to search for.  | 
1358  |  |  *  | 
1359  |  |  * @return the field index, or -1 if no matching field is found.  | 
1360  |  |  */  | 
1361  |  |  | 
1362  |  | /************************************************************************/  | 
1363  |  | /*                        OGR_F_GetFieldIndex()                         */  | 
1364  |  | /************************************************************************/  | 
1365  |  |  | 
1366  |  | /**  | 
1367  |  |  * \brief Fetch the field index given field name.  | 
1368  |  |  *  | 
1369  |  |  * This is a cover for the OGRFeatureDefn::GetFieldIndex() method.  | 
1370  |  |  *  | 
1371  |  |  * This function is the same as the C++ method OGRFeature::GetFieldIndex().  | 
1372  |  |  *  | 
1373  |  |  * @param hFeat handle to the feature on which the field is found.  | 
1374  |  |  * @param pszName the name of the field to search for.  | 
1375  |  |  *  | 
1376  |  |  * @return the field index, or -1 if no matching field is found.  | 
1377  |  |  */  | 
1378  |  |  | 
1379  |  | int OGR_F_GetFieldIndex(OGRFeatureH hFeat, const char *pszName)  | 
1380  |  |  | 
1381  | 0  | { | 
1382  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldIndex", 0);  | 
1383  |  |  | 
1384  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldIndex(pszName);  | 
1385  | 0  | }  | 
1386  |  |  | 
1387  |  | /************************************************************************/  | 
1388  |  | /*                         GetGeomFieldCount()                          */  | 
1389  |  | /************************************************************************/  | 
1390  |  |  | 
1391  |  | /**  | 
1392  |  |  * \fn int OGRFeature::GetGeomFieldCount() const;  | 
1393  |  |  *  | 
1394  |  |  * \brief Fetch number of geometry fields on this feature.  | 
1395  |  |  * This will always be the same  | 
1396  |  |  * as the geometry field count for the OGRFeatureDefn.  | 
1397  |  |  *  | 
1398  |  |  * This method is the same as the C function OGR_F_GetGeomFieldCount().  | 
1399  |  |  *  | 
1400  |  |  * @return count of geometry fields.  | 
1401  |  |  *  | 
1402  |  |  * @since GDAL 1.11  | 
1403  |  |  */  | 
1404  |  |  | 
1405  |  | /************************************************************************/  | 
1406  |  | /*                      OGR_F_GetGeomFieldCount()                       */  | 
1407  |  | /************************************************************************/  | 
1408  |  |  | 
1409  |  | /**  | 
1410  |  |  * \brief Fetch number of geometry fields on this feature  | 
1411  |  |  * This will always be the same  | 
1412  |  |  * as the geometry field count for the OGRFeatureDefn.  | 
1413  |  |  *  | 
1414  |  |  * This function is the same as the C++ method OGRFeature::GetGeomFieldCount().  | 
1415  |  |  *  | 
1416  |  |  * @param hFeat handle to the feature to get the geometry fields count from.  | 
1417  |  |  * @return count of geometry fields.  | 
1418  |  |  *  | 
1419  |  |  * @since GDAL 1.11  | 
1420  |  |  */  | 
1421  |  |  | 
1422  |  | int OGR_F_GetGeomFieldCount(OGRFeatureH hFeat)  | 
1423  |  |  | 
1424  | 0  | { | 
1425  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetGeomFieldCount", 0);  | 
1426  |  |  | 
1427  | 0  |     return OGRFeature::FromHandle(hFeat)->GetGeomFieldCount();  | 
1428  | 0  | }  | 
1429  |  |  | 
1430  |  | /************************************************************************/  | 
1431  |  | /*                        GetGeomFieldDefnRef()                         */  | 
1432  |  | /************************************************************************/  | 
1433  |  |  | 
1434  |  | /**  | 
1435  |  |  * \fn OGRGeomFieldDefn *OGRFeature::GetGeomFieldDefnRef( int iGeomField );  | 
1436  |  |  *  | 
1437  |  |  * \brief Fetch definition for this geometry field.  | 
1438  |  |  *  | 
1439  |  |  * This method is the same as the C function OGR_F_GetGeomFieldDefnRef().  | 
1440  |  |  *  | 
1441  |  |  * @param iGeomField the field to fetch, from 0 to GetGeomFieldCount()-1.  | 
1442  |  |  *  | 
1443  |  |  * @return the field definition (from the OGRFeatureDefn).  This is an  | 
1444  |  |  * internal reference, and should not be deleted or modified.  | 
1445  |  |  *  | 
1446  |  |  * @since GDAL 1.11  | 
1447  |  |  */  | 
1448  |  |  | 
1449  |  | /* clang-format off */  | 
1450  |  | /**  | 
1451  |  |  * \fn const OGRGeomFieldDefn *OGRFeature::GetGeomFieldDefnRef( int iGeomField ) const;  | 
1452  |  |  *  | 
1453  |  |  * \brief Fetch definition for this geometry field.  | 
1454  |  |  *  | 
1455  |  |  * This method is the same as the C function OGR_F_GetGeomFieldDefnRef().  | 
1456  |  |  *  | 
1457  |  |  * @param iGeomField the field to fetch, from 0 to GetGeomFieldCount()-1.  | 
1458  |  |  *  | 
1459  |  |  * @return the field definition (from the OGRFeatureDefn).  This is an  | 
1460  |  |  * internal reference, and should not be deleted or modified.  | 
1461  |  |  *  | 
1462  |  |  * @since GDAL 2.3  | 
1463  |  |  */  | 
1464  |  | /* clang-format on */  | 
1465  |  |  | 
1466  |  | /************************************************************************/  | 
1467  |  | /*                       OGR_F_GetGeomFieldDefnRef()                    */  | 
1468  |  | /************************************************************************/  | 
1469  |  |  | 
1470  |  | /**  | 
1471  |  |  * \brief Fetch definition for this geometry field.  | 
1472  |  |  *  | 
1473  |  |  * This function is the same as the C++ method  | 
1474  |  |  * OGRFeature::GetGeomFieldDefnRef().  | 
1475  |  |  *  | 
1476  |  |  * @param hFeat handle to the feature on which the field is found.  | 
1477  |  |  * @param i the field to fetch, from 0 to GetGeomFieldCount()-1.  | 
1478  |  |  *  | 
1479  |  |  * @return a handle to the field definition (from the OGRFeatureDefn).  | 
1480  |  |  * This is an internal reference, and should not be deleted or modified.  | 
1481  |  |  *  | 
1482  |  |  * @since GDAL 1.11  | 
1483  |  |  */  | 
1484  |  |  | 
1485  |  | OGRGeomFieldDefnH OGR_F_GetGeomFieldDefnRef(OGRFeatureH hFeat, int i)  | 
1486  |  |  | 
1487  | 0  | { | 
1488  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetGeomFieldDefnRef", nullptr);  | 
1489  |  |  | 
1490  | 0  |     return OGRGeomFieldDefn::ToHandle(  | 
1491  | 0  |         OGRFeature::FromHandle(hFeat)->GetGeomFieldDefnRef(i));  | 
1492  | 0  | }  | 
1493  |  |  | 
1494  |  | /************************************************************************/  | 
1495  |  | /*                           GetGeomFieldIndex()                            */  | 
1496  |  | /************************************************************************/  | 
1497  |  |  | 
1498  |  | /**  | 
1499  |  |  * \fn int OGRFeature::GetGeomFieldIndex( const char * pszName );  | 
1500  |  |  *  | 
1501  |  |  * \brief Fetch the geometry field index given geometry field name.  | 
1502  |  |  *  | 
1503  |  |  * This is a cover for the OGRFeatureDefn::GetGeomFieldIndex() method.  | 
1504  |  |  *  | 
1505  |  |  * This method is the same as the C function OGR_F_GetGeomFieldIndex().  | 
1506  |  |  *  | 
1507  |  |  * @param pszName the name of the geometry field to search for.  | 
1508  |  |  *  | 
1509  |  |  * @return the geometry field index, or -1 if no matching geometry field is  | 
1510  |  |  * found.  | 
1511  |  |  *  | 
1512  |  |  * @since GDAL 1.11  | 
1513  |  |  */  | 
1514  |  |  | 
1515  |  | /************************************************************************/  | 
1516  |  | /*                       OGR_F_GetGeomFieldIndex()                      */  | 
1517  |  | /************************************************************************/  | 
1518  |  |  | 
1519  |  | /**  | 
1520  |  |  * \brief Fetch the geometry field index given geometry field name.  | 
1521  |  |  *  | 
1522  |  |  * This is a cover for the OGRFeatureDefn::GetGeomFieldIndex() method.  | 
1523  |  |  *  | 
1524  |  |  * This function is the same as the C++ method OGRFeature::GetGeomFieldIndex().  | 
1525  |  |  *  | 
1526  |  |  * @param hFeat handle to the feature on which the geometry field is found.  | 
1527  |  |  * @param pszName the name of the geometry field to search for.  | 
1528  |  |  *  | 
1529  |  |  * @return the geometry field index, or -1 if no matching geometry field is  | 
1530  |  |  * found.  | 
1531  |  |  *  | 
1532  |  |  * @since GDAL 1.11  | 
1533  |  |  */  | 
1534  |  |  | 
1535  |  | int OGR_F_GetGeomFieldIndex(OGRFeatureH hFeat, const char *pszName)  | 
1536  |  |  | 
1537  | 0  | { | 
1538  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetGeomFieldIndex", 0);  | 
1539  |  |  | 
1540  | 0  |     return OGRFeature::FromHandle(hFeat)->GetGeomFieldIndex(pszName);  | 
1541  | 0  | }  | 
1542  |  |  | 
1543  |  | /************************************************************************/  | 
1544  |  | /*                             IsFieldSet()                             */  | 
1545  |  | /************************************************************************/  | 
1546  |  |  | 
1547  |  | /**  | 
1548  |  |  * \brief Test if a field has ever been assigned a value or not.  | 
1549  |  |  *  | 
1550  |  |  * This method is the same as the C function OGR_F_IsFieldSet().  | 
1551  |  |  *  | 
1552  |  |  * @param iField the field to test.  | 
1553  |  |  *  | 
1554  |  |  * @return TRUE if the field has been set, otherwise false.  | 
1555  |  |  */  | 
1556  |  |  | 
1557  |  | int OGRFeature::IsFieldSet(int iField) const  | 
1558  |  |  | 
1559  | 0  | { | 
1560  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
1561  | 0  |     if (iSpecialField >= 0)  | 
1562  | 0  |     { | 
1563  |  |         // Special field value accessors.  | 
1564  | 0  |         switch (iSpecialField)  | 
1565  | 0  |         { | 
1566  | 0  |             case SPF_FID:  | 
1567  | 0  |                 return GetFID() != OGRNullFID;  | 
1568  |  |  | 
1569  | 0  |             case SPF_OGR_GEOM_WKT:  | 
1570  | 0  |             case SPF_OGR_GEOMETRY:  | 
1571  | 0  |                 return GetGeomFieldCount() > 0 && papoGeometries[0] != nullptr;  | 
1572  |  |  | 
1573  | 0  |             case SPF_OGR_STYLE:  | 
1574  | 0  |                 return GetStyleString() != nullptr;  | 
1575  |  |  | 
1576  | 0  |             case SPF_OGR_GEOM_AREA:  | 
1577  | 0  |                 if (GetGeomFieldCount() == 0 || papoGeometries[0] == nullptr)  | 
1578  | 0  |                     return FALSE;  | 
1579  |  |  | 
1580  | 0  |                 return OGR_G_Area(OGRGeometry::ToHandle(papoGeometries[0])) !=  | 
1581  | 0  |                        0.0;  | 
1582  |  |  | 
1583  | 0  |             default:  | 
1584  | 0  |                 return FALSE;  | 
1585  | 0  |         }  | 
1586  | 0  |     }  | 
1587  | 0  |     else  | 
1588  | 0  |     { | 
1589  | 0  |         return !OGR_RawField_IsUnset(&pauFields[iField]);  | 
1590  | 0  |     }  | 
1591  | 0  | }  | 
1592  |  |  | 
1593  |  | /************************************************************************/  | 
1594  |  | /*                          OGR_F_IsFieldSet()                          */  | 
1595  |  | /************************************************************************/  | 
1596  |  |  | 
1597  |  | /**  | 
1598  |  |  * \brief Test if a field has ever been assigned a value or not.  | 
1599  |  |  *  | 
1600  |  |  * This function is the same as the C++ method OGRFeature::IsFieldSet().  | 
1601  |  |  *  | 
1602  |  |  * @param hFeat handle to the feature on which the field is.  | 
1603  |  |  * @param iField the field to test.  | 
1604  |  |  *  | 
1605  |  |  * @return TRUE if the field has been set, otherwise false.  | 
1606  |  |  */  | 
1607  |  |  | 
1608  |  | int OGR_F_IsFieldSet(OGRFeatureH hFeat, int iField)  | 
1609  |  |  | 
1610  | 0  | { | 
1611  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_IsFieldSet", 0);  | 
1612  |  |  | 
1613  | 0  |     const OGRFeature *poFeature = OGRFeature::FromHandle(hFeat);  | 
1614  | 0  |     if (iField < 0 || iField >= poFeature->GetFieldCount())  | 
1615  | 0  |     { | 
1616  | 0  |         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);  | 
1617  | 0  |         return FALSE;  | 
1618  | 0  |     }  | 
1619  |  |  | 
1620  | 0  |     return poFeature->IsFieldSet(iField);  | 
1621  | 0  | }  | 
1622  |  |  | 
1623  |  | /************************************************************************/  | 
1624  |  | /*                             UnsetField()                             */  | 
1625  |  | /************************************************************************/  | 
1626  |  |  | 
1627  |  | /**  | 
1628  |  |  * \brief Clear a field, marking it as unset.  | 
1629  |  |  *  | 
1630  |  |  * This method is the same as the C function OGR_F_UnsetField().  | 
1631  |  |  *  | 
1632  |  |  * @param iField the field to unset.  | 
1633  |  |  */  | 
1634  |  |  | 
1635  |  | void OGRFeature::UnsetField(int iField)  | 
1636  |  |  | 
1637  | 0  | { | 
1638  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
1639  |  | 
  | 
1640  | 0  |     if (poFDefn == nullptr || !IsFieldSet(iField))  | 
1641  | 0  |         return;  | 
1642  |  |  | 
1643  | 0  |     if (!IsFieldNull(iField))  | 
1644  | 0  |     { | 
1645  | 0  |         switch (poFDefn->GetType())  | 
1646  | 0  |         { | 
1647  | 0  |             case OFTRealList:  | 
1648  | 0  |             case OFTIntegerList:  | 
1649  | 0  |             case OFTInteger64List:  | 
1650  | 0  |                 CPLFree(pauFields[iField].IntegerList.paList);  | 
1651  | 0  |                 break;  | 
1652  |  |  | 
1653  | 0  |             case OFTStringList:  | 
1654  | 0  |                 CSLDestroy(pauFields[iField].StringList.paList);  | 
1655  | 0  |                 break;  | 
1656  |  |  | 
1657  | 0  |             case OFTString:  | 
1658  | 0  |                 CPLFree(pauFields[iField].String);  | 
1659  | 0  |                 break;  | 
1660  |  |  | 
1661  | 0  |             case OFTBinary:  | 
1662  | 0  |                 CPLFree(pauFields[iField].Binary.paData);  | 
1663  | 0  |                 break;  | 
1664  |  |  | 
1665  | 0  |             default:  | 
1666  | 0  |                 break;  | 
1667  | 0  |         }  | 
1668  | 0  |     }  | 
1669  |  |  | 
1670  | 0  |     OGR_RawField_SetUnset(&pauFields[iField]);  | 
1671  | 0  | }  | 
1672  |  |  | 
1673  |  | /************************************************************************/  | 
1674  |  | /*                          OGR_F_UnsetField()                          */  | 
1675  |  | /************************************************************************/  | 
1676  |  |  | 
1677  |  | /**  | 
1678  |  |  * \brief Clear a field, marking it as unset.  | 
1679  |  |  *  | 
1680  |  |  * This function is the same as the C++ method OGRFeature::UnsetField().  | 
1681  |  |  *  | 
1682  |  |  * @param hFeat handle to the feature on which the field is.  | 
1683  |  |  * @param iField the field to unset.  | 
1684  |  |  */  | 
1685  |  |  | 
1686  |  | void OGR_F_UnsetField(OGRFeatureH hFeat, int iField)  | 
1687  |  |  | 
1688  | 0  | { | 
1689  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_UnsetField");  | 
1690  |  |  | 
1691  | 0  |     OGRFeature::FromHandle(hFeat)->UnsetField(iField);  | 
1692  | 0  | }  | 
1693  |  |  | 
1694  |  | /************************************************************************/  | 
1695  |  | /*                            IsFieldNull()                             */  | 
1696  |  | /************************************************************************/  | 
1697  |  |  | 
1698  |  | /**  | 
1699  |  |  * \brief Test if a field is null.  | 
1700  |  |  *  | 
1701  |  |  * This method is the same as the C function OGR_F_IsFieldNull().  | 
1702  |  |  *  | 
1703  |  |  * @param iField the field to test.  | 
1704  |  |  *  | 
1705  |  |  * @return TRUE if the field is null, otherwise false.  | 
1706  |  |  *  | 
1707  |  |  * @since GDAL 2.2  | 
1708  |  |  */  | 
1709  |  |  | 
1710  |  | bool OGRFeature::IsFieldNull(int iField) const  | 
1711  |  |  | 
1712  | 0  | { | 
1713  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
1714  | 0  |     if (iSpecialField >= 0)  | 
1715  | 0  |     { | 
1716  |  |         // FIXME?  | 
1717  | 0  |         return false;  | 
1718  | 0  |     }  | 
1719  | 0  |     else  | 
1720  | 0  |     { | 
1721  | 0  |         return CPL_TO_BOOL(OGR_RawField_IsNull(&pauFields[iField]));  | 
1722  | 0  |     }  | 
1723  | 0  | }  | 
1724  |  |  | 
1725  |  | /************************************************************************/  | 
1726  |  | /*                          OGR_F_IsFieldNull()                         */  | 
1727  |  | /************************************************************************/  | 
1728  |  |  | 
1729  |  | /**  | 
1730  |  |  * \brief Test if a field is null.  | 
1731  |  |  *  | 
1732  |  |  * This function is the same as the C++ method OGRFeature::IsFieldNull().  | 
1733  |  |  *  | 
1734  |  |  * @param hFeat handle to the feature on which the field is.  | 
1735  |  |  * @param iField the field to test.  | 
1736  |  |  *  | 
1737  |  |  * @return TRUE if the field is null, otherwise false.  | 
1738  |  |  *  | 
1739  |  |  * @since GDAL 2.2  | 
1740  |  |  */  | 
1741  |  |  | 
1742  |  | int OGR_F_IsFieldNull(OGRFeatureH hFeat, int iField)  | 
1743  |  |  | 
1744  | 0  | { | 
1745  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_IsFieldNull", 0);  | 
1746  |  |  | 
1747  | 0  |     const OGRFeature *poFeature = OGRFeature::FromHandle(hFeat);  | 
1748  | 0  |     if (iField < 0 || iField >= poFeature->GetFieldCount())  | 
1749  | 0  |     { | 
1750  | 0  |         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);  | 
1751  | 0  |         return FALSE;  | 
1752  | 0  |     }  | 
1753  |  |  | 
1754  | 0  |     return poFeature->IsFieldNull(iField);  | 
1755  | 0  | }  | 
1756  |  |  | 
1757  |  | /************************************************************************/  | 
1758  |  | /*                       IsFieldSetAndNull()                            */  | 
1759  |  | /************************************************************************/  | 
1760  |  |  | 
1761  |  | /**  | 
1762  |  |  * \brief Test if a field is set and not null.  | 
1763  |  |  *  | 
1764  |  |  * This method is the same as the C function OGR_F_IsFieldSetAndNotNull().  | 
1765  |  |  *  | 
1766  |  |  * @param iField the field to test.  | 
1767  |  |  *  | 
1768  |  |  * @return TRUE if the field is set and not null, otherwise false.  | 
1769  |  |  *  | 
1770  |  |  * @since GDAL 2.2  | 
1771  |  |  */  | 
1772  |  |  | 
1773  |  | bool OGRFeature::IsFieldSetAndNotNull(int iField) const  | 
1774  |  |  | 
1775  | 0  | { | 
1776  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
1777  | 0  |     if (iSpecialField >= 0)  | 
1778  | 0  |     { | 
1779  | 0  |         return CPL_TO_BOOL(IsFieldSet(iField));  | 
1780  | 0  |     }  | 
1781  | 0  |     else  | 
1782  | 0  |     { | 
1783  | 0  |         return IsFieldSetAndNotNullUnsafe(iField);  | 
1784  | 0  |     }  | 
1785  | 0  | }  | 
1786  |  |  | 
1787  |  | /************************************************************************/  | 
1788  |  | /*                      OGR_F_IsFieldSetAndNotNull()                    */  | 
1789  |  | /************************************************************************/  | 
1790  |  |  | 
1791  |  | /**  | 
1792  |  |  * \brief Test if a field is set and not null.  | 
1793  |  |  *  | 
1794  |  |  * This function is the same as the C++ method  | 
1795  |  |  * OGRFeature::IsFieldSetAndNotNull().  | 
1796  |  |  *  | 
1797  |  |  * @param hFeat handle to the feature on which the field is.  | 
1798  |  |  * @param iField the field to test.  | 
1799  |  |  *  | 
1800  |  |  * @return TRUE if the field is set and not null, otherwise false.  | 
1801  |  |  *  | 
1802  |  |  * @since GDAL 2.2  | 
1803  |  |  */  | 
1804  |  |  | 
1805  |  | int OGR_F_IsFieldSetAndNotNull(OGRFeatureH hFeat, int iField)  | 
1806  |  |  | 
1807  | 0  | { | 
1808  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_IsFieldSetAndNotNull", 0);  | 
1809  |  |  | 
1810  | 0  |     OGRFeature *poFeature = OGRFeature::FromHandle(hFeat);  | 
1811  |  | 
  | 
1812  | 0  |     if (iField < 0 || iField >= poFeature->GetFieldCount())  | 
1813  | 0  |     { | 
1814  | 0  |         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);  | 
1815  | 0  |         return FALSE;  | 
1816  | 0  |     }  | 
1817  |  |  | 
1818  | 0  |     return poFeature->IsFieldSetAndNotNull(iField);  | 
1819  | 0  | }  | 
1820  |  |  | 
1821  |  | /************************************************************************/  | 
1822  |  | /*                             SetFieldNull()                           */  | 
1823  |  | /************************************************************************/  | 
1824  |  |  | 
1825  |  | /**  | 
1826  |  |  * \brief Clear a field, marking it as null.  | 
1827  |  |  *  | 
1828  |  |  * This method is the same as the C function OGR_F_SetFieldNull().  | 
1829  |  |  *  | 
1830  |  |  * @param iField the field to set to null.  | 
1831  |  |  *  | 
1832  |  |  * @since GDAL 2.2  | 
1833  |  |  */  | 
1834  |  |  | 
1835  |  | void OGRFeature::SetFieldNull(int iField)  | 
1836  |  |  | 
1837  | 0  | { | 
1838  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
1839  |  | 
  | 
1840  | 0  |     if (poFDefn == nullptr || IsFieldNull(iField))  | 
1841  | 0  |         return;  | 
1842  |  |  | 
1843  | 0  |     if (IsFieldSet(iField))  | 
1844  | 0  |     { | 
1845  | 0  |         switch (poFDefn->GetType())  | 
1846  | 0  |         { | 
1847  | 0  |             case OFTRealList:  | 
1848  | 0  |             case OFTIntegerList:  | 
1849  | 0  |             case OFTInteger64List:  | 
1850  | 0  |                 CPLFree(pauFields[iField].IntegerList.paList);  | 
1851  | 0  |                 break;  | 
1852  |  |  | 
1853  | 0  |             case OFTStringList:  | 
1854  | 0  |                 CSLDestroy(pauFields[iField].StringList.paList);  | 
1855  | 0  |                 break;  | 
1856  |  |  | 
1857  | 0  |             case OFTString:  | 
1858  | 0  |                 CPLFree(pauFields[iField].String);  | 
1859  | 0  |                 break;  | 
1860  |  |  | 
1861  | 0  |             case OFTBinary:  | 
1862  | 0  |                 CPLFree(pauFields[iField].Binary.paData);  | 
1863  | 0  |                 break;  | 
1864  |  |  | 
1865  | 0  |             default:  | 
1866  | 0  |                 break;  | 
1867  | 0  |         }  | 
1868  | 0  |     }  | 
1869  |  |  | 
1870  | 0  |     OGR_RawField_SetNull(&pauFields[iField]);  | 
1871  | 0  | }  | 
1872  |  |  | 
1873  |  | /************************************************************************/  | 
1874  |  | /*                          OGR_F_SetFieldNull()                        */  | 
1875  |  | /************************************************************************/  | 
1876  |  |  | 
1877  |  | /**  | 
1878  |  |  * \brief Clear a field, marking it as null.  | 
1879  |  |  *  | 
1880  |  |  * This function is the same as the C++ method OGRFeature::SetFieldNull().  | 
1881  |  |  *  | 
1882  |  |  * @param hFeat handle to the feature on which the field is.  | 
1883  |  |  * @param iField the field to set to null.  | 
1884  |  |  *  | 
1885  |  |  * @since GDAL 2.2  | 
1886  |  |  */  | 
1887  |  |  | 
1888  |  | void OGR_F_SetFieldNull(OGRFeatureH hFeat, int iField)  | 
1889  |  |  | 
1890  | 0  | { | 
1891  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldNull");  | 
1892  |  |  | 
1893  | 0  |     OGRFeature::FromHandle(hFeat)->SetFieldNull(iField);  | 
1894  | 0  | }  | 
1895  |  |  | 
1896  |  | /************************************************************************/  | 
1897  |  | /*                           operator[]                                */  | 
1898  |  | /************************************************************************/  | 
1899  |  |  | 
1900  |  | /**  | 
1901  |  |  * \brief Return a field value.  | 
1902  |  |  *  | 
1903  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1. This is not  | 
1904  |  |  *               checked by the method !  | 
1905  |  |  *  | 
1906  |  |  * @return the field value.  | 
1907  |  |  * @since GDAL 2.3  | 
1908  |  |  */  | 
1909  |  | const OGRFeature::FieldValue OGRFeature::operator[](int iField) const  | 
1910  | 0  | { | 
1911  | 0  |     return {this, iField}; | 
1912  | 0  | }  | 
1913  |  |  | 
1914  |  | /**  | 
1915  |  |  * \brief Return a field value.  | 
1916  |  |  *  | 
1917  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1. This is not  | 
1918  |  |  *               checked by the method !  | 
1919  |  |  *  | 
1920  |  |  * @return the field value.  | 
1921  |  |  * @since GDAL 2.3  | 
1922  |  |  */  | 
1923  |  | OGRFeature::FieldValue OGRFeature::operator[](int iField)  | 
1924  | 0  | { | 
1925  | 0  |     return {this, iField}; | 
1926  | 0  | }  | 
1927  |  |  | 
1928  |  | /**  | 
1929  |  |  * \brief Return a field value.  | 
1930  |  |  *  | 
1931  |  |  * @param pszFieldName field name  | 
1932  |  |  *  | 
1933  |  |  * @return the field value, or throw a FieldNotFoundException if not found.  | 
1934  |  |  * @since GDAL 2.3  | 
1935  |  |  */  | 
1936  |  | const OGRFeature::FieldValue  | 
1937  |  | OGRFeature::operator[](const char *pszFieldName) const  | 
1938  | 0  | { | 
1939  | 0  |     int iField = GetFieldIndex(pszFieldName);  | 
1940  | 0  |     if (iField < 0)  | 
1941  | 0  |         throw FieldNotFoundException();  | 
1942  | 0  |     return {this, iField}; | 
1943  | 0  | }  | 
1944  |  |  | 
1945  |  | /**  | 
1946  |  |  * \brief Return a field value.  | 
1947  |  |  *  | 
1948  |  |  * @param pszFieldName field name  | 
1949  |  |  *  | 
1950  |  |  * @return the field value, or throw a FieldNotFoundException if not found.  | 
1951  |  |  * @since GDAL 2.3  | 
1952  |  |  */  | 
1953  |  | OGRFeature::FieldValue OGRFeature::operator[](const char *pszFieldName)  | 
1954  | 0  | { | 
1955  | 0  |     int iField = GetFieldIndex(pszFieldName);  | 
1956  | 0  |     if (iField < 0)  | 
1957  | 0  |         throw FieldNotFoundException();  | 
1958  | 0  |     return {this, iField}; | 
1959  | 0  | }  | 
1960  |  |  | 
1961  |  | /************************************************************************/  | 
1962  |  | /*                           GetRawFieldRef()                           */  | 
1963  |  | /************************************************************************/  | 
1964  |  |  | 
1965  |  | /**  | 
1966  |  |  * \fn OGRField *OGRFeature::GetRawFieldRef( int iField );  | 
1967  |  |  *  | 
1968  |  |  * \brief Fetch a pointer to the internal field value given the index.  | 
1969  |  |  *  | 
1970  |  |  * This method is the same as the C function OGR_F_GetRawFieldRef().  | 
1971  |  |  *  | 
1972  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
1973  |  |  *  | 
1974  |  |  * @return the returned pointer is to an internal data structure, and should  | 
1975  |  |  * not be freed, or modified.  | 
1976  |  |  */  | 
1977  |  |  | 
1978  |  | /**  | 
1979  |  |  * \fn const OGRField *OGRFeature::GetRawFieldRef( int iField ) const;  | 
1980  |  |  *  | 
1981  |  |  * \brief Fetch a pointer to the internal field value given the index.  | 
1982  |  |  *  | 
1983  |  |  * This method is the same as the C function OGR_F_GetRawFieldRef().  | 
1984  |  |  *  | 
1985  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
1986  |  |  *  | 
1987  |  |  * @return the returned pointer is to an internal data structure, and should  | 
1988  |  |  * not be freed, or modified.  | 
1989  |  |  * @since GDAL 2.3  | 
1990  |  |  */  | 
1991  |  |  | 
1992  |  | /************************************************************************/  | 
1993  |  | /*                        OGR_F_GetRawFieldRef()                        */  | 
1994  |  | /************************************************************************/  | 
1995  |  |  | 
1996  |  | /**  | 
1997  |  |  * \brief Fetch a handle to the internal field value given the index.  | 
1998  |  |  *  | 
1999  |  |  * This function is the same as the C++ method OGRFeature::GetRawFieldRef().  | 
2000  |  |  *  | 
2001  |  |  * @param hFeat handle to the feature on which field is found.  | 
2002  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2003  |  |  *  | 
2004  |  |  * @return the returned handle is to an internal data structure, and should  | 
2005  |  |  * not be freed, or modified.  | 
2006  |  |  */  | 
2007  |  |  | 
2008  |  | OGRField *OGR_F_GetRawFieldRef(OGRFeatureH hFeat, int iField)  | 
2009  |  |  | 
2010  | 0  | { | 
2011  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetRawFieldRef", nullptr);  | 
2012  |  |  | 
2013  | 0  |     return OGRFeature::FromHandle(hFeat)->GetRawFieldRef(iField);  | 
2014  | 0  | }  | 
2015  |  |  | 
2016  |  | /************************************************************************/  | 
2017  |  | /*                         GetFieldAsInteger()                          */  | 
2018  |  | /************************************************************************/  | 
2019  |  |  | 
2020  |  | /**  | 
2021  |  |  * \fn OGRFeature::GetFieldAsInteger( const char* pszFName ) const  | 
2022  |  |  * \brief Fetch field value as integer.  | 
2023  |  |  *  | 
2024  |  |  * OFTString features will be translated using atoi().  OFTReal fields  | 
2025  |  |  * will be cast to integer. OFTInteger64 are demoted to 32 bit, with  | 
2026  |  |  * clamping if out-of-range. Other field types, or errors will result in  | 
2027  |  |  * a return value of zero.  | 
2028  |  |  *  | 
2029  |  |  * @param pszFName the name of the field to fetch.  | 
2030  |  |  *  | 
2031  |  |  * @return the field value.  | 
2032  |  |  */  | 
2033  |  |  | 
2034  |  | /**  | 
2035  |  |  * \brief Fetch field value as integer.  | 
2036  |  |  *  | 
2037  |  |  * OFTString features will be translated using atoi().  OFTReal fields  | 
2038  |  |  * will be cast to integer. OFTInteger64 are demoted to 32 bit, with  | 
2039  |  |  * clamping if out-of-range. Other field types, or errors will result in  | 
2040  |  |  * a return value of zero.  | 
2041  |  |  *  | 
2042  |  |  * This method is the same as the C function OGR_F_GetFieldAsInteger().  | 
2043  |  |  *  | 
2044  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2045  |  |  *  | 
2046  |  |  * @return the field value.  | 
2047  |  |  */  | 
2048  |  |  | 
2049  |  | int OGRFeature::GetFieldAsInteger(int iField) const  | 
2050  |  |  | 
2051  | 0  | { | 
2052  | 0  |     int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
2053  | 0  |     if (iSpecialField >= 0)  | 
2054  | 0  |     { | 
2055  |  |         // Special field value accessors.  | 
2056  | 0  |         switch (iSpecialField)  | 
2057  | 0  |         { | 
2058  | 0  |             case SPF_FID:  | 
2059  | 0  |             { | 
2060  | 0  |                 const int nVal = nFID > INT_MAX   ? INT_MAX  | 
2061  | 0  |                                  : nFID < INT_MIN ? INT_MIN  | 
2062  | 0  |                                                   : static_cast<int>(nFID);  | 
2063  |  | 
  | 
2064  | 0  |                 if (nVal != nFID)  | 
2065  | 0  |                 { | 
2066  | 0  |                     CPLError(CE_Warning, CPLE_AppDefined,  | 
2067  | 0  |                              "Field %s.FID: Integer overflow occurred when "  | 
2068  | 0  |                              "trying to return 64 bit integer %" PRId64  | 
2069  | 0  |                              ". Use GetFieldAsInteger64() instead",  | 
2070  | 0  |                              poDefn->GetName(), static_cast<int64_t>(nVal));  | 
2071  | 0  |                 }  | 
2072  | 0  |                 return nVal;  | 
2073  | 0  |             }  | 
2074  |  |  | 
2075  | 0  |             case SPF_OGR_GEOM_AREA:  | 
2076  | 0  |                 if (GetGeomFieldCount() == 0 || papoGeometries[0] == nullptr)  | 
2077  | 0  |                     return 0;  | 
2078  | 0  |                 return static_cast<int>(  | 
2079  | 0  |                     OGR_G_Area(OGRGeometry::ToHandle(papoGeometries[0])));  | 
2080  |  |  | 
2081  | 0  |             default:  | 
2082  | 0  |                 return 0;  | 
2083  | 0  |         }  | 
2084  | 0  |     }  | 
2085  |  |  | 
2086  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
2087  |  | 
  | 
2088  | 0  |     if (poFDefn == nullptr)  | 
2089  | 0  |         return 0;  | 
2090  |  |  | 
2091  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
2092  | 0  |         return 0;  | 
2093  |  |  | 
2094  | 0  |     const OGRFieldType eType = poFDefn->GetType();  | 
2095  | 0  |     if (eType == OFTInteger)  | 
2096  | 0  |     { | 
2097  | 0  |         return pauFields[iField].Integer;  | 
2098  | 0  |     }  | 
2099  | 0  |     else if (eType == OFTInteger64)  | 
2100  | 0  |     { | 
2101  | 0  |         const GIntBig nVal64 = pauFields[iField].Integer64;  | 
2102  | 0  |         const int nVal = nVal64 > INT_MAX   ? INT_MAX  | 
2103  | 0  |                          : nVal64 < INT_MIN ? INT_MIN  | 
2104  | 0  |                                             : static_cast<int>(nVal64);  | 
2105  |  | 
  | 
2106  | 0  |         if (nVal != nVal64)  | 
2107  | 0  |         { | 
2108  | 0  |             CPLError(CE_Warning, CPLE_AppDefined,  | 
2109  | 0  |                      "Field %s.%s: Integer overflow occurred when trying to "  | 
2110  | 0  |                      "return 64 bit integer %" PRId64  | 
2111  | 0  |                      ". Use GetFieldAsInteger64() instead",  | 
2112  | 0  |                      poDefn->GetName(), poFDefn->GetNameRef(),  | 
2113  | 0  |                      static_cast<int64_t>(nVal64));  | 
2114  | 0  |         }  | 
2115  | 0  |         return nVal;  | 
2116  | 0  |     }  | 
2117  | 0  |     else if (eType == OFTReal)  | 
2118  | 0  |     { | 
2119  | 0  |         return static_cast<int>(pauFields[iField].Real);  | 
2120  | 0  |     }  | 
2121  | 0  |     else if (eType == OFTString)  | 
2122  | 0  |     { | 
2123  | 0  |         if (pauFields[iField].String == nullptr)  | 
2124  | 0  |             return 0;  | 
2125  | 0  |         else  | 
2126  | 0  |             return atoi(pauFields[iField].String);  | 
2127  | 0  |     }  | 
2128  |  |  | 
2129  | 0  |     return 0;  | 
2130  | 0  | }  | 
2131  |  |  | 
2132  |  | /************************************************************************/  | 
2133  |  | /*                      OGR_F_GetFieldAsInteger()                       */  | 
2134  |  | /************************************************************************/  | 
2135  |  |  | 
2136  |  | /**  | 
2137  |  |  * \brief Fetch field value as integer.  | 
2138  |  |  *  | 
2139  |  |  * OFTString features will be translated using atoi().  OFTReal fields  | 
2140  |  |  * will be cast to integer.   Other field types, or errors will result in  | 
2141  |  |  * a return value of zero.  | 
2142  |  |  *  | 
2143  |  |  * This function is the same as the C++ method OGRFeature::GetFieldAsInteger().  | 
2144  |  |  *  | 
2145  |  |  * @param hFeat handle to the feature that owned the field.  | 
2146  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2147  |  |  *  | 
2148  |  |  * @return the field value.  | 
2149  |  |  */  | 
2150  |  |  | 
2151  |  | int OGR_F_GetFieldAsInteger(OGRFeatureH hFeat, int iField)  | 
2152  |  |  | 
2153  | 0  | { | 
2154  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsInteger", 0);  | 
2155  |  |  | 
2156  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsInteger(iField);  | 
2157  | 0  | }  | 
2158  |  |  | 
2159  |  | /************************************************************************/  | 
2160  |  | /*                        GetFieldAsInteger64()                         */  | 
2161  |  | /************************************************************************/  | 
2162  |  |  | 
2163  |  | /**  | 
2164  |  |  * \fn OGRFeature::GetFieldAsInteger64( const char* pszFName ) const  | 
2165  |  |  * \brief Fetch field value as integer 64 bit.  | 
2166  |  |  *  | 
2167  |  |  * OFTInteger are promoted to 64 bit.  | 
2168  |  |  * OFTString features will be translated using CPLAtoGIntBig().  OFTReal fields  | 
2169  |  |  * will be cast to integer.   Other field types, or errors will result in  | 
2170  |  |  * a return value of zero.  | 
2171  |  |  *  | 
2172  |  |  * @param pszFName the name of the field to fetch.  | 
2173  |  |  *  | 
2174  |  |  * @return the field value.  | 
2175  |  |  */  | 
2176  |  |  | 
2177  |  | /**  | 
2178  |  |  * \brief Fetch field value as integer 64 bit.  | 
2179  |  |  *  | 
2180  |  |  * OFTInteger are promoted to 64 bit.  | 
2181  |  |  * OFTString features will be translated using CPLAtoGIntBig().  OFTReal fields  | 
2182  |  |  * will be cast to integer.   Other field types, or errors will result in  | 
2183  |  |  * a return value of zero.  | 
2184  |  |  *  | 
2185  |  |  * This method is the same as the C function OGR_F_GetFieldAsInteger64().  | 
2186  |  |  *  | 
2187  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2188  |  |  *  | 
2189  |  |  * @return the field value.  | 
2190  |  |  * @since GDAL 2.0  | 
2191  |  |  */  | 
2192  |  |  | 
2193  |  | GIntBig OGRFeature::GetFieldAsInteger64(int iField) const  | 
2194  |  |  | 
2195  | 0  | { | 
2196  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
2197  | 0  |     if (iSpecialField >= 0)  | 
2198  | 0  |     { | 
2199  |  |         // Special field value accessors.  | 
2200  | 0  |         switch (iSpecialField)  | 
2201  | 0  |         { | 
2202  | 0  |             case SPF_FID:  | 
2203  | 0  |                 return nFID;  | 
2204  |  |  | 
2205  | 0  |             case SPF_OGR_GEOM_AREA:  | 
2206  | 0  |                 if (GetGeomFieldCount() == 0 || papoGeometries[0] == nullptr)  | 
2207  | 0  |                     return 0;  | 
2208  | 0  |                 return static_cast<int>(  | 
2209  | 0  |                     OGR_G_Area(OGRGeometry::ToHandle(papoGeometries[0])));  | 
2210  |  |  | 
2211  | 0  |             default:  | 
2212  | 0  |                 return 0;  | 
2213  | 0  |         }  | 
2214  | 0  |     }  | 
2215  |  |  | 
2216  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
2217  |  | 
  | 
2218  | 0  |     if (poFDefn == nullptr)  | 
2219  | 0  |         return 0;  | 
2220  |  |  | 
2221  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
2222  | 0  |         return 0;  | 
2223  |  |  | 
2224  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
2225  | 0  |     if (eType == OFTInteger)  | 
2226  | 0  |     { | 
2227  | 0  |         return static_cast<GIntBig>(pauFields[iField].Integer);  | 
2228  | 0  |     }  | 
2229  | 0  |     else if (eType == OFTInteger64)  | 
2230  | 0  |     { | 
2231  | 0  |         return pauFields[iField].Integer64;  | 
2232  | 0  |     }  | 
2233  | 0  |     else if (eType == OFTReal)  | 
2234  | 0  |     { | 
2235  | 0  |         return static_cast<GIntBig>(pauFields[iField].Real);  | 
2236  | 0  |     }  | 
2237  | 0  |     else if (eType == OFTString)  | 
2238  | 0  |     { | 
2239  | 0  |         if (pauFields[iField].String == nullptr)  | 
2240  | 0  |             return 0;  | 
2241  | 0  |         else  | 
2242  | 0  |         { | 
2243  | 0  |             return CPLAtoGIntBigEx(pauFields[iField].String, TRUE, nullptr);  | 
2244  | 0  |         }  | 
2245  | 0  |     }  | 
2246  |  |  | 
2247  | 0  |     return 0;  | 
2248  | 0  | }  | 
2249  |  |  | 
2250  |  | /************************************************************************/  | 
2251  |  | /*                      OGR_F_GetFieldAsInteger64()                     */  | 
2252  |  | /************************************************************************/  | 
2253  |  |  | 
2254  |  | /**  | 
2255  |  |  * \brief Fetch field value as integer 64 bit.  | 
2256  |  |  *  | 
2257  |  |  * OFTInteger are promoted to 64 bit.  | 
2258  |  |  * OFTString features will be translated using CPLAtoGIntBig().  OFTReal fields  | 
2259  |  |  * will be cast to integer.   Other field types, or errors will result in  | 
2260  |  |  * a return value of zero.  | 
2261  |  |  *  | 
2262  |  |  * This function is the same as the C++ method  | 
2263  |  |  * OGRFeature::GetFieldAsInteger64().  | 
2264  |  |  *  | 
2265  |  |  * @param hFeat handle to the feature that owned the field.  | 
2266  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2267  |  |  *  | 
2268  |  |  * @return the field value.  | 
2269  |  |  * @since GDAL 2.0  | 
2270  |  |  */  | 
2271  |  |  | 
2272  |  | GIntBig OGR_F_GetFieldAsInteger64(OGRFeatureH hFeat, int iField)  | 
2273  |  |  | 
2274  | 0  | { | 
2275  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsInteger64", 0);  | 
2276  |  |  | 
2277  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsInteger64(iField);  | 
2278  | 0  | }  | 
2279  |  |  | 
2280  |  | /************************************************************************/  | 
2281  |  | /*                          GetFieldAsDouble()                          */  | 
2282  |  | /************************************************************************/  | 
2283  |  |  | 
2284  |  | /**  | 
2285  |  |  * \fn OGRFeature::GetFieldAsDouble( const char* pszFName ) const  | 
2286  |  |  * \brief Fetch field value as a double.  | 
2287  |  |  *  | 
2288  |  |  * OFTString features will be translated using CPLAtof().  OFTInteger and  | 
2289  |  |  * OFTInteger64 fields will be cast to double.  Other field types, or errors  | 
2290  |  |  * will result in a return value of zero.  | 
2291  |  |  *  | 
2292  |  |  * @param pszFName the name of the field to fetch.  | 
2293  |  |  *  | 
2294  |  |  * @return the field value.  | 
2295  |  |  */  | 
2296  |  |  | 
2297  |  | /**  | 
2298  |  |  * \brief Fetch field value as a double.  | 
2299  |  |  *  | 
2300  |  |  * OFTString features will be translated using CPLAtof().  OFTInteger and  | 
2301  |  |  * OFTInteger64 fields will be cast to double.  Other field types, or errors  | 
2302  |  |  * will result in a return value of zero.  | 
2303  |  |  *  | 
2304  |  |  * This method is the same as the C function OGR_F_GetFieldAsDouble().  | 
2305  |  |  *  | 
2306  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2307  |  |  *  | 
2308  |  |  * @return the field value.  | 
2309  |  |  */  | 
2310  |  |  | 
2311  |  | double OGRFeature::GetFieldAsDouble(int iField) const  | 
2312  |  |  | 
2313  | 0  | { | 
2314  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
2315  | 0  |     if (iSpecialField >= 0)  | 
2316  | 0  |     { | 
2317  |  |         // Special field value accessors.  | 
2318  | 0  |         switch (iSpecialField)  | 
2319  | 0  |         { | 
2320  | 0  |             case SPF_FID:  | 
2321  | 0  |                 return static_cast<double>(GetFID());  | 
2322  |  |  | 
2323  | 0  |             case SPF_OGR_GEOM_AREA:  | 
2324  | 0  |                 if (GetGeomFieldCount() == 0 || papoGeometries[0] == nullptr)  | 
2325  | 0  |                     return 0.0;  | 
2326  | 0  |                 return OGR_G_Area(OGRGeometry::ToHandle(papoGeometries[0]));  | 
2327  |  |  | 
2328  | 0  |             default:  | 
2329  | 0  |                 return 0.0;  | 
2330  | 0  |         }  | 
2331  | 0  |     }  | 
2332  |  |  | 
2333  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
2334  |  | 
  | 
2335  | 0  |     if (poFDefn == nullptr)  | 
2336  | 0  |         return 0.0;  | 
2337  |  |  | 
2338  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
2339  | 0  |         return 0.0;  | 
2340  |  |  | 
2341  | 0  |     const OGRFieldType eType = poFDefn->GetType();  | 
2342  | 0  |     if (eType == OFTReal)  | 
2343  | 0  |     { | 
2344  | 0  |         return pauFields[iField].Real;  | 
2345  | 0  |     }  | 
2346  | 0  |     else if (eType == OFTInteger)  | 
2347  | 0  |     { | 
2348  | 0  |         return pauFields[iField].Integer;  | 
2349  | 0  |     }  | 
2350  | 0  |     else if (eType == OFTInteger64)  | 
2351  | 0  |     { | 
2352  | 0  |         return static_cast<double>(pauFields[iField].Integer64);  | 
2353  | 0  |     }  | 
2354  | 0  |     else if (eType == OFTString)  | 
2355  | 0  |     { | 
2356  | 0  |         if (pauFields[iField].String == nullptr)  | 
2357  | 0  |             return 0;  | 
2358  | 0  |         else  | 
2359  | 0  |             return CPLAtof(pauFields[iField].String);  | 
2360  | 0  |     }  | 
2361  |  |  | 
2362  | 0  |     return 0.0;  | 
2363  | 0  | }  | 
2364  |  |  | 
2365  |  | /************************************************************************/  | 
2366  |  | /*                       OGR_F_GetFieldAsDouble()                       */  | 
2367  |  | /************************************************************************/  | 
2368  |  |  | 
2369  |  | /**  | 
2370  |  |  * \brief Fetch field value as a double.  | 
2371  |  |  *  | 
2372  |  |  * OFTString features will be translated using CPLAtof().  OFTInteger fields  | 
2373  |  |  * will be cast to double.   Other field types, or errors will result in  | 
2374  |  |  * a return value of zero.  | 
2375  |  |  *  | 
2376  |  |  * This function is the same as the C++ method OGRFeature::GetFieldAsDouble().  | 
2377  |  |  *  | 
2378  |  |  * @param hFeat handle to the feature that owned the field.  | 
2379  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2380  |  |  *  | 
2381  |  |  * @return the field value.  | 
2382  |  |  */  | 
2383  |  |  | 
2384  |  | double OGR_F_GetFieldAsDouble(OGRFeatureH hFeat, int iField)  | 
2385  |  |  | 
2386  | 0  | { | 
2387  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsDouble", 0);  | 
2388  |  |  | 
2389  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsDouble(iField);  | 
2390  | 0  | }  | 
2391  |  |  | 
2392  |  | /************************************************************************/  | 
2393  |  | /*                      OGRFeatureFormatDateTimeBuffer()                */  | 
2394  |  | /************************************************************************/  | 
2395  |  |  | 
2396  |  | static void OGRFeatureFormatDateTimeBuffer(char *szTempBuffer, size_t nMaxSize,  | 
2397  |  |                                            int nYear, int nMonth, int nDay,  | 
2398  |  |                                            int nHour, int nMinute,  | 
2399  |  |                                            float fSecond, int nTZFlag)  | 
2400  | 0  | { | 
2401  | 0  |     const int ms = OGR_GET_MS(fSecond);  | 
2402  | 0  |     if (ms != 0)  | 
2403  | 0  |         CPLsnprintf(szTempBuffer, nMaxSize, "%04d/%02d/%02d %02d:%02d:%06.3f",  | 
2404  | 0  |                     nYear, nMonth, nDay, nHour, nMinute, fSecond);  | 
2405  | 0  |     else  // Default format.  | 
2406  | 0  |     { | 
2407  | 0  |         if (std::isnan(fSecond) || fSecond < 0.0 || fSecond > 62.0)  | 
2408  | 0  |         { | 
2409  | 0  |             fSecond = 0.0;  | 
2410  | 0  |             CPLError(CE_Failure, CPLE_NotSupported,  | 
2411  | 0  |                      "OGRFeatureFormatDateTimeBuffer: fSecond is invalid.  "  | 
2412  | 0  |                      "Forcing '%f' to 0.0.",  | 
2413  | 0  |                      fSecond);  | 
2414  | 0  |         }  | 
2415  | 0  |         snprintf(szTempBuffer, nMaxSize, "%04d/%02d/%02d %02d:%02d:%02d", nYear,  | 
2416  | 0  |                  nMonth, nDay, nHour, nMinute, static_cast<int>(fSecond));  | 
2417  | 0  |     }  | 
2418  |  | 
  | 
2419  | 0  |     if (nTZFlag > 1)  | 
2420  | 0  |     { | 
2421  | 0  |         char chSign;  | 
2422  | 0  |         const int nOffset = (nTZFlag - 100) * 15;  | 
2423  | 0  |         int nHours = static_cast<int>(nOffset / 60);  // Round towards zero.  | 
2424  | 0  |         const int nMinutes = std::abs(nOffset - nHours * 60);  | 
2425  |  | 
  | 
2426  | 0  |         if (nOffset < 0)  | 
2427  | 0  |         { | 
2428  | 0  |             chSign = '-';  | 
2429  | 0  |             nHours = std::abs(nHours);  | 
2430  | 0  |         }  | 
2431  | 0  |         else  | 
2432  | 0  |         { | 
2433  | 0  |             chSign = '+';  | 
2434  | 0  |         }  | 
2435  |  | 
  | 
2436  | 0  |         if (nMinutes == 0)  | 
2437  | 0  |             snprintf(szTempBuffer + strlen(szTempBuffer),  | 
2438  | 0  |                      nMaxSize - strlen(szTempBuffer), "%c%02d", chSign, nHours);  | 
2439  | 0  |         else  | 
2440  | 0  |             snprintf(szTempBuffer + strlen(szTempBuffer),  | 
2441  | 0  |                      nMaxSize - strlen(szTempBuffer), "%c%02d%02d", chSign,  | 
2442  | 0  |                      nHours, nMinutes);  | 
2443  | 0  |     }  | 
2444  | 0  | }  | 
2445  |  |  | 
2446  |  | /************************************************************************/  | 
2447  |  | /*                          GetFieldAsString()                          */  | 
2448  |  | /************************************************************************/  | 
2449  |  |  | 
2450  |  | /**  | 
2451  |  |  * \fn OGRFeature::GetFieldAsString( const char* pszFName ) const  | 
2452  |  |  * \brief Fetch field value as a string.  | 
2453  |  |  *  | 
2454  |  |  * OFTReal, OFTInteger, OFTInteger64 fields will be translated to string using  | 
2455  |  |  * sprintf(), but not necessarily using the established formatting rules.  | 
2456  |  |  * OFTDateTime fields are formatted with "YYYY/MM/DD HH:MM:SS[.sss]+ZZ"  | 
2457  |  |  * (note this is not a ISO-8601 compliant string. Use  | 
2458  |  |  * GetFieldAsISO8601DateTime())  | 
2459  |  |  * OFTDate fields are formatted as "YYYY/MM/DD"  | 
2460  |  |  * OFTTime fields are formatted as "HH:MM:SS[.sss]"  | 
2461  |  |  * OFTRealList, OFTIntegerList, OFTInteger64List, OFTStringList fields are  | 
2462  |  |  * formatted as "(number_of_values:val1,val2,...,valN)"  | 
2463  |  |  * OFTBinary fields are formatted as an hexadecimal representation.  | 
2464  |  |  * Other field types, or errors will result in a return of an empty string.  | 
2465  |  |  *  | 
2466  |  |  * @param pszFName the name of the field to fetch.  | 
2467  |  |  *  | 
2468  |  |  * @return the field value.  This string is internal, and should not be  | 
2469  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
2470  |  |  */  | 
2471  |  |  | 
2472  |  | /**  | 
2473  |  |  * \brief Fetch field value as a string.  | 
2474  |  |  *  | 
2475  |  |  * OFTReal, OFTInteger, OFTInteger64 fields will be translated to string using  | 
2476  |  |  * sprintf(), but not necessarily using the established formatting rules.  | 
2477  |  |  * OFTDateTime fields are formatted with "YYYY/MM/DD HH:MM:SS[.sss]+ZZ"  | 
2478  |  |  * (note this is not a ISO-8601 compliant string. Use  | 
2479  |  |  * GetFieldAsISO8601DateTime())  | 
2480  |  |  * OFTDate fields are formatted as "YYYY/MM/DD"  | 
2481  |  |  * OFTTime fields are formatted as "HH:MM:SS[.sss]"  | 
2482  |  |  * OFTRealList, OFTIntegerList, OFTInteger64List, OFTStringList fields are  | 
2483  |  |  * formatted as "(number_of_values:val1,val2,...,valN)"  | 
2484  |  |  * OFTBinary fields are formatted as an hexadecimal representation.  | 
2485  |  |  * Other field types, or errors will result in a return of an empty string.  | 
2486  |  |  *  | 
2487  |  |  * This method is the same as the C function OGR_F_GetFieldAsString().  | 
2488  |  |  *  | 
2489  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2490  |  |  *  | 
2491  |  |  * @return the field value.  This string is internal, and should not be  | 
2492  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
2493  |  |  */  | 
2494  |  |  | 
2495  |  | const char *OGRFeature::GetFieldAsString(int iField) const  | 
2496  |  |  | 
2497  | 0  | { | 
2498  | 0  |     CPLFree(m_pszTmpFieldValue);  | 
2499  | 0  |     m_pszTmpFieldValue = nullptr;  | 
2500  |  | 
  | 
2501  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
2502  | 0  |     if (iSpecialField >= 0)  | 
2503  | 0  |     { | 
2504  |  |         // Special field value accessors.  | 
2505  | 0  |         switch (iSpecialField)  | 
2506  | 0  |         { | 
2507  | 0  |             case SPF_FID:  | 
2508  | 0  |             { | 
2509  | 0  |                 constexpr size_t MAX_SIZE = 20 + 1;  | 
2510  | 0  |                 m_pszTmpFieldValue = static_cast<char *>(CPLMalloc(MAX_SIZE));  | 
2511  | 0  |                 CPLsnprintf(m_pszTmpFieldValue, MAX_SIZE, CPL_FRMT_GIB,  | 
2512  | 0  |                             GetFID());  | 
2513  | 0  |                 return m_pszTmpFieldValue;  | 
2514  | 0  |             }  | 
2515  |  |  | 
2516  | 0  |             case SPF_OGR_GEOMETRY:  | 
2517  | 0  |                 if (GetGeomFieldCount() > 0 && papoGeometries[0] != nullptr)  | 
2518  | 0  |                     return papoGeometries[0]->getGeometryName();  | 
2519  | 0  |                 else  | 
2520  | 0  |                     return "";  | 
2521  |  |  | 
2522  | 0  |             case SPF_OGR_STYLE:  | 
2523  | 0  |                 if (GetStyleString() == nullptr)  | 
2524  | 0  |                     return "";  | 
2525  | 0  |                 else  | 
2526  | 0  |                     return GetStyleString();  | 
2527  |  |  | 
2528  | 0  |             case SPF_OGR_GEOM_WKT:  | 
2529  | 0  |             { | 
2530  | 0  |                 if (GetGeomFieldCount() == 0 || papoGeometries[0] == nullptr)  | 
2531  | 0  |                     return "";  | 
2532  |  |  | 
2533  | 0  |                 if (papoGeometries[0]->exportToWkt(&m_pszTmpFieldValue) ==  | 
2534  | 0  |                     OGRERR_NONE)  | 
2535  | 0  |                     return m_pszTmpFieldValue;  | 
2536  | 0  |                 else  | 
2537  | 0  |                     return "";  | 
2538  | 0  |             }  | 
2539  |  |  | 
2540  | 0  |             case SPF_OGR_GEOM_AREA:  | 
2541  | 0  |             { | 
2542  | 0  |                 if (GetGeomFieldCount() == 0 || papoGeometries[0] == nullptr)  | 
2543  | 0  |                     return "";  | 
2544  |  |  | 
2545  | 0  |                 constexpr size_t MAX_SIZE = 20 + 1;  | 
2546  | 0  |                 m_pszTmpFieldValue = static_cast<char *>(CPLMalloc(MAX_SIZE));  | 
2547  | 0  |                 CPLsnprintf(  | 
2548  | 0  |                     m_pszTmpFieldValue, MAX_SIZE, "%.16g",  | 
2549  | 0  |                     OGR_G_Area(OGRGeometry::ToHandle(papoGeometries[0])));  | 
2550  | 0  |                 return m_pszTmpFieldValue;  | 
2551  | 0  |             }  | 
2552  |  |  | 
2553  | 0  |             default:  | 
2554  | 0  |                 return "";  | 
2555  | 0  |         }  | 
2556  | 0  |     }  | 
2557  |  |  | 
2558  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
2559  |  | 
  | 
2560  | 0  |     if (poFDefn == nullptr)  | 
2561  | 0  |         return "";  | 
2562  |  |  | 
2563  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
2564  | 0  |         return "";  | 
2565  |  |  | 
2566  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
2567  | 0  |     if (eType == OFTString)  | 
2568  | 0  |     { | 
2569  | 0  |         if (pauFields[iField].String == nullptr)  | 
2570  | 0  |             return "";  | 
2571  | 0  |         else  | 
2572  | 0  |             return pauFields[iField].String;  | 
2573  | 0  |     }  | 
2574  | 0  |     else if (eType == OFTInteger)  | 
2575  | 0  |     { | 
2576  | 0  |         constexpr size_t MAX_SIZE = 11 + 1;  | 
2577  | 0  |         m_pszTmpFieldValue = static_cast<char *>(CPLMalloc(MAX_SIZE));  | 
2578  | 0  |         snprintf(m_pszTmpFieldValue, MAX_SIZE, "%d", pauFields[iField].Integer);  | 
2579  | 0  |         return m_pszTmpFieldValue;  | 
2580  | 0  |     }  | 
2581  | 0  |     else if (eType == OFTInteger64)  | 
2582  | 0  |     { | 
2583  | 0  |         constexpr size_t MAX_SIZE = 20 + 1;  | 
2584  | 0  |         m_pszTmpFieldValue = static_cast<char *>(CPLMalloc(MAX_SIZE));  | 
2585  | 0  |         CPLsnprintf(m_pszTmpFieldValue, MAX_SIZE, CPL_FRMT_GIB,  | 
2586  | 0  |                     pauFields[iField].Integer64);  | 
2587  | 0  |         return m_pszTmpFieldValue;  | 
2588  | 0  |     }  | 
2589  | 0  |     else if (eType == OFTReal)  | 
2590  | 0  |     { | 
2591  | 0  |         char szFormat[32] = {}; | 
2592  | 0  |         constexpr int TEMP_BUFFER_SIZE = 80;  | 
2593  | 0  |         char szTempBuffer[TEMP_BUFFER_SIZE] = {}; | 
2594  |  | 
  | 
2595  | 0  |         if (poFDefn->GetWidth() != 0)  | 
2596  | 0  |         { | 
2597  | 0  |             snprintf(szFormat, sizeof(szFormat), "%%.%df",  | 
2598  | 0  |                      poFDefn->GetPrecision());  | 
2599  |  | 
  | 
2600  | 0  |             CPLsnprintf(szTempBuffer, TEMP_BUFFER_SIZE, szFormat,  | 
2601  | 0  |                         pauFields[iField].Real);  | 
2602  | 0  |         }  | 
2603  | 0  |         else  | 
2604  | 0  |         { | 
2605  | 0  |             if (poFDefn->GetSubType() == OFSTFloat32)  | 
2606  | 0  |             { | 
2607  | 0  |                 OGRFormatFloat(szTempBuffer, TEMP_BUFFER_SIZE,  | 
2608  | 0  |                                static_cast<float>(pauFields[iField].Real), -1,  | 
2609  | 0  |                                'g');  | 
2610  | 0  |             }  | 
2611  | 0  |             else  | 
2612  | 0  |             { | 
2613  | 0  |                 strcpy(szFormat, "%.15g");  | 
2614  |  | 
  | 
2615  | 0  |                 CPLsnprintf(szTempBuffer, TEMP_BUFFER_SIZE, szFormat,  | 
2616  | 0  |                             pauFields[iField].Real);  | 
2617  | 0  |             }  | 
2618  | 0  |         }  | 
2619  |  | 
  | 
2620  | 0  |         m_pszTmpFieldValue = VSI_STRDUP_VERBOSE(szTempBuffer);  | 
2621  | 0  |         if (m_pszTmpFieldValue == nullptr)  | 
2622  | 0  |             return "";  | 
2623  | 0  |         return m_pszTmpFieldValue;  | 
2624  | 0  |     }  | 
2625  | 0  |     else if (eType == OFTDateTime)  | 
2626  | 0  |     { | 
2627  |  |         // "YYYY/MM/DD HH:MM:SS.sss+ZZ"  | 
2628  | 0  |         constexpr size_t EXTRA_SPACE_FOR_NEGATIVE_OR_LARGE_YEARS = 5;  | 
2629  | 0  |         constexpr size_t MAX_SIZE =  | 
2630  | 0  |             26 + EXTRA_SPACE_FOR_NEGATIVE_OR_LARGE_YEARS + 1;  | 
2631  | 0  |         m_pszTmpFieldValue = static_cast<char *>(CPLMalloc(MAX_SIZE));  | 
2632  | 0  |         OGRFeatureFormatDateTimeBuffer(  | 
2633  | 0  |             m_pszTmpFieldValue, MAX_SIZE, pauFields[iField].Date.Year,  | 
2634  | 0  |             pauFields[iField].Date.Month, pauFields[iField].Date.Day,  | 
2635  | 0  |             pauFields[iField].Date.Hour, pauFields[iField].Date.Minute,  | 
2636  | 0  |             pauFields[iField].Date.Second, pauFields[iField].Date.TZFlag);  | 
2637  |  | 
  | 
2638  | 0  |         return m_pszTmpFieldValue;  | 
2639  | 0  |     }  | 
2640  | 0  |     else if (eType == OFTDate)  | 
2641  | 0  |     { | 
2642  | 0  |         constexpr size_t EXTRA_SPACE_FOR_NEGATIVE_OR_LARGE_YEARS = 5;  | 
2643  | 0  |         constexpr size_t MAX_SIZE =  | 
2644  | 0  |             10 + EXTRA_SPACE_FOR_NEGATIVE_OR_LARGE_YEARS + 1;  | 
2645  | 0  |         m_pszTmpFieldValue = static_cast<char *>(CPLMalloc(MAX_SIZE));  | 
2646  | 0  |         snprintf(m_pszTmpFieldValue, MAX_SIZE, "%04d/%02d/%02d",  | 
2647  | 0  |                  pauFields[iField].Date.Year, pauFields[iField].Date.Month,  | 
2648  | 0  |                  pauFields[iField].Date.Day);  | 
2649  | 0  |         return m_pszTmpFieldValue;  | 
2650  | 0  |     }  | 
2651  | 0  |     else if (eType == OFTTime)  | 
2652  | 0  |     { | 
2653  | 0  |         constexpr size_t EXTRA_SPACE_TO_MAKE_GCC_HAPPY = 2;  | 
2654  | 0  |         constexpr size_t MAX_SIZE = 12 + EXTRA_SPACE_TO_MAKE_GCC_HAPPY + 1;  | 
2655  | 0  |         m_pszTmpFieldValue = static_cast<char *>(CPLMalloc(MAX_SIZE));  | 
2656  | 0  |         const int ms = OGR_GET_MS(pauFields[iField].Date.Second);  | 
2657  | 0  |         if (ms != 0 || std::isnan(pauFields[iField].Date.Second))  | 
2658  | 0  |             snprintf(m_pszTmpFieldValue, MAX_SIZE, "%02d:%02d:%06.3f",  | 
2659  | 0  |                      pauFields[iField].Date.Hour, pauFields[iField].Date.Minute,  | 
2660  | 0  |                      pauFields[iField].Date.Second);  | 
2661  | 0  |         else  | 
2662  | 0  |             snprintf(m_pszTmpFieldValue, MAX_SIZE, "%02d:%02d:%02d",  | 
2663  | 0  |                      pauFields[iField].Date.Hour, pauFields[iField].Date.Minute,  | 
2664  | 0  |                      static_cast<int>(pauFields[iField].Date.Second));  | 
2665  |  | 
  | 
2666  | 0  |         return m_pszTmpFieldValue;  | 
2667  | 0  |     }  | 
2668  | 0  |     else if (eType == OFTIntegerList)  | 
2669  | 0  |     { | 
2670  | 0  |         char szItem[32] = {}; | 
2671  | 0  |         const int nCount = pauFields[iField].IntegerList.nCount;  | 
2672  | 0  |         CPLString osBuffer;  | 
2673  |  | 
  | 
2674  | 0  |         osBuffer.Printf("(%d:", nCount); | 
2675  | 0  |         for (int i = 0; i < nCount; i++)  | 
2676  | 0  |         { | 
2677  | 0  |             snprintf(szItem, sizeof(szItem), "%d",  | 
2678  | 0  |                      pauFields[iField].IntegerList.paList[i]);  | 
2679  | 0  |             if (i > 0)  | 
2680  | 0  |                 osBuffer += ',';  | 
2681  | 0  |             osBuffer += szItem;  | 
2682  | 0  |         }  | 
2683  | 0  |         osBuffer += ')';  | 
2684  |  | 
  | 
2685  | 0  |         m_pszTmpFieldValue = VSI_STRDUP_VERBOSE(osBuffer.c_str());  | 
2686  | 0  |         if (m_pszTmpFieldValue == nullptr)  | 
2687  | 0  |             return "";  | 
2688  | 0  |         return m_pszTmpFieldValue;  | 
2689  | 0  |     }  | 
2690  | 0  |     else if (eType == OFTInteger64List)  | 
2691  | 0  |     { | 
2692  | 0  |         char szItem[32] = {}; | 
2693  | 0  |         const int nCount = pauFields[iField].Integer64List.nCount;  | 
2694  | 0  |         CPLString osBuffer;  | 
2695  |  | 
  | 
2696  | 0  |         osBuffer.Printf("(%d:", nCount); | 
2697  | 0  |         for (int i = 0; i < nCount; i++)  | 
2698  | 0  |         { | 
2699  | 0  |             CPLsnprintf(szItem, sizeof(szItem), CPL_FRMT_GIB,  | 
2700  | 0  |                         pauFields[iField].Integer64List.paList[i]);  | 
2701  | 0  |             if (i > 0)  | 
2702  | 0  |                 osBuffer += ',';  | 
2703  | 0  |             osBuffer += szItem;  | 
2704  | 0  |         }  | 
2705  | 0  |         osBuffer += ')';  | 
2706  |  | 
  | 
2707  | 0  |         m_pszTmpFieldValue = VSI_STRDUP_VERBOSE(osBuffer.c_str());  | 
2708  | 0  |         if (m_pszTmpFieldValue == nullptr)  | 
2709  | 0  |             return "";  | 
2710  | 0  |         return m_pszTmpFieldValue;  | 
2711  | 0  |     }  | 
2712  | 0  |     else if (eType == OFTRealList)  | 
2713  | 0  |     { | 
2714  | 0  |         char szItem[40] = {}; | 
2715  | 0  |         char szFormat[64] = {}; | 
2716  | 0  |         const int nCount = pauFields[iField].RealList.nCount;  | 
2717  | 0  |         const bool bIsFloat32 = poFDefn->GetSubType() == OFSTFloat32;  | 
2718  | 0  |         const bool bIsZeroWidth = poFDefn->GetWidth() == 0;  | 
2719  |  | 
  | 
2720  | 0  |         if (!bIsZeroWidth)  | 
2721  | 0  |         { | 
2722  | 0  |             snprintf(szFormat, sizeof(szFormat), "%%%d.%df",  | 
2723  | 0  |                      poFDefn->GetWidth(), poFDefn->GetPrecision());  | 
2724  | 0  |         }  | 
2725  | 0  |         else  | 
2726  | 0  |             strcpy(szFormat, "%.16g");  | 
2727  |  | 
  | 
2728  | 0  |         CPLString osBuffer;  | 
2729  |  | 
  | 
2730  | 0  |         osBuffer.Printf("(%d:", nCount); | 
2731  |  | 
  | 
2732  | 0  |         for (int i = 0; i < nCount; i++)  | 
2733  | 0  |         { | 
2734  | 0  |             if (bIsFloat32 && bIsZeroWidth)  | 
2735  | 0  |             { | 
2736  | 0  |                 OGRFormatFloat(  | 
2737  | 0  |                     szItem, sizeof(szItem),  | 
2738  | 0  |                     static_cast<float>(pauFields[iField].RealList.paList[i]),  | 
2739  | 0  |                     -1, 'g');  | 
2740  | 0  |             }  | 
2741  | 0  |             else  | 
2742  | 0  |             { | 
2743  | 0  |                 CPLsnprintf(szItem, sizeof(szItem), szFormat,  | 
2744  | 0  |                             pauFields[iField].RealList.paList[i]);  | 
2745  | 0  |             }  | 
2746  | 0  |             if (i > 0)  | 
2747  | 0  |                 osBuffer += ',';  | 
2748  | 0  |             osBuffer += szItem;  | 
2749  | 0  |         }  | 
2750  | 0  |         osBuffer += ')';  | 
2751  |  | 
  | 
2752  | 0  |         m_pszTmpFieldValue = VSI_STRDUP_VERBOSE(osBuffer.c_str());  | 
2753  | 0  |         if (m_pszTmpFieldValue == nullptr)  | 
2754  | 0  |             return "";  | 
2755  | 0  |         return m_pszTmpFieldValue;  | 
2756  | 0  |     }  | 
2757  | 0  |     else if (eType == OFTStringList)  | 
2758  | 0  |     { | 
2759  | 0  |         const int nCount = pauFields[iField].StringList.nCount;  | 
2760  |  | 
  | 
2761  | 0  |         CPLString osBuffer;  | 
2762  |  | 
  | 
2763  | 0  |         osBuffer.Printf("(%d:", nCount); | 
2764  | 0  |         for (int i = 0; i < nCount; i++)  | 
2765  | 0  |         { | 
2766  | 0  |             const char *pszItem = pauFields[iField].StringList.paList[i];  | 
2767  | 0  |             if (i > 0)  | 
2768  | 0  |                 osBuffer += ',';  | 
2769  | 0  |             osBuffer += pszItem;  | 
2770  | 0  |         }  | 
2771  | 0  |         osBuffer += ')';  | 
2772  |  | 
  | 
2773  | 0  |         m_pszTmpFieldValue = VSI_STRDUP_VERBOSE(osBuffer.c_str());  | 
2774  | 0  |         if (m_pszTmpFieldValue == nullptr)  | 
2775  | 0  |             return "";  | 
2776  | 0  |         return m_pszTmpFieldValue;  | 
2777  | 0  |     }  | 
2778  | 0  |     else if (eType == OFTBinary)  | 
2779  | 0  |     { | 
2780  | 0  |         const int nCount = pauFields[iField].Binary.nCount;  | 
2781  | 0  |         m_pszTmpFieldValue =  | 
2782  | 0  |             CPLBinaryToHex(nCount, pauFields[iField].Binary.paData);  | 
2783  | 0  |         if (m_pszTmpFieldValue == nullptr)  | 
2784  | 0  |             return "";  | 
2785  | 0  |         return m_pszTmpFieldValue;  | 
2786  | 0  |     }  | 
2787  |  |  | 
2788  | 0  |     return "";  | 
2789  | 0  | }  | 
2790  |  |  | 
2791  |  | /************************************************************************/  | 
2792  |  | /*                       OGR_F_GetFieldAsString()                       */  | 
2793  |  | /************************************************************************/  | 
2794  |  |  | 
2795  |  | /**  | 
2796  |  |  * \brief Fetch field value as a string.  | 
2797  |  |  *  | 
2798  |  |  * OFTReal and OFTInteger fields will be translated to string using  | 
2799  |  |  * sprintf(), but not necessarily using the established formatting rules.  | 
2800  |  |  * Other field types, or errors will result in a return value of zero.  | 
2801  |  |  *  | 
2802  |  |  * This function is the same as the C++ method OGRFeature::GetFieldAsString().  | 
2803  |  |  *  | 
2804  |  |  * @param hFeat handle to the feature that owned the field.  | 
2805  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2806  |  |  *  | 
2807  |  |  * @return the field value.  This string is internal, and should not be  | 
2808  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
2809  |  |  */  | 
2810  |  |  | 
2811  |  | const char *OGR_F_GetFieldAsString(OGRFeatureH hFeat, int iField)  | 
2812  |  |  | 
2813  | 0  | { | 
2814  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsString", nullptr);  | 
2815  |  |  | 
2816  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsString(iField);  | 
2817  | 0  | }  | 
2818  |  |  | 
2819  |  | /************************************************************************/  | 
2820  |  | /*                     GetFieldAsISO8601DateTime()                      */  | 
2821  |  | /************************************************************************/  | 
2822  |  |  | 
2823  |  | /* clang-format off */  | 
2824  |  | /**  | 
2825  |  |  * \fn OGRFeature::GetFieldAsISO8601DateTime( const char* pszFName, CSLConstList papszOptions ) const  | 
2826  |  |  * \brief Fetch OFTDateTime field value as a ISO8601 representation.  | 
2827  |  |  *  | 
2828  |  |  * Return a string like "YYYY-MM-DDTHH:MM:SS(.sss)?(Z|([+|-]HH:MM))?"  | 
2829  |  |  * Milliseconds are omitted if equal to zero.  | 
2830  |  |  * Other field types, or errors will result in a return of an empty string.  | 
2831  |  |  *  | 
2832  |  |  * @param pszFName the name of the field to fetch.  | 
2833  |  |  * @param papszOptions NULL terminated list of strings, or NULL.  | 
2834  |  |  * No options are defined currently.  | 
2835  |  |  *  | 
2836  |  |  * @return the field value.  This string is internal, and should not be  | 
2837  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
2838  |  |  *  | 
2839  |  |  * @since GDAL 3.7  | 
2840  |  |  */  | 
2841  |  | /* clang-format on */  | 
2842  |  |  | 
2843  |  | /**  | 
2844  |  |  * \brief Fetch OFTDateTime field value as a ISO8601 representation.  | 
2845  |  |  *  | 
2846  |  |  * Return a string like "YYYY-MM-DDTHH:MM:SS(.sss)?(Z|([+|-]HH:MM))?"  | 
2847  |  |  * Milliseconds are omitted if equal to zero.  | 
2848  |  |  * Other field types, or errors will result in a return of an empty string.  | 
2849  |  |  *  | 
2850  |  |  * This method is the same as the C function OGR_F_GetFieldAsISO8601DateTime().  | 
2851  |  |  *  | 
2852  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2853  |  |  * @param papszOptions NULL terminated list of strings, or NULL.  | 
2854  |  |  * No options are defined currently.  | 
2855  |  |  *  | 
2856  |  |  * @return the field value.  This string is internal, and should not be  | 
2857  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
2858  |  |  *  | 
2859  |  |  * @since GDAL 3.7  | 
2860  |  |  */  | 
2861  |  |  | 
2862  |  | const char *OGRFeature::GetFieldAsISO8601DateTime(  | 
2863  |  |     int iField, CPL_UNUSED CSLConstList papszOptions) const  | 
2864  |  |  | 
2865  | 0  | { | 
2866  | 0  |     CPLFree(m_pszTmpFieldValue);  | 
2867  | 0  |     m_pszTmpFieldValue = nullptr;  | 
2868  |  | 
  | 
2869  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
2870  | 0  |     if (iSpecialField >= 0)  | 
2871  | 0  |     { | 
2872  | 0  |         return "";  | 
2873  | 0  |     }  | 
2874  |  |  | 
2875  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
2876  |  | 
  | 
2877  | 0  |     if (poFDefn == nullptr)  | 
2878  | 0  |         return "";  | 
2879  |  |  | 
2880  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
2881  | 0  |         return "";  | 
2882  |  |  | 
2883  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
2884  | 0  |     if (eType != OFTDateTime)  | 
2885  | 0  |         return "";  | 
2886  |  |  | 
2887  | 0  |     m_pszTmpFieldValue =  | 
2888  | 0  |         static_cast<char *>(CPLMalloc(OGR_SIZEOF_ISO8601_DATETIME_BUFFER));  | 
2889  | 0  |     constexpr bool bAlwaysMillisecond = false;  | 
2890  | 0  |     OGRGetISO8601DateTime(&pauFields[iField], bAlwaysMillisecond,  | 
2891  | 0  |                           m_pszTmpFieldValue);  | 
2892  | 0  |     return m_pszTmpFieldValue;  | 
2893  | 0  |     ;  | 
2894  | 0  | }  | 
2895  |  |  | 
2896  |  | /************************************************************************/  | 
2897  |  | /*                     OGR_F_GetFieldAsISO8601DateTime()                */  | 
2898  |  | /************************************************************************/  | 
2899  |  |  | 
2900  |  | /**  | 
2901  |  |  * \brief Fetch OFTDateTime field value as a ISO8601 representation.  | 
2902  |  |  *  | 
2903  |  |  * Return a string like "YYYY-MM6DDTHH:MM:SS(.sss)?(Z|([+|-]HH:MM))?"  | 
2904  |  |  * Milliseconds are omitted if equal to zero.  | 
2905  |  |  * Other field types, or errors will result in a return of an empty string.  | 
2906  |  |  *  | 
2907  |  |  * This function is the same as the C++ method OGRFeature::GetFieldAsISO8601DateTime().  | 
2908  |  |  *  | 
2909  |  |  * @param hFeat handle to the feature that owned the field.  | 
2910  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2911  |  |  * @param papszOptions NULL terminated list of strings, or NULL.  | 
2912  |  |  * No options are defined currently.  | 
2913  |  |  *  | 
2914  |  |  * @return the field value.  This string is internal, and should not be  | 
2915  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
2916  |  |  *  | 
2917  |  |  * @since GDAL 3.7  | 
2918  |  |  */  | 
2919  |  |  | 
2920  |  | const char *OGR_F_GetFieldAsISO8601DateTime(OGRFeatureH hFeat, int iField,  | 
2921  |  |                                             CSLConstList papszOptions)  | 
2922  |  |  | 
2923  | 0  | { | 
2924  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsISO8601DateTime", nullptr);  | 
2925  |  |  | 
2926  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsISO8601DateTime(  | 
2927  | 0  |         iField, papszOptions);  | 
2928  | 0  | }  | 
2929  |  |  | 
2930  |  | /************************************************************************/  | 
2931  |  | /*                       GetFieldAsIntegerList()                        */  | 
2932  |  | /************************************************************************/  | 
2933  |  |  | 
2934  |  | /* clang-format off */  | 
2935  |  | /**  | 
2936  |  |  * \fn OGRFeature::GetFieldAsIntegerList( const char* pszFName, int *pnCount ) const  | 
2937  |  |  * \brief Fetch field value as a list of integers.  | 
2938  |  |  *  | 
2939  |  |  * Currently this method only works for OFTIntegerList fields.  | 
2940  |  |  | 
2941  |  |  * @param pszFName the name of the field to fetch.  | 
2942  |  |  * @param pnCount an integer to put the list count (number of integers) into.  | 
2943  |  |  *  | 
2944  |  |  * @return the field value.  This list is internal, and should not be  | 
2945  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
2946  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
2947  |  |  * OFTReal and OFTInteger fields will be translated to string using  | 
2948  |  |  * sprintf(), but not necessarily using the established formatting rules.  | 
2949  |  |  * Other field types, or errors will result in a return value of zero.  | 
2950  |  |  */  | 
2951  |  | /* clang-format on */  | 
2952  |  |  | 
2953  |  | /**  | 
2954  |  |  * \brief Fetch field value as a list of integers.  | 
2955  |  |  *  | 
2956  |  |  * Currently this method only works for OFTIntegerList fields.  | 
2957  |  |  *  | 
2958  |  |  * This method is the same as the C function OGR_F_GetFieldAsIntegerList().  | 
2959  |  |  *  | 
2960  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
2961  |  |  * @param pnCount an integer to put the list count (number of integers) into.  | 
2962  |  |  *  | 
2963  |  |  * @return the field value.  This list is internal, and should not be  | 
2964  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
2965  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
2966  |  |  */  | 
2967  |  |  | 
2968  |  | const int *OGRFeature::GetFieldAsIntegerList(int iField, int *pnCount) const  | 
2969  |  |  | 
2970  | 0  | { | 
2971  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
2972  |  | 
  | 
2973  | 0  |     if (poFDefn != nullptr && IsFieldSetAndNotNullUnsafe(iField) &&  | 
2974  | 0  |         poFDefn->GetType() == OFTIntegerList)  | 
2975  | 0  |     { | 
2976  | 0  |         if (pnCount != nullptr)  | 
2977  | 0  |             *pnCount = pauFields[iField].IntegerList.nCount;  | 
2978  |  | 
  | 
2979  | 0  |         return pauFields[iField].IntegerList.paList;  | 
2980  | 0  |     }  | 
2981  |  |  | 
2982  | 0  |     if (pnCount != nullptr)  | 
2983  | 0  |         *pnCount = 0;  | 
2984  |  | 
  | 
2985  | 0  |     return nullptr;  | 
2986  | 0  | }  | 
2987  |  |  | 
2988  |  | /************************************************************************/  | 
2989  |  | /*                    OGR_F_GetFieldAsIntegerList()                     */  | 
2990  |  | /************************************************************************/  | 
2991  |  |  | 
2992  |  | /**  | 
2993  |  |  * \brief Fetch field value as a list of integers.  | 
2994  |  |  *  | 
2995  |  |  * Currently this function only works for OFTIntegerList fields.  | 
2996  |  |  *  | 
2997  |  |  * This function is the same as the C++ method  | 
2998  |  |  * OGRFeature::GetFieldAsIntegerList().  | 
2999  |  |  *  | 
3000  |  |  * @param hFeat handle to the feature that owned the field.  | 
3001  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3002  |  |  * @param pnCount an integer to put the list count (number of integers) into.  | 
3003  |  |  *  | 
3004  |  |  * @return the field value.  This list is internal, and should not be  | 
3005  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
3006  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
3007  |  |  */  | 
3008  |  |  | 
3009  |  | const int *OGR_F_GetFieldAsIntegerList(OGRFeatureH hFeat, int iField,  | 
3010  |  |                                        int *pnCount)  | 
3011  |  |  | 
3012  | 0  | { | 
3013  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsIntegerList", nullptr);  | 
3014  |  |  | 
3015  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsIntegerList(iField,  | 
3016  | 0  |                                                                 pnCount);  | 
3017  | 0  | }  | 
3018  |  |  | 
3019  |  | /************************************************************************/  | 
3020  |  | /*                      GetFieldAsInteger64List()                       */  | 
3021  |  | /************************************************************************/  | 
3022  |  |  | 
3023  |  | /* clang-format off */  | 
3024  |  | /**  | 
3025  |  |  * \fn OGRFeature::GetFieldAsInteger64List( const char* pszFName, int *pnCount ) const  | 
3026  |  |  * \brief Fetch field value as a list of 64 bit integers.  | 
3027  |  |  *  | 
3028  |  |  * Currently this method only works for OFTInteger64List fields.  | 
3029  |  |  | 
3030  |  |  * @param pszFName the name of the field to fetch.  | 
3031  |  |  * @param pnCount an integer to put the list count (number of integers) into.  | 
3032  |  |  *  | 
3033  |  |  * @return the field value.  This list is internal, and should not be  | 
3034  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
3035  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
3036  |  |  * @since GDAL 2.0  | 
3037  |  |  */  | 
3038  |  | /* clang-format on */  | 
3039  |  |  | 
3040  |  | /**  | 
3041  |  |  * \brief Fetch field value as a list of 64 bit integers.  | 
3042  |  |  *  | 
3043  |  |  * Currently this method only works for OFTInteger64List fields.  | 
3044  |  |  *  | 
3045  |  |  * This method is the same as the C function OGR_F_GetFieldAsInteger64List().  | 
3046  |  |  *  | 
3047  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3048  |  |  * @param pnCount an integer to put the list count (number of integers) into.  | 
3049  |  |  *  | 
3050  |  |  * @return the field value.  This list is internal, and should not be  | 
3051  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
3052  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
3053  |  |  * @since GDAL 2.0  | 
3054  |  |  */  | 
3055  |  |  | 
3056  |  | const GIntBig *OGRFeature::GetFieldAsInteger64List(int iField,  | 
3057  |  |                                                    int *pnCount) const  | 
3058  |  |  | 
3059  | 0  | { | 
3060  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3061  |  | 
  | 
3062  | 0  |     if (poFDefn != nullptr && IsFieldSetAndNotNullUnsafe(iField) &&  | 
3063  | 0  |         poFDefn->GetType() == OFTInteger64List)  | 
3064  | 0  |     { | 
3065  | 0  |         if (pnCount != nullptr)  | 
3066  | 0  |             *pnCount = pauFields[iField].Integer64List.nCount;  | 
3067  |  | 
  | 
3068  | 0  |         return pauFields[iField].Integer64List.paList;  | 
3069  | 0  |     }  | 
3070  |  |  | 
3071  | 0  |     if (pnCount != nullptr)  | 
3072  | 0  |         *pnCount = 0;  | 
3073  |  | 
  | 
3074  | 0  |     return nullptr;  | 
3075  | 0  | }  | 
3076  |  |  | 
3077  |  | /************************************************************************/  | 
3078  |  | /*                   OGR_F_GetFieldAsInteger64List()                    */  | 
3079  |  | /************************************************************************/  | 
3080  |  |  | 
3081  |  | /**  | 
3082  |  |  * \brief Fetch field value as a list of 64 bit integers.  | 
3083  |  |  *  | 
3084  |  |  * Currently this function only works for OFTInteger64List fields.  | 
3085  |  |  *  | 
3086  |  |  * This function is the same as the C++ method  | 
3087  |  |  * OGRFeature::GetFieldAsInteger64List().  | 
3088  |  |  *  | 
3089  |  |  * @param hFeat handle to the feature that owned the field.  | 
3090  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3091  |  |  * @param pnCount an integer to put the list count (number of integers) into.  | 
3092  |  |  *  | 
3093  |  |  * @return the field value.  This list is internal, and should not be  | 
3094  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
3095  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
3096  |  |  * @since GDAL 2.0  | 
3097  |  |  */  | 
3098  |  |  | 
3099  |  | const GIntBig *OGR_F_GetFieldAsInteger64List(OGRFeatureH hFeat, int iField,  | 
3100  |  |                                              int *pnCount)  | 
3101  |  |  | 
3102  | 0  | { | 
3103  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsInteger64List", nullptr);  | 
3104  |  |  | 
3105  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsInteger64List(iField,  | 
3106  | 0  |                                                                   pnCount);  | 
3107  | 0  | }  | 
3108  |  |  | 
3109  |  | /************************************************************************/  | 
3110  |  | /*                        GetFieldAsDoubleList()                        */  | 
3111  |  | /************************************************************************/  | 
3112  |  |  | 
3113  |  | /* clang-format off */  | 
3114  |  | /**  | 
3115  |  |  * \fn OGRFeature::GetFieldAsDoubleList( const char* pszFName, int *pnCount ) const  | 
3116  |  |  * \brief Fetch field value as a list of doubles.  | 
3117  |  |  *  | 
3118  |  |  * Currently this method only works for OFTRealList fields.  | 
3119  |  |  | 
3120  |  |  * @param pszFName the name of the field to fetch.  | 
3121  |  |  * @param pnCount an integer to put the list count (number of doubles) into.  | 
3122  |  |  *  | 
3123  |  |  * @return the field value.  This list is internal, and should not be  | 
3124  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
3125  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
3126  |  |  */  | 
3127  |  | /* clang-format on */  | 
3128  |  |  | 
3129  |  | /**  | 
3130  |  |  * \brief Fetch field value as a list of doubles.  | 
3131  |  |  *  | 
3132  |  |  * Currently this method only works for OFTRealList fields.  | 
3133  |  |  *  | 
3134  |  |  * This method is the same as the C function OGR_F_GetFieldAsDoubleList().  | 
3135  |  |  *  | 
3136  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3137  |  |  * @param pnCount an integer to put the list count (number of doubles) into.  | 
3138  |  |  *  | 
3139  |  |  * @return the field value.  This list is internal, and should not be  | 
3140  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
3141  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
3142  |  |  */  | 
3143  |  |  | 
3144  |  | const double *OGRFeature::GetFieldAsDoubleList(int iField, int *pnCount) const  | 
3145  |  |  | 
3146  | 0  | { | 
3147  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3148  |  | 
  | 
3149  | 0  |     if (poFDefn != nullptr && IsFieldSetAndNotNullUnsafe(iField) &&  | 
3150  | 0  |         poFDefn->GetType() == OFTRealList)  | 
3151  | 0  |     { | 
3152  | 0  |         if (pnCount != nullptr)  | 
3153  | 0  |             *pnCount = pauFields[iField].RealList.nCount;  | 
3154  |  | 
  | 
3155  | 0  |         return pauFields[iField].RealList.paList;  | 
3156  | 0  |     }  | 
3157  |  |  | 
3158  | 0  |     if (pnCount != nullptr)  | 
3159  | 0  |         *pnCount = 0;  | 
3160  |  | 
  | 
3161  | 0  |     return nullptr;  | 
3162  | 0  | }  | 
3163  |  |  | 
3164  |  | /************************************************************************/  | 
3165  |  | /*                     OGR_F_GetFieldAsDoubleList()                     */  | 
3166  |  | /************************************************************************/  | 
3167  |  |  | 
3168  |  | /**  | 
3169  |  |  * \brief Fetch field value as a list of doubles.  | 
3170  |  |  *  | 
3171  |  |  * Currently this function only works for OFTRealList fields.  | 
3172  |  |  *  | 
3173  |  |  * This function is the same as the C++ method  | 
3174  |  |  * OGRFeature::GetFieldAsDoubleList().  | 
3175  |  |  *  | 
3176  |  |  * @param hFeat handle to the feature that owned the field.  | 
3177  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3178  |  |  * @param pnCount an integer to put the list count (number of doubles) into.  | 
3179  |  |  *  | 
3180  |  |  * @return the field value.  This list is internal, and should not be  | 
3181  |  |  * modified, or freed.  Its lifetime may be very brief.  If *pnCount is zero  | 
3182  |  |  * on return the returned pointer may be NULL or non-NULL.  | 
3183  |  |  */  | 
3184  |  |  | 
3185  |  | const double *OGR_F_GetFieldAsDoubleList(OGRFeatureH hFeat, int iField,  | 
3186  |  |                                          int *pnCount)  | 
3187  |  |  | 
3188  | 0  | { | 
3189  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsDoubleList", nullptr);  | 
3190  |  |  | 
3191  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsDoubleList(iField, pnCount);  | 
3192  | 0  | }  | 
3193  |  |  | 
3194  |  | /************************************************************************/  | 
3195  |  | /*                        GetFieldAsStringList()                        */  | 
3196  |  | /************************************************************************/  | 
3197  |  | /**  | 
3198  |  |  * \fn OGRFeature::GetFieldAsStringList( const char* pszFName ) const  | 
3199  |  |  * \brief Fetch field value as a list of strings.  | 
3200  |  |  *  | 
3201  |  |  * Currently this method only works for OFTStringList fields.  | 
3202  |  |  *  | 
3203  |  |  * The returned list is terminated by a NULL pointer. The number of  | 
3204  |  |  * elements can also be calculated using CSLCount().  | 
3205  |  |  *  | 
3206  |  |  * @param pszFName the name of the field to fetch.  | 
3207  |  |  *  | 
3208  |  |  * @return the field value.  This list is internal, and should not be  | 
3209  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
3210  |  |  */  | 
3211  |  |  | 
3212  |  | /**  | 
3213  |  |  * \brief Fetch field value as a list of strings.  | 
3214  |  |  *  | 
3215  |  |  * Currently this method only works for OFTStringList fields.  | 
3216  |  |  *  | 
3217  |  |  * The returned list is terminated by a NULL pointer. The number of  | 
3218  |  |  * elements can also be calculated using CSLCount().  | 
3219  |  |  *  | 
3220  |  |  * This method is the same as the C function OGR_F_GetFieldAsStringList().  | 
3221  |  |  *  | 
3222  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3223  |  |  *  | 
3224  |  |  * @return the field value.  This list is internal, and should not be  | 
3225  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
3226  |  |  */  | 
3227  |  |  | 
3228  |  | char **OGRFeature::GetFieldAsStringList(int iField) const  | 
3229  |  |  | 
3230  | 0  | { | 
3231  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3232  |  | 
  | 
3233  | 0  |     if (poFDefn == nullptr)  | 
3234  | 0  |         return nullptr;  | 
3235  |  |  | 
3236  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
3237  | 0  |         return nullptr;  | 
3238  |  |  | 
3239  | 0  |     if (poFDefn->GetType() == OFTStringList)  | 
3240  | 0  |     { | 
3241  | 0  |         return pauFields[iField].StringList.paList;  | 
3242  | 0  |     }  | 
3243  |  |  | 
3244  | 0  |     return nullptr;  | 
3245  | 0  | }  | 
3246  |  |  | 
3247  |  | /************************************************************************/  | 
3248  |  | /*                     OGR_F_GetFieldAsStringList()                     */  | 
3249  |  | /************************************************************************/  | 
3250  |  |  | 
3251  |  | /**  | 
3252  |  |  * \brief Fetch field value as a list of strings.  | 
3253  |  |  *  | 
3254  |  |  * Currently this method only works for OFTStringList fields.  | 
3255  |  |  *  | 
3256  |  |  * The returned list is terminated by a NULL pointer. The number of  | 
3257  |  |  * elements can also be calculated using CSLCount().  | 
3258  |  |  *  | 
3259  |  |  * This function is the same as the C++ method  | 
3260  |  |  * OGRFeature::GetFieldAsStringList().  | 
3261  |  |  *  | 
3262  |  |  * @param hFeat handle to the feature that owned the field.  | 
3263  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3264  |  |  *  | 
3265  |  |  * @return the field value.  This list is internal, and should not be  | 
3266  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
3267  |  |  */  | 
3268  |  |  | 
3269  |  | char **OGR_F_GetFieldAsStringList(OGRFeatureH hFeat, int iField)  | 
3270  |  |  | 
3271  | 0  | { | 
3272  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsStringList", nullptr);  | 
3273  |  |  | 
3274  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsStringList(iField);  | 
3275  | 0  | }  | 
3276  |  |  | 
3277  |  | /************************************************************************/  | 
3278  |  | /*                          GetFieldAsBinary()                          */  | 
3279  |  | /************************************************************************/  | 
3280  |  |  | 
3281  |  | /**  | 
3282  |  |  * \brief Fetch field value as binary data.  | 
3283  |  |  *  | 
3284  |  |  * This method only works for OFTBinary and OFTString fields.  | 
3285  |  |  *  | 
3286  |  |  * This method is the same as the C function OGR_F_GetFieldAsBinary().  | 
3287  |  |  *  | 
3288  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3289  |  |  * @param pnBytes location to put the number of bytes returned.  | 
3290  |  |  *  | 
3291  |  |  * @return the field value.  This data is internal, and should not be  | 
3292  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
3293  |  |  */  | 
3294  |  |  | 
3295  |  | GByte *OGRFeature::GetFieldAsBinary(int iField, int *pnBytes) const  | 
3296  |  |  | 
3297  | 0  | { | 
3298  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3299  |  | 
  | 
3300  | 0  |     *pnBytes = 0;  | 
3301  |  | 
  | 
3302  | 0  |     if (poFDefn == nullptr)  | 
3303  | 0  |         return nullptr;  | 
3304  |  |  | 
3305  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
3306  | 0  |         return nullptr;  | 
3307  |  |  | 
3308  | 0  |     if (poFDefn->GetType() == OFTBinary)  | 
3309  | 0  |     { | 
3310  | 0  |         *pnBytes = pauFields[iField].Binary.nCount;  | 
3311  | 0  |         return pauFields[iField].Binary.paData;  | 
3312  | 0  |     }  | 
3313  | 0  |     else if (poFDefn->GetType() == OFTString)  | 
3314  | 0  |     { | 
3315  | 0  |         *pnBytes = static_cast<int>(strlen(pauFields[iField].String));  | 
3316  | 0  |         return reinterpret_cast<GByte *>(pauFields[iField].String);  | 
3317  | 0  |     }  | 
3318  |  |  | 
3319  | 0  |     return nullptr;  | 
3320  | 0  | }  | 
3321  |  |  | 
3322  |  | /************************************************************************/  | 
3323  |  | /*                       OGR_F_GetFieldAsBinary()                       */  | 
3324  |  | /************************************************************************/  | 
3325  |  |  | 
3326  |  | /**  | 
3327  |  |  * \brief Fetch field value as binary.  | 
3328  |  |  *  | 
3329  |  |  * This method only works for OFTBinary and OFTString fields.  | 
3330  |  |  *  | 
3331  |  |  * This function is the same as the C++ method  | 
3332  |  |  * OGRFeature::GetFieldAsBinary().  | 
3333  |  |  *  | 
3334  |  |  * @param hFeat handle to the feature that owned the field.  | 
3335  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3336  |  |  * @param pnBytes location to place count of bytes returned.  | 
3337  |  |  *  | 
3338  |  |  * @return the field value.  This list is internal, and should not be  | 
3339  |  |  * modified, or freed.  Its lifetime may be very brief.  | 
3340  |  |  */  | 
3341  |  |  | 
3342  |  | GByte *OGR_F_GetFieldAsBinary(OGRFeatureH hFeat, int iField, int *pnBytes)  | 
3343  |  |  | 
3344  | 0  | { | 
3345  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsBinary", nullptr);  | 
3346  | 0  |     VALIDATE_POINTER1(pnBytes, "OGR_F_GetFieldAsBinary", nullptr);  | 
3347  |  |  | 
3348  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsBinary(iField, pnBytes);  | 
3349  | 0  | }  | 
3350  |  |  | 
3351  |  | /************************************************************************/  | 
3352  |  | /*                         GetFieldAsDateTime()                         */  | 
3353  |  | /************************************************************************/  | 
3354  |  |  | 
3355  |  | /**  | 
3356  |  |  * \brief Fetch field value as date and time.  | 
3357  |  |  *  | 
3358  |  |  * Currently this method only works for OFTDate, OFTTime and OFTDateTime fields.  | 
3359  |  |  *  | 
3360  |  |  * This method is the same as the C function OGR_F_GetFieldAsDateTime().  | 
3361  |  |  *  | 
3362  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3363  |  |  * @param pnYear (including century)  | 
3364  |  |  * @param pnMonth (1-12)  | 
3365  |  |  * @param pnDay (1-31)  | 
3366  |  |  * @param pnHour (0-23)  | 
3367  |  |  * @param pnMinute (0-59)  | 
3368  |  |  * @param pfSecond (0-59 with millisecond accuracy)  | 
3369  |  |  * @param pnTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
3370  |  |  *  | 
3371  |  |  * @return TRUE on success or FALSE on failure.  | 
3372  |  |  */  | 
3373  |  |  | 
3374  |  | int OGRFeature::GetFieldAsDateTime(int iField, int *pnYear, int *pnMonth,  | 
3375  |  |                                    int *pnDay, int *pnHour, int *pnMinute,  | 
3376  |  |                                    float *pfSecond, int *pnTZFlag) const  | 
3377  |  |  | 
3378  | 0  | { | 
3379  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3380  |  | 
  | 
3381  | 0  |     if (poFDefn == nullptr)  | 
3382  | 0  |         return FALSE;  | 
3383  |  |  | 
3384  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
3385  | 0  |         return FALSE;  | 
3386  |  |  | 
3387  | 0  |     if (poFDefn->GetType() == OFTDate || poFDefn->GetType() == OFTTime ||  | 
3388  | 0  |         poFDefn->GetType() == OFTDateTime)  | 
3389  | 0  |     { | 
3390  | 0  |         if (pnYear)  | 
3391  | 0  |             *pnYear = pauFields[iField].Date.Year;  | 
3392  | 0  |         if (pnMonth)  | 
3393  | 0  |             *pnMonth = pauFields[iField].Date.Month;  | 
3394  | 0  |         if (pnDay)  | 
3395  | 0  |             *pnDay = pauFields[iField].Date.Day;  | 
3396  | 0  |         if (pnHour)  | 
3397  | 0  |             *pnHour = pauFields[iField].Date.Hour;  | 
3398  | 0  |         if (pnMinute)  | 
3399  | 0  |             *pnMinute = pauFields[iField].Date.Minute;  | 
3400  | 0  |         if (pfSecond)  | 
3401  | 0  |             *pfSecond = pauFields[iField].Date.Second;  | 
3402  | 0  |         if (pnTZFlag)  | 
3403  | 0  |             *pnTZFlag = pauFields[iField].Date.TZFlag;  | 
3404  |  | 
  | 
3405  | 0  |         return TRUE;  | 
3406  | 0  |     }  | 
3407  |  |  | 
3408  | 0  |     return FALSE;  | 
3409  | 0  | }  | 
3410  |  |  | 
3411  |  | /**  | 
3412  |  |  * \brief Fetch field value as date and time.  | 
3413  |  |  *  | 
3414  |  |  * Currently this method only works for OFTDate, OFTTime and OFTDateTime fields.  | 
3415  |  |  *  | 
3416  |  |  * This method is the same as the C function OGR_F_GetFieldAsDateTime().  | 
3417  |  |  *  | 
3418  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3419  |  |  * @param pnYear (including century)  | 
3420  |  |  * @param pnMonth (1-12)  | 
3421  |  |  * @param pnDay (1-31)  | 
3422  |  |  * @param pnHour (0-23)  | 
3423  |  |  * @param pnMinute (0-59)  | 
3424  |  |  * @param pnSecond (0-59)  | 
3425  |  |  * @param pnTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
3426  |  |  *  | 
3427  |  |  * @return TRUE on success or FALSE on failure.  | 
3428  |  |  */  | 
3429  |  |  | 
3430  |  | int OGRFeature::GetFieldAsDateTime(int iField, int *pnYear, int *pnMonth,  | 
3431  |  |                                    int *pnDay, int *pnHour, int *pnMinute,  | 
3432  |  |                                    int *pnSecond, int *pnTZFlag) const  | 
3433  | 0  | { | 
3434  | 0  |     float fSecond = 0.0f;  | 
3435  | 0  |     const bool bRet = CPL_TO_BOOL(GetFieldAsDateTime(  | 
3436  | 0  |         iField, pnYear, pnMonth, pnDay, pnHour, pnMinute, &fSecond, pnTZFlag));  | 
3437  | 0  |     if (bRet && pnSecond)  | 
3438  | 0  |         *pnSecond = static_cast<int>(fSecond);  | 
3439  | 0  |     return bRet;  | 
3440  | 0  | }  | 
3441  |  |  | 
3442  |  | /************************************************************************/  | 
3443  |  | /*                      OGR_F_GetFieldAsDateTime()                      */  | 
3444  |  | /************************************************************************/  | 
3445  |  |  | 
3446  |  | /**  | 
3447  |  |  * \brief Fetch field value as date and time.  | 
3448  |  |  *  | 
3449  |  |  * Currently this method only works for OFTDate, OFTTime and OFTDateTime fields.  | 
3450  |  |  *  | 
3451  |  |  * This function is the same as the C++ method  | 
3452  |  |  * OGRFeature::GetFieldAsDateTime().  | 
3453  |  |  *  | 
3454  |  |  * @param hFeat handle to the feature that owned the field.  | 
3455  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3456  |  |  * @param pnYear (including century)  | 
3457  |  |  * @param pnMonth (1-12)  | 
3458  |  |  * @param pnDay (1-31)  | 
3459  |  |  * @param pnHour (0-23)  | 
3460  |  |  * @param pnMinute (0-59)  | 
3461  |  |  * @param pnSecond (0-59)  | 
3462  |  |  * @param pnTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
3463  |  |  *  | 
3464  |  |  * @return TRUE on success or FALSE on failure.  | 
3465  |  |  *  | 
3466  |  |  * @see Use OGR_F_GetFieldAsDateTimeEx() for second with millisecond accuracy.  | 
3467  |  |  */  | 
3468  |  |  | 
3469  |  | int OGR_F_GetFieldAsDateTime(OGRFeatureH hFeat, int iField, int *pnYear,  | 
3470  |  |                              int *pnMonth, int *pnDay, int *pnHour,  | 
3471  |  |                              int *pnMinute, int *pnSecond, int *pnTZFlag)  | 
3472  |  |  | 
3473  | 0  | { | 
3474  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsDateTime", 0);  | 
3475  |  |  | 
3476  | 0  |     float fSecond = 0.0f;  | 
3477  | 0  |     const bool bRet =  | 
3478  | 0  |         CPL_TO_BOOL(OGRFeature::FromHandle(hFeat)->GetFieldAsDateTime(  | 
3479  | 0  |             iField, pnYear, pnMonth, pnDay, pnHour, pnMinute, &fSecond,  | 
3480  | 0  |             pnTZFlag));  | 
3481  | 0  |     if (bRet && pnSecond)  | 
3482  | 0  |         *pnSecond = static_cast<int>(fSecond);  | 
3483  | 0  |     return bRet;  | 
3484  | 0  | }  | 
3485  |  |  | 
3486  |  | /************************************************************************/  | 
3487  |  | /*                     OGR_F_GetFieldAsDateTimeEx()                     */  | 
3488  |  | /************************************************************************/  | 
3489  |  |  | 
3490  |  | /**  | 
3491  |  |  * \brief Fetch field value as date and time.  | 
3492  |  |  *  | 
3493  |  |  * Currently this method only works for OFTDate, OFTTime and OFTDateTime fields.  | 
3494  |  |  *  | 
3495  |  |  * This function is the same as the C++ method  | 
3496  |  |  * OGRFeature::GetFieldAsDateTime().  | 
3497  |  |  *  | 
3498  |  |  * @param hFeat handle to the feature that owned the field.  | 
3499  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3500  |  |  * @param pnYear (including century)  | 
3501  |  |  * @param pnMonth (1-12)  | 
3502  |  |  * @param pnDay (1-31)  | 
3503  |  |  * @param pnHour (0-23)  | 
3504  |  |  * @param pnMinute (0-59)  | 
3505  |  |  * @param pfSecond (0-59 with millisecond accuracy)  | 
3506  |  |  * @param pnTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
3507  |  |  *  | 
3508  |  |  * @return TRUE on success or FALSE on failure.  | 
3509  |  |  * @since GDAL 2.0  | 
3510  |  |  */  | 
3511  |  |  | 
3512  |  | int OGR_F_GetFieldAsDateTimeEx(OGRFeatureH hFeat, int iField, int *pnYear,  | 
3513  |  |                                int *pnMonth, int *pnDay, int *pnHour,  | 
3514  |  |                                int *pnMinute, float *pfSecond, int *pnTZFlag)  | 
3515  |  |  | 
3516  | 0  | { | 
3517  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFieldAsDateTimeEx", 0);  | 
3518  |  |  | 
3519  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFieldAsDateTime(  | 
3520  | 0  |         iField, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);  | 
3521  | 0  | }  | 
3522  |  |  | 
3523  |  | /************************************************************************/  | 
3524  |  | /*                        OGRFeatureGetIntegerValue()                   */  | 
3525  |  | /************************************************************************/  | 
3526  |  |  | 
3527  |  | static int OGRFeatureGetIntegerValue(const OGRFeatureDefn *poDefn,  | 
3528  |  |                                      const OGRFieldDefn *poFDefn, int nValue)  | 
3529  | 0  | { | 
3530  | 0  |     if (poFDefn->GetSubType() == OFSTBoolean && nValue != 0 && nValue != 1)  | 
3531  | 0  |     { | 
3532  | 0  |         CPLError(CE_Warning, CPLE_AppDefined,  | 
3533  | 0  |                  "Field %s.%s: Only 0 or 1 should be passed for a OFSTBoolean "  | 
3534  | 0  |                  "subtype. Considering non-zero value %d as 1.",  | 
3535  | 0  |                  poDefn->GetName(), poFDefn->GetNameRef(), nValue);  | 
3536  | 0  |         nValue = 1;  | 
3537  | 0  |     }  | 
3538  | 0  |     else if (poFDefn->GetSubType() == OFSTInt16)  | 
3539  | 0  |     { | 
3540  | 0  |         if (nValue < -32768)  | 
3541  | 0  |         { | 
3542  | 0  |             CPLError(CE_Warning, CPLE_AppDefined,  | 
3543  | 0  |                      "Field %s.%s: Out-of-range value for a OFSTInt16 subtype. "  | 
3544  | 0  |                      "Considering value %d as -32768.",  | 
3545  | 0  |                      poDefn->GetName(), poFDefn->GetNameRef(), nValue);  | 
3546  | 0  |             nValue = -32768;  | 
3547  | 0  |         }  | 
3548  | 0  |         else if (nValue > 32767)  | 
3549  | 0  |         { | 
3550  | 0  |             CPLError(CE_Warning, CPLE_AppDefined,  | 
3551  | 0  |                      "Field %s.%s: Out-of-range value for a OFSTInt16 subtype. "  | 
3552  | 0  |                      "Considering value %d as 32767.",  | 
3553  | 0  |                      poDefn->GetName(), poFDefn->GetNameRef(), nValue);  | 
3554  | 0  |             nValue = 32767;  | 
3555  | 0  |         }  | 
3556  | 0  |     }  | 
3557  | 0  |     return nValue;  | 
3558  | 0  | }  | 
3559  |  |  | 
3560  |  | /************************************************************************/  | 
3561  |  | /*                        GetFieldAsSerializedJSon()                   */  | 
3562  |  | /************************************************************************/  | 
3563  |  |  | 
3564  |  | /**  | 
3565  |  |  * \brief Fetch field value as a serialized JSon object.  | 
3566  |  |  *  | 
3567  |  |  * Currently this method only works for OFTString with OFSTJSON subtype,  | 
3568  |  |  * OFTStringList, OFTIntegerList,  | 
3569  |  |  * OFTInteger64List and OFTRealList  | 
3570  |  |  *  | 
3571  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3572  |  |  *  | 
3573  |  |  * @return a string that must be de-allocate with CPLFree()  | 
3574  |  |  * @since GDAL 2.2  | 
3575  |  |  */  | 
3576  |  | char *OGRFeature::GetFieldAsSerializedJSon(int iField) const  | 
3577  |  |  | 
3578  | 0  | { | 
3579  | 0  |     const int iSpecialField = iField - poDefn->GetFieldCountUnsafe();  | 
3580  | 0  |     if (iSpecialField >= 0)  | 
3581  | 0  |     { | 
3582  | 0  |         return nullptr;  | 
3583  | 0  |     }  | 
3584  |  |  | 
3585  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3586  |  | 
  | 
3587  | 0  |     if (poFDefn == nullptr)  | 
3588  | 0  |         return nullptr;  | 
3589  |  |  | 
3590  | 0  |     if (!IsFieldSetAndNotNullUnsafe(iField))  | 
3591  | 0  |         return nullptr;  | 
3592  |  |  | 
3593  | 0  |     char *pszRet = nullptr;  | 
3594  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
3595  | 0  |     if (eType == OFTString && poFDefn->GetSubType() == OFSTJSON)  | 
3596  | 0  |     { | 
3597  | 0  |         if (pauFields[iField].String[0] != '[' &&  | 
3598  | 0  |             pauFields[iField].String[0] != '{' && | 
3599  | 0  |             strcmp(pauFields[iField].String, "true") != 0 &&  | 
3600  | 0  |             strcmp(pauFields[iField].String, "false") != 0 &&  | 
3601  | 0  |             CPLGetValueType(pauFields[iField].String) == CPL_VALUE_STRING)  | 
3602  | 0  |         { | 
3603  | 0  |             pszRet = CPLStrdup(('"' + | 
3604  | 0  |                                 CPLString(pauFields[iField].String)  | 
3605  | 0  |                                     .replaceAll('\\', "\\\\") | 
3606  | 0  |                                     .replaceAll('"', "\\\"") + | 
3607  | 0  |                                 '"')  | 
3608  | 0  |                                    .c_str());  | 
3609  | 0  |         }  | 
3610  | 0  |         else  | 
3611  | 0  |         { | 
3612  | 0  |             pszRet = CPLStrdup(pauFields[iField].String);  | 
3613  | 0  |         }  | 
3614  | 0  |     }  | 
3615  | 0  |     else if (eType == OFTStringList)  | 
3616  | 0  |     { | 
3617  | 0  |         char **papszValues = GetFieldAsStringList(iField);  | 
3618  | 0  |         if (papszValues == nullptr)  | 
3619  | 0  |         { | 
3620  | 0  |             pszRet = CPLStrdup("[]"); | 
3621  | 0  |         }  | 
3622  | 0  |         else  | 
3623  | 0  |         { | 
3624  | 0  |             json_object *poObj = json_object_new_array();  | 
3625  | 0  |             for (int i = 0; papszValues[i] != nullptr; i++)  | 
3626  | 0  |             { | 
3627  | 0  |                 json_object_array_add(poObj,  | 
3628  | 0  |                                       json_object_new_string(papszValues[i]));  | 
3629  | 0  |             }  | 
3630  | 0  |             pszRet = CPLStrdup(json_object_to_json_string(poObj));  | 
3631  | 0  |             json_object_put(poObj);  | 
3632  | 0  |         }  | 
3633  | 0  |     }  | 
3634  | 0  |     else if (eType == OFTIntegerList)  | 
3635  | 0  |     { | 
3636  | 0  |         json_object *poObj = json_object_new_array();  | 
3637  | 0  |         int nCount = 0;  | 
3638  | 0  |         const int *panValues = GetFieldAsIntegerList(iField, &nCount);  | 
3639  | 0  |         if (poFDefn->GetSubType() == OFSTBoolean)  | 
3640  | 0  |         { | 
3641  | 0  |             for (int i = 0; i < nCount; i++)  | 
3642  | 0  |             { | 
3643  | 0  |                 json_object_array_add(  | 
3644  | 0  |                     poObj, json_object_new_boolean(panValues[i] != 0));  | 
3645  | 0  |             }  | 
3646  | 0  |         }  | 
3647  | 0  |         else  | 
3648  | 0  |         { | 
3649  | 0  |             for (int i = 0; i < nCount; i++)  | 
3650  | 0  |             { | 
3651  | 0  |                 json_object_array_add(poObj, json_object_new_int(panValues[i]));  | 
3652  | 0  |             }  | 
3653  | 0  |         }  | 
3654  | 0  |         pszRet = CPLStrdup(json_object_to_json_string(poObj));  | 
3655  | 0  |         json_object_put(poObj);  | 
3656  | 0  |     }  | 
3657  | 0  |     else if (eType == OFTInteger64List)  | 
3658  | 0  |     { | 
3659  | 0  |         json_object *poObj = json_object_new_array();  | 
3660  | 0  |         int nCount = 0;  | 
3661  | 0  |         const GIntBig *panValues = GetFieldAsInteger64List(iField, &nCount);  | 
3662  | 0  |         for (int i = 0; i < nCount; i++)  | 
3663  | 0  |         { | 
3664  | 0  |             json_object_array_add(poObj, json_object_new_int64(panValues[i]));  | 
3665  | 0  |         }  | 
3666  | 0  |         pszRet = CPLStrdup(json_object_to_json_string(poObj));  | 
3667  | 0  |         json_object_put(poObj);  | 
3668  | 0  |     }  | 
3669  | 0  |     else if (eType == OFTRealList)  | 
3670  | 0  |     { | 
3671  | 0  |         json_object *poObj = json_object_new_array();  | 
3672  | 0  |         int nCount = 0;  | 
3673  | 0  |         const double *padfValues = GetFieldAsDoubleList(iField, &nCount);  | 
3674  | 0  |         for (int i = 0; i < nCount; i++)  | 
3675  | 0  |         { | 
3676  | 0  |             json_object_array_add(poObj, json_object_new_double(padfValues[i]));  | 
3677  | 0  |         }  | 
3678  | 0  |         pszRet = CPLStrdup(json_object_to_json_string(poObj));  | 
3679  | 0  |         json_object_put(poObj);  | 
3680  | 0  |     }  | 
3681  |  | 
  | 
3682  | 0  |     return pszRet;  | 
3683  | 0  | }  | 
3684  |  |  | 
3685  |  | /************************************************************************/  | 
3686  |  | /*                              SetField()                              */  | 
3687  |  | /************************************************************************/  | 
3688  |  |  | 
3689  |  | /**  | 
3690  |  |  * \fn OGRFeature::SetField( const char* pszFName, int nValue )  | 
3691  |  |  * \brief Set field to integer value.  | 
3692  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
3693  |  |  * fields will be assigned a string representation of the value, but not  | 
3694  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
3695  |  |  * field types may be unaffected.  | 
3696  |  |  *  | 
3697  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
3698  |  |  * this object comes from a layer and the modifications must be serialized back  | 
3699  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
3700  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
3701  |  |  *  | 
3702  |  |  * @param pszFName the name of the field to set.  | 
3703  |  |  * @param nValue the value to assign.  | 
3704  |  |  */  | 
3705  |  |  | 
3706  |  | /**  | 
3707  |  |  * \brief Set field to integer value.  | 
3708  |  |  *  | 
3709  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
3710  |  |  * fields will be assigned a string representation of the value, but not  | 
3711  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
3712  |  |  * field types may be unaffected.  | 
3713  |  |  *  | 
3714  |  |  * This method is the same as the C function OGR_F_SetFieldInteger().  | 
3715  |  |  *  | 
3716  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
3717  |  |  * this object comes from a layer and the modifications must be serialized back  | 
3718  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
3719  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
3720  |  |  *  | 
3721  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3722  |  |  * @param nValue the value to assign.  | 
3723  |  |  */  | 
3724  |  |  | 
3725  |  | void OGRFeature::SetField(int iField, int nValue)  | 
3726  |  |  | 
3727  | 0  | { | 
3728  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3729  |  | 
  | 
3730  | 0  |     if (poFDefn == nullptr)  | 
3731  | 0  |         return;  | 
3732  |  |  | 
3733  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
3734  | 0  |     if (eType == OFTInteger)  | 
3735  | 0  |     { | 
3736  | 0  |         pauFields[iField].Integer =  | 
3737  | 0  |             OGRFeatureGetIntegerValue(poDefn, poFDefn, nValue);  | 
3738  | 0  |         pauFields[iField].Set.nMarker2 = 0;  | 
3739  | 0  |         pauFields[iField].Set.nMarker3 = 0;  | 
3740  | 0  |     }  | 
3741  | 0  |     else if (eType == OFTInteger64)  | 
3742  | 0  |     { | 
3743  | 0  |         pauFields[iField].Integer64 =  | 
3744  | 0  |             OGRFeatureGetIntegerValue(poDefn, poFDefn, nValue);  | 
3745  | 0  |     }  | 
3746  | 0  |     else if (eType == OFTReal)  | 
3747  | 0  |     { | 
3748  | 0  |         pauFields[iField].Real = nValue;  | 
3749  | 0  |     }  | 
3750  | 0  |     else if (eType == OFTIntegerList)  | 
3751  | 0  |     { | 
3752  | 0  |         SetField(iField, 1, &nValue);  | 
3753  | 0  |     }  | 
3754  | 0  |     else if (eType == OFTInteger64List)  | 
3755  | 0  |     { | 
3756  | 0  |         GIntBig nVal64 = nValue;  | 
3757  | 0  |         SetField(iField, 1, &nVal64);  | 
3758  | 0  |     }  | 
3759  | 0  |     else if (eType == OFTRealList)  | 
3760  | 0  |     { | 
3761  | 0  |         double dfValue = nValue;  | 
3762  | 0  |         SetField(iField, 1, &dfValue);  | 
3763  | 0  |     }  | 
3764  | 0  |     else if (eType == OFTString)  | 
3765  | 0  |     { | 
3766  | 0  |         char szTempBuffer[64] = {}; | 
3767  |  | 
  | 
3768  | 0  |         snprintf(szTempBuffer, sizeof(szTempBuffer), "%d", nValue);  | 
3769  |  | 
  | 
3770  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
3771  | 0  |             CPLFree(pauFields[iField].String);  | 
3772  |  | 
  | 
3773  | 0  |         pauFields[iField].String = VSI_STRDUP_VERBOSE(szTempBuffer);  | 
3774  | 0  |         if (pauFields[iField].String == nullptr)  | 
3775  | 0  |         { | 
3776  | 0  |             OGR_RawField_SetUnset(&pauFields[iField]);  | 
3777  | 0  |         }  | 
3778  | 0  |     }  | 
3779  | 0  |     else if (eType == OFTStringList)  | 
3780  | 0  |     { | 
3781  | 0  |         char szTempBuffer[64] = {}; | 
3782  |  | 
  | 
3783  | 0  |         snprintf(szTempBuffer, sizeof(szTempBuffer), "%d", nValue);  | 
3784  | 0  |         char *apszValues[2] = {szTempBuffer, nullptr}; | 
3785  | 0  |         SetField(iField, apszValues);  | 
3786  | 0  |     }  | 
3787  | 0  |     else  | 
3788  | 0  |     { | 
3789  |  |         // Do nothing for other field types.  | 
3790  | 0  |     }  | 
3791  | 0  | }  | 
3792  |  |  | 
3793  |  | /************************************************************************/  | 
3794  |  | /*                       OGR_F_SetFieldInteger()                        */  | 
3795  |  | /************************************************************************/  | 
3796  |  |  | 
3797  |  | /**  | 
3798  |  |  * \brief Set field to integer value.  | 
3799  |  |  *  | 
3800  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
3801  |  |  * fields will be assigned a string representation of the value, but not  | 
3802  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
3803  |  |  * field types may be unaffected.  | 
3804  |  |  *  | 
3805  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
3806  |  |  *  | 
3807  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
3808  |  |  * this object comes from a layer and the modifications must be serialized back  | 
3809  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
3810  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
3811  |  |  *  | 
3812  |  |  * @param hFeat handle to the feature that owned the field.  | 
3813  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3814  |  |  * @param nValue the value to assign.  | 
3815  |  |  */  | 
3816  |  |  | 
3817  |  | void OGR_F_SetFieldInteger(OGRFeatureH hFeat, int iField, int nValue)  | 
3818  |  |  | 
3819  | 0  | { | 
3820  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldInteger");  | 
3821  |  |  | 
3822  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, nValue);  | 
3823  | 0  | }  | 
3824  |  |  | 
3825  |  | /************************************************************************/  | 
3826  |  | /*                              SetField()                              */  | 
3827  |  | /************************************************************************/  | 
3828  |  |  | 
3829  |  | /**  | 
3830  |  |  * \fn OGRFeature::SetField( const char* pszFName, GIntBig nValue )  | 
3831  |  |  * \brief Set field to 64 bit integer value.  | 
3832  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
3833  |  |  * fields will be assigned a string representation of the value, but not  | 
3834  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
3835  |  |  * field types may be unaffected.  | 
3836  |  |  *  | 
3837  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
3838  |  |  * this object comes from a layer and the modifications must be serialized back  | 
3839  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
3840  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
3841  |  |  *  | 
3842  |  |  * @param pszFName the name of the field to set.  | 
3843  |  |  * @param nValue the value to assign.  | 
3844  |  |  */  | 
3845  |  |  | 
3846  |  | /**  | 
3847  |  |  * \brief Set field to 64 bit integer value.  | 
3848  |  |  *  | 
3849  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
3850  |  |  * fields will be assigned a string representation of the value, but not  | 
3851  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
3852  |  |  * field types may be unaffected.  | 
3853  |  |  *  | 
3854  |  |  * This method is the same as the C function OGR_F_SetFieldInteger64().  | 
3855  |  |  *  | 
3856  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
3857  |  |  * this object comes from a layer and the modifications must be serialized back  | 
3858  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
3859  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
3860  |  |  *  | 
3861  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3862  |  |  * @param nValue the value to assign.  | 
3863  |  |  * @since GDAL 2.0  | 
3864  |  |  */  | 
3865  |  |  | 
3866  |  | void OGRFeature::SetField(int iField, GIntBig nValue)  | 
3867  |  |  | 
3868  | 0  | { | 
3869  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
3870  |  | 
  | 
3871  | 0  |     if (poFDefn == nullptr)  | 
3872  | 0  |         return;  | 
3873  |  |  | 
3874  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
3875  | 0  |     if (eType == OFTInteger)  | 
3876  | 0  |     { | 
3877  | 0  |         const int nVal32 = nValue < INT_MIN   ? INT_MIN  | 
3878  | 0  |                            : nValue > INT_MAX ? INT_MAX  | 
3879  | 0  |                                               : static_cast<int>(nValue);  | 
3880  |  | 
  | 
3881  | 0  |         if (nVal32 != nValue)  | 
3882  | 0  |         { | 
3883  | 0  |             CPLError(  | 
3884  | 0  |                 CE_Warning, CPLE_AppDefined,  | 
3885  | 0  |                 "Field %s.%s: integer overflow occurred when trying to set "  | 
3886  | 0  |                 "%" PRId64 " as 32 bit integer.",  | 
3887  | 0  |                 poDefn->GetName(), poFDefn->GetNameRef(),  | 
3888  | 0  |                 static_cast<int64_t>(nValue));  | 
3889  | 0  |         }  | 
3890  | 0  |         SetField(iField, nVal32);  | 
3891  | 0  |     }  | 
3892  | 0  |     else if (eType == OFTInteger64)  | 
3893  | 0  |     { | 
3894  | 0  |         pauFields[iField].Integer64 = nValue;  | 
3895  | 0  |     }  | 
3896  | 0  |     else if (eType == OFTReal)  | 
3897  | 0  |     { | 
3898  | 0  |         pauFields[iField].Real = static_cast<double>(nValue);  | 
3899  |  |         // Values in the range [INT64_MAX - 1023, INT64_MAX - 1]  | 
3900  |  |         // get converted to a double that once cast to int64_t is  | 
3901  |  |         // INT64_MAX + 1 ...  | 
3902  | 0  |         if (pauFields[iField].Real >=  | 
3903  | 0  |                 static_cast<double>(std::numeric_limits<int64_t>::max()) ||  | 
3904  | 0  |             static_cast<GIntBig>(pauFields[iField].Real) != nValue)  | 
3905  | 0  |         { | 
3906  | 0  |             CPLError(  | 
3907  | 0  |                 CE_Warning, CPLE_AppDefined,  | 
3908  | 0  |                 "Field %s.%s: Lossy conversion occurred when trying to set "  | 
3909  | 0  |                 "a real field from 64 bit integer value %" PRId64 ".",  | 
3910  | 0  |                 poDefn->GetName(), poFDefn->GetNameRef(),  | 
3911  | 0  |                 static_cast<int64_t>(nValue));  | 
3912  | 0  |         }  | 
3913  | 0  |     }  | 
3914  | 0  |     else if (eType == OFTIntegerList)  | 
3915  | 0  |     { | 
3916  | 0  |         int nVal32 = nValue < INT_MIN   ? INT_MIN  | 
3917  | 0  |                      : nValue > INT_MAX ? INT_MAX  | 
3918  | 0  |                                         : static_cast<int>(nValue);  | 
3919  |  | 
  | 
3920  | 0  |         if (nVal32 != nValue)  | 
3921  | 0  |         { | 
3922  | 0  |             CPLError(  | 
3923  | 0  |                 CE_Warning, CPLE_AppDefined,  | 
3924  | 0  |                 "Field %s.%s: Integer overflow occurred when trying to set "  | 
3925  | 0  |                 "%" PRId64 " as 32 bit value.",  | 
3926  | 0  |                 poDefn->GetName(), poFDefn->GetNameRef(),  | 
3927  | 0  |                 static_cast<int64_t>(nValue));  | 
3928  | 0  |         }  | 
3929  | 0  |         SetField(iField, 1, &nVal32);  | 
3930  | 0  |     }  | 
3931  | 0  |     else if (eType == OFTInteger64List)  | 
3932  | 0  |     { | 
3933  | 0  |         SetField(iField, 1, &nValue);  | 
3934  | 0  |     }  | 
3935  | 0  |     else if (eType == OFTRealList)  | 
3936  | 0  |     { | 
3937  | 0  |         double dfValue = static_cast<double>(nValue);  | 
3938  | 0  |         SetField(iField, 1, &dfValue);  | 
3939  | 0  |     }  | 
3940  | 0  |     else if (eType == OFTString)  | 
3941  | 0  |     { | 
3942  | 0  |         char szTempBuffer[64] = {}; | 
3943  |  | 
  | 
3944  | 0  |         CPLsnprintf(szTempBuffer, sizeof(szTempBuffer), CPL_FRMT_GIB, nValue);  | 
3945  |  | 
  | 
3946  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
3947  | 0  |             CPLFree(pauFields[iField].String);  | 
3948  |  | 
  | 
3949  | 0  |         pauFields[iField].String = VSI_STRDUP_VERBOSE(szTempBuffer);  | 
3950  | 0  |         if (pauFields[iField].String == nullptr)  | 
3951  | 0  |         { | 
3952  | 0  |             OGR_RawField_SetUnset(&pauFields[iField]);  | 
3953  | 0  |         }  | 
3954  | 0  |     }  | 
3955  | 0  |     else if (eType == OFTStringList)  | 
3956  | 0  |     { | 
3957  | 0  |         char szTempBuffer[64] = {}; | 
3958  |  | 
  | 
3959  | 0  |         CPLsnprintf(szTempBuffer, sizeof(szTempBuffer), CPL_FRMT_GIB, nValue);  | 
3960  | 0  |         char *apszValues[2] = {szTempBuffer, nullptr}; | 
3961  | 0  |         SetField(iField, apszValues);  | 
3962  | 0  |     }  | 
3963  | 0  |     else  | 
3964  | 0  |     { | 
3965  |  |         // Do nothing for other field types.  | 
3966  | 0  |     }  | 
3967  | 0  | }  | 
3968  |  |  | 
3969  |  | /************************************************************************/  | 
3970  |  | /*                      OGR_F_SetFieldInteger64()                       */  | 
3971  |  | /************************************************************************/  | 
3972  |  |  | 
3973  |  | /**  | 
3974  |  |  * \brief Set field to 64 bit integer value.  | 
3975  |  |  *  | 
3976  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
3977  |  |  * fields will be assigned a string representation of the value, but not  | 
3978  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
3979  |  |  * field types may be unaffected.  | 
3980  |  |  *  | 
3981  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
3982  |  |  *  | 
3983  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
3984  |  |  * this object comes from a layer and the modifications must be serialized back  | 
3985  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
3986  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
3987  |  |  *  | 
3988  |  |  * @param hFeat handle to the feature that owned the field.  | 
3989  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
3990  |  |  * @param nValue the value to assign.  | 
3991  |  |  * @since GDAL 2.0  | 
3992  |  |  */  | 
3993  |  |  | 
3994  |  | void OGR_F_SetFieldInteger64(OGRFeatureH hFeat, int iField, GIntBig nValue)  | 
3995  |  |  | 
3996  | 0  | { | 
3997  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldInteger64");  | 
3998  |  |  | 
3999  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, nValue);  | 
4000  | 0  | }  | 
4001  |  |  | 
4002  |  | /************************************************************************/  | 
4003  |  | /*                              SetField()                              */  | 
4004  |  | /************************************************************************/  | 
4005  |  |  | 
4006  |  | /**  | 
4007  |  |  * \fn OGRFeature::SetField( const char* pszFName, double dfValue )  | 
4008  |  |  * \brief Set field to double value.  | 
4009  |  |  *  | 
4010  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
4011  |  |  * fields will be assigned a string representation of the value, but not  | 
4012  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
4013  |  |  * field types may be unaffected.  | 
4014  |  |  *  | 
4015  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4016  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4017  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4018  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4019  |  |  *  | 
4020  |  |  * @param pszFName the name of the field to set.  | 
4021  |  |  * @param dfValue the value to assign.  | 
4022  |  |  */  | 
4023  |  |  | 
4024  |  | /**  | 
4025  |  |  * \brief Set field to double value.  | 
4026  |  |  *  | 
4027  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
4028  |  |  * fields will be assigned a string representation of the value, but not  | 
4029  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
4030  |  |  * field types may be unaffected.  | 
4031  |  |  *  | 
4032  |  |  * This method is the same as the C function OGR_F_SetFieldDouble().  | 
4033  |  |  *  | 
4034  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4035  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4036  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4037  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4038  |  |  *  | 
4039  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
4040  |  |  * @param dfValue the value to assign.  | 
4041  |  |  */  | 
4042  |  |  | 
4043  |  | void OGRFeature::SetField(int iField, double dfValue)  | 
4044  |  |  | 
4045  | 0  | { | 
4046  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
4047  |  | 
  | 
4048  | 0  |     if (poFDefn == nullptr)  | 
4049  | 0  |         return;  | 
4050  |  |  | 
4051  | 0  |     const OGRFieldType eType = poFDefn->GetType();  | 
4052  | 0  |     if (eType == OFTReal)  | 
4053  | 0  |     { | 
4054  |  |         // if( poFDefn->GetSubType() == OFSTFloat32 &&  | 
4055  |  |         //     dfValue != (double)(float)dfValue )  | 
4056  |  |         // { | 
4057  |  |         //     CPLError(CE_Warning, CPLE_AppDefined,  | 
4058  |  |         //              "Passed value cannot be exactly representing as "  | 
4059  |  |         //              "a single-precision floating point value.");  | 
4060  |  |         //     dfValue = (double)(float)dfValue;  | 
4061  |  |         // }  | 
4062  | 0  |         pauFields[iField].Real = dfValue;  | 
4063  | 0  |     }  | 
4064  | 0  |     else if (eType == OFTInteger)  | 
4065  | 0  |     { | 
4066  | 0  |         constexpr int nMin = std::numeric_limits<int>::min();  | 
4067  | 0  |         if (std::isnan(dfValue))  | 
4068  | 0  |         { | 
4069  | 0  |             pauFields[iField].Integer = nMin;  | 
4070  | 0  |             CPLError(  | 
4071  | 0  |                 CE_Warning, CPLE_AppDefined,  | 
4072  | 0  |                 "Field %s.%s: Lossy conversion occurred when trying to set "  | 
4073  | 0  |                 "32 bit integer field from real value %.17g.",  | 
4074  | 0  |                 poDefn->GetName(), poFDefn->GetNameRef(), dfValue);  | 
4075  | 0  |         }  | 
4076  | 0  |         else  | 
4077  | 0  |         { | 
4078  | 0  |             constexpr int nMax = std::numeric_limits<int>::max();  | 
4079  | 0  |             const int nVal = dfValue < nMin   ? nMin  | 
4080  | 0  |                              : dfValue > nMax ? nMax  | 
4081  | 0  |                                               : static_cast<int>(dfValue);  | 
4082  | 0  |             pauFields[iField].Integer =  | 
4083  | 0  |                 OGRFeatureGetIntegerValue(poDefn, poFDefn, nVal);  | 
4084  | 0  |             if (!(nVal == dfValue))  | 
4085  | 0  |             { | 
4086  | 0  |                 CPLError(  | 
4087  | 0  |                     CE_Warning, CPLE_AppDefined,  | 
4088  | 0  |                     "Field %s.%s: Lossy conversion occurred when trying to set "  | 
4089  | 0  |                     "32 bit integer field from real value %.17g.",  | 
4090  | 0  |                     poDefn->GetName(), poFDefn->GetNameRef(), dfValue);  | 
4091  | 0  |             }  | 
4092  | 0  |         }  | 
4093  | 0  |         pauFields[iField].Set.nMarker2 = 0;  | 
4094  | 0  |         pauFields[iField].Set.nMarker3 = 0;  | 
4095  | 0  |     }  | 
4096  | 0  |     else if (eType == OFTInteger64)  | 
4097  | 0  |     { | 
4098  | 0  |         constexpr auto nMin = std::numeric_limits<GIntBig>::min();  | 
4099  | 0  |         if (std::isnan(dfValue))  | 
4100  | 0  |         { | 
4101  | 0  |             pauFields[iField].Integer64 = nMin;  | 
4102  | 0  |             CPLError(  | 
4103  | 0  |                 CE_Warning, CPLE_AppDefined,  | 
4104  | 0  |                 "Field %s.%s: Lossy conversion occurred when trying to set "  | 
4105  | 0  |                 "64 bit integer field from real value %.17g.",  | 
4106  | 0  |                 poDefn->GetName(), poFDefn->GetNameRef(), dfValue);  | 
4107  | 0  |         }  | 
4108  | 0  |         else  | 
4109  | 0  |         { | 
4110  | 0  |             constexpr auto nMax = std::numeric_limits<GIntBig>::max();  | 
4111  | 0  |             const auto nVal = dfValue < static_cast<double>(nMin) ? nMin  | 
4112  | 0  |                               : dfValue > static_cast<double>(nMax)  | 
4113  | 0  |                                   ? nMax  | 
4114  | 0  |                                   : static_cast<GIntBig>(dfValue);  | 
4115  | 0  |             pauFields[iField].Integer64 = nVal;  | 
4116  | 0  |             if (!(static_cast<double>(nVal) == dfValue))  | 
4117  | 0  |             { | 
4118  | 0  |                 CPLError(  | 
4119  | 0  |                     CE_Warning, CPLE_AppDefined,  | 
4120  | 0  |                     "Field %s.%s: Lossy conversion occurred when trying to set "  | 
4121  | 0  |                     "64 bit integer field from real value %.17g.",  | 
4122  | 0  |                     poDefn->GetName(), poFDefn->GetNameRef(), dfValue);  | 
4123  | 0  |             }  | 
4124  | 0  |         }  | 
4125  | 0  |         pauFields[iField].Set.nMarker3 = 0;  | 
4126  | 0  |     }  | 
4127  | 0  |     else if (eType == OFTRealList)  | 
4128  | 0  |     { | 
4129  | 0  |         SetField(iField, 1, &dfValue);  | 
4130  | 0  |     }  | 
4131  | 0  |     else if (eType == OFTIntegerList)  | 
4132  | 0  |     { | 
4133  | 0  |         int nValue = static_cast<int>(dfValue);  | 
4134  | 0  |         SetField(iField, 1, &nValue);  | 
4135  | 0  |     }  | 
4136  | 0  |     else if (eType == OFTInteger64List)  | 
4137  | 0  |     { | 
4138  | 0  |         GIntBig nValue = static_cast<GIntBig>(dfValue);  | 
4139  | 0  |         SetField(iField, 1, &nValue);  | 
4140  | 0  |     }  | 
4141  | 0  |     else if (eType == OFTString)  | 
4142  | 0  |     { | 
4143  | 0  |         char szTempBuffer[128] = {}; | 
4144  |  | 
  | 
4145  | 0  |         CPLsnprintf(szTempBuffer, sizeof(szTempBuffer), "%.16g", dfValue);  | 
4146  |  | 
  | 
4147  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
4148  | 0  |             CPLFree(pauFields[iField].String);  | 
4149  |  | 
  | 
4150  | 0  |         pauFields[iField].String = VSI_STRDUP_VERBOSE(szTempBuffer);  | 
4151  | 0  |         if (pauFields[iField].String == nullptr)  | 
4152  | 0  |         { | 
4153  | 0  |             OGR_RawField_SetUnset(&pauFields[iField]);  | 
4154  | 0  |         }  | 
4155  | 0  |     }  | 
4156  | 0  |     else if (eType == OFTStringList)  | 
4157  | 0  |     { | 
4158  | 0  |         char szTempBuffer[64] = {}; | 
4159  |  | 
  | 
4160  | 0  |         CPLsnprintf(szTempBuffer, sizeof(szTempBuffer), "%.16g", dfValue);  | 
4161  | 0  |         char *apszValues[2] = {szTempBuffer, nullptr}; | 
4162  | 0  |         SetField(iField, apszValues);  | 
4163  | 0  |     }  | 
4164  | 0  |     else  | 
4165  | 0  |     { | 
4166  |  |         // Do nothing for other field types.  | 
4167  | 0  |     }  | 
4168  | 0  | }  | 
4169  |  |  | 
4170  |  | /************************************************************************/  | 
4171  |  | /*                        OGR_F_SetFieldDouble()                        */  | 
4172  |  | /************************************************************************/  | 
4173  |  |  | 
4174  |  | /**  | 
4175  |  |  * \brief Set field to double value.  | 
4176  |  |  *  | 
4177  |  |  * OFTInteger, OFTInteger64 and OFTReal fields will be set directly.  OFTString  | 
4178  |  |  * fields will be assigned a string representation of the value, but not  | 
4179  |  |  * necessarily taking into account formatting constraints on this field.  Other  | 
4180  |  |  * field types may be unaffected.  | 
4181  |  |  *  | 
4182  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
4183  |  |  *  | 
4184  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4185  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4186  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4187  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4188  |  |  *  | 
4189  |  |  * @param hFeat handle to the feature that owned the field.  | 
4190  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
4191  |  |  * @param dfValue the value to assign.  | 
4192  |  |  */  | 
4193  |  |  | 
4194  |  | void OGR_F_SetFieldDouble(OGRFeatureH hFeat, int iField, double dfValue)  | 
4195  |  |  | 
4196  | 0  | { | 
4197  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldDouble");  | 
4198  |  |  | 
4199  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, dfValue);  | 
4200  | 0  | }  | 
4201  |  |  | 
4202  |  | /************************************************************************/  | 
4203  |  | /*                              SetField()                              */  | 
4204  |  | /************************************************************************/  | 
4205  |  |  | 
4206  |  | /**  | 
4207  |  |  * \fn OGRFeature::SetField( const char* pszFName, const char * pszValue )  | 
4208  |  |  * \brief Set field to string value.  | 
4209  |  |  *  | 
4210  |  |  * OFTInteger fields will be set based on an atoi() conversion of the string.  | 
4211  |  |  * OFTInteger64 fields will be set based on an CPLAtoGIntBig() conversion of the  | 
4212  |  |  * string.  OFTReal fields will be set based on an CPLAtof() conversion of the  | 
4213  |  |  * string.  Other field types may be unaffected.  | 
4214  |  |  *  | 
4215  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4216  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4217  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4218  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4219  |  |  *  | 
4220  |  |  * @param pszFName the name of the field to set.  | 
4221  |  |  * @param pszValue the value to assign.  | 
4222  |  |  */  | 
4223  |  |  | 
4224  |  | /**  | 
4225  |  |  * \brief Set field to string value.  | 
4226  |  |  *  | 
4227  |  |  * OFTInteger fields will be set based on an atoi() conversion of the string.  | 
4228  |  |  * OFTInteger64 fields will be set based on an CPLAtoGIntBig() conversion of the  | 
4229  |  |  * string.  OFTReal fields will be set based on an CPLAtof() conversion of the  | 
4230  |  |  * string.  Other field types may be unaffected.  | 
4231  |  |  *  | 
4232  |  |  * This method is the same as the C function OGR_F_SetFieldString().  | 
4233  |  |  *  | 
4234  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4235  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4236  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4237  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4238  |  |  *  | 
4239  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
4240  |  |  * @param pszValue the value to assign.  | 
4241  |  |  */  | 
4242  |  |  | 
4243  |  | void OGRFeature::SetField(int iField, const char *pszValue)  | 
4244  |  |  | 
4245  | 0  | { | 
4246  | 0  |     static int bWarn = -1;  | 
4247  | 0  |     if (bWarn < 0)  | 
4248  | 0  |         bWarn = CPLTestBool(  | 
4249  | 0  |             CPLGetConfigOption("OGR_SETFIELD_NUMERIC_WARNING", "YES")); | 
4250  |  | 
  | 
4251  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
4252  | 0  |     if (poFDefn == nullptr)  | 
4253  | 0  |         return;  | 
4254  |  |  | 
4255  | 0  |     char *pszLast = nullptr;  | 
4256  |  | 
  | 
4257  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
4258  | 0  |     if (eType == OFTString)  | 
4259  | 0  |     { | 
4260  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
4261  | 0  |             CPLFree(pauFields[iField].String);  | 
4262  |  | 
  | 
4263  | 0  |         pauFields[iField].String = VSI_STRDUP_VERBOSE(pszValue ? pszValue : "");  | 
4264  | 0  |         if (pauFields[iField].String == nullptr)  | 
4265  | 0  |         { | 
4266  | 0  |             OGR_RawField_SetUnset(&pauFields[iField]);  | 
4267  | 0  |         }  | 
4268  | 0  |     }  | 
4269  | 0  |     else if (eType == OFTInteger)  | 
4270  | 0  |     { | 
4271  | 0  |         if (poFDefn->GetSubType() == OFSTBoolean)  | 
4272  | 0  |         { | 
4273  | 0  |             constexpr char DIGIT_ZERO = '0';  | 
4274  | 0  |             if ((pszValue[0] == '1' && pszValue[1] == '\0') ||  | 
4275  | 0  |                 EQUAL(pszValue, "true") || EQUAL(pszValue, "on") ||  | 
4276  | 0  |                 EQUAL(pszValue, "yes"))  | 
4277  | 0  |             { | 
4278  | 0  |                 pauFields[iField].Integer = 1;  | 
4279  | 0  |                 pauFields[iField].Set.nMarker2 = 0;  | 
4280  | 0  |                 pauFields[iField].Set.nMarker3 = 0;  | 
4281  | 0  |             }  | 
4282  | 0  |             else if ((pszValue[0] == DIGIT_ZERO && pszValue[1] == '\0') ||  | 
4283  | 0  |                      EQUAL(pszValue, "false") || EQUAL(pszValue, "off") ||  | 
4284  | 0  |                      EQUAL(pszValue, "no"))  | 
4285  | 0  |             { | 
4286  | 0  |                 pauFields[iField].Integer = 0;  | 
4287  | 0  |                 pauFields[iField].Set.nMarker2 = 0;  | 
4288  | 0  |                 pauFields[iField].Set.nMarker3 = 0;  | 
4289  | 0  |             }  | 
4290  | 0  |             else  | 
4291  | 0  |             { | 
4292  | 0  |                 if (CPLGetValueType(pszValue) == CPL_VALUE_STRING)  | 
4293  | 0  |                 { | 
4294  | 0  |                     CPLError(CE_Warning, CPLE_AppDefined,  | 
4295  | 0  |                              "Invalid value '%s' for boolean field %s.%s. "  | 
4296  | 0  |                              "Assuming it to be false.",  | 
4297  | 0  |                              pszValue, poDefn->GetName(),  | 
4298  | 0  |                              poFDefn->GetNameRef());  | 
4299  | 0  |                     pauFields[iField].Integer = 0;  | 
4300  | 0  |                     pauFields[iField].Set.nMarker2 = 0;  | 
4301  | 0  |                     pauFields[iField].Set.nMarker3 = 0;  | 
4302  | 0  |                 }  | 
4303  | 0  |                 else  | 
4304  | 0  |                 { | 
4305  | 0  |                     CPLError(CE_Warning, CPLE_AppDefined,  | 
4306  | 0  |                              "Invalid value '%s' for boolean field %s.%s. "  | 
4307  | 0  |                              "Assuming it to be true.",  | 
4308  | 0  |                              pszValue, poDefn->GetName(),  | 
4309  | 0  |                              poFDefn->GetNameRef());  | 
4310  | 0  |                     pauFields[iField].Integer = 1;  | 
4311  | 0  |                     pauFields[iField].Set.nMarker2 = 0;  | 
4312  | 0  |                     pauFields[iField].Set.nMarker3 = 0;  | 
4313  | 0  |                 }  | 
4314  | 0  |             }  | 
4315  | 0  |         }  | 
4316  | 0  |         else  | 
4317  | 0  |         { | 
4318  |  |             // As allowed by C standard, some systems like MSVC do not reset errno.  | 
4319  | 0  |             errno = 0;  | 
4320  |  | 
  | 
4321  | 0  |             long long nVal64 = std::strtoll(pszValue, &pszLast, 10);  | 
4322  | 0  |             int nVal32 = nVal64 > INT_MAX   ? INT_MAX  | 
4323  | 0  |                          : nVal64 < INT_MIN ? INT_MIN  | 
4324  | 0  |                                             : static_cast<int>(nVal64);  | 
4325  | 0  |             pauFields[iField].Integer =  | 
4326  | 0  |                 OGRFeatureGetIntegerValue(poDefn, poFDefn, nVal32);  | 
4327  | 0  |             if (bWarn && pauFields[iField].Integer == nVal32 &&  | 
4328  | 0  |                 (errno == ERANGE || nVal32 != nVal64 || !pszLast || *pszLast))  | 
4329  | 0  |                 CPLError(CE_Warning, CPLE_AppDefined,  | 
4330  | 0  |                          "Value '%s' of field %s.%s parsed incompletely to "  | 
4331  | 0  |                          "integer %d.",  | 
4332  | 0  |                          pszValue, poDefn->GetName(), poFDefn->GetNameRef(),  | 
4333  | 0  |                          pauFields[iField].Integer);  | 
4334  | 0  |             pauFields[iField].Set.nMarker2 = 0;  | 
4335  | 0  |             pauFields[iField].Set.nMarker3 = 0;  | 
4336  | 0  |         }  | 
4337  | 0  |     }  | 
4338  | 0  |     else if (eType == OFTInteger64)  | 
4339  | 0  |     { | 
4340  | 0  |         pauFields[iField].Integer64 = CPLAtoGIntBigEx(pszValue, bWarn, nullptr);  | 
4341  | 0  |         pauFields[iField].Set.nMarker3 = 0;  | 
4342  | 0  |     }  | 
4343  | 0  |     else if (eType == OFTReal)  | 
4344  | 0  |     { | 
4345  | 0  |         pauFields[iField].Real = CPLStrtod(pszValue, &pszLast);  | 
4346  | 0  |         if (bWarn && (!pszLast || *pszLast))  | 
4347  | 0  |             CPLError(  | 
4348  | 0  |                 CE_Warning, CPLE_AppDefined,  | 
4349  | 0  |                 "Value '%s' of field %s.%s parsed incompletely to real %.16g.",  | 
4350  | 0  |                 pszValue, poDefn->GetName(), poFDefn->GetNameRef(),  | 
4351  | 0  |                 pauFields[iField].Real);  | 
4352  | 0  |     }  | 
4353  | 0  |     else if (eType == OFTDate || eType == OFTTime || eType == OFTDateTime)  | 
4354  | 0  |     { | 
4355  | 0  |         OGRField sWrkField;  | 
4356  |  | 
  | 
4357  | 0  |         if (OGRParseDate(pszValue, &sWrkField, 0))  | 
4358  | 0  |             memcpy(pauFields + iField, &sWrkField, sizeof(sWrkField));  | 
4359  | 0  |     }  | 
4360  | 0  |     else if (eType == OFTIntegerList || eType == OFTInteger64List ||  | 
4361  | 0  |              eType == OFTRealList)  | 
4362  | 0  |     { | 
4363  | 0  |         json_object *poJSonObj = nullptr;  | 
4364  | 0  |         if (pszValue[0] == '[' && pszValue[strlen(pszValue) - 1] == ']' &&  | 
4365  | 0  |             OGRJSonParse(pszValue, &poJSonObj, false))  | 
4366  | 0  |         { | 
4367  | 0  |             const auto nLength = json_object_array_length(poJSonObj);  | 
4368  | 0  |             if (eType == OFTIntegerList && nLength > 0)  | 
4369  | 0  |             { | 
4370  | 0  |                 std::vector<int> anValues;  | 
4371  | 0  |                 for (auto i = decltype(nLength){0}; i < nLength; i++) | 
4372  | 0  |                 { | 
4373  | 0  |                     json_object *poItem =  | 
4374  | 0  |                         json_object_array_get_idx(poJSonObj, i);  | 
4375  | 0  |                     anValues.push_back(json_object_get_int(poItem));  | 
4376  | 0  |                 }  | 
4377  | 0  |                 SetField(iField, static_cast<int>(nLength), &(anValues[0]));  | 
4378  | 0  |             }  | 
4379  | 0  |             else if (eType == OFTInteger64List && nLength > 0)  | 
4380  | 0  |             { | 
4381  | 0  |                 std::vector<GIntBig> anValues;  | 
4382  | 0  |                 for (auto i = decltype(nLength){0}; i < nLength; i++) | 
4383  | 0  |                 { | 
4384  | 0  |                     json_object *poItem =  | 
4385  | 0  |                         json_object_array_get_idx(poJSonObj, i);  | 
4386  | 0  |                     anValues.push_back(json_object_get_int64(poItem));  | 
4387  | 0  |                 }  | 
4388  | 0  |                 SetField(iField, static_cast<int>(nLength), &(anValues[0]));  | 
4389  | 0  |             }  | 
4390  | 0  |             else if (eType == OFTRealList && nLength > 0)  | 
4391  | 0  |             { | 
4392  | 0  |                 std::vector<double> adfValues;  | 
4393  | 0  |                 for (auto i = decltype(nLength){0}; i < nLength; i++) | 
4394  | 0  |                 { | 
4395  | 0  |                     json_object *poItem =  | 
4396  | 0  |                         json_object_array_get_idx(poJSonObj, i);  | 
4397  | 0  |                     adfValues.push_back(json_object_get_double(poItem));  | 
4398  | 0  |                 }  | 
4399  | 0  |                 SetField(iField, static_cast<int>(nLength), &(adfValues[0]));  | 
4400  | 0  |             }  | 
4401  |  | 
  | 
4402  | 0  |             json_object_put(poJSonObj);  | 
4403  | 0  |         }  | 
4404  | 0  |         else  | 
4405  | 0  |         { | 
4406  | 0  |             char **papszValueList = nullptr;  | 
4407  |  | 
  | 
4408  | 0  |             if (pszValue[0] == '(' && strchr(pszValue, ':') != nullptr) | 
4409  | 0  |             { | 
4410  | 0  |                 papszValueList = CSLTokenizeString2(pszValue, ",:()", 0);  | 
4411  | 0  |             }  | 
4412  |  | 
  | 
4413  | 0  |             if (papszValueList == nullptr || *papszValueList == nullptr ||  | 
4414  | 0  |                 atoi(papszValueList[0]) != CSLCount(papszValueList) - 1)  | 
4415  | 0  |             { | 
4416  |  |                 // Do nothing - the count does not match entries.  | 
4417  | 0  |             }  | 
4418  | 0  |             else if (eType == OFTIntegerList)  | 
4419  | 0  |             { | 
4420  | 0  |                 const int nCount = atoi(papszValueList[0]);  | 
4421  | 0  |                 std::vector<int> anValues;  | 
4422  | 0  |                 if (nCount == CSLCount(papszValueList) - 1)  | 
4423  | 0  |                 { | 
4424  | 0  |                     for (int i = 0; i < nCount; i++)  | 
4425  | 0  |                     { | 
4426  |  |                         // As allowed by C standard, some systems like  | 
4427  |  |                         // MSVC do not reset errno.  | 
4428  | 0  |                         errno = 0;  | 
4429  | 0  |                         int nVal = atoi(papszValueList[i + 1]);  | 
4430  | 0  |                         if (errno == ERANGE)  | 
4431  | 0  |                         { | 
4432  | 0  |                             CPLError(  | 
4433  | 0  |                                 CE_Warning, CPLE_AppDefined,  | 
4434  | 0  |                                 "Field %s.%s: 32 bit integer overflow when "  | 
4435  | 0  |                                 "converting %s",  | 
4436  | 0  |                                 poDefn->GetName(), poFDefn->GetNameRef(),  | 
4437  | 0  |                                 pszValue);  | 
4438  | 0  |                         }  | 
4439  | 0  |                         anValues.push_back(nVal);  | 
4440  | 0  |                     }  | 
4441  | 0  |                     if (nCount > 0)  | 
4442  | 0  |                         SetField(iField, nCount, &(anValues[0]));  | 
4443  | 0  |                 }  | 
4444  | 0  |             }  | 
4445  | 0  |             else if (eType == OFTInteger64List)  | 
4446  | 0  |             { | 
4447  | 0  |                 const int nCount = atoi(papszValueList[0]);  | 
4448  | 0  |                 std::vector<GIntBig> anValues;  | 
4449  | 0  |                 if (nCount == CSLCount(papszValueList) - 1)  | 
4450  | 0  |                 { | 
4451  | 0  |                     for (int i = 0; i < nCount; i++)  | 
4452  | 0  |                     { | 
4453  | 0  |                         const GIntBig nVal = CPLAtoGIntBigEx(  | 
4454  | 0  |                             papszValueList[i + 1], TRUE, nullptr);  | 
4455  | 0  |                         anValues.push_back(nVal);  | 
4456  | 0  |                     }  | 
4457  | 0  |                     if (nCount > 0)  | 
4458  | 0  |                         SetField(iField, nCount, &(anValues[0]));  | 
4459  | 0  |                 }  | 
4460  | 0  |             }  | 
4461  | 0  |             else if (eType == OFTRealList)  | 
4462  | 0  |             { | 
4463  | 0  |                 int nCount = atoi(papszValueList[0]);  | 
4464  | 0  |                 std::vector<double> adfValues;  | 
4465  | 0  |                 if (nCount == CSLCount(papszValueList) - 1)  | 
4466  | 0  |                 { | 
4467  | 0  |                     for (int i = 0; i < nCount; i++)  | 
4468  | 0  |                         adfValues.push_back(CPLAtof(papszValueList[i + 1]));  | 
4469  | 0  |                     if (nCount > 0)  | 
4470  | 0  |                         SetField(iField, nCount, &(adfValues[0]));  | 
4471  | 0  |                 }  | 
4472  | 0  |             }  | 
4473  |  | 
  | 
4474  | 0  |             CSLDestroy(papszValueList);  | 
4475  | 0  |         }  | 
4476  | 0  |     }  | 
4477  | 0  |     else if (eType == OFTStringList)  | 
4478  | 0  |     { | 
4479  | 0  |         if (pszValue && *pszValue)  | 
4480  | 0  |         { | 
4481  | 0  |             json_object *poJSonObj = nullptr;  | 
4482  | 0  |             if (pszValue[0] == '(' && strchr(pszValue, ':') != nullptr && | 
4483  | 0  |                 pszValue[strlen(pszValue) - 1] == ')')  | 
4484  | 0  |             { | 
4485  | 0  |                 char **papszValueList = CSLTokenizeString2(pszValue, ",:()", 0);  | 
4486  | 0  |                 const int nCount =  | 
4487  | 0  |                     papszValueList[0] == nullptr ? 0 : atoi(papszValueList[0]);  | 
4488  | 0  |                 std::vector<char *> aosValues;  | 
4489  | 0  |                 if (nCount == CSLCount(papszValueList) - 1)  | 
4490  | 0  |                 { | 
4491  | 0  |                     for (int i = 0; i < nCount; i++)  | 
4492  | 0  |                         aosValues.push_back(papszValueList[i + 1]);  | 
4493  | 0  |                     aosValues.push_back(nullptr);  | 
4494  | 0  |                     SetField(iField, &(aosValues[0]));  | 
4495  | 0  |                 }  | 
4496  | 0  |                 CSLDestroy(papszValueList);  | 
4497  | 0  |             }  | 
4498  |  |             // Is this a JSon array?  | 
4499  | 0  |             else if (pszValue[0] == '[' &&  | 
4500  | 0  |                      pszValue[strlen(pszValue) - 1] == ']' &&  | 
4501  | 0  |                      OGRJSonParse(pszValue, &poJSonObj, false))  | 
4502  | 0  |             { | 
4503  | 0  |                 CPLStringList aoList;  | 
4504  | 0  |                 const auto nLength = json_object_array_length(poJSonObj);  | 
4505  | 0  |                 for (auto i = decltype(nLength){0}; i < nLength; i++) | 
4506  | 0  |                 { | 
4507  | 0  |                     json_object *poItem =  | 
4508  | 0  |                         json_object_array_get_idx(poJSonObj, i);  | 
4509  | 0  |                     if (!poItem)  | 
4510  | 0  |                         aoList.AddString(""); | 
4511  | 0  |                     else  | 
4512  | 0  |                         aoList.AddString(json_object_get_string(poItem));  | 
4513  | 0  |                 }  | 
4514  | 0  |                 SetField(iField, aoList.List());  | 
4515  | 0  |                 json_object_put(poJSonObj);  | 
4516  | 0  |             }  | 
4517  | 0  |             else  | 
4518  | 0  |             { | 
4519  | 0  |                 const char *const papszValues[2] = {pszValue, nullptr}; | 
4520  | 0  |                 SetField(iField, papszValues);  | 
4521  | 0  |             }  | 
4522  | 0  |         }  | 
4523  | 0  |     }  | 
4524  | 0  |     else  | 
4525  | 0  |     { | 
4526  |  |         // Do nothing for other field types.  | 
4527  | 0  |     }  | 
4528  | 0  | }  | 
4529  |  |  | 
4530  |  | /************************************************************************/  | 
4531  |  | /*                        OGR_F_SetFieldString()                        */  | 
4532  |  | /************************************************************************/  | 
4533  |  |  | 
4534  |  | /**  | 
4535  |  |  * \brief Set field to string value.  | 
4536  |  |  *  | 
4537  |  |  * OFTInteger fields will be set based on an atoi() conversion of the string.  | 
4538  |  |  * OFTInteger64 fields will be set based on an CPLAtoGIntBig() conversion of the  | 
4539  |  |  * string.  OFTReal fields will be set based on an CPLAtof() conversion of the  | 
4540  |  |  * string.  Other field types may be unaffected.  | 
4541  |  |  *  | 
4542  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
4543  |  |  *  | 
4544  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4545  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4546  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4547  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4548  |  |  *  | 
4549  |  |  * @param hFeat handle to the feature that owned the field.  | 
4550  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
4551  |  |  * @param pszValue the value to assign.  | 
4552  |  |  */  | 
4553  |  |  | 
4554  |  | void OGR_F_SetFieldString(OGRFeatureH hFeat, int iField, const char *pszValue)  | 
4555  |  |  | 
4556  | 0  | { | 
4557  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldString");  | 
4558  |  |  | 
4559  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, pszValue);  | 
4560  | 0  | }  | 
4561  |  |  | 
4562  |  | /************************************************************************/  | 
4563  |  | /*                              SetField()                              */  | 
4564  |  | /************************************************************************/  | 
4565  |  |  | 
4566  |  | /**  | 
4567  |  |  * \fn OGRFeature::SetField( const char* pszFName, int nCount, const int  | 
4568  |  |  * *panValues ) \brief Set field to list of integers value.  | 
4569  |  |  *  | 
4570  |  |  * This method currently on has an effect of OFTIntegerList, OFTInteger64List  | 
4571  |  |  * and OFTRealList fields.  | 
4572  |  |  *  | 
4573  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4574  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4575  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4576  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4577  |  |  *  | 
4578  |  |  * @param pszFName the name of the field to set.  | 
4579  |  |  * @param nCount the number of values in the list being assigned.  | 
4580  |  |  * @param panValues the values to assign.  | 
4581  |  |  */  | 
4582  |  |  | 
4583  |  | /**  | 
4584  |  |  * \brief Set field to list of integers value.  | 
4585  |  |  *  | 
4586  |  |  * This method currently on has an effect of OFTIntegerList, OFTInteger64List  | 
4587  |  |  * and OFTRealList fields.  | 
4588  |  |  *  | 
4589  |  |  * This method is the same as the C function OGR_F_SetFieldIntegerList().  | 
4590  |  |  *  | 
4591  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4592  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4593  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4594  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4595  |  |  *  | 
4596  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
4597  |  |  * @param nCount the number of values in the list being assigned.  | 
4598  |  |  * @param panValues the values to assign.  | 
4599  |  |  */  | 
4600  |  |  | 
4601  |  | void OGRFeature::SetField(int iField, int nCount, const int *panValues)  | 
4602  |  |  | 
4603  | 0  | { | 
4604  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
4605  |  | 
  | 
4606  | 0  |     if (poFDefn == nullptr)  | 
4607  | 0  |         return;  | 
4608  |  |  | 
4609  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
4610  | 0  |     if (eType == OFTIntegerList)  | 
4611  | 0  |     { | 
4612  | 0  |         OGRField uField;  | 
4613  | 0  |         int *panValuesMod = nullptr;  | 
4614  |  | 
  | 
4615  | 0  |         if (poFDefn->GetSubType() == OFSTBoolean ||  | 
4616  | 0  |             poFDefn->GetSubType() == OFSTInt16)  | 
4617  | 0  |         { | 
4618  | 0  |             for (int i = 0; i < nCount; i++)  | 
4619  | 0  |             { | 
4620  | 0  |                 int nVal =  | 
4621  | 0  |                     OGRFeatureGetIntegerValue(poDefn, poFDefn, panValues[i]);  | 
4622  | 0  |                 if (panValues[i] != nVal)  | 
4623  | 0  |                 { | 
4624  | 0  |                     if (panValuesMod == nullptr)  | 
4625  | 0  |                     { | 
4626  | 0  |                         panValuesMod = static_cast<int *>(  | 
4627  | 0  |                             VSI_MALLOC_VERBOSE(nCount * sizeof(int)));  | 
4628  | 0  |                         if (panValuesMod == nullptr)  | 
4629  | 0  |                             return;  | 
4630  | 0  |                         if (nCount > 0)  | 
4631  | 0  |                             memcpy(panValuesMod, panValues,  | 
4632  | 0  |                                    nCount * sizeof(int));  | 
4633  | 0  |                     }  | 
4634  | 0  |                     panValuesMod[i] = nVal;  | 
4635  | 0  |                 }  | 
4636  | 0  |             }  | 
4637  | 0  |         }  | 
4638  |  |  | 
4639  | 0  |         uField.IntegerList.nCount = nCount;  | 
4640  | 0  |         uField.Set.nMarker2 = 0;  | 
4641  | 0  |         uField.Set.nMarker3 = 0;  | 
4642  | 0  |         uField.IntegerList.paList =  | 
4643  | 0  |             panValuesMod ? panValuesMod : const_cast<int *>(panValues);  | 
4644  |  | 
  | 
4645  | 0  |         SetField(iField, &uField);  | 
4646  | 0  |         CPLFree(panValuesMod);  | 
4647  | 0  |     }  | 
4648  | 0  |     else if (eType == OFTInteger64List)  | 
4649  | 0  |     { | 
4650  | 0  |         std::vector<GIntBig> anValues;  | 
4651  | 0  |         anValues.reserve(nCount);  | 
4652  | 0  |         for (int i = 0; i < nCount; i++)  | 
4653  | 0  |             anValues.push_back(panValues[i]);  | 
4654  | 0  |         if (nCount > 0)  | 
4655  | 0  |             SetField(iField, nCount, &anValues[0]);  | 
4656  | 0  |     }  | 
4657  | 0  |     else if (eType == OFTRealList)  | 
4658  | 0  |     { | 
4659  | 0  |         std::vector<double> adfValues;  | 
4660  | 0  |         adfValues.reserve(nCount);  | 
4661  | 0  |         for (int i = 0; i < nCount; i++)  | 
4662  | 0  |             adfValues.push_back(static_cast<double>(panValues[i]));  | 
4663  | 0  |         if (nCount > 0)  | 
4664  | 0  |             SetField(iField, nCount, &adfValues[0]);  | 
4665  | 0  |     }  | 
4666  | 0  |     else if ((eType == OFTInteger || eType == OFTInteger64 ||  | 
4667  | 0  |               eType == OFTReal) &&  | 
4668  | 0  |              nCount == 1)  | 
4669  | 0  |     { | 
4670  | 0  |         SetField(iField, panValues[0]);  | 
4671  | 0  |     }  | 
4672  | 0  |     else if (eType == OFTStringList)  | 
4673  | 0  |     { | 
4674  | 0  |         char **papszValues = static_cast<char **>(  | 
4675  | 0  |             VSI_MALLOC_VERBOSE((nCount + 1) * sizeof(char *)));  | 
4676  | 0  |         if (papszValues == nullptr)  | 
4677  | 0  |             return;  | 
4678  | 0  |         for (int i = 0; i < nCount; i++)  | 
4679  | 0  |             papszValues[i] = VSI_STRDUP_VERBOSE(CPLSPrintf("%d", panValues[i])); | 
4680  | 0  |         papszValues[nCount] = nullptr;  | 
4681  | 0  |         SetField(iField, papszValues);  | 
4682  | 0  |         CSLDestroy(papszValues);  | 
4683  | 0  |     }  | 
4684  | 0  | }  | 
4685  |  |  | 
4686  |  | /************************************************************************/  | 
4687  |  | /*                     OGR_F_SetFieldIntegerList()                      */  | 
4688  |  | /************************************************************************/  | 
4689  |  |  | 
4690  |  | /**  | 
4691  |  |  * \brief Set field to list of integers value.  | 
4692  |  |  *  | 
4693  |  |  * This function currently on has an effect of OFTIntegerList, OFTInteger64List  | 
4694  |  |  * and OFTRealList fields.  | 
4695  |  |  *  | 
4696  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
4697  |  |  *  | 
4698  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4699  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4700  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4701  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4702  |  |  *  | 
4703  |  |  * @param hFeat handle to the feature that owned the field.  | 
4704  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
4705  |  |  * @param nCount the number of values in the list being assigned.  | 
4706  |  |  * @param panValues the values to assign.  | 
4707  |  |  */  | 
4708  |  |  | 
4709  |  | void OGR_F_SetFieldIntegerList(OGRFeatureH hFeat, int iField, int nCount,  | 
4710  |  |                                const int *panValues)  | 
4711  |  |  | 
4712  | 0  | { | 
4713  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldIntegerList");  | 
4714  |  |  | 
4715  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, nCount, panValues);  | 
4716  | 0  | }  | 
4717  |  |  | 
4718  |  | /************************************************************************/  | 
4719  |  | /*                              SetField()                              */  | 
4720  |  | /************************************************************************/  | 
4721  |  |  | 
4722  |  | /**  | 
4723  |  |  * \fn OGRFeature::SetField( const char* pszFName, int nCount, const GIntBig  | 
4724  |  |  * *panValues )  | 
4725  |  |  * \brief Set field to list of 64 bit integers value.  | 
4726  |  |  *  | 
4727  |  |  * This method currently on has an effect of OFTIntegerList, OFTInteger64List  | 
4728  |  |  * and OFTRealList fields.  | 
4729  |  |  *  | 
4730  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4731  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4732  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4733  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4734  |  |  *  | 
4735  |  |  * @param pszFName the name of the field to set.  | 
4736  |  |  * @param nCount the number of values in the list being assigned.  | 
4737  |  |  * @param panValues the values to assign.  | 
4738  |  |  */  | 
4739  |  |  | 
4740  |  | /**  | 
4741  |  |  * \brief Set field to list of 64 bit integers value.  | 
4742  |  |  *  | 
4743  |  |  * This method currently on has an effect of OFTIntegerList, OFTInteger64List  | 
4744  |  |  * and OFTRealList fields.  | 
4745  |  |  *  | 
4746  |  |  * This method is the same as the C function OGR_F_SetFieldInteger64List().  | 
4747  |  |  *  | 
4748  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4749  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4750  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4751  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4752  |  |  *  | 
4753  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
4754  |  |  * @param nCount the number of values in the list being assigned.  | 
4755  |  |  * @param panValues the values to assign.  | 
4756  |  |  * @since GDAL 2.0  | 
4757  |  |  */  | 
4758  |  |  | 
4759  |  | void OGRFeature::SetField(int iField, int nCount, const GIntBig *panValues)  | 
4760  |  |  | 
4761  | 0  | { | 
4762  | 0  |     const OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
4763  |  | 
  | 
4764  | 0  |     if (poFDefn == nullptr)  | 
4765  | 0  |         return;  | 
4766  |  |  | 
4767  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
4768  | 0  |     if (eType == OFTIntegerList)  | 
4769  | 0  |     { | 
4770  | 0  |         std::vector<int> anValues;  | 
4771  |  | 
  | 
4772  | 0  |         for (int i = 0; i < nCount; i++)  | 
4773  | 0  |         { | 
4774  | 0  |             const GIntBig nValue = panValues[i];  | 
4775  | 0  |             const int nVal32 = nValue < INT_MIN   ? INT_MIN  | 
4776  | 0  |                                : nValue > INT_MAX ? INT_MAX  | 
4777  | 0  |                                                   : static_cast<int>(nValue);  | 
4778  |  | 
  | 
4779  | 0  |             if (nVal32 != nValue)  | 
4780  | 0  |             { | 
4781  | 0  |                 CPLError(  | 
4782  | 0  |                     CE_Warning, CPLE_AppDefined,  | 
4783  | 0  |                     "Field %s.%s: Integer overflow occurred when trying to "  | 
4784  | 0  |                     "set %" PRId64 " as 32 bit value.",  | 
4785  | 0  |                     poDefn->GetName(), poFDefn->GetNameRef(),  | 
4786  | 0  |                     static_cast<int64_t>(nValue));  | 
4787  | 0  |             }  | 
4788  | 0  |             anValues.push_back(nVal32);  | 
4789  | 0  |         }  | 
4790  | 0  |         if (nCount > 0)  | 
4791  | 0  |             SetField(iField, nCount, &anValues[0]);  | 
4792  | 0  |     }  | 
4793  | 0  |     else if (eType == OFTInteger64List)  | 
4794  | 0  |     { | 
4795  | 0  |         OGRField uField;  | 
4796  | 0  |         uField.Integer64List.nCount = nCount;  | 
4797  | 0  |         uField.Set.nMarker2 = 0;  | 
4798  | 0  |         uField.Set.nMarker3 = 0;  | 
4799  | 0  |         uField.Integer64List.paList = const_cast<GIntBig *>(panValues);  | 
4800  |  | 
  | 
4801  | 0  |         SetField(iField, &uField);  | 
4802  | 0  |     }  | 
4803  | 0  |     else if (eType == OFTRealList)  | 
4804  | 0  |     { | 
4805  | 0  |         std::vector<double> adfValues;  | 
4806  | 0  |         adfValues.reserve(nCount);  | 
4807  | 0  |         for (int i = 0; i < nCount; i++)  | 
4808  | 0  |             adfValues.push_back(static_cast<double>(panValues[i]));  | 
4809  | 0  |         if (nCount > 0)  | 
4810  | 0  |             SetField(iField, nCount, &adfValues[0]);  | 
4811  | 0  |     }  | 
4812  | 0  |     else if ((eType == OFTInteger || eType == OFTInteger64 ||  | 
4813  | 0  |               eType == OFTReal) &&  | 
4814  | 0  |              nCount == 1)  | 
4815  | 0  |     { | 
4816  | 0  |         SetField(iField, panValues[0]);  | 
4817  | 0  |     }  | 
4818  | 0  |     else if (eType == OFTStringList)  | 
4819  | 0  |     { | 
4820  | 0  |         char **papszValues = static_cast<char **>(  | 
4821  | 0  |             VSI_MALLOC_VERBOSE((nCount + 1) * sizeof(char *)));  | 
4822  | 0  |         if (papszValues == nullptr)  | 
4823  | 0  |             return;  | 
4824  | 0  |         for (int i = 0; i < nCount; i++)  | 
4825  | 0  |             papszValues[i] =  | 
4826  | 0  |                 VSI_STRDUP_VERBOSE(CPLSPrintf(CPL_FRMT_GIB, panValues[i]));  | 
4827  | 0  |         papszValues[nCount] = nullptr;  | 
4828  | 0  |         SetField(iField, papszValues);  | 
4829  | 0  |         CSLDestroy(papszValues);  | 
4830  | 0  |     }  | 
4831  | 0  | }  | 
4832  |  |  | 
4833  |  | /************************************************************************/  | 
4834  |  | /*                    OGR_F_SetFieldInteger64List()                     */  | 
4835  |  | /************************************************************************/  | 
4836  |  |  | 
4837  |  | /**  | 
4838  |  |  * \brief Set field to list of 64 bit integers value.  | 
4839  |  |  *  | 
4840  |  |  * This function currently on has an effect of OFTIntegerList, OFTInteger64List  | 
4841  |  |  * and OFTRealList fields.  | 
4842  |  |  *  | 
4843  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
4844  |  |  *  | 
4845  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4846  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4847  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4848  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4849  |  |  *  | 
4850  |  |  * @param hFeat handle to the feature that owned the field.  | 
4851  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
4852  |  |  * @param nCount the number of values in the list being assigned.  | 
4853  |  |  * @param panValues the values to assign.  | 
4854  |  |  * @since GDAL 2.0  | 
4855  |  |  */  | 
4856  |  |  | 
4857  |  | void OGR_F_SetFieldInteger64List(OGRFeatureH hFeat, int iField, int nCount,  | 
4858  |  |                                  const GIntBig *panValues)  | 
4859  |  |  | 
4860  | 0  | { | 
4861  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldInteger64List");  | 
4862  |  |  | 
4863  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, nCount, panValues);  | 
4864  | 0  | }  | 
4865  |  |  | 
4866  |  | /************************************************************************/  | 
4867  |  | /*                              SetField()                              */  | 
4868  |  | /************************************************************************/  | 
4869  |  |  | 
4870  |  | /**  | 
4871  |  |  * \fn OGRFeature::SetField( const char* pszFName, int nCount, const double *  | 
4872  |  |  * padfValues ) \brief Set field to list of doubles value.  | 
4873  |  |  *  | 
4874  |  |  * This method currently on has an effect of OFTIntegerList, OFTInteger64List,  | 
4875  |  |  * OFTRealList fields.  | 
4876  |  |  *  | 
4877  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4878  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4879  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4880  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4881  |  |  *  | 
4882  |  |  * @param pszFName the name of the field to set.  | 
4883  |  |  * @param nCount the number of values in the list being assigned.  | 
4884  |  |  * @param padfValues the values to assign.  | 
4885  |  |  */  | 
4886  |  |  | 
4887  |  | /**  | 
4888  |  |  * \brief Set field to list of doubles value.  | 
4889  |  |  *  | 
4890  |  |  * This method currently on has an effect of OFTIntegerList, OFTInteger64List,  | 
4891  |  |  * OFTRealList fields.  | 
4892  |  |  *  | 
4893  |  |  * This method is the same as the C function OGR_F_SetFieldDoubleList().  | 
4894  |  |  *  | 
4895  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4896  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4897  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4898  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4899  |  |  *  | 
4900  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
4901  |  |  * @param nCount the number of values in the list being assigned.  | 
4902  |  |  * @param padfValues the values to assign.  | 
4903  |  |  */  | 
4904  |  |  | 
4905  |  | void OGRFeature::SetField(int iField, int nCount, const double *padfValues)  | 
4906  |  |  | 
4907  | 0  | { | 
4908  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
4909  |  | 
  | 
4910  | 0  |     if (poFDefn == nullptr)  | 
4911  | 0  |         return;  | 
4912  |  |  | 
4913  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
4914  | 0  |     if (eType == OFTRealList)  | 
4915  | 0  |     { | 
4916  | 0  |         OGRField uField;  | 
4917  |  | 
  | 
4918  | 0  |         uField.RealList.nCount = nCount;  | 
4919  | 0  |         uField.Set.nMarker2 = 0;  | 
4920  | 0  |         uField.Set.nMarker3 = 0;  | 
4921  | 0  |         uField.RealList.paList = const_cast<double *>(padfValues);  | 
4922  |  | 
  | 
4923  | 0  |         SetField(iField, &uField);  | 
4924  | 0  |     }  | 
4925  | 0  |     else if (eType == OFTIntegerList)  | 
4926  | 0  |     { | 
4927  | 0  |         std::vector<int> anValues;  | 
4928  | 0  |         anValues.reserve(nCount);  | 
4929  | 0  |         for (int i = 0; i < nCount; i++)  | 
4930  | 0  |             anValues.push_back(static_cast<int>(padfValues[i]));  | 
4931  |  | 
  | 
4932  | 0  |         if (nCount > 0)  | 
4933  | 0  |             SetField(iField, nCount, &anValues[0]);  | 
4934  | 0  |     }  | 
4935  | 0  |     else if (eType == OFTInteger64List)  | 
4936  | 0  |     { | 
4937  | 0  |         std::vector<GIntBig> anValues;  | 
4938  | 0  |         anValues.reserve(nCount);  | 
4939  | 0  |         for (int i = 0; i < nCount; i++)  | 
4940  | 0  |             anValues.push_back(static_cast<GIntBig>(padfValues[i]));  | 
4941  | 0  |         if (nCount > 0)  | 
4942  | 0  |             SetField(iField, nCount, &anValues[0]);  | 
4943  | 0  |     }  | 
4944  | 0  |     else if ((eType == OFTInteger || eType == OFTInteger64 ||  | 
4945  | 0  |               eType == OFTReal) &&  | 
4946  | 0  |              nCount == 1)  | 
4947  | 0  |     { | 
4948  | 0  |         SetField(iField, padfValues[0]);  | 
4949  | 0  |     }  | 
4950  | 0  |     else if (eType == OFTStringList)  | 
4951  | 0  |     { | 
4952  | 0  |         char **papszValues = static_cast<char **>(  | 
4953  | 0  |             VSI_MALLOC_VERBOSE((nCount + 1) * sizeof(char *)));  | 
4954  | 0  |         if (papszValues == nullptr)  | 
4955  | 0  |             return;  | 
4956  | 0  |         for (int i = 0; i < nCount; i++)  | 
4957  | 0  |             papszValues[i] =  | 
4958  | 0  |                 VSI_STRDUP_VERBOSE(CPLSPrintf("%.16g", padfValues[i])); | 
4959  | 0  |         papszValues[nCount] = nullptr;  | 
4960  | 0  |         SetField(iField, papszValues);  | 
4961  | 0  |         CSLDestroy(papszValues);  | 
4962  | 0  |     }  | 
4963  | 0  | }  | 
4964  |  |  | 
4965  |  | /************************************************************************/  | 
4966  |  | /*                      OGR_F_SetFieldDoubleList()                      */  | 
4967  |  | /************************************************************************/  | 
4968  |  |  | 
4969  |  | /**  | 
4970  |  |  * \brief Set field to list of doubles value.  | 
4971  |  |  *  | 
4972  |  |  * This function currently on has an effect of OFTIntegerList, OFTInteger64List,  | 
4973  |  |  * OFTRealList fields.  | 
4974  |  |  *  | 
4975  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
4976  |  |  *  | 
4977  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
4978  |  |  * this object comes from a layer and the modifications must be serialized back  | 
4979  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
4980  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
4981  |  |  *  | 
4982  |  |  * @param hFeat handle to the feature that owned the field.  | 
4983  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
4984  |  |  * @param nCount the number of values in the list being assigned.  | 
4985  |  |  * @param padfValues the values to assign.  | 
4986  |  |  */  | 
4987  |  |  | 
4988  |  | void OGR_F_SetFieldDoubleList(OGRFeatureH hFeat, int iField, int nCount,  | 
4989  |  |                               const double *padfValues)  | 
4990  |  |  | 
4991  | 0  | { | 
4992  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldDoubleList");  | 
4993  |  |  | 
4994  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, nCount, padfValues);  | 
4995  | 0  | }  | 
4996  |  |  | 
4997  |  | /************************************************************************/  | 
4998  |  | /*                              SetField()                              */  | 
4999  |  | /************************************************************************/  | 
5000  |  |  | 
5001  |  | /**  | 
5002  |  |  * \fn OGRFeature::SetField( const char* pszFName,  const char * const *  | 
5003  |  |  * papszValues ) \brief Set field to list of strings value.  | 
5004  |  |  *  | 
5005  |  |  * This method currently on has an effect of OFTStringList fields.  | 
5006  |  |  *  | 
5007  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5008  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5009  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5010  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5011  |  |  *  | 
5012  |  |  * @param pszFName the name of the field to set.  | 
5013  |  |  * @param papszValues the values to assign. List of NUL-terminated string,  | 
5014  |  |  * ending with a NULL pointer.  | 
5015  |  |  */  | 
5016  |  |  | 
5017  |  | /**  | 
5018  |  |  * \brief Set field to list of strings value.  | 
5019  |  |  *  | 
5020  |  |  * This method currently on has an effect of OFTStringList fields.  | 
5021  |  |  *  | 
5022  |  |  * This method is the same as the C function OGR_F_SetFieldStringList().  | 
5023  |  |  *  | 
5024  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5025  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5026  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5027  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5028  |  |  *  | 
5029  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
5030  |  |  * @param papszValues the values to assign. List of NUL-terminated string,  | 
5031  |  |  * ending with a NULL pointer.  | 
5032  |  |  */  | 
5033  |  |  | 
5034  |  | void OGRFeature::SetField(int iField, const char *const *papszValues)  | 
5035  |  |  | 
5036  | 0  | { | 
5037  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
5038  |  | 
  | 
5039  | 0  |     if (poFDefn == nullptr)  | 
5040  | 0  |         return;  | 
5041  |  |  | 
5042  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
5043  | 0  |     if (eType == OFTStringList)  | 
5044  | 0  |     { | 
5045  | 0  |         if (!IsFieldSetAndNotNullUnsafe(iField) ||  | 
5046  | 0  |             papszValues != pauFields[iField].StringList.paList)  | 
5047  | 0  |         { | 
5048  | 0  |             OGRField uField;  | 
5049  |  | 
  | 
5050  | 0  |             uField.StringList.nCount = CSLCount(papszValues);  | 
5051  | 0  |             uField.Set.nMarker2 = 0;  | 
5052  | 0  |             uField.Set.nMarker3 = 0;  | 
5053  | 0  |             uField.StringList.paList = const_cast<char **>(papszValues);  | 
5054  |  | 
  | 
5055  | 0  |             SetField(iField, &uField);  | 
5056  | 0  |         }  | 
5057  | 0  |     }  | 
5058  | 0  |     else if (eType == OFTIntegerList)  | 
5059  | 0  |     { | 
5060  | 0  |         const int nValues = CSLCount(papszValues);  | 
5061  | 0  |         int *panValues =  | 
5062  | 0  |             static_cast<int *>(VSI_MALLOC_VERBOSE(nValues * sizeof(int)));  | 
5063  | 0  |         if (panValues == nullptr)  | 
5064  | 0  |             return;  | 
5065  | 0  |         for (int i = 0; i < nValues; i++)  | 
5066  | 0  |         { | 
5067  |  |             // As allowed by C standard, some systems like MSVC do not  | 
5068  |  |             // reset errno.  | 
5069  | 0  |             errno = 0;  | 
5070  |  | 
  | 
5071  | 0  |             int nVal = atoi(papszValues[i]);  | 
5072  | 0  |             if (errno == ERANGE)  | 
5073  | 0  |             { | 
5074  | 0  |                 CPLError(  | 
5075  | 0  |                     CE_Warning, CPLE_AppDefined,  | 
5076  | 0  |                     "Field %s.%s: 32 bit integer overflow when converting %s",  | 
5077  | 0  |                     poDefn->GetName(), poFDefn->GetNameRef(), papszValues[i]);  | 
5078  | 0  |                 if (papszValues[i][0] == '-')  | 
5079  | 0  |                     nVal = INT_MIN;  | 
5080  | 0  |                 else  | 
5081  | 0  |                     nVal = INT_MAX;  | 
5082  | 0  |             }  | 
5083  | 0  |             panValues[i] = nVal;  | 
5084  | 0  |         }  | 
5085  | 0  |         SetField(iField, nValues, panValues);  | 
5086  | 0  |         CPLFree(panValues);  | 
5087  | 0  |     }  | 
5088  | 0  |     else if (eType == OFTInteger64List)  | 
5089  | 0  |     { | 
5090  | 0  |         const int nValues = CSLCount(papszValues);  | 
5091  | 0  |         GIntBig *panValues = static_cast<GIntBig *>(  | 
5092  | 0  |             VSI_MALLOC_VERBOSE(nValues * sizeof(GIntBig)));  | 
5093  | 0  |         if (panValues == nullptr)  | 
5094  | 0  |             return;  | 
5095  | 0  |         for (int i = 0; i < nValues; i++)  | 
5096  | 0  |         { | 
5097  | 0  |             panValues[i] = CPLAtoGIntBigEx(papszValues[i], TRUE, nullptr);  | 
5098  | 0  |         }  | 
5099  | 0  |         SetField(iField, nValues, panValues);  | 
5100  | 0  |         CPLFree(panValues);  | 
5101  | 0  |     }  | 
5102  | 0  |     else if (eType == OFTRealList)  | 
5103  | 0  |     { | 
5104  | 0  |         const int nValues = CSLCount(papszValues);  | 
5105  | 0  |         double *padfValues =  | 
5106  | 0  |             static_cast<double *>(VSI_MALLOC_VERBOSE(nValues * sizeof(double)));  | 
5107  | 0  |         if (padfValues == nullptr)  | 
5108  | 0  |             return;  | 
5109  | 0  |         for (int i = 0; i < nValues; i++)  | 
5110  | 0  |         { | 
5111  | 0  |             padfValues[i] = CPLAtof(papszValues[i]);  | 
5112  | 0  |         }  | 
5113  | 0  |         SetField(iField, nValues, padfValues);  | 
5114  | 0  |         CPLFree(padfValues);  | 
5115  | 0  |     }  | 
5116  | 0  | }  | 
5117  |  |  | 
5118  |  | /************************************************************************/  | 
5119  |  | /*                      OGR_F_SetFieldStringList()                      */  | 
5120  |  | /************************************************************************/  | 
5121  |  |  | 
5122  |  | /**  | 
5123  |  |  * \brief Set field to list of strings value.  | 
5124  |  |  *  | 
5125  |  |  * This function currently on has an effect of OFTStringList fields.  | 
5126  |  |  *  | 
5127  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
5128  |  |  *  | 
5129  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5130  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5131  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5132  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5133  |  |  *  | 
5134  |  |  * @param hFeat handle to the feature that owned the field.  | 
5135  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
5136  |  |  * @param papszValues the values to assign. List of NUL-terminated string,  | 
5137  |  |  * ending with a NULL pointer.  | 
5138  |  |  */  | 
5139  |  |  | 
5140  |  | void OGR_F_SetFieldStringList(OGRFeatureH hFeat, int iField,  | 
5141  |  |                               CSLConstList papszValues)  | 
5142  |  |  | 
5143  | 0  | { | 
5144  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldStringList");  | 
5145  |  |  | 
5146  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, papszValues);  | 
5147  | 0  | }  | 
5148  |  |  | 
5149  |  | /************************************************************************/  | 
5150  |  | /*                              SetField()                              */  | 
5151  |  | /************************************************************************/  | 
5152  |  |  | 
5153  |  | /**  | 
5154  |  |  * \brief Set field to binary data.  | 
5155  |  |  *  | 
5156  |  |  * This method currently on has an effect of OFTBinary fields.  | 
5157  |  |  *  | 
5158  |  |  * This method is the same as the C function OGR_F_SetFieldBinary().  | 
5159  |  |  *  | 
5160  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5161  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5162  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5163  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5164  |  |  *  | 
5165  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
5166  |  |  * @param nBytes bytes of data being set.  | 
5167  |  |  * @param pabyData the raw data being applied.  | 
5168  |  |  */  | 
5169  |  |  | 
5170  |  | void OGRFeature::SetField(int iField, int nBytes, const void *pabyData)  | 
5171  |  |  | 
5172  | 0  | { | 
5173  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
5174  |  | 
  | 
5175  | 0  |     if (poFDefn == nullptr)  | 
5176  | 0  |         return;  | 
5177  |  |  | 
5178  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
5179  | 0  |     if (eType == OFTBinary)  | 
5180  | 0  |     { | 
5181  | 0  |         OGRField uField;  | 
5182  |  | 
  | 
5183  | 0  |         uField.Binary.nCount = nBytes;  | 
5184  | 0  |         uField.Set.nMarker2 = 0;  | 
5185  | 0  |         uField.Set.nMarker3 = 0;  | 
5186  | 0  |         uField.Binary.paData =  | 
5187  | 0  |             const_cast<GByte *>(static_cast<const GByte *>(pabyData));  | 
5188  |  | 
  | 
5189  | 0  |         SetField(iField, &uField);  | 
5190  | 0  |     }  | 
5191  | 0  |     else if (eType == OFTString || eType == OFTStringList)  | 
5192  | 0  |     { | 
5193  | 0  |         char *pszStr = static_cast<char *>(VSI_MALLOC_VERBOSE(nBytes + 1));  | 
5194  | 0  |         if (pszStr == nullptr)  | 
5195  | 0  |             return;  | 
5196  | 0  |         if (nBytes > 0)  | 
5197  | 0  |             memcpy(pszStr, pabyData, nBytes);  | 
5198  | 0  |         pszStr[nBytes] = 0;  | 
5199  | 0  |         SetField(iField, pszStr);  | 
5200  | 0  |         CPLFree(pszStr);  | 
5201  | 0  |     }  | 
5202  | 0  | }  | 
5203  |  |  | 
5204  |  | /************************************************************************/  | 
5205  |  | /*                        OGR_F_SetFieldBinary()                        */  | 
5206  |  | /************************************************************************/  | 
5207  |  |  | 
5208  |  | /**  | 
5209  |  |  * \brief Set field to binary data.  | 
5210  |  |  *  | 
5211  |  |  * This function currently on has an effect of OFTBinary fields.  | 
5212  |  |  *  | 
5213  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
5214  |  |  *  | 
5215  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5216  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5217  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5218  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5219  |  |  *  | 
5220  |  |  * @param hFeat handle to the feature that owned the field.  | 
5221  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
5222  |  |  * @param nBytes the number of bytes in pabyData array.  | 
5223  |  |  * @param pabyData the data to apply.  | 
5224  |  |  */  | 
5225  |  |  | 
5226  |  | void OGR_F_SetFieldBinary(OGRFeatureH hFeat, int iField, int nBytes,  | 
5227  |  |                           const void *pabyData)  | 
5228  |  |  | 
5229  | 0  | { | 
5230  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldBinary");  | 
5231  |  |  | 
5232  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, nBytes, pabyData);  | 
5233  | 0  | }  | 
5234  |  |  | 
5235  |  | /************************************************************************/  | 
5236  |  | /*                              SetField()                              */  | 
5237  |  | /************************************************************************/  | 
5238  |  |  | 
5239  |  | /**  | 
5240  |  |  * \fn OGRFeature::SetField( const char* pszFName, int nYear, int nMonth,  | 
5241  |  |  *                           int nDay, int nHour, int nMinute, float fSecond,  | 
5242  |  |  *                           int nTZFlag )  | 
5243  |  |  * \brief Set field to date.  | 
5244  |  |  *  | 
5245  |  |  * This method currently only has an effect for OFTDate, OFTTime and OFTDateTime  | 
5246  |  |  * fields.  | 
5247  |  |  *  | 
5248  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5249  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5250  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5251  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5252  |  |  *  | 
5253  |  |  * @param pszFName the name of the field to set.  | 
5254  |  |  * @param nYear (including century)  | 
5255  |  |  * @param nMonth (1-12)  | 
5256  |  |  * @param nDay (1-31)  | 
5257  |  |  * @param nHour (0-23)  | 
5258  |  |  * @param nMinute (0-59)  | 
5259  |  |  * @param fSecond (0-59, with millisecond accuracy)  | 
5260  |  |  * @param nTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
5261  |  |  */  | 
5262  |  |  | 
5263  |  | /**  | 
5264  |  |  * \brief Set field to date.  | 
5265  |  |  *  | 
5266  |  |  * This method currently only has an effect for OFTDate, OFTTime and OFTDateTime  | 
5267  |  |  * fields.  | 
5268  |  |  *  | 
5269  |  |  * This method is the same as the C function OGR_F_SetFieldDateTime().  | 
5270  |  |  *  | 
5271  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5272  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5273  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5274  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5275  |  |  *  | 
5276  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
5277  |  |  * @param nYear (including century)  | 
5278  |  |  * @param nMonth (1-12)  | 
5279  |  |  * @param nDay (1-31)  | 
5280  |  |  * @param nHour (0-23)  | 
5281  |  |  * @param nMinute (0-59)  | 
5282  |  |  * @param fSecond (0-59, with millisecond accuracy)  | 
5283  |  |  * @param nTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
5284  |  |  */  | 
5285  |  |  | 
5286  |  | void OGRFeature::SetField(int iField, int nYear, int nMonth, int nDay,  | 
5287  |  |                           int nHour, int nMinute, float fSecond, int nTZFlag)  | 
5288  |  |  | 
5289  | 0  | { | 
5290  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
5291  |  | 
  | 
5292  | 0  |     if (poFDefn == nullptr)  | 
5293  | 0  |         return;  | 
5294  |  |  | 
5295  | 0  |     OGRFieldType eType = poFDefn->GetType();  | 
5296  | 0  |     if (eType == OFTDate || eType == OFTTime || eType == OFTDateTime)  | 
5297  | 0  |     { | 
5298  | 0  |         if (static_cast<GInt16>(nYear) != nYear)  | 
5299  | 0  |         { | 
5300  | 0  |             CPLError(CE_Failure, CPLE_NotSupported,  | 
5301  | 0  |                      "Years < -32768 or > 32767 are not supported");  | 
5302  | 0  |             return;  | 
5303  | 0  |         }  | 
5304  |  |  | 
5305  | 0  |         pauFields[iField].Date.Year = static_cast<GInt16>(nYear);  | 
5306  | 0  |         pauFields[iField].Date.Month = static_cast<GByte>(nMonth);  | 
5307  | 0  |         pauFields[iField].Date.Day = static_cast<GByte>(nDay);  | 
5308  | 0  |         pauFields[iField].Date.Hour = static_cast<GByte>(nHour);  | 
5309  | 0  |         pauFields[iField].Date.Minute = static_cast<GByte>(nMinute);  | 
5310  | 0  |         pauFields[iField].Date.Second = fSecond;  | 
5311  | 0  |         pauFields[iField].Date.TZFlag = static_cast<GByte>(nTZFlag);  | 
5312  | 0  |     }  | 
5313  | 0  |     else if (eType == OFTString || eType == OFTStringList)  | 
5314  | 0  |     { | 
5315  |  |         // "YYYY/MM/DD HH:MM:SS.sss+ZZ"  | 
5316  | 0  |         constexpr size_t MAX_SIZE = 26 + 1;  | 
5317  | 0  |         char szTempBuffer[MAX_SIZE] = {}; | 
5318  | 0  |         OGRFeatureFormatDateTimeBuffer(szTempBuffer, MAX_SIZE, nYear, nMonth,  | 
5319  | 0  |                                        nDay, nHour, nMinute, fSecond, nTZFlag);  | 
5320  | 0  |         SetField(iField, szTempBuffer);  | 
5321  | 0  |     }  | 
5322  | 0  | }  | 
5323  |  |  | 
5324  |  | /************************************************************************/  | 
5325  |  | /*                       OGR_F_SetFieldDateTime()                       */  | 
5326  |  | /************************************************************************/  | 
5327  |  |  | 
5328  |  | /**  | 
5329  |  |  * \brief Set field to datetime.  | 
5330  |  |  *  | 
5331  |  |  * This method currently only has an effect for OFTDate, OFTTime and OFTDateTime  | 
5332  |  |  * fields.  | 
5333  |  |  *  | 
5334  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5335  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5336  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5337  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5338  |  |  *  | 
5339  |  |  * @param hFeat handle to the feature that owned the field.  | 
5340  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
5341  |  |  * @param nYear (including century)  | 
5342  |  |  * @param nMonth (1-12)  | 
5343  |  |  * @param nDay (1-31)  | 
5344  |  |  * @param nHour (0-23)  | 
5345  |  |  * @param nMinute (0-59)  | 
5346  |  |  * @param nSecond (0-59)  | 
5347  |  |  * @param nTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
5348  |  |  *  | 
5349  |  |  * @see Use OGR_F_SetFieldDateTimeEx() for second with millisecond accuracy.  | 
5350  |  |  */  | 
5351  |  |  | 
5352  |  | void OGR_F_SetFieldDateTime(OGRFeatureH hFeat, int iField, int nYear,  | 
5353  |  |                             int nMonth, int nDay, int nHour, int nMinute,  | 
5354  |  |                             int nSecond, int nTZFlag)  | 
5355  |  |  | 
5356  | 0  | { | 
5357  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldDateTime");  | 
5358  |  |  | 
5359  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(  | 
5360  | 0  |         iField, nYear, nMonth, nDay, nHour, nMinute,  | 
5361  | 0  |         static_cast<float>(nSecond), nTZFlag);  | 
5362  | 0  | }  | 
5363  |  |  | 
5364  |  | /************************************************************************/  | 
5365  |  | /*                      OGR_F_SetFieldDateTimeEx()                      */  | 
5366  |  | /************************************************************************/  | 
5367  |  |  | 
5368  |  | /**  | 
5369  |  |  * \brief Set field to datetime.  | 
5370  |  |  *  | 
5371  |  |  * This method currently only has an effect for OFTDate, OFTTime and OFTDateTime  | 
5372  |  |  * fields.  | 
5373  |  |  *  | 
5374  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5375  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5376  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5377  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5378  |  |  *  | 
5379  |  |  * @param hFeat handle to the feature that owned the field.  | 
5380  |  |  * @param iField the field to set, from 0 to GetFieldCount()-1.  | 
5381  |  |  * @param nYear (including century)  | 
5382  |  |  * @param nMonth (1-12)  | 
5383  |  |  * @param nDay (1-31)  | 
5384  |  |  * @param nHour (0-23)  | 
5385  |  |  * @param nMinute (0-59)  | 
5386  |  |  * @param fSecond (0-59, with millisecond accuracy)  | 
5387  |  |  * @param nTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)  | 
5388  |  |  *  | 
5389  |  |  * @since GDAL 2.0  | 
5390  |  |  */  | 
5391  |  |  | 
5392  |  | void OGR_F_SetFieldDateTimeEx(OGRFeatureH hFeat, int iField, int nYear,  | 
5393  |  |                               int nMonth, int nDay, int nHour, int nMinute,  | 
5394  |  |                               float fSecond, int nTZFlag)  | 
5395  |  |  | 
5396  | 0  | { | 
5397  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldDateTimeEx");  | 
5398  |  |  | 
5399  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, nYear, nMonth, nDay, nHour,  | 
5400  | 0  |                                             nMinute, fSecond, nTZFlag);  | 
5401  | 0  | }  | 
5402  |  |  | 
5403  |  | /************************************************************************/  | 
5404  |  | /*                              SetField()                              */  | 
5405  |  | /************************************************************************/  | 
5406  |  |  | 
5407  |  | /**  | 
5408  |  |  * \fn OGRFeature::SetField( const char* pszFName, const OGRField * puValue )  | 
5409  |  |  * \brief Set field.  | 
5410  |  |  *  | 
5411  |  |  * The passed value OGRField must be of exactly the same type as the  | 
5412  |  |  * target field, or an application crash may occur.  The passed value  | 
5413  |  |  * is copied, and will not be affected.  It remains the responsibility of  | 
5414  |  |  * the caller.  | 
5415  |  |  *  | 
5416  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5417  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5418  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5419  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5420  |  |  *  | 
5421  |  |  * @param pszFName the name of the field to set.  | 
5422  |  |  * @param puValue the value to assign.  | 
5423  |  |  */  | 
5424  |  |  | 
5425  |  | /**  | 
5426  |  |  * \brief Set field.  | 
5427  |  |  *  | 
5428  |  |  * The passed value OGRField must be of exactly the same type as the  | 
5429  |  |  * target field, or an application crash may occur.  The passed value  | 
5430  |  |  * is copied, and will not be affected.  It remains the responsibility of  | 
5431  |  |  * the caller.  | 
5432  |  |  *  | 
5433  |  |  * This method is the same as the C function OGR_F_SetFieldRaw().  | 
5434  |  |  *  | 
5435  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5436  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5437  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5438  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5439  |  |  *  | 
5440  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
5441  |  |  * @param puValue the value to assign.  | 
5442  |  |  */  | 
5443  |  |  | 
5444  |  | void OGRFeature::SetField(int iField, const OGRField *puValue)  | 
5445  |  |  | 
5446  | 0  | { | 
5447  | 0  |     SetFieldInternal(iField, puValue);  | 
5448  | 0  | }  | 
5449  |  |  | 
5450  |  | bool OGRFeature::SetFieldInternal(int iField, const OGRField *puValue)  | 
5451  |  |  | 
5452  | 0  | { | 
5453  | 0  |     OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);  | 
5454  | 0  |     if (iField < 0 || poFDefn == nullptr)  | 
5455  | 0  |         return false;  | 
5456  |  |  | 
5457  | 0  |     if (poFDefn->GetType() == OFTInteger)  | 
5458  | 0  |     { | 
5459  | 0  |         pauFields[iField] = *puValue;  | 
5460  | 0  |     }  | 
5461  | 0  |     else if (poFDefn->GetType() == OFTInteger64)  | 
5462  | 0  |     { | 
5463  | 0  |         pauFields[iField] = *puValue;  | 
5464  | 0  |     }  | 
5465  | 0  |     else if (poFDefn->GetType() == OFTReal)  | 
5466  | 0  |     { | 
5467  | 0  |         pauFields[iField] = *puValue;  | 
5468  | 0  |     }  | 
5469  | 0  |     else if (poFDefn->GetType() == OFTString)  | 
5470  | 0  |     { | 
5471  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
5472  | 0  |             CPLFree(pauFields[iField].String);  | 
5473  |  | 
  | 
5474  | 0  |         if (puValue->String == nullptr)  | 
5475  | 0  |             pauFields[iField].String = nullptr;  | 
5476  | 0  |         else if (OGR_RawField_IsUnset(puValue) || OGR_RawField_IsNull(puValue))  | 
5477  | 0  |             pauFields[iField] = *puValue;  | 
5478  | 0  |         else  | 
5479  | 0  |         { | 
5480  | 0  |             pauFields[iField].String = VSI_STRDUP_VERBOSE(puValue->String);  | 
5481  | 0  |             if (pauFields[iField].String == nullptr)  | 
5482  | 0  |             { | 
5483  | 0  |                 OGR_RawField_SetUnset(&pauFields[iField]);  | 
5484  | 0  |                 return false;  | 
5485  | 0  |             }  | 
5486  | 0  |         }  | 
5487  | 0  |     }  | 
5488  | 0  |     else if (poFDefn->GetType() == OFTDate || poFDefn->GetType() == OFTTime ||  | 
5489  | 0  |              poFDefn->GetType() == OFTDateTime)  | 
5490  | 0  |     { | 
5491  | 0  |         memcpy(pauFields + iField, puValue, sizeof(OGRField));  | 
5492  | 0  |     }  | 
5493  | 0  |     else if (poFDefn->GetType() == OFTIntegerList)  | 
5494  | 0  |     { | 
5495  | 0  |         const int nCount = puValue->IntegerList.nCount;  | 
5496  |  | 
  | 
5497  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
5498  | 0  |             CPLFree(pauFields[iField].IntegerList.paList);  | 
5499  |  | 
  | 
5500  | 0  |         if (OGR_RawField_IsUnset(puValue) || OGR_RawField_IsNull(puValue))  | 
5501  | 0  |         { | 
5502  | 0  |             pauFields[iField] = *puValue;  | 
5503  | 0  |         }  | 
5504  | 0  |         else  | 
5505  | 0  |         { | 
5506  | 0  |             pauFields[iField].IntegerList.paList =  | 
5507  | 0  |                 static_cast<int *>(VSI_MALLOC_VERBOSE(sizeof(int) * nCount));  | 
5508  | 0  |             if (pauFields[iField].IntegerList.paList == nullptr)  | 
5509  | 0  |             { | 
5510  | 0  |                 OGR_RawField_SetUnset(&pauFields[iField]);  | 
5511  | 0  |                 return false;  | 
5512  | 0  |             }  | 
5513  | 0  |             if (nCount > 0)  | 
5514  | 0  |             { | 
5515  | 0  |                 memcpy(pauFields[iField].IntegerList.paList,  | 
5516  | 0  |                        puValue->IntegerList.paList, sizeof(int) * nCount);  | 
5517  | 0  |             }  | 
5518  | 0  |             pauFields[iField].IntegerList.nCount = nCount;  | 
5519  | 0  |         }  | 
5520  | 0  |     }  | 
5521  | 0  |     else if (poFDefn->GetType() == OFTInteger64List)  | 
5522  | 0  |     { | 
5523  | 0  |         const int nCount = puValue->Integer64List.nCount;  | 
5524  |  | 
  | 
5525  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
5526  | 0  |             CPLFree(pauFields[iField].Integer64List.paList);  | 
5527  |  | 
  | 
5528  | 0  |         if (OGR_RawField_IsUnset(puValue) || OGR_RawField_IsNull(puValue))  | 
5529  | 0  |         { | 
5530  | 0  |             pauFields[iField] = *puValue;  | 
5531  | 0  |         }  | 
5532  | 0  |         else  | 
5533  | 0  |         { | 
5534  | 0  |             pauFields[iField].Integer64List.paList = static_cast<GIntBig *>(  | 
5535  | 0  |                 VSI_MALLOC_VERBOSE(sizeof(GIntBig) * nCount));  | 
5536  | 0  |             if (pauFields[iField].Integer64List.paList == nullptr)  | 
5537  | 0  |             { | 
5538  | 0  |                 OGR_RawField_SetUnset(&pauFields[iField]);  | 
5539  | 0  |                 return false;  | 
5540  | 0  |             }  | 
5541  | 0  |             if (nCount > 0)  | 
5542  | 0  |             { | 
5543  | 0  |                 memcpy(pauFields[iField].Integer64List.paList,  | 
5544  | 0  |                        puValue->Integer64List.paList, sizeof(GIntBig) * nCount);  | 
5545  | 0  |             }  | 
5546  | 0  |             pauFields[iField].Integer64List.nCount = nCount;  | 
5547  | 0  |         }  | 
5548  | 0  |     }  | 
5549  | 0  |     else if (poFDefn->GetType() == OFTRealList)  | 
5550  | 0  |     { | 
5551  | 0  |         const int nCount = puValue->RealList.nCount;  | 
5552  |  | 
  | 
5553  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
5554  | 0  |             CPLFree(pauFields[iField].RealList.paList);  | 
5555  |  | 
  | 
5556  | 0  |         if (OGR_RawField_IsUnset(puValue) || OGR_RawField_IsNull(puValue))  | 
5557  | 0  |         { | 
5558  | 0  |             pauFields[iField] = *puValue;  | 
5559  | 0  |         }  | 
5560  | 0  |         else  | 
5561  | 0  |         { | 
5562  | 0  |             pauFields[iField].RealList.paList = static_cast<double *>(  | 
5563  | 0  |                 VSI_MALLOC_VERBOSE(sizeof(double) * nCount));  | 
5564  | 0  |             if (pauFields[iField].RealList.paList == nullptr)  | 
5565  | 0  |             { | 
5566  | 0  |                 OGR_RawField_SetUnset(&pauFields[iField]);  | 
5567  | 0  |                 return false;  | 
5568  | 0  |             }  | 
5569  | 0  |             if (nCount > 0)  | 
5570  | 0  |             { | 
5571  | 0  |                 memcpy(pauFields[iField].RealList.paList,  | 
5572  | 0  |                        puValue->RealList.paList, sizeof(double) * nCount);  | 
5573  | 0  |             }  | 
5574  | 0  |             pauFields[iField].RealList.nCount = nCount;  | 
5575  | 0  |         }  | 
5576  | 0  |     }  | 
5577  | 0  |     else if (poFDefn->GetType() == OFTStringList)  | 
5578  | 0  |     { | 
5579  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
5580  | 0  |             CSLDestroy(pauFields[iField].StringList.paList);  | 
5581  |  | 
  | 
5582  | 0  |         if (OGR_RawField_IsUnset(puValue) || OGR_RawField_IsNull(puValue))  | 
5583  | 0  |         { | 
5584  | 0  |             pauFields[iField] = *puValue;  | 
5585  | 0  |         }  | 
5586  | 0  |         else  | 
5587  | 0  |         { | 
5588  | 0  |             char **papszNewList = nullptr;  | 
5589  | 0  |             for (char **papszIter = puValue->StringList.paList;  | 
5590  | 0  |                  papszIter != nullptr && *papszIter != nullptr; ++papszIter)  | 
5591  | 0  |             { | 
5592  | 0  |                 char **papszNewList2 =  | 
5593  | 0  |                     CSLAddStringMayFail(papszNewList, *papszIter);  | 
5594  | 0  |                 if (papszNewList2 == nullptr)  | 
5595  | 0  |                 { | 
5596  | 0  |                     CSLDestroy(papszNewList);  | 
5597  | 0  |                     OGR_RawField_SetUnset(&pauFields[iField]);  | 
5598  | 0  |                     return false;  | 
5599  | 0  |                 }  | 
5600  | 0  |                 papszNewList = papszNewList2;  | 
5601  | 0  |             }  | 
5602  | 0  |             pauFields[iField].StringList.paList = papszNewList;  | 
5603  | 0  |             pauFields[iField].StringList.nCount = puValue->StringList.nCount;  | 
5604  | 0  |             CPLAssert(CSLCount(puValue->StringList.paList) ==  | 
5605  | 0  |                       puValue->StringList.nCount);  | 
5606  | 0  |         }  | 
5607  | 0  |     }  | 
5608  | 0  |     else if (poFDefn->GetType() == OFTBinary)  | 
5609  | 0  |     { | 
5610  | 0  |         if (IsFieldSetAndNotNullUnsafe(iField))  | 
5611  | 0  |             CPLFree(pauFields[iField].Binary.paData);  | 
5612  |  | 
  | 
5613  | 0  |         if (OGR_RawField_IsUnset(puValue) || OGR_RawField_IsNull(puValue))  | 
5614  | 0  |         { | 
5615  | 0  |             pauFields[iField] = *puValue;  | 
5616  | 0  |         }  | 
5617  | 0  |         else  | 
5618  | 0  |         { | 
5619  | 0  |             pauFields[iField].Binary.paData = static_cast<GByte *>(  | 
5620  | 0  |                 VSI_MALLOC_VERBOSE(puValue->Binary.nCount));  | 
5621  | 0  |             if (pauFields[iField].Binary.paData == nullptr)  | 
5622  | 0  |             { | 
5623  | 0  |                 OGR_RawField_SetUnset(&pauFields[iField]);  | 
5624  | 0  |                 return false;  | 
5625  | 0  |             }  | 
5626  | 0  |             if (puValue->Binary.nCount > 0)  | 
5627  | 0  |             { | 
5628  | 0  |                 memcpy(pauFields[iField].Binary.paData, puValue->Binary.paData,  | 
5629  | 0  |                        puValue->Binary.nCount);  | 
5630  | 0  |             }  | 
5631  | 0  |             pauFields[iField].Binary.nCount = puValue->Binary.nCount;  | 
5632  | 0  |         }  | 
5633  | 0  |     }  | 
5634  | 0  |     else  | 
5635  | 0  |     { | 
5636  |  |         // Do nothing for other field types.  | 
5637  | 0  |     }  | 
5638  | 0  |     return true;  | 
5639  | 0  | }  | 
5640  |  |  | 
5641  |  | /************************************************************************/  | 
5642  |  | /*                      OGR_F_SetFieldRaw()                             */  | 
5643  |  | /************************************************************************/  | 
5644  |  |  | 
5645  |  | /**  | 
5646  |  |  * \brief Set field.  | 
5647  |  |  *  | 
5648  |  |  * The passed value OGRField must be of exactly the same type as the  | 
5649  |  |  * target field, or an application crash may occur.  The passed value  | 
5650  |  |  * is copied, and will not be affected.  It remains the responsibility of  | 
5651  |  |  * the caller.  | 
5652  |  |  *  | 
5653  |  |  * This function is the same as the C++ method OGRFeature::SetField().  | 
5654  |  |  *  | 
5655  |  |  * @note This method has only an effect on the in-memory feature object. If  | 
5656  |  |  * this object comes from a layer and the modifications must be serialized back  | 
5657  |  |  * to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is  | 
5658  |  |  * a new feature, OGR_L_CreateFeature() must be used afterwards.  | 
5659  |  |  *  | 
5660  |  |  * @param hFeat handle to the feature that owned the field.  | 
5661  |  |  * @param iField the field to fetch, from 0 to GetFieldCount()-1.  | 
5662  |  |  * @param psValue handle on the value to assign.  | 
5663  |  |  */  | 
5664  |  |  | 
5665  |  | void OGR_F_SetFieldRaw(OGRFeatureH hFeat, int iField, const OGRField *psValue)  | 
5666  |  |  | 
5667  | 0  | { | 
5668  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetFieldRaw");  | 
5669  |  |  | 
5670  | 0  |     OGRFeature::FromHandle(hFeat)->SetField(iField, psValue);  | 
5671  | 0  | }  | 
5672  |  |  | 
5673  |  | /************************************************************************/  | 
5674  |  | /*                            DumpReadable()                            */  | 
5675  |  | /************************************************************************/  | 
5676  |  |  | 
5677  |  | /**  | 
5678  |  |  * \brief Dump this feature in a human readable form.  | 
5679  |  |  *  | 
5680  |  |  * This dumps the attributes, and geometry; however, it doesn't definition  | 
5681  |  |  * information (other than field types and names), nor does it report the  | 
5682  |  |  * geometry spatial reference system.  | 
5683  |  |  *  | 
5684  |  |  * A few options can be defined to change the default dump :  | 
5685  |  |  * <ul>  | 
5686  |  |  * <li>DISPLAY_FIELDS=NO : to hide the dump of the attributes</li>  | 
5687  |  |  * <li>DISPLAY_STYLE=NO : to hide the dump of the style string</li>  | 
5688  |  |  * <li>DISPLAY_GEOMETRY=NO : to hide the dump of the geometry</li>  | 
5689  |  |  * <li>DISPLAY_GEOMETRY=SUMMARY : to get only a summary of the geometry</li>  | 
5690  |  |  * </ul>  | 
5691  |  |  *  | 
5692  |  |  * This method is the same as the C function OGR_F_DumpReadable().  | 
5693  |  |  *  | 
5694  |  |  * @param fpOut the stream to write to, such as stdout.  If NULL stdout will  | 
5695  |  |  * be used.  | 
5696  |  |  * @param papszOptions NULL terminated list of options (may be NULL)  | 
5697  |  |  */  | 
5698  |  |  | 
5699  |  | void OGRFeature::DumpReadable(FILE *fpOut, CSLConstList papszOptions) const  | 
5700  |  |  | 
5701  | 0  | { | 
5702  | 0  |     if (fpOut == nullptr)  | 
5703  | 0  |         fpOut = stdout;  | 
5704  |  | 
  | 
5705  | 0  |     const auto osStr = DumpReadableAsString(papszOptions);  | 
5706  | 0  |     fprintf(fpOut, "%s", osStr.c_str());  | 
5707  | 0  | }  | 
5708  |  |  | 
5709  |  | /************************************************************************/  | 
5710  |  | /*                       DumpReadableAsString()                         */  | 
5711  |  | /************************************************************************/  | 
5712  |  |  | 
5713  |  | /**  | 
5714  |  |  * \brief Dump this feature in a human readable form.  | 
5715  |  |  *  | 
5716  |  |  * This dumps the attributes, and geometry; however, it doesn't definition  | 
5717  |  |  * information (other than field types and names), nor does it report the  | 
5718  |  |  * geometry spatial reference system.  | 
5719  |  |  *  | 
5720  |  |  * A few options can be defined to change the default dump :  | 
5721  |  |  * <ul>  | 
5722  |  |  * <li>DISPLAY_FIELDS=NO : to hide the dump of the attributes</li>  | 
5723  |  |  * <li>DISPLAY_STYLE=NO : to hide the dump of the style string</li>  | 
5724  |  |  * <li>DISPLAY_GEOMETRY=NO : to hide the dump of the geometry</li>  | 
5725  |  |  * <li>DISPLAY_GEOMETRY=SUMMARY : to get only a summary of the geometry</li>  | 
5726  |  |  * </ul>  | 
5727  |  |  *  | 
5728  |  |  * @param papszOptions NULL terminated list of options (may be NULL)  | 
5729  |  |  * @return a string with the feature representation.  | 
5730  |  |  * @since GDAL 3.7  | 
5731  |  |  */  | 
5732  |  |  | 
5733  |  | std::string OGRFeature::DumpReadableAsString(CSLConstList papszOptions) const  | 
5734  | 0  | { | 
5735  | 0  |     std::string osRet;  | 
5736  |  | 
  | 
5737  | 0  |     osRet += CPLOPrintf("OGRFeature(%s):" CPL_FRMT_GIB "\n", poDefn->GetName(), | 
5738  | 0  |                         GetFID());  | 
5739  |  | 
  | 
5740  | 0  |     const char *pszDisplayFields =  | 
5741  | 0  |         CSLFetchNameValue(papszOptions, "DISPLAY_FIELDS");  | 
5742  | 0  |     if (pszDisplayFields == nullptr || CPLTestBool(pszDisplayFields))  | 
5743  | 0  |     { | 
5744  | 0  |         const int nFieldCount = GetFieldCount();  | 
5745  | 0  |         for (int iField = 0; iField < nFieldCount; iField++)  | 
5746  | 0  |         { | 
5747  | 0  |             if (!IsFieldSet(iField))  | 
5748  | 0  |                 continue;  | 
5749  | 0  |             const OGRFieldDefn *poFDefn = poDefn->GetFieldDefnUnsafe(iField);  | 
5750  |  | 
  | 
5751  | 0  |             const char *pszType =  | 
5752  | 0  |                 (poFDefn->GetSubType() != OFSTNone)  | 
5753  | 0  |                     ? CPLSPrintf(  | 
5754  | 0  |                           "%s(%s)",  | 
5755  | 0  |                           poFDefn->GetFieldTypeName(poFDefn->GetType()),  | 
5756  | 0  |                           poFDefn->GetFieldSubTypeName(poFDefn->GetSubType()))  | 
5757  | 0  |                     : poFDefn->GetFieldTypeName(poFDefn->GetType());  | 
5758  |  | 
  | 
5759  | 0  |             osRet += CPLOPrintf("  %s (%s) = ", poFDefn->GetNameRef(), pszType); | 
5760  |  | 
  | 
5761  | 0  |             if (IsFieldNull(iField))  | 
5762  | 0  |                 osRet += "(null)\n";  | 
5763  | 0  |             else  | 
5764  | 0  |                 osRet += CPLOPrintf("%s\n", GetFieldAsString(iField)); | 
5765  | 0  |         }  | 
5766  | 0  |     }  | 
5767  |  | 
  | 
5768  | 0  |     if (GetStyleString() != nullptr)  | 
5769  | 0  |     { | 
5770  | 0  |         const char *pszDisplayStyle =  | 
5771  | 0  |             CSLFetchNameValue(papszOptions, "DISPLAY_STYLE");  | 
5772  | 0  |         if (pszDisplayStyle == nullptr || CPLTestBool(pszDisplayStyle))  | 
5773  | 0  |         { | 
5774  | 0  |             osRet += CPLOPrintf("  Style = %s\n", GetStyleString()); | 
5775  | 0  |         }  | 
5776  | 0  |     }  | 
5777  |  | 
  | 
5778  | 0  |     const int nGeomFieldCount = GetGeomFieldCount();  | 
5779  | 0  |     if (nGeomFieldCount > 0)  | 
5780  | 0  |     { | 
5781  | 0  |         const char *pszDisplayGeometry =  | 
5782  | 0  |             CSLFetchNameValue(papszOptions, "DISPLAY_GEOMETRY");  | 
5783  | 0  |         if (!(pszDisplayGeometry != nullptr && EQUAL(pszDisplayGeometry, "NO")))  | 
5784  | 0  |         { | 
5785  | 0  |             for (int iField = 0; iField < nGeomFieldCount; iField++)  | 
5786  | 0  |             { | 
5787  | 0  |                 const OGRGeomFieldDefn *poFDefn =  | 
5788  | 0  |                     poDefn->GetGeomFieldDefn(iField);  | 
5789  |  | 
  | 
5790  | 0  |                 if (papoGeometries[iField] != nullptr)  | 
5791  | 0  |                 { | 
5792  | 0  |                     CPLStringList aosGeomOptions(papszOptions);  | 
5793  |  | 
  | 
5794  | 0  |                     const auto &oCoordPrec = poFDefn->GetCoordinatePrecision();  | 
5795  |  | 
  | 
5796  | 0  |                     if (oCoordPrec.dfXYResolution !=  | 
5797  | 0  |                         OGRGeomCoordinatePrecision::UNKNOWN)  | 
5798  | 0  |                     { | 
5799  | 0  |                         aosGeomOptions.SetNameValue(  | 
5800  | 0  |                             "XY_COORD_PRECISION",  | 
5801  | 0  |                             CPLSPrintf("%d", | 
5802  | 0  |                                        OGRGeomCoordinatePrecision::  | 
5803  | 0  |                                            ResolutionToPrecision(  | 
5804  | 0  |                                                oCoordPrec.dfXYResolution)));  | 
5805  | 0  |                     }  | 
5806  | 0  |                     if (oCoordPrec.dfZResolution !=  | 
5807  | 0  |                         OGRGeomCoordinatePrecision::UNKNOWN)  | 
5808  | 0  |                     { | 
5809  | 0  |                         aosGeomOptions.SetNameValue(  | 
5810  | 0  |                             "Z_COORD_PRECISION",  | 
5811  | 0  |                             CPLSPrintf("%d", | 
5812  | 0  |                                        OGRGeomCoordinatePrecision::  | 
5813  | 0  |                                            ResolutionToPrecision(  | 
5814  | 0  |                                                oCoordPrec.dfZResolution)));  | 
5815  | 0  |                     }  | 
5816  |  | 
  | 
5817  | 0  |                     osRet += "  ";  | 
5818  | 0  |                     if (strlen(poFDefn->GetNameRef()) > 0 &&  | 
5819  | 0  |                         GetGeomFieldCount() > 1)  | 
5820  | 0  |                         osRet += CPLOPrintf("%s = ", poFDefn->GetNameRef()); | 
5821  | 0  |                     osRet += papoGeometries[iField]->dumpReadable(  | 
5822  | 0  |                         nullptr, aosGeomOptions.List());  | 
5823  | 0  |                 }  | 
5824  | 0  |             }  | 
5825  | 0  |         }  | 
5826  | 0  |     }  | 
5827  |  | 
  | 
5828  | 0  |     osRet += "\n";  | 
5829  | 0  |     return osRet;  | 
5830  | 0  | }  | 
5831  |  |  | 
5832  |  | /************************************************************************/  | 
5833  |  | /*                         OGR_F_DumpReadable()                         */  | 
5834  |  | /************************************************************************/  | 
5835  |  |  | 
5836  |  | /**  | 
5837  |  |  * \brief Dump this feature in a human readable form.  | 
5838  |  |  *  | 
5839  |  |  * This dumps the attributes, and geometry; however, it doesn't definition  | 
5840  |  |  * information (other than field types and names), nor does it report the  | 
5841  |  |  * geometry spatial reference system.  | 
5842  |  |  *  | 
5843  |  |  * This function is the same as the C++ method OGRFeature::DumpReadable().  | 
5844  |  |  *  | 
5845  |  |  * @param hFeat handle to the feature to dump.  | 
5846  |  |  * @param fpOut the stream to write to, such as strout.  | 
5847  |  |  */  | 
5848  |  |  | 
5849  |  | void OGR_F_DumpReadable(OGRFeatureH hFeat, FILE *fpOut)  | 
5850  |  |  | 
5851  | 0  | { | 
5852  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_DumpReadable");  | 
5853  |  |  | 
5854  | 0  |     OGRFeature::FromHandle(hFeat)->DumpReadable(fpOut);  | 
5855  | 0  | }  | 
5856  |  |  | 
5857  |  | /************************************************************************/  | 
5858  |  | /*                         OGR_F_DumpReadableAsString()                 */  | 
5859  |  | /************************************************************************/  | 
5860  |  |  | 
5861  |  | /**  | 
5862  |  |  * \brief Dump this feature in a human readable form.  | 
5863  |  |  *  | 
5864  |  |  * This dumps the attributes, and geometry; however, it doesn't include  | 
5865  |  |  * definition information (other than field types and names), nor does  | 
5866  |  |  * it report the geometry spatial reference system.  | 
5867  |  |  *  | 
5868  |  |  * A few options can be defined to change the default dump :  | 
5869  |  |  * <ul>  | 
5870  |  |  * <li>DISPLAY_FIELDS=NO : to hide the dump of the attributes</li>  | 
5871  |  |  * <li>DISPLAY_STYLE=NO : to hide the dump of the style string</li>  | 
5872  |  |  * <li>DISPLAY_GEOMETRY=NO : to hide the dump of the geometry</li>  | 
5873  |  |  * <li>DISPLAY_GEOMETRY=SUMMARY : to get only a summary of the geometry</li>  | 
5874  |  |  * </ul>  | 
5875  |  |  *  | 
5876  |  |  * @param hFeat handle to the feature to dump.  | 
5877  |  |  * @param papszOptions NULL terminated list of options (may be NULL)  | 
5878  |  |  * @return a string with the feature representation (to be freed with CPLFree())  | 
5879  |  |  * @since GDAL 3.8  | 
5880  |  |  */  | 
5881  |  |  | 
5882  |  | char *OGR_F_DumpReadableAsString(OGRFeatureH hFeat, CSLConstList papszOptions)  | 
5883  | 0  | { | 
5884  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_DumpReadableAsString", nullptr);  | 
5885  |  |  | 
5886  | 0  |     return CPLStrdup(OGRFeature::FromHandle(hFeat)  | 
5887  | 0  |                          ->DumpReadableAsString(papszOptions)  | 
5888  | 0  |                          .c_str());  | 
5889  | 0  | }  | 
5890  |  |  | 
5891  |  | /************************************************************************/  | 
5892  |  | /*                               GetFID()                               */  | 
5893  |  | /************************************************************************/  | 
5894  |  |  | 
5895  |  | /**  | 
5896  |  |  * \fn GIntBig OGRFeature::GetFID() const;  | 
5897  |  |  *  | 
5898  |  |  * \brief Get feature identifier.  | 
5899  |  |  *  | 
5900  |  |  * This method is the same as the C function OGR_F_GetFID().  | 
5901  |  |  * Note: since GDAL 2.0, this method returns a GIntBig (previously a long)  | 
5902  |  |  *  | 
5903  |  |  * @return feature id or OGRNullFID if none has been assigned.  | 
5904  |  |  */  | 
5905  |  |  | 
5906  |  | /************************************************************************/  | 
5907  |  | /*                            OGR_F_GetFID()                          */  | 
5908  |  | /************************************************************************/  | 
5909  |  |  | 
5910  |  | /**  | 
5911  |  |  * \brief Get feature identifier.  | 
5912  |  |  *  | 
5913  |  |  * This function is the same as the C++ method OGRFeature::GetFID().  | 
5914  |  |  * Note: since GDAL 2.0, this method returns a GIntBig (previously a long)  | 
5915  |  |  *  | 
5916  |  |  * @param hFeat handle to the feature from which to get the feature  | 
5917  |  |  * identifier.  | 
5918  |  |  * @return feature id or OGRNullFID if none has been assigned.  | 
5919  |  |  */  | 
5920  |  |  | 
5921  |  | GIntBig OGR_F_GetFID(OGRFeatureH hFeat)  | 
5922  |  |  | 
5923  | 0  | { | 
5924  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetFID", 0);  | 
5925  |  |  | 
5926  | 0  |     return OGRFeature::FromHandle(hFeat)->GetFID();  | 
5927  | 0  | }  | 
5928  |  |  | 
5929  |  | /************************************************************************/  | 
5930  |  | /*                               SetFID()                               */  | 
5931  |  | /************************************************************************/  | 
5932  |  |  | 
5933  |  | /**  | 
5934  |  |  * \brief Set the feature identifier.  | 
5935  |  |  *  | 
5936  |  |  * For specific types of features this operation may fail on illegal  | 
5937  |  |  * features ids.  Generally it always succeeds.  Feature ids should be  | 
5938  |  |  * greater than or equal to zero, with the exception of OGRNullFID (-1)  | 
5939  |  |  * indicating that the feature id is unknown.  | 
5940  |  |  *  | 
5941  |  |  * This method is the same as the C function OGR_F_SetFID().  | 
5942  |  |  *  | 
5943  |  |  * @param nFIDIn the new feature identifier value to assign.  | 
5944  |  |  *  | 
5945  |  |  * @return On success OGRERR_NONE, or on failure some other value.  | 
5946  |  |  */  | 
5947  |  |  | 
5948  |  | OGRErr OGRFeature::SetFID(GIntBig nFIDIn)  | 
5949  |  |  | 
5950  | 0  | { | 
5951  | 0  |     nFID = nFIDIn;  | 
5952  |  | 
  | 
5953  | 0  |     return OGRERR_NONE;  | 
5954  | 0  | }  | 
5955  |  |  | 
5956  |  | /************************************************************************/  | 
5957  |  | /*                            OGR_F_SetFID()                            */  | 
5958  |  | /************************************************************************/  | 
5959  |  |  | 
5960  |  | /**  | 
5961  |  |  * \brief Set the feature identifier.  | 
5962  |  |  *  | 
5963  |  |  * For specific types of features this operation may fail on illegal  | 
5964  |  |  * features ids.  Generally it always succeeds.  Feature ids should be  | 
5965  |  |  * greater than or equal to zero, with the exception of OGRNullFID (-1)  | 
5966  |  |  * indicating that the feature id is unknown.  | 
5967  |  |  *  | 
5968  |  |  * This function is the same as the C++ method OGRFeature::SetFID().  | 
5969  |  |  *  | 
5970  |  |  * @param hFeat handle to the feature to set the feature id to.  | 
5971  |  |  * @param nFID the new feature identifier value to assign.  | 
5972  |  |  *  | 
5973  |  |  * @return On success OGRERR_NONE, or on failure some other value.  | 
5974  |  |  */  | 
5975  |  |  | 
5976  |  | OGRErr OGR_F_SetFID(OGRFeatureH hFeat, GIntBig nFID)  | 
5977  |  |  | 
5978  | 0  | { | 
5979  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_SetFID", OGRERR_FAILURE);  | 
5980  |  |  | 
5981  | 0  |     return OGRFeature::FromHandle(hFeat)->SetFID(nFID);  | 
5982  | 0  | }  | 
5983  |  |  | 
5984  |  | /************************************************************************/  | 
5985  |  | /*                               Equal()                                */  | 
5986  |  | /************************************************************************/  | 
5987  |  |  | 
5988  |  | /**  | 
5989  |  |  * \brief Test if two features are the same.  | 
5990  |  |  *  | 
5991  |  |  * Two features are considered equal if the share them (pointer equality)  | 
5992  |  |  * same OGRFeatureDefn, have the same field values, and the same geometry  | 
5993  |  |  * (as tested by OGRGeometry::Equal()) as well as the same feature id.  | 
5994  |  |  *  | 
5995  |  |  * This method is the same as the C function OGR_F_Equal().  | 
5996  |  |  *  | 
5997  |  |  * @param poFeature the other feature to test this one against.  | 
5998  |  |  *  | 
5999  |  |  * @return TRUE if they are equal, otherwise FALSE.  | 
6000  |  |  */  | 
6001  |  |  | 
6002  |  | OGRBoolean OGRFeature::Equal(const OGRFeature *poFeature) const  | 
6003  |  |  | 
6004  | 0  | { | 
6005  | 0  |     if (poFeature == this)  | 
6006  | 0  |         return TRUE;  | 
6007  |  |  | 
6008  | 0  |     if (GetFID() != poFeature->GetFID())  | 
6009  | 0  |         return FALSE;  | 
6010  |  |  | 
6011  | 0  |     if (GetDefnRef() != poFeature->GetDefnRef())  | 
6012  | 0  |         return FALSE;  | 
6013  |  |  | 
6014  | 0  |     const int nFields = GetDefnRef()->GetFieldCountUnsafe();  | 
6015  | 0  |     for (int i = 0; i < nFields; i++)  | 
6016  | 0  |     { | 
6017  | 0  |         if (IsFieldSet(i) != poFeature->IsFieldSet(i))  | 
6018  | 0  |             return FALSE;  | 
6019  | 0  |         if (IsFieldNull(i) != poFeature->IsFieldNull(i))  | 
6020  | 0  |             return FALSE;  | 
6021  | 0  |         if (!IsFieldSetAndNotNullUnsafe(i))  | 
6022  | 0  |             continue;  | 
6023  |  |  | 
6024  | 0  |         switch (GetDefnRef()->GetFieldDefnUnsafe(i)->GetType())  | 
6025  | 0  |         { | 
6026  | 0  |             case OFTInteger:  | 
6027  | 0  |                 if (GetFieldAsInteger(i) != poFeature->GetFieldAsInteger(i))  | 
6028  | 0  |                     return FALSE;  | 
6029  | 0  |                 break;  | 
6030  |  |  | 
6031  | 0  |             case OFTInteger64:  | 
6032  | 0  |                 if (GetFieldAsInteger64(i) != poFeature->GetFieldAsInteger64(i))  | 
6033  | 0  |                     return FALSE;  | 
6034  | 0  |                 break;  | 
6035  |  |  | 
6036  | 0  |             case OFTReal:  | 
6037  | 0  |             { | 
6038  | 0  |                 const double dfVal1 = GetFieldAsDouble(i);  | 
6039  | 0  |                 const double dfVal2 = poFeature->GetFieldAsDouble(i);  | 
6040  | 0  |                 if (std::isnan(dfVal1))  | 
6041  | 0  |                 { | 
6042  | 0  |                     if (!std::isnan(dfVal2))  | 
6043  | 0  |                         return FALSE;  | 
6044  | 0  |                 }  | 
6045  | 0  |                 else if (std::isnan(dfVal2))  | 
6046  | 0  |                 { | 
6047  | 0  |                     return FALSE;  | 
6048  | 0  |                 }  | 
6049  | 0  |                 else if (dfVal1 != dfVal2)  | 
6050  | 0  |                 { | 
6051  | 0  |                     return FALSE;  | 
6052  | 0  |                 }  | 
6053  | 0  |                 break;  | 
6054  | 0  |             }  | 
6055  |  |  | 
6056  | 0  |             case OFTString:  | 
6057  | 0  |                 if (strcmp(GetFieldAsString(i),  | 
6058  | 0  |                            poFeature->GetFieldAsString(i)) != 0)  | 
6059  | 0  |                     return FALSE;  | 
6060  | 0  |                 break;  | 
6061  |  |  | 
6062  | 0  |             case OFTIntegerList:  | 
6063  | 0  |             { | 
6064  | 0  |                 int nCount1 = 0;  | 
6065  | 0  |                 int nCount2 = 0;  | 
6066  | 0  |                 const int *pnList1 = GetFieldAsIntegerList(i, &nCount1);  | 
6067  | 0  |                 const int *pnList2 =  | 
6068  | 0  |                     poFeature->GetFieldAsIntegerList(i, &nCount2);  | 
6069  | 0  |                 if (nCount1 != nCount2)  | 
6070  | 0  |                     return FALSE;  | 
6071  | 0  |                 for (int j = 0; j < nCount1; j++)  | 
6072  | 0  |                 { | 
6073  | 0  |                     if (pnList1[j] != pnList2[j])  | 
6074  | 0  |                         return FALSE;  | 
6075  | 0  |                 }  | 
6076  | 0  |                 break;  | 
6077  | 0  |             }  | 
6078  |  |  | 
6079  | 0  |             case OFTInteger64List:  | 
6080  | 0  |             { | 
6081  | 0  |                 int nCount1 = 0;  | 
6082  | 0  |                 int nCount2 = 0;  | 
6083  | 0  |                 const GIntBig *pnList1 = GetFieldAsInteger64List(i, &nCount1);  | 
6084  | 0  |                 const GIntBig *pnList2 =  | 
6085  | 0  |                     poFeature->GetFieldAsInteger64List(i, &nCount2);  | 
6086  | 0  |                 if (nCount1 != nCount2)  | 
6087  | 0  |                     return FALSE;  | 
6088  | 0  |                 for (int j = 0; j < nCount1; j++)  | 
6089  | 0  |                 { | 
6090  | 0  |                     if (pnList1[j] != pnList2[j])  | 
6091  | 0  |                         return FALSE;  | 
6092  | 0  |                 }  | 
6093  | 0  |                 break;  | 
6094  | 0  |             }  | 
6095  |  |  | 
6096  | 0  |             case OFTRealList:  | 
6097  | 0  |             { | 
6098  | 0  |                 int nCount1 = 0;  | 
6099  | 0  |                 int nCount2 = 0;  | 
6100  | 0  |                 const double *padfList1 = GetFieldAsDoubleList(i, &nCount1);  | 
6101  | 0  |                 const double *padfList2 =  | 
6102  | 0  |                     poFeature->GetFieldAsDoubleList(i, &nCount2);  | 
6103  | 0  |                 if (nCount1 != nCount2)  | 
6104  | 0  |                     return FALSE;  | 
6105  | 0  |                 for (int j = 0; j < nCount1; j++)  | 
6106  | 0  |                 { | 
6107  | 0  |                     const double dfVal1 = padfList1[j];  | 
6108  | 0  |                     const double dfVal2 = padfList2[j];  | 
6109  | 0  |                     if (std::isnan(dfVal1))  | 
6110  | 0  |                     { | 
6111  | 0  |                         if (!std::isnan(dfVal2))  | 
6112  | 0  |                             return FALSE;  | 
6113  | 0  |                     }  | 
6114  | 0  |                     else if (std::isnan(dfVal2))  | 
6115  | 0  |                     { | 
6116  | 0  |                         return FALSE;  | 
6117  | 0  |                     }  | 
6118  | 0  |                     else if (dfVal1 != dfVal2)  | 
6119  | 0  |                     { | 
6120  | 0  |                         return FALSE;  | 
6121  | 0  |                     }  | 
6122  | 0  |                 }  | 
6123  | 0  |                 break;  | 
6124  | 0  |             }  | 
6125  |  |  | 
6126  | 0  |             case OFTStringList:  | 
6127  | 0  |             { | 
6128  | 0  |                 int nCount1 = 0;  | 
6129  | 0  |                 int nCount2 = 0;  | 
6130  | 0  |                 char **papszList1 = GetFieldAsStringList(i);  | 
6131  | 0  |                 char **papszList2 = poFeature->GetFieldAsStringList(i);  | 
6132  | 0  |                 nCount1 = CSLCount(papszList1);  | 
6133  | 0  |                 nCount2 = CSLCount(papszList2);  | 
6134  | 0  |                 if (nCount1 != nCount2)  | 
6135  | 0  |                     return FALSE;  | 
6136  | 0  |                 for (int j = 0; j < nCount1; j++)  | 
6137  | 0  |                 { | 
6138  | 0  |                     if (strcmp(papszList1[j], papszList2[j]) != 0)  | 
6139  | 0  |                         return FALSE;  | 
6140  | 0  |                 }  | 
6141  | 0  |                 break;  | 
6142  | 0  |             }  | 
6143  |  |  | 
6144  | 0  |             case OFTTime:  | 
6145  | 0  |             case OFTDate:  | 
6146  | 0  |             case OFTDateTime:  | 
6147  | 0  |             { | 
6148  | 0  |                 int nYear1 = 0;  | 
6149  | 0  |                 int nMonth1 = 0;  | 
6150  | 0  |                 int nDay1 = 0;  | 
6151  | 0  |                 int nHour1 = 0;  | 
6152  | 0  |                 int nMinute1 = 0;  | 
6153  | 0  |                 int nTZFlag1 = 0;  | 
6154  | 0  |                 int nYear2 = 0;  | 
6155  | 0  |                 int nMonth2 = 0;  | 
6156  | 0  |                 int nDay2 = 0;  | 
6157  | 0  |                 int nHour2 = 0;  | 
6158  | 0  |                 int nMinute2 = 0;  | 
6159  | 0  |                 int nTZFlag2 = 0;  | 
6160  | 0  |                 float fSecond1 = 0.0f;  | 
6161  | 0  |                 float fSecond2 = 0.0f;  | 
6162  | 0  |                 GetFieldAsDateTime(i, &nYear1, &nMonth1, &nDay1, &nHour1,  | 
6163  | 0  |                                    &nMinute1, &fSecond1, &nTZFlag1);  | 
6164  | 0  |                 poFeature->GetFieldAsDateTime(i, &nYear2, &nMonth2, &nDay2,  | 
6165  | 0  |                                               &nHour2, &nMinute2, &fSecond2,  | 
6166  | 0  |                                               &nTZFlag2);  | 
6167  |  | 
  | 
6168  | 0  |                 if (!(nYear1 == nYear2 && nMonth1 == nMonth2 &&  | 
6169  | 0  |                       nDay1 == nDay2 && nHour1 == nHour2 &&  | 
6170  | 0  |                       nMinute1 == nMinute2 && fSecond1 == fSecond2 &&  | 
6171  | 0  |                       nTZFlag1 == nTZFlag2))  | 
6172  | 0  |                     return FALSE;  | 
6173  | 0  |                 break;  | 
6174  | 0  |             }  | 
6175  |  |  | 
6176  | 0  |             case OFTBinary:  | 
6177  | 0  |             { | 
6178  | 0  |                 int nCount1 = 0;  | 
6179  | 0  |                 int nCount2 = 0;  | 
6180  | 0  |                 GByte *pabyData1 = GetFieldAsBinary(i, &nCount1);  | 
6181  | 0  |                 GByte *pabyData2 = poFeature->GetFieldAsBinary(i, &nCount2);  | 
6182  | 0  |                 if (nCount1 != nCount2)  | 
6183  | 0  |                     return FALSE;  | 
6184  | 0  |                 if (memcmp(pabyData1, pabyData2, nCount1) != 0)  | 
6185  | 0  |                     return FALSE;  | 
6186  | 0  |                 break;  | 
6187  | 0  |             }  | 
6188  |  |  | 
6189  | 0  |             default:  | 
6190  | 0  |                 if (strcmp(GetFieldAsString(i),  | 
6191  | 0  |                            poFeature->GetFieldAsString(i)) != 0)  | 
6192  | 0  |                     return FALSE;  | 
6193  | 0  |                 break;  | 
6194  | 0  |         }  | 
6195  | 0  |     }  | 
6196  |  |  | 
6197  | 0  |     const int nGeomFieldCount = GetGeomFieldCount();  | 
6198  | 0  |     for (int i = 0; i < nGeomFieldCount; i++)  | 
6199  | 0  |     { | 
6200  | 0  |         const OGRGeometry *poThisGeom = GetGeomFieldRef(i);  | 
6201  | 0  |         const OGRGeometry *poOtherGeom = poFeature->GetGeomFieldRef(i);  | 
6202  |  | 
  | 
6203  | 0  |         if (poThisGeom == nullptr && poOtherGeom != nullptr)  | 
6204  | 0  |             return FALSE;  | 
6205  |  |  | 
6206  | 0  |         if (poThisGeom != nullptr && poOtherGeom == nullptr)  | 
6207  | 0  |             return FALSE;  | 
6208  |  |  | 
6209  | 0  |         if (poThisGeom != nullptr && poOtherGeom != nullptr &&  | 
6210  | 0  |             (!poThisGeom->Equals(poOtherGeom)))  | 
6211  | 0  |             return FALSE;  | 
6212  | 0  |     }  | 
6213  |  |  | 
6214  | 0  |     return TRUE;  | 
6215  | 0  | }  | 
6216  |  |  | 
6217  |  | /************************************************************************/  | 
6218  |  | /*                            OGR_F_Equal()                             */  | 
6219  |  | /************************************************************************/  | 
6220  |  |  | 
6221  |  | /**  | 
6222  |  |  * \brief Test if two features are the same.  | 
6223  |  |  *  | 
6224  |  |  * Two features are considered equal if the share them (handle equality)  | 
6225  |  |  * same OGRFeatureDefn, have the same field values, and the same geometry  | 
6226  |  |  * (as tested by OGR_G_Equal()) as well as the same feature id.  | 
6227  |  |  *  | 
6228  |  |  * This function is the same as the C++ method OGRFeature::Equal().  | 
6229  |  |  *  | 
6230  |  |  * @param hFeat handle to one of the feature.  | 
6231  |  |  * @param hOtherFeat handle to the other feature to test this one against.  | 
6232  |  |  *  | 
6233  |  |  * @return TRUE if they are equal, otherwise FALSE.  | 
6234  |  |  */  | 
6235  |  |  | 
6236  |  | int OGR_F_Equal(OGRFeatureH hFeat, OGRFeatureH hOtherFeat)  | 
6237  |  |  | 
6238  | 0  | { | 
6239  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_Equal", 0);  | 
6240  | 0  |     VALIDATE_POINTER1(hOtherFeat, "OGR_F_Equal", 0);  | 
6241  |  |  | 
6242  | 0  |     return OGRFeature::FromHandle(hFeat)->Equal(  | 
6243  | 0  |         OGRFeature::FromHandle(hOtherFeat));  | 
6244  | 0  | }  | 
6245  |  |  | 
6246  |  | /************************************************************************/  | 
6247  |  | /*                              SetFrom()                               */  | 
6248  |  | /************************************************************************/  | 
6249  |  |  | 
6250  |  | /**  | 
6251  |  |  * \brief Set one feature from another.  | 
6252  |  |  *  | 
6253  |  |  * Overwrite the contents of this feature from the geometry and attributes  | 
6254  |  |  * of another.  The poSrcFeature does not need to have the same  | 
6255  |  |  * OGRFeatureDefn.  Field values are copied by corresponding field names.  | 
6256  |  |  * Field types do not have to exactly match.  SetField() method conversion  | 
6257  |  |  * rules will be applied as needed.  | 
6258  |  |  *  | 
6259  |  |  * This method is the same as the C function OGR_F_SetFrom().  | 
6260  |  |  *  | 
6261  |  |  * @param poSrcFeature the feature from which geometry, and field values will  | 
6262  |  |  * be copied.  | 
6263  |  |  *  | 
6264  |  |  * @param bForgiving TRUE if the operation should continue despite lacking  | 
6265  |  |  * output fields matching some of the source fields.  | 
6266  |  |  *  | 
6267  |  |  * @return OGRERR_NONE if the operation succeeds, even if some values are  | 
6268  |  |  * not transferred, otherwise an error code.  | 
6269  |  |  */  | 
6270  |  |  | 
6271  |  | OGRErr OGRFeature::SetFrom(const OGRFeature *poSrcFeature, int bForgiving)  | 
6272  |  |  | 
6273  | 0  | { | 
6274  | 0  |     const auto &oMap = poDefn->ComputeMapForSetFrom(poSrcFeature->GetDefnRef(),  | 
6275  | 0  |                                                     CPL_TO_BOOL(bForgiving));  | 
6276  | 0  |     if (oMap.empty())  | 
6277  | 0  |     { | 
6278  | 0  |         if (poSrcFeature->GetFieldCount())  | 
6279  | 0  |             return OGRERR_FAILURE;  | 
6280  | 0  |         int dummy = 0;  | 
6281  | 0  |         return SetFrom(poSrcFeature, &dummy, bForgiving);  | 
6282  | 0  |     }  | 
6283  | 0  |     return SetFrom(poSrcFeature, oMap.data(), bForgiving);  | 
6284  | 0  | }  | 
6285  |  |  | 
6286  |  | /************************************************************************/  | 
6287  |  | /*                           OGR_F_SetFrom()                            */  | 
6288  |  | /************************************************************************/  | 
6289  |  |  | 
6290  |  | /**  | 
6291  |  |  * \brief Set one feature from another.  | 
6292  |  |  *  | 
6293  |  |  * Overwrite the contents of this feature from the geometry and attributes  | 
6294  |  |  * of another.  The hOtherFeature does not need to have the same  | 
6295  |  |  * OGRFeatureDefn.  Field values are copied by corresponding field names.  | 
6296  |  |  * Field types do not have to exactly match.  OGR_F_SetField*() function  | 
6297  |  |  * conversion rules will be applied as needed.  | 
6298  |  |  *  | 
6299  |  |  * This function is the same as the C++ method OGRFeature::SetFrom().  | 
6300  |  |  *  | 
6301  |  |  * @param hFeat handle to the feature to set to.  | 
6302  |  |  * @param hOtherFeat handle to the feature from which geometry,  | 
6303  |  |  * and field values will be copied.  | 
6304  |  |  *  | 
6305  |  |  * @param bForgiving TRUE if the operation should continue despite lacking  | 
6306  |  |  * output fields matching some of the source fields.  | 
6307  |  |  *  | 
6308  |  |  * @return OGRERR_NONE if the operation succeeds, even if some values are  | 
6309  |  |  * not transferred, otherwise an error code.  | 
6310  |  |  */  | 
6311  |  |  | 
6312  |  | OGRErr OGR_F_SetFrom(OGRFeatureH hFeat, OGRFeatureH hOtherFeat, int bForgiving)  | 
6313  |  |  | 
6314  | 0  | { | 
6315  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_SetFrom", OGRERR_FAILURE);  | 
6316  | 0  |     VALIDATE_POINTER1(hOtherFeat, "OGR_F_SetFrom", OGRERR_FAILURE);  | 
6317  |  |  | 
6318  | 0  |     return OGRFeature::FromHandle(hFeat)->SetFrom(  | 
6319  | 0  |         OGRFeature::FromHandle(hOtherFeat), bForgiving);  | 
6320  | 0  | }  | 
6321  |  |  | 
6322  |  | /************************************************************************/  | 
6323  |  | /*                              SetFrom()                               */  | 
6324  |  | /************************************************************************/  | 
6325  |  |  | 
6326  |  | /**  | 
6327  |  |  * \brief Set one feature from another.  | 
6328  |  |  *  | 
6329  |  |  * Overwrite the contents of this feature from the geometry and attributes  | 
6330  |  |  * of another.  The poSrcFeature does not need to have the same  | 
6331  |  |  * OGRFeatureDefn.  Field values are copied according to the provided indices  | 
6332  |  |  * map. Field types do not have to exactly match.  SetField() method  | 
6333  |  |  * conversion rules will be applied as needed. This is more efficient than  | 
6334  |  |  * OGR_F_SetFrom() in that this doesn't lookup the fields by their names.  | 
6335  |  |  * Particularly useful when the field names don't match.  | 
6336  |  |  *  | 
6337  |  |  * This method is the same as the C function OGR_F_SetFromWithMap().  | 
6338  |  |  *  | 
6339  |  |  * @param poSrcFeature the feature from which geometry, and field values will  | 
6340  |  |  * be copied.  | 
6341  |  |  *  | 
6342  |  |  * @param panMap Array of the indices of the feature's fields  | 
6343  |  |  * stored at the corresponding index of the source feature's fields. A value of  | 
6344  |  |  * -1 should be used to ignore the source's field. The array should not be NULL  | 
6345  |  |  * and be as long as the number of fields in the source feature.  | 
6346  |  |  *  | 
6347  |  |  * @param bForgiving TRUE if the operation should continue despite lacking  | 
6348  |  |  * output fields matching some of the source fields.  | 
6349  |  |  *  | 
6350  |  |  * @param bUseISO8601ForDateTimeAsString true if datetime fields  | 
6351  |  |  * converted to string should use ISO8601 formatting rather than OGR own format.  | 
6352  |  |  *  | 
6353  |  |  * @return OGRERR_NONE if the operation succeeds, even if some values are  | 
6354  |  |  * not transferred, otherwise an error code.  | 
6355  |  |  */  | 
6356  |  |  | 
6357  |  | OGRErr OGRFeature::SetFrom(const OGRFeature *poSrcFeature, const int *panMap,  | 
6358  |  |                            int bForgiving, bool bUseISO8601ForDateTimeAsString)  | 
6359  |  |  | 
6360  | 0  | { | 
6361  | 0  |     if (poSrcFeature == this)  | 
6362  | 0  |         return OGRERR_FAILURE;  | 
6363  |  |  | 
6364  | 0  |     SetFID(OGRNullFID);  | 
6365  |  |  | 
6366  |  |     /* -------------------------------------------------------------------- */  | 
6367  |  |     /*      Set the geometry.                                               */  | 
6368  |  |     /* -------------------------------------------------------------------- */  | 
6369  | 0  |     if (GetGeomFieldCount() == 1)  | 
6370  | 0  |     { | 
6371  | 0  |         const OGRGeomFieldDefn *poGFieldDefn = GetGeomFieldDefnRef(0);  | 
6372  |  | 
  | 
6373  | 0  |         int iSrc = poSrcFeature->GetGeomFieldIndex(poGFieldDefn->GetNameRef());  | 
6374  | 0  |         if (iSrc >= 0)  | 
6375  | 0  |             SetGeomField(0, poSrcFeature->GetGeomFieldRef(iSrc));  | 
6376  | 0  |         else  | 
6377  |  |             // Whatever the geometry field names are.  For backward  | 
6378  |  |             // compatibility.  | 
6379  | 0  |             SetGeomField(0, poSrcFeature->GetGeomFieldRef(0));  | 
6380  | 0  |     }  | 
6381  | 0  |     else  | 
6382  | 0  |     { | 
6383  | 0  |         for (int i = 0; i < GetGeomFieldCount(); i++)  | 
6384  | 0  |         { | 
6385  | 0  |             const OGRGeomFieldDefn *poGFieldDefn = GetGeomFieldDefnRef(i);  | 
6386  |  | 
  | 
6387  | 0  |             const int iSrc =  | 
6388  | 0  |                 poSrcFeature->GetGeomFieldIndex(poGFieldDefn->GetNameRef());  | 
6389  | 0  |             if (iSrc >= 0)  | 
6390  | 0  |                 SetGeomField(i, poSrcFeature->GetGeomFieldRef(iSrc));  | 
6391  | 0  |             else  | 
6392  | 0  |                 SetGeomField(i, nullptr);  | 
6393  | 0  |         }  | 
6394  | 0  |     }  | 
6395  |  |  | 
6396  |  |     /* -------------------------------------------------------------------- */  | 
6397  |  |     /*      Copy feature style string.                                      */  | 
6398  |  |     /* -------------------------------------------------------------------- */  | 
6399  | 0  |     SetStyleString(poSrcFeature->GetStyleString());  | 
6400  |  |  | 
6401  |  |     /* -------------------------------------------------------------------- */  | 
6402  |  |     /*      Copy native data.                                               */  | 
6403  |  |     /* -------------------------------------------------------------------- */  | 
6404  | 0  |     SetNativeData(poSrcFeature->GetNativeData());  | 
6405  | 0  |     SetNativeMediaType(poSrcFeature->GetNativeMediaType());  | 
6406  |  |  | 
6407  |  |     /* -------------------------------------------------------------------- */  | 
6408  |  |     /*      Set the fields by name.                                         */  | 
6409  |  |     /* -------------------------------------------------------------------- */  | 
6410  |  | 
  | 
6411  | 0  |     const OGRErr eErr = SetFieldsFrom(poSrcFeature, panMap, bForgiving,  | 
6412  | 0  |                                       bUseISO8601ForDateTimeAsString);  | 
6413  | 0  |     if (eErr != OGRERR_NONE)  | 
6414  | 0  |         return eErr;  | 
6415  |  |  | 
6416  | 0  |     return OGRERR_NONE;  | 
6417  | 0  | }  | 
6418  |  |  | 
6419  |  | /************************************************************************/  | 
6420  |  | /*                      OGR_F_SetFromWithMap()                          */  | 
6421  |  | /************************************************************************/  | 
6422  |  |  | 
6423  |  | /**  | 
6424  |  |  * \brief Set one feature from another.  | 
6425  |  |  *  | 
6426  |  |  * Overwrite the contents of this feature from the geometry and attributes  | 
6427  |  |  * of another.  The hOtherFeature does not need to have the same  | 
6428  |  |  * OGRFeatureDefn.  Field values are copied according to the provided indices  | 
6429  |  |  * map. Field types do not have to exactly match.  OGR_F_SetField*() function  | 
6430  |  |  * conversion rules will be applied as needed. This is more efficient than  | 
6431  |  |  * OGR_F_SetFrom() in that this doesn't lookup the fields by their names.  | 
6432  |  |  * Particularly useful when the field names don't match.  | 
6433  |  |  *  | 
6434  |  |  * This function is the same as the C++ method OGRFeature::SetFrom().  | 
6435  |  |  *  | 
6436  |  |  * @param hFeat handle to the feature to set to.  | 
6437  |  |  * @param hOtherFeat handle to the feature from which geometry,  | 
6438  |  |  * and field values will be copied.  | 
6439  |  |  *  | 
6440  |  |  * @param panMap Array of the indices of the destination feature's fields  | 
6441  |  |  * stored at the corresponding index of the source feature's fields. A value of  | 
6442  |  |  * -1 should be used to ignore the source's field. The array should not be NULL  | 
6443  |  |  * and be as long as the number of fields in the source feature.  | 
6444  |  |  *  | 
6445  |  |  * @param bForgiving TRUE if the operation should continue despite lacking  | 
6446  |  |  * output fields matching some of the source fields.  | 
6447  |  |  *  | 
6448  |  |  * @return OGRERR_NONE if the operation succeeds, even if some values are  | 
6449  |  |  * not transferred, otherwise an error code.  | 
6450  |  |  */  | 
6451  |  |  | 
6452  |  | OGRErr OGR_F_SetFromWithMap(OGRFeatureH hFeat, OGRFeatureH hOtherFeat,  | 
6453  |  |                             int bForgiving, const int *panMap)  | 
6454  |  |  | 
6455  | 0  | { | 
6456  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_SetFrom", OGRERR_FAILURE);  | 
6457  | 0  |     VALIDATE_POINTER1(hOtherFeat, "OGR_F_SetFrom", OGRERR_FAILURE);  | 
6458  | 0  |     VALIDATE_POINTER1(panMap, "OGR_F_SetFrom", OGRERR_FAILURE);  | 
6459  |  |  | 
6460  | 0  |     return OGRFeature::FromHandle(hFeat)->SetFrom(  | 
6461  | 0  |         OGRFeature::FromHandle(hOtherFeat), panMap, bForgiving);  | 
6462  | 0  | }  | 
6463  |  |  | 
6464  |  | /************************************************************************/  | 
6465  |  | /*                           SetFieldsFrom()                            */  | 
6466  |  | /************************************************************************/  | 
6467  |  |  | 
6468  |  | /**  | 
6469  |  |  * \brief Set fields from another feature.  | 
6470  |  |  *  | 
6471  |  |  * Overwrite the fields of this feature from the attributes of  | 
6472  |  |  * another. The FID and the style string are not set. The poSrcFeature  | 
6473  |  |  * does not need to have the same OGRFeatureDefn.  Field values are  | 
6474  |  |  * copied according to the provided indices map. Field types do not  | 
6475  |  |  * have to exactly match.  SetField() method conversion rules will be  | 
6476  |  |  * applied as needed. This is more efficient than OGR_F_SetFrom() in  | 
6477  |  |  * that this doesn't lookup the fields by their names.  Particularly  | 
6478  |  |  * useful when the field names don't match.  | 
6479  |  |  *  | 
6480  |  |  * @param poSrcFeature the feature from which geometry, and field values will  | 
6481  |  |  * be copied.  | 
6482  |  |  *  | 
6483  |  |  * @param panMap Array of the indices of the feature's fields  | 
6484  |  |  * stored at the corresponding index of the source feature's fields. A value of  | 
6485  |  |  * -1 should be used to ignore the source's field. The array should not be NULL  | 
6486  |  |  * and be as long as the number of fields in the source feature.  | 
6487  |  |  *  | 
6488  |  |  * @param bForgiving TRUE if the operation should continue despite lacking  | 
6489  |  |  * output fields matching some of the source fields.  | 
6490  |  |  *  | 
6491  |  |  * @param bUseISO8601ForDateTimeAsString true if datetime fields  | 
6492  |  |  * converted to string should use ISO8601 formatting rather than OGR own format.  | 
6493  |  |  *  | 
6494  |  |  * @return OGRERR_NONE if the operation succeeds, even if some values are  | 
6495  |  |  * not transferred, otherwise an error code.  | 
6496  |  |  */  | 
6497  |  |  | 
6498  |  | OGRErr OGRFeature::SetFieldsFrom(const OGRFeature *poSrcFeature,  | 
6499  |  |                                  const int *panMap, int bForgiving,  | 
6500  |  |                                  bool bUseISO8601ForDateTimeAsString)  | 
6501  |  |  | 
6502  | 0  | { | 
6503  | 0  |     const int nSrcFieldCount = poSrcFeature->poDefn->GetFieldCountUnsafe();  | 
6504  | 0  |     const int nFieldCount = poDefn->GetFieldCountUnsafe();  | 
6505  | 0  |     for (int iField = 0; iField < nSrcFieldCount; iField++)  | 
6506  | 0  |     { | 
6507  | 0  |         const int iDstField = panMap[iField];  | 
6508  |  | 
  | 
6509  | 0  |         if (iDstField < 0)  | 
6510  | 0  |             continue;  | 
6511  |  |  | 
6512  | 0  |         if (nFieldCount <= iDstField)  | 
6513  | 0  |             return OGRERR_FAILURE;  | 
6514  |  |  | 
6515  | 0  |         if (!poSrcFeature->IsFieldSetUnsafe(iField))  | 
6516  | 0  |         { | 
6517  | 0  |             UnsetField(iDstField);  | 
6518  | 0  |             continue;  | 
6519  | 0  |         }  | 
6520  |  |  | 
6521  | 0  |         if (poSrcFeature->IsFieldNullUnsafe(iField))  | 
6522  | 0  |         { | 
6523  | 0  |             SetFieldNull(iDstField);  | 
6524  | 0  |             continue;  | 
6525  | 0  |         }  | 
6526  |  |  | 
6527  | 0  |         const auto eSrcType =  | 
6528  | 0  |             poSrcFeature->poDefn->GetFieldDefnUnsafe(iField)->GetType();  | 
6529  | 0  |         const auto eDstType = poDefn->GetFieldDefnUnsafe(iDstField)->GetType();  | 
6530  | 0  |         if (eSrcType == eDstType)  | 
6531  | 0  |         { | 
6532  | 0  |             if (eSrcType == OFTInteger)  | 
6533  | 0  |             { | 
6534  | 0  |                 SetFieldSameTypeUnsafe(  | 
6535  | 0  |                     iDstField, poSrcFeature->GetFieldAsIntegerUnsafe(iField));  | 
6536  | 0  |                 continue;  | 
6537  | 0  |             }  | 
6538  | 0  |             if (eSrcType == OFTInteger64)  | 
6539  | 0  |             { | 
6540  | 0  |                 SetFieldSameTypeUnsafe(  | 
6541  | 0  |                     iDstField, poSrcFeature->GetFieldAsInteger64Unsafe(iField));  | 
6542  | 0  |                 continue;  | 
6543  | 0  |             }  | 
6544  | 0  |             if (eSrcType == OFTReal)  | 
6545  | 0  |             { | 
6546  | 0  |                 SetFieldSameTypeUnsafe(  | 
6547  | 0  |                     iDstField, poSrcFeature->GetFieldAsDoubleUnsafe(iField));  | 
6548  | 0  |                 continue;  | 
6549  | 0  |             }  | 
6550  | 0  |             if (eSrcType == OFTString)  | 
6551  | 0  |             { | 
6552  | 0  |                 if (IsFieldSetAndNotNullUnsafe(iDstField))  | 
6553  | 0  |                     CPLFree(pauFields[iDstField].String);  | 
6554  |  | 
  | 
6555  | 0  |                 SetFieldSameTypeUnsafe(  | 
6556  | 0  |                     iDstField,  | 
6557  | 0  |                     VSI_STRDUP_VERBOSE(  | 
6558  | 0  |                         poSrcFeature->GetFieldAsStringUnsafe(iField)));  | 
6559  | 0  |                 continue;  | 
6560  | 0  |             }  | 
6561  | 0  |         }  | 
6562  |  |  | 
6563  |  |         // Check if we must convert list types to JSON  | 
6564  | 0  |         if (eDstType == OFTString)  | 
6565  | 0  |         { | 
6566  | 0  |             const auto eDstSubType =  | 
6567  | 0  |                 poDefn->GetFieldDefnUnsafe(iDstField)->GetSubType();  | 
6568  | 0  |             if (eDstSubType == OFSTJSON &&  | 
6569  | 0  |                 (eSrcType == OFTIntegerList || eSrcType == OFTInteger64List ||  | 
6570  | 0  |                  eSrcType == OFTRealList || eSrcType == OFTStringList))  | 
6571  | 0  |             { | 
6572  | 0  |                 char *pszVal = poSrcFeature->GetFieldAsSerializedJSon(iField);  | 
6573  | 0  |                 if (pszVal)  | 
6574  | 0  |                 { | 
6575  | 0  |                     SetField(iDstField, pszVal);  | 
6576  | 0  |                     CPLFree(pszVal);  | 
6577  | 0  |                     continue;  | 
6578  | 0  |                 }  | 
6579  | 0  |             }  | 
6580  | 0  |         }  | 
6581  |  |  | 
6582  | 0  |         switch (eSrcType)  | 
6583  | 0  |         { | 
6584  | 0  |             case OFTInteger:  | 
6585  | 0  |                 SetField(iDstField,  | 
6586  | 0  |                          poSrcFeature->GetFieldAsIntegerUnsafe(iField));  | 
6587  | 0  |                 break;  | 
6588  |  |  | 
6589  | 0  |             case OFTInteger64:  | 
6590  | 0  |                 SetField(iDstField,  | 
6591  | 0  |                          poSrcFeature->GetFieldAsInteger64Unsafe(iField));  | 
6592  | 0  |                 break;  | 
6593  |  |  | 
6594  | 0  |             case OFTReal:  | 
6595  | 0  |                 SetField(iDstField,  | 
6596  | 0  |                          poSrcFeature->GetFieldAsDoubleUnsafe(iField));  | 
6597  | 0  |                 break;  | 
6598  |  |  | 
6599  | 0  |             case OFTString:  | 
6600  | 0  |                 SetField(iDstField,  | 
6601  | 0  |                          poSrcFeature->GetFieldAsStringUnsafe(iField));  | 
6602  | 0  |                 break;  | 
6603  |  |  | 
6604  | 0  |             case OFTIntegerList:  | 
6605  | 0  |             { | 
6606  | 0  |                 if (eDstType == OFTString)  | 
6607  | 0  |                 { | 
6608  | 0  |                     SetField(iDstField, poSrcFeature->GetFieldAsString(iField));  | 
6609  | 0  |                 }  | 
6610  | 0  |                 else  | 
6611  | 0  |                 { | 
6612  | 0  |                     int nCount = 0;  | 
6613  | 0  |                     const int *panValues =  | 
6614  | 0  |                         poSrcFeature->GetFieldAsIntegerList(iField, &nCount);  | 
6615  | 0  |                     SetField(iDstField, nCount, panValues);  | 
6616  | 0  |                 }  | 
6617  | 0  |             }  | 
6618  | 0  |             break;  | 
6619  |  |  | 
6620  | 0  |             case OFTInteger64List:  | 
6621  | 0  |             { | 
6622  | 0  |                 if (eDstType == OFTString)  | 
6623  | 0  |                 { | 
6624  | 0  |                     SetField(iDstField, poSrcFeature->GetFieldAsString(iField));  | 
6625  | 0  |                 }  | 
6626  | 0  |                 else  | 
6627  | 0  |                 { | 
6628  | 0  |                     int nCount = 0;  | 
6629  | 0  |                     const GIntBig *panValues =  | 
6630  | 0  |                         poSrcFeature->GetFieldAsInteger64List(iField, &nCount);  | 
6631  | 0  |                     SetField(iDstField, nCount, panValues);  | 
6632  | 0  |                 }  | 
6633  | 0  |             }  | 
6634  | 0  |             break;  | 
6635  |  |  | 
6636  | 0  |             case OFTRealList:  | 
6637  | 0  |             { | 
6638  | 0  |                 if (eDstType == OFTString)  | 
6639  | 0  |                 { | 
6640  | 0  |                     SetField(iDstField, poSrcFeature->GetFieldAsString(iField));  | 
6641  | 0  |                 }  | 
6642  | 0  |                 else  | 
6643  | 0  |                 { | 
6644  | 0  |                     int nCount = 0;  | 
6645  | 0  |                     const double *padfValues =  | 
6646  | 0  |                         poSrcFeature->GetFieldAsDoubleList(iField, &nCount);  | 
6647  | 0  |                     SetField(iDstField, nCount, padfValues);  | 
6648  | 0  |                 }  | 
6649  | 0  |             }  | 
6650  | 0  |             break;  | 
6651  |  |  | 
6652  | 0  |             case OFTDate:  | 
6653  | 0  |             case OFTDateTime:  | 
6654  | 0  |             case OFTTime:  | 
6655  | 0  |             { | 
6656  | 0  |                 if (eDstType == OFTDate || eDstType == OFTTime ||  | 
6657  | 0  |                     eDstType == OFTDateTime)  | 
6658  | 0  |                 { | 
6659  | 0  |                     SetField(iDstField, poSrcFeature->GetRawFieldRef(iField));  | 
6660  | 0  |                 }  | 
6661  | 0  |                 else if (eDstType == OFTString || eDstType == OFTStringList)  | 
6662  | 0  |                 { | 
6663  | 0  |                     SetField(iDstField,  | 
6664  | 0  |                              eSrcType == OFTDateTime &&  | 
6665  | 0  |                                      bUseISO8601ForDateTimeAsString  | 
6666  | 0  |                                  ? poSrcFeature->GetFieldAsISO8601DateTime(  | 
6667  | 0  |                                        iField, nullptr)  | 
6668  | 0  |                                  : poSrcFeature->GetFieldAsString(iField));  | 
6669  | 0  |                 }  | 
6670  | 0  |                 else if (!bForgiving)  | 
6671  | 0  |                     return OGRERR_FAILURE;  | 
6672  | 0  |                 break;  | 
6673  | 0  |             }  | 
6674  |  |  | 
6675  | 0  |             default:  | 
6676  | 0  |             { | 
6677  | 0  |                 if (eSrcType == eDstType)  | 
6678  | 0  |                 { | 
6679  | 0  |                     SetField(iDstField, poSrcFeature->GetRawFieldRef(iField));  | 
6680  | 0  |                 }  | 
6681  | 0  |                 else if (eDstType == OFTString || eDstType == OFTStringList)  | 
6682  | 0  |                 { | 
6683  | 0  |                     SetField(iDstField, poSrcFeature->GetFieldAsString(iField));  | 
6684  | 0  |                 }  | 
6685  | 0  |                 else if (!bForgiving)  | 
6686  | 0  |                     return OGRERR_FAILURE;  | 
6687  | 0  |                 break;  | 
6688  | 0  |             }  | 
6689  | 0  |         }  | 
6690  | 0  |     }  | 
6691  |  |  | 
6692  | 0  |     return OGRERR_NONE;  | 
6693  | 0  | }  | 
6694  |  |  | 
6695  |  | /************************************************************************/  | 
6696  |  | /*                             GetStyleString()                         */  | 
6697  |  | /************************************************************************/  | 
6698  |  |  | 
6699  |  | /**  | 
6700  |  |  * \brief Fetch style string for this feature.  | 
6701  |  |  *  | 
6702  |  |  * Set the OGR Feature Style Specification for details on the format of  | 
6703  |  |  * this string, and ogr_featurestyle.h for services available to parse it.  | 
6704  |  |  *  | 
6705  |  |  * This method is the same as the C function OGR_F_GetStyleString().  | 
6706  |  |  *  | 
6707  |  |  * @return a reference to a representation in string format, or NULL if  | 
6708  |  |  * there isn't one.  | 
6709  |  |  */  | 
6710  |  |  | 
6711  |  | const char *OGRFeature::GetStyleString() const  | 
6712  | 0  | { | 
6713  | 0  |     if (m_pszStyleString)  | 
6714  | 0  |         return m_pszStyleString;  | 
6715  |  |  | 
6716  | 0  |     const int iStyleFieldIndex = GetFieldIndex("OGR_STYLE"); | 
6717  | 0  |     if (iStyleFieldIndex >= 0)  | 
6718  | 0  |         return GetFieldAsString(iStyleFieldIndex);  | 
6719  |  |  | 
6720  | 0  |     return nullptr;  | 
6721  | 0  | }  | 
6722  |  |  | 
6723  |  | /************************************************************************/  | 
6724  |  | /*                        OGR_F_GetStyleString()                        */  | 
6725  |  | /************************************************************************/  | 
6726  |  |  | 
6727  |  | /**  | 
6728  |  |  * \brief Fetch style string for this feature.  | 
6729  |  |  *  | 
6730  |  |  * Set the OGR Feature Style Specification for details on the format of  | 
6731  |  |  * this string, and ogr_featurestyle.h for services available to parse it.  | 
6732  |  |  *  | 
6733  |  |  * This function is the same as the C++ method OGRFeature::GetStyleString().  | 
6734  |  |  *  | 
6735  |  |  * @param hFeat handle to the feature to get the style from.  | 
6736  |  |  * @return a reference to a representation in string format, or NULL if  | 
6737  |  |  * there isn't one.  | 
6738  |  |  */  | 
6739  |  |  | 
6740  |  | const char *OGR_F_GetStyleString(OGRFeatureH hFeat)  | 
6741  | 0  | { | 
6742  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetStyleString", nullptr);  | 
6743  |  |  | 
6744  | 0  |     return OGRFeature::FromHandle(hFeat)->GetStyleString();  | 
6745  | 0  | }  | 
6746  |  |  | 
6747  |  | /************************************************************************/  | 
6748  |  | /*                             SetStyleString()                         */  | 
6749  |  | /************************************************************************/  | 
6750  |  |  | 
6751  |  | /**  | 
6752  |  |  * \brief Set feature style string.  | 
6753  |  |  *  | 
6754  |  |  * This method operates the same as OGRFeature::SetStyleStringDirectly() except  | 
6755  |  |  * that it does not assume ownership of the passed string, but instead makes a  | 
6756  |  |  * copy of it.  | 
6757  |  |  *  | 
6758  |  |  * This method is the same as the C function OGR_F_SetStyleString().  | 
6759  |  |  *  | 
6760  |  |  * @param pszString the style string to apply to this feature, cannot be NULL.  | 
6761  |  |  */  | 
6762  |  |  | 
6763  |  | void OGRFeature::SetStyleString(const char *pszString)  | 
6764  | 0  | { | 
6765  | 0  |     if (m_pszStyleString)  | 
6766  | 0  |     { | 
6767  | 0  |         CPLFree(m_pszStyleString);  | 
6768  | 0  |         m_pszStyleString = nullptr;  | 
6769  | 0  |     }  | 
6770  |  | 
  | 
6771  | 0  |     if (pszString)  | 
6772  | 0  |         m_pszStyleString = VSI_STRDUP_VERBOSE(pszString);  | 
6773  | 0  | }  | 
6774  |  |  | 
6775  |  | /************************************************************************/  | 
6776  |  | /*                        OGR_F_SetStyleString()                        */  | 
6777  |  | /************************************************************************/  | 
6778  |  |  | 
6779  |  | /**  | 
6780  |  |  * \brief Set feature style string.  | 
6781  |  |  *  | 
6782  |  |  * This method operates the same as OGR_F_SetStyleStringDirectly() except that it  | 
6783  |  |  * does not assume ownership of the passed string, but instead makes a copy of  | 
6784  |  |  * it.  | 
6785  |  |  *  | 
6786  |  |  * This function is the same as the C++ method OGRFeature::SetStyleString().  | 
6787  |  |  *  | 
6788  |  |  * @param hFeat handle to the feature to set style to.  | 
6789  |  |  * @param pszStyle the style string to apply to this feature, cannot be NULL.  | 
6790  |  |  */  | 
6791  |  |  | 
6792  |  | void OGR_F_SetStyleString(OGRFeatureH hFeat, const char *pszStyle)  | 
6793  |  |  | 
6794  | 0  | { | 
6795  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetStyleString");  | 
6796  |  |  | 
6797  | 0  |     OGRFeature::FromHandle(hFeat)->SetStyleString(pszStyle);  | 
6798  | 0  | }  | 
6799  |  |  | 
6800  |  | /************************************************************************/  | 
6801  |  | /*                       SetStyleStringDirectly()                       */  | 
6802  |  | /************************************************************************/  | 
6803  |  |  | 
6804  |  | /**  | 
6805  |  |  * \brief Set feature style string.  | 
6806  |  |  *  | 
6807  |  |  * This method operates the same as OGRFeature::SetStyleString() except that it  | 
6808  |  |  * assumes ownership of the passed string.  | 
6809  |  |  *  | 
6810  |  |  * This method is the same as the C function OGR_F_SetStyleStringDirectly().  | 
6811  |  |  *  | 
6812  |  |  * @param pszString the style string to apply to this feature, cannot be NULL.  | 
6813  |  |  */  | 
6814  |  |  | 
6815  |  | void OGRFeature::SetStyleStringDirectly(char *pszString)  | 
6816  | 0  | { | 
6817  | 0  |     CPLFree(m_pszStyleString);  | 
6818  | 0  |     m_pszStyleString = pszString;  | 
6819  | 0  | }  | 
6820  |  |  | 
6821  |  | /************************************************************************/  | 
6822  |  | /*                     OGR_F_SetStyleStringDirectly()                   */  | 
6823  |  | /************************************************************************/  | 
6824  |  |  | 
6825  |  | /**  | 
6826  |  |  * \brief Set feature style string.  | 
6827  |  |  *  | 
6828  |  |  * This method operates the same as OGR_F_SetStyleString() except that it assumes  | 
6829  |  |  * ownership of the passed string.  | 
6830  |  |  *  | 
6831  |  |  * This function is the same as the C++ method  | 
6832  |  |  * OGRFeature::SetStyleStringDirectly().  | 
6833  |  |  *  | 
6834  |  |  * @param hFeat handle to the feature to set style to.  | 
6835  |  |  * @param pszStyle the style string to apply to this feature, cannot be NULL.  | 
6836  |  |  */  | 
6837  |  |  | 
6838  |  | void OGR_F_SetStyleStringDirectly(OGRFeatureH hFeat, char *pszStyle)  | 
6839  |  |  | 
6840  | 0  | { | 
6841  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetStyleStringDirectly");  | 
6842  |  |  | 
6843  | 0  |     OGRFeature::FromHandle(hFeat)->SetStyleStringDirectly(pszStyle);  | 
6844  | 0  | }  | 
6845  |  |  | 
6846  |  | //************************************************************************/  | 
6847  |  | /*                           SetStyleTable()                            */  | 
6848  |  | /************************************************************************/  | 
6849  |  |  | 
6850  |  | /** Set style table.  | 
6851  |  |  * @param poStyleTable new style table (will be cloned)  | 
6852  |  |  */  | 
6853  |  | void OGRFeature::SetStyleTable(OGRStyleTable *poStyleTable)  | 
6854  | 0  | { | 
6855  | 0  |     if (m_poStyleTable)  | 
6856  | 0  |         delete m_poStyleTable;  | 
6857  | 0  |     m_poStyleTable = poStyleTable ? poStyleTable->Clone() : nullptr;  | 
6858  | 0  | }  | 
6859  |  |  | 
6860  |  | //************************************************************************/  | 
6861  |  | /*                          SetStyleTableDirectly()                      */  | 
6862  |  | /************************************************************************/  | 
6863  |  |  | 
6864  |  | /** Set style table.  | 
6865  |  |  * @param poStyleTable new style table (ownership transferred to the object)  | 
6866  |  |  */  | 
6867  |  | void OGRFeature::SetStyleTableDirectly(OGRStyleTable *poStyleTable)  | 
6868  | 0  | { | 
6869  | 0  |     if (m_poStyleTable)  | 
6870  | 0  |         delete m_poStyleTable;  | 
6871  | 0  |     m_poStyleTable = poStyleTable;  | 
6872  | 0  | }  | 
6873  |  |  | 
6874  |  | //! @cond Doxygen_Suppress  | 
6875  |  |  | 
6876  |  | /************************************************************************/  | 
6877  |  | /*                            RemapFields()                             */  | 
6878  |  | /*                                                                      */  | 
6879  |  | /*      This is used to transform a feature "in place" from one         */  | 
6880  |  | /*      feature defn to another with minimum work.                      */  | 
6881  |  | /************************************************************************/  | 
6882  |  |  | 
6883  |  | OGRErr OGRFeature::RemapFields(OGRFeatureDefn *poNewDefn,  | 
6884  |  |                                const int *panRemapSource)  | 
6885  |  |  | 
6886  | 0  | { | 
6887  | 0  |     if (poNewDefn == nullptr)  | 
6888  | 0  |         poNewDefn = poDefn;  | 
6889  |  | 
  | 
6890  | 0  |     const int nNewFieldCount = poNewDefn->GetFieldCount();  | 
6891  | 0  |     OGRField *pauNewFields =  | 
6892  | 0  |         static_cast<OGRField *>(CPLCalloc(nNewFieldCount, sizeof(OGRField)));  | 
6893  |  | 
  | 
6894  | 0  |     const int nFieldCount = poDefn->GetFieldCount();  | 
6895  | 0  |     for (int iDstField = 0; iDstField < nFieldCount; iDstField++)  | 
6896  | 0  |     { | 
6897  | 0  |         if (panRemapSource[iDstField] == -1)  | 
6898  | 0  |         { | 
6899  | 0  |             OGR_RawField_SetUnset(&pauNewFields[iDstField]);  | 
6900  | 0  |         }  | 
6901  | 0  |         else  | 
6902  | 0  |         { | 
6903  | 0  |             memcpy(pauNewFields + iDstField,  | 
6904  | 0  |                    pauFields + panRemapSource[iDstField], sizeof(OGRField));  | 
6905  | 0  |         }  | 
6906  | 0  |     }  | 
6907  |  |  | 
6908  |  |     // We really should be freeing memory for old columns that  | 
6909  |  |     // are no longer present.  We don't for now because it is a bit messy  | 
6910  |  |     // and would take too long to test.  | 
6911  |  |  | 
6912  |  |     /* -------------------------------------------------------------------- */  | 
6913  |  |     /*      Apply new definition and fields.                                */  | 
6914  |  |     /* -------------------------------------------------------------------- */  | 
6915  | 0  |     CPLFree(pauFields);  | 
6916  | 0  |     pauFields = pauNewFields;  | 
6917  |  | 
  | 
6918  | 0  |     poDefn = poNewDefn;  | 
6919  |  | 
  | 
6920  | 0  |     return OGRERR_NONE;  | 
6921  | 0  | }  | 
6922  |  |  | 
6923  |  | /************************************************************************/  | 
6924  |  | /*                            AppendField()                             */  | 
6925  |  | /*                                                                      */  | 
6926  |  | /*      This is used to transform a feature "in place" by appending     */  | 
6927  |  | /*      an unset field.                                                 */  | 
6928  |  | /************************************************************************/  | 
6929  |  |  | 
6930  |  | void OGRFeature::AppendField()  | 
6931  | 0  | { | 
6932  | 0  |     const int nFieldCount = poDefn->GetFieldCountUnsafe();  | 
6933  | 0  |     pauFields = static_cast<OGRField *>(  | 
6934  | 0  |         CPLRealloc(pauFields, nFieldCount * sizeof(OGRField)));  | 
6935  | 0  |     OGR_RawField_SetUnset(&pauFields[nFieldCount - 1]);  | 
6936  | 0  | }  | 
6937  |  |  | 
6938  |  | /************************************************************************/  | 
6939  |  | /*                        RemapGeomFields()                             */  | 
6940  |  | /*                                                                      */  | 
6941  |  | /*      This is used to transform a feature "in place" from one         */  | 
6942  |  | /*      feature defn to another with minimum work.                      */  | 
6943  |  | /************************************************************************/  | 
6944  |  |  | 
6945  |  | OGRErr OGRFeature::RemapGeomFields(OGRFeatureDefn *poNewDefn,  | 
6946  |  |                                    const int *panRemapSource)  | 
6947  |  |  | 
6948  | 0  | { | 
6949  | 0  |     if (poNewDefn == nullptr)  | 
6950  | 0  |         poNewDefn = poDefn;  | 
6951  |  | 
  | 
6952  | 0  |     OGRGeometry **papoNewGeomFields = static_cast<OGRGeometry **>(  | 
6953  | 0  |         CPLCalloc(poNewDefn->GetGeomFieldCount(), sizeof(OGRGeometry *)));  | 
6954  |  | 
  | 
6955  | 0  |     for (int iDstField = 0; iDstField < poDefn->GetGeomFieldCount();  | 
6956  | 0  |          iDstField++)  | 
6957  | 0  |     { | 
6958  | 0  |         if (panRemapSource[iDstField] == -1)  | 
6959  | 0  |         { | 
6960  | 0  |             papoNewGeomFields[iDstField] = nullptr;  | 
6961  | 0  |         }  | 
6962  | 0  |         else  | 
6963  | 0  |         { | 
6964  | 0  |             papoNewGeomFields[iDstField] =  | 
6965  | 0  |                 papoGeometries[panRemapSource[iDstField]];  | 
6966  | 0  |         }  | 
6967  | 0  |     }  | 
6968  |  |  | 
6969  |  |     // We really should be freeing memory for old columns that  | 
6970  |  |     // are no longer present.  We don't for now because it is a bit messy  | 
6971  |  |     // and would take too long to test.  | 
6972  |  |  | 
6973  |  |     /* -------------------------------------------------------------------- */  | 
6974  |  |     /*      Apply new definition and fields.                                */  | 
6975  |  |     /* -------------------------------------------------------------------- */  | 
6976  | 0  |     CPLFree(papoGeometries);  | 
6977  | 0  |     papoGeometries = papoNewGeomFields;  | 
6978  |  | 
  | 
6979  | 0  |     poDefn = poNewDefn;  | 
6980  |  | 
  | 
6981  | 0  |     return OGRERR_NONE;  | 
6982  | 0  | }  | 
6983  |  |  | 
6984  |  | //! @endcond  | 
6985  |  |  | 
6986  |  | /************************************************************************/  | 
6987  |  | /*                         OGR_F_GetStyleTable()                        */  | 
6988  |  | /************************************************************************/  | 
6989  |  |  | 
6990  |  | OGRStyleTableH OGR_F_GetStyleTable(OGRFeatureH hFeat)  | 
6991  |  |  | 
6992  | 0  | { | 
6993  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetStyleTable", nullptr);  | 
6994  |  |  | 
6995  | 0  |     return reinterpret_cast<OGRStyleTableH>(  | 
6996  | 0  |         OGRFeature::FromHandle(hFeat)->GetStyleTable());  | 
6997  | 0  | }  | 
6998  |  |  | 
6999  |  | /************************************************************************/  | 
7000  |  | /*                         OGR_F_SetStyleTableDirectly()                */  | 
7001  |  | /************************************************************************/  | 
7002  |  |  | 
7003  |  | void OGR_F_SetStyleTableDirectly(OGRFeatureH hFeat, OGRStyleTableH hStyleTable)  | 
7004  |  |  | 
7005  | 0  | { | 
7006  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetStyleTableDirectly");  | 
7007  |  |  | 
7008  | 0  |     OGRFeature::FromHandle(hFeat)->SetStyleTableDirectly(  | 
7009  | 0  |         reinterpret_cast<OGRStyleTable *>(hStyleTable));  | 
7010  | 0  | }  | 
7011  |  |  | 
7012  |  | /************************************************************************/  | 
7013  |  | /*                         OGR_F_SetStyleTable()                        */  | 
7014  |  | /************************************************************************/  | 
7015  |  |  | 
7016  |  | void OGR_F_SetStyleTable(OGRFeatureH hFeat, OGRStyleTableH hStyleTable)  | 
7017  |  |  | 
7018  | 0  | { | 
7019  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetStyleTable");  | 
7020  | 0  |     VALIDATE_POINTER0(hStyleTable, "OGR_F_SetStyleTable");  | 
7021  |  |  | 
7022  | 0  |     OGRFeature::FromHandle(hFeat)->SetStyleTable(  | 
7023  | 0  |         reinterpret_cast<OGRStyleTable *>(hStyleTable));  | 
7024  | 0  | }  | 
7025  |  |  | 
7026  |  | /************************************************************************/  | 
7027  |  | /*                          FillUnsetWithDefault()                      */  | 
7028  |  | /************************************************************************/  | 
7029  |  |  | 
7030  |  | /**  | 
7031  |  |  * \brief Fill unset fields with default values that might be defined.  | 
7032  |  |  *  | 
7033  |  |  * This method is the same as the C function OGR_F_FillUnsetWithDefault().  | 
7034  |  |  *  | 
7035  |  |  * @param bNotNullableOnly if we should fill only unset fields with a not-null  | 
7036  |  |  *                     constraint.  | 
7037  |  |  * @param papszOptions unused currently. Must be set to NULL.  | 
7038  |  |  * @since GDAL 2.0  | 
7039  |  |  */  | 
7040  |  |  | 
7041  |  | void OGRFeature::FillUnsetWithDefault(int bNotNullableOnly,  | 
7042  |  |                                       CPL_UNUSED char **papszOptions)  | 
7043  | 0  | { | 
7044  | 0  |     const int nFieldCount = poDefn->GetFieldCount();  | 
7045  | 0  |     for (int i = 0; i < nFieldCount; i++)  | 
7046  | 0  |     { | 
7047  | 0  |         if (IsFieldSetUnsafe(i))  | 
7048  | 0  |             continue;  | 
7049  | 0  |         const auto poFieldDefn = poDefn->GetFieldDefn(i);  | 
7050  | 0  |         if (bNotNullableOnly && poFieldDefn->IsNullable())  | 
7051  | 0  |             continue;  | 
7052  | 0  |         const char *pszDefault = poFieldDefn->GetDefault();  | 
7053  | 0  |         OGRFieldType eType = poFieldDefn->GetType();  | 
7054  | 0  |         if (pszDefault != nullptr)  | 
7055  | 0  |         { | 
7056  | 0  |             if (eType == OFTDate || eType == OFTTime || eType == OFTDateTime)  | 
7057  | 0  |             { | 
7058  | 0  |                 if (STARTS_WITH_CI(pszDefault, "CURRENT"))  | 
7059  | 0  |                 { | 
7060  | 0  |                     time_t t = time(nullptr);  | 
7061  | 0  |                     struct tm brokendown;  | 
7062  | 0  |                     CPLUnixTimeToYMDHMS(t, &brokendown);  | 
7063  | 0  |                     SetField(i, brokendown.tm_year + 1900,  | 
7064  | 0  |                              brokendown.tm_mon + 1, brokendown.tm_mday,  | 
7065  | 0  |                              brokendown.tm_hour, brokendown.tm_min,  | 
7066  | 0  |                              static_cast<float>(brokendown.tm_sec), 100);  | 
7067  | 0  |                 }  | 
7068  | 0  |                 else  | 
7069  | 0  |                 { | 
7070  | 0  |                     int nYear = 0;  | 
7071  | 0  |                     int nMonth = 0;  | 
7072  | 0  |                     int nDay = 0;  | 
7073  | 0  |                     int nHour = 0;  | 
7074  | 0  |                     int nMinute = 0;  | 
7075  | 0  |                     float fSecond = 0.0f;  | 
7076  | 0  |                     if (sscanf(pszDefault, "'%d/%d/%d %d:%d:%f'", &nYear,  | 
7077  | 0  |                                &nMonth, &nDay, &nHour, &nMinute, &fSecond) == 6)  | 
7078  | 0  |                     { | 
7079  | 0  |                         SetField(i, nYear, nMonth, nDay, nHour, nMinute,  | 
7080  | 0  |                                  fSecond, 100);  | 
7081  | 0  |                     }  | 
7082  | 0  |                 }  | 
7083  | 0  |             }  | 
7084  | 0  |             else if (eType == OFTString && pszDefault[0] == '\'' &&  | 
7085  | 0  |                      pszDefault[strlen(pszDefault) - 1] == '\'')  | 
7086  | 0  |             { | 
7087  | 0  |                 CPLString osDefault(pszDefault + 1);  | 
7088  | 0  |                 osDefault.pop_back();  | 
7089  | 0  |                 char *pszTmp = CPLUnescapeString(osDefault, nullptr, CPLES_SQL);  | 
7090  | 0  |                 SetField(i, pszTmp);  | 
7091  | 0  |                 CPLFree(pszTmp);  | 
7092  | 0  |             }  | 
7093  | 0  |             else if (!poFieldDefn->IsDefaultDriverSpecific())  | 
7094  | 0  |                 SetField(i, pszDefault);  | 
7095  | 0  |         }  | 
7096  | 0  |     }  | 
7097  | 0  | }  | 
7098  |  |  | 
7099  |  | /************************************************************************/  | 
7100  |  | /*                     OGR_F_FillUnsetWithDefault()                     */  | 
7101  |  | /************************************************************************/  | 
7102  |  |  | 
7103  |  | /**  | 
7104  |  |  * \brief Fill unset fields with default values that might be defined.  | 
7105  |  |  *  | 
7106  |  |  * This function is the same as the C++ method  | 
7107  |  |  * OGRFeature::FillUnsetWithDefault().  | 
7108  |  |  *  | 
7109  |  |  * @param hFeat handle to the feature.  | 
7110  |  |  * @param bNotNullableOnly if we should fill only unset fields with a not-null  | 
7111  |  |  *                     constraint.  | 
7112  |  |  * @param papszOptions unused currently. Must be set to NULL.  | 
7113  |  |  * @since GDAL 2.0  | 
7114  |  |  */  | 
7115  |  |  | 
7116  |  | void OGR_F_FillUnsetWithDefault(OGRFeatureH hFeat, int bNotNullableOnly,  | 
7117  |  |                                 char **papszOptions)  | 
7118  |  |  | 
7119  | 0  | { | 
7120  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_FillUnsetWithDefault");  | 
7121  |  |  | 
7122  | 0  |     OGRFeature::FromHandle(hFeat)->FillUnsetWithDefault(bNotNullableOnly,  | 
7123  | 0  |                                                         papszOptions);  | 
7124  | 0  | }  | 
7125  |  |  | 
7126  |  | /************************************************************************/  | 
7127  |  | /*                              Validate()                              */  | 
7128  |  | /************************************************************************/  | 
7129  |  |  | 
7130  |  | /**  | 
7131  |  |  * \brief Validate that a feature meets constraints of its schema.  | 
7132  |  |  *  | 
7133  |  |  * The scope of test is specified with the nValidateFlags parameter.  | 
7134  |  |  *  | 
7135  |  |  * Regarding OGR_F_VAL_WIDTH, the test is done assuming the string width must be  | 
7136  |  |  * interpreted as the number of UTF-8 characters. Some drivers might interpret  | 
7137  |  |  * the width as the number of bytes instead. So this test is rather conservative  | 
7138  |  |  * (if it fails, then it will fail for all interpretations).  | 
7139  |  |  *  | 
7140  |  |  * This method is the same as the C function OGR_F_Validate().  | 
7141  |  |  *  | 
7142  |  |  * @param nValidateFlags OGR_F_VAL_ALL or combination of OGR_F_VAL_NULL,  | 
7143  |  |  *                       OGR_F_VAL_GEOM_TYPE, OGR_F_VAL_WIDTH and  | 
7144  |  |  *                       OGR_F_VAL_ALLOW_NULL_WHEN_DEFAULT,  | 
7145  |  |  *                       OGR_F_VAL_ALLOW_DIFFERENT_GEOM_DIM with '|' operator  | 
7146  |  |  * @param bEmitError TRUE if a CPLError() must be emitted when a check fails  | 
7147  |  |  * @return TRUE if all enabled validation tests pass.  | 
7148  |  |  * @since GDAL 2.0  | 
7149  |  |  */  | 
7150  |  |  | 
7151  |  | int OGRFeature::Validate(int nValidateFlags, int bEmitError) const  | 
7152  |  |  | 
7153  | 0  | { | 
7154  | 0  |     bool bRet = true;  | 
7155  |  | 
  | 
7156  | 0  |     const int nGeomFieldCount = poDefn->GetGeomFieldCount();  | 
7157  | 0  |     for (int i = 0; i < nGeomFieldCount; i++)  | 
7158  | 0  |     { | 
7159  | 0  |         if ((nValidateFlags & OGR_F_VAL_NULL) &&  | 
7160  | 0  |             !poDefn->GetGeomFieldDefn(i)->IsNullable() &&  | 
7161  | 0  |             GetGeomFieldRef(i) == nullptr)  | 
7162  | 0  |         { | 
7163  | 0  |             bRet = false;  | 
7164  | 0  |             if (bEmitError)  | 
7165  | 0  |             { | 
7166  | 0  |                 CPLError(  | 
7167  | 0  |                     CE_Failure, CPLE_AppDefined,  | 
7168  | 0  |                     "Geometry field %s has a NULL content which is not allowed",  | 
7169  | 0  |                     poDefn->GetGeomFieldDefn(i)->GetNameRef());  | 
7170  | 0  |             }  | 
7171  | 0  |         }  | 
7172  | 0  |         if ((nValidateFlags & OGR_F_VAL_GEOM_TYPE) &&  | 
7173  | 0  |             poDefn->GetGeomFieldDefn(i)->GetType() != wkbUnknown)  | 
7174  | 0  |         { | 
7175  | 0  |             const OGRGeometry *poGeom = GetGeomFieldRef(i);  | 
7176  | 0  |             if (poGeom != nullptr)  | 
7177  | 0  |             { | 
7178  | 0  |                 const OGRwkbGeometryType eType =  | 
7179  | 0  |                     poDefn->GetGeomFieldDefn(i)->GetType();  | 
7180  | 0  |                 const OGRwkbGeometryType eFType = poGeom->getGeometryType();  | 
7181  | 0  |                 if ((nValidateFlags & OGR_F_VAL_ALLOW_DIFFERENT_GEOM_DIM) &&  | 
7182  | 0  |                     (wkbFlatten(eFType) == wkbFlatten(eType) ||  | 
7183  | 0  |                      wkbFlatten(eType) == wkbUnknown))  | 
7184  | 0  |                 { | 
7185  |  |                     // Ok.  | 
7186  | 0  |                 }  | 
7187  | 0  |                 else if ((eType == wkbSetZ(wkbUnknown) && !wkbHasZ(eFType)) ||  | 
7188  | 0  |                          (eType != wkbSetZ(wkbUnknown) && eFType != eType))  | 
7189  | 0  |                 { | 
7190  | 0  |                     bRet = false;  | 
7191  | 0  |                     if (bEmitError)  | 
7192  | 0  |                     { | 
7193  | 0  |                         CPLError(CE_Failure, CPLE_AppDefined,  | 
7194  | 0  |                                  "Geometry field %s has a %s geometry whereas "  | 
7195  | 0  |                                  "%s is expected",  | 
7196  | 0  |                                  poDefn->GetGeomFieldDefn(i)->GetNameRef(),  | 
7197  | 0  |                                  OGRGeometryTypeToName(eFType),  | 
7198  | 0  |                                  OGRGeometryTypeToName(eType));  | 
7199  | 0  |                     }  | 
7200  | 0  |                 }  | 
7201  | 0  |             }  | 
7202  | 0  |         }  | 
7203  | 0  |     }  | 
7204  | 0  |     const int nFieldCount = poDefn->GetFieldCount();  | 
7205  | 0  |     for (int i = 0; i < nFieldCount; i++)  | 
7206  | 0  |     { | 
7207  | 0  |         if ((nValidateFlags & OGR_F_VAL_NULL) &&  | 
7208  | 0  |             !poDefn->GetFieldDefn(i)->IsNullable() && !IsFieldSet(i) &&  | 
7209  | 0  |             (!(nValidateFlags & OGR_F_VAL_ALLOW_NULL_WHEN_DEFAULT) ||  | 
7210  | 0  |              poDefn->GetFieldDefn(i)->GetDefault() == nullptr))  | 
7211  | 0  |         { | 
7212  | 0  |             bRet = false;  | 
7213  | 0  |             if (bEmitError)  | 
7214  | 0  |             { | 
7215  | 0  |                 CPLError(CE_Failure, CPLE_AppDefined,  | 
7216  | 0  |                          "Field %s.%s has a NULL content which is not allowed",  | 
7217  | 0  |                          poDefn->GetName(),  | 
7218  | 0  |                          poDefn->GetFieldDefn(i)->GetNameRef());  | 
7219  | 0  |             }  | 
7220  | 0  |         }  | 
7221  | 0  |         if ((nValidateFlags & OGR_F_VAL_WIDTH) &&  | 
7222  | 0  |             poDefn->GetFieldDefn(i)->GetWidth() > 0 &&  | 
7223  | 0  |             poDefn->GetFieldDefn(i)->GetType() == OFTString && IsFieldSet(i) &&  | 
7224  | 0  |             CPLIsUTF8(GetFieldAsString(i), -1) &&  | 
7225  | 0  |             CPLStrlenUTF8Ex(GetFieldAsString(i)) >  | 
7226  | 0  |                 static_cast<size_t>(poDefn->GetFieldDefn(i)->GetWidth()))  | 
7227  | 0  |         { | 
7228  | 0  |             bRet = false;  | 
7229  | 0  |             if (bEmitError)  | 
7230  | 0  |             { | 
7231  | 0  |                 CPLError(  | 
7232  | 0  |                     CE_Failure, CPLE_AppDefined,  | 
7233  | 0  |                     "Field %s.%s has %" PRIu64 " UTF-8 characters whereas "  | 
7234  | 0  |                     "a maximum of %d is allowed",  | 
7235  | 0  |                     poDefn->GetName(), poDefn->GetFieldDefn(i)->GetNameRef(),  | 
7236  | 0  |                     static_cast<uint64_t>(CPLStrlenUTF8Ex(GetFieldAsString(i))),  | 
7237  | 0  |                     poDefn->GetFieldDefn(i)->GetWidth());  | 
7238  | 0  |             }  | 
7239  | 0  |         }  | 
7240  | 0  |     }  | 
7241  |  | 
  | 
7242  | 0  |     return bRet;  | 
7243  | 0  | }  | 
7244  |  |  | 
7245  |  | /************************************************************************/  | 
7246  |  | /*                           OGR_F_Validate()                           */  | 
7247  |  | /************************************************************************/  | 
7248  |  |  | 
7249  |  | /**  | 
7250  |  |  * \brief Validate that a feature meets constraints of its schema.  | 
7251  |  |  *  | 
7252  |  |  * The scope of test is specified with the nValidateFlags parameter.  | 
7253  |  |  *  | 
7254  |  |  * Regarding OGR_F_VAL_WIDTH, the test is done assuming the string width must be  | 
7255  |  |  * interpreted as the number of UTF-8 characters. Some drivers might interpret  | 
7256  |  |  * the width as the number of bytes instead. So this test is rather conservative  | 
7257  |  |  * (if it fails, then it will fail for all interpretations).  | 
7258  |  |  *  | 
7259  |  |  * This function is the same as the C++ method  | 
7260  |  |  * OGRFeature::Validate().  | 
7261  |  |  *  | 
7262  |  |  * @param hFeat handle to the feature to validate.  | 
7263  |  |  * @param nValidateFlags OGR_F_VAL_ALL or combination of OGR_F_VAL_NULL,  | 
7264  |  |  *                       OGR_F_VAL_GEOM_TYPE, OGR_F_VAL_WIDTH and  | 
7265  |  |  *                       OGR_F_VAL_ALLOW_NULL_WHEN_DEFAULT with '|' operator  | 
7266  |  |  * @param bEmitError TRUE if a CPLError() must be emitted when a check fails  | 
7267  |  |  * @return TRUE if all enabled validation tests pass.  | 
7268  |  |  * @since GDAL 2.0  | 
7269  |  |  */  | 
7270  |  |  | 
7271  |  | int OGR_F_Validate(OGRFeatureH hFeat, int nValidateFlags, int bEmitError)  | 
7272  |  |  | 
7273  | 0  | { | 
7274  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_Validate", FALSE);  | 
7275  |  |  | 
7276  | 0  |     return OGRFeature::FromHandle(hFeat)->Validate(nValidateFlags, bEmitError);  | 
7277  | 0  | }  | 
7278  |  |  | 
7279  |  | /************************************************************************/  | 
7280  |  | /*                          GetNativeData()                             */  | 
7281  |  | /************************************************************************/  | 
7282  |  |  | 
7283  |  | /**  | 
7284  |  |  * \fn const char* OGRFeature::GetNativeData() const;  | 
7285  |  |  *  | 
7286  |  |  * \brief Returns the native data for the feature.  | 
7287  |  |  *  | 
7288  |  |  * The native data is the representation in a "natural" form that comes from  | 
7289  |  |  * the driver that created this feature, or that is aimed at an output driver.  | 
7290  |  |  * The native data may be in different format, which is indicated by  | 
7291  |  |  * GetNativeMediaType().  | 
7292  |  |  *  | 
7293  |  |  * Note that most drivers do not support storing the native data in the feature  | 
7294  |  |  * object, and if they do, generally the NATIVE_DATA open option must be passed  | 
7295  |  |  * at dataset opening.  | 
7296  |  |  *  | 
7297  |  |  * The "native data" does not imply it is something more performant or powerful  | 
7298  |  |  * than what can be obtained with the rest of the API, but it may be useful in  | 
7299  |  |  * round-tripping scenarios where some characteristics of the underlying format  | 
7300  |  |  * are not captured otherwise by the OGR abstraction.  | 
7301  |  |  *  | 
7302  |  |  * This function is the same as the C function  | 
7303  |  |  * OGR_F_GetNativeData().  | 
7304  |  |  *  | 
7305  |  |  * @return a string with the native data, or NULL if there is none.  | 
7306  |  |  * @since GDAL 2.1  | 
7307  |  |  *  | 
7308  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7309  |  |  */  | 
7310  |  |  | 
7311  |  | /************************************************************************/  | 
7312  |  | /*                         OGR_F_GetNativeData()                        */  | 
7313  |  | /************************************************************************/  | 
7314  |  |  | 
7315  |  | /**  | 
7316  |  |  * \brief Returns the native data for the feature.  | 
7317  |  |  *  | 
7318  |  |  * The native data is the representation in a "natural" form that comes from  | 
7319  |  |  * the driver that created this feature, or that is aimed at an output driver.  | 
7320  |  |  * The native data may be in different format, which is indicated by  | 
7321  |  |  * OGR_F_GetNativeMediaType().  | 
7322  |  |  *  | 
7323  |  |  * Note that most drivers do not support storing the native data in the feature  | 
7324  |  |  * object, and if they do, generally the NATIVE_DATA open option must be passed  | 
7325  |  |  * at dataset opening.  | 
7326  |  |  *  | 
7327  |  |  * The "native data" does not imply it is something more performant or powerful  | 
7328  |  |  * than what can be obtained with the rest of the API, but it may be useful in  | 
7329  |  |  * round-tripping scenarios where some characteristics of the underlying format  | 
7330  |  |  * are not captured otherwise by the OGR abstraction.  | 
7331  |  |  *  | 
7332  |  |  * This function is the same as the C++ method  | 
7333  |  |  * OGRFeature::GetNativeData().  | 
7334  |  |  *  | 
7335  |  |  * @param hFeat handle to the feature.  | 
7336  |  |  * @return a string with the native data, or NULL if there is none.  | 
7337  |  |  * @since GDAL 2.1  | 
7338  |  |  *  | 
7339  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7340  |  |  */  | 
7341  |  |  | 
7342  |  | const char *OGR_F_GetNativeData(OGRFeatureH hFeat)  | 
7343  |  |  | 
7344  | 0  | { | 
7345  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetNativeData", nullptr);  | 
7346  |  |  | 
7347  | 0  |     return OGRFeature::FromHandle(hFeat)->GetNativeData();  | 
7348  | 0  | }  | 
7349  |  |  | 
7350  |  | /************************************************************************/  | 
7351  |  | /*                        GetNativeMediaType()                          */  | 
7352  |  | /************************************************************************/  | 
7353  |  |  | 
7354  |  | /**  | 
7355  |  |  * \fn const char* OGRFeature::GetNativeMediaType() const;  | 
7356  |  |  *  | 
7357  |  |  * \brief Returns the native media type for the feature.  | 
7358  |  |  *  | 
7359  |  |  * The native media type is the identifier for the format of the native data.  | 
7360  |  |  * It follows the IANA RFC 2045 (see https://en.wikipedia.org/wiki/Media_type),  | 
7361  |  |  * e.g. "application/vnd.geo+json" for JSon.  | 
7362  |  |  *  | 
7363  |  |  * This function is the same as the C function  | 
7364  |  |  * OGR_F_GetNativeMediaType().  | 
7365  |  |  *  | 
7366  |  |  * @return a string with the native media type, or NULL if there is none.  | 
7367  |  |  * @since GDAL 2.1  | 
7368  |  |  *  | 
7369  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7370  |  |  */  | 
7371  |  |  | 
7372  |  | /************************************************************************/  | 
7373  |  | /*                       OGR_F_GetNativeMediaType()                     */  | 
7374  |  | /************************************************************************/  | 
7375  |  |  | 
7376  |  | /**  | 
7377  |  |  * \brief Returns the native media type for the feature.  | 
7378  |  |  *  | 
7379  |  |  * The native media type is the identifier for the format of the native data.  | 
7380  |  |  * It follows the IANA RFC 2045 (see https://en.wikipedia.org/wiki/Media_type),  | 
7381  |  |  * e.g. "application/vnd.geo+json" for JSon.  | 
7382  |  |  *  | 
7383  |  |  * This function is the same as the C function  | 
7384  |  |  * OGR_F_GetNativeMediaType().  | 
7385  |  |  *  | 
7386  |  |  * @param hFeat handle to the feature.  | 
7387  |  |  * @return a string with the native media type, or NULL if there is none.  | 
7388  |  |  * @since GDAL 2.1  | 
7389  |  |  *  | 
7390  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7391  |  |  */  | 
7392  |  |  | 
7393  |  | const char *OGR_F_GetNativeMediaType(OGRFeatureH hFeat)  | 
7394  | 0  | { | 
7395  | 0  |     VALIDATE_POINTER1(hFeat, "OGR_F_GetNativeMediaType", nullptr);  | 
7396  |  |  | 
7397  | 0  |     return OGRFeature::FromHandle(hFeat)->GetNativeMediaType();  | 
7398  | 0  | }  | 
7399  |  |  | 
7400  |  | /************************************************************************/  | 
7401  |  | /*                           SetNativeData()                            */  | 
7402  |  | /************************************************************************/  | 
7403  |  |  | 
7404  |  | /**  | 
7405  |  |  * \brief Sets the native data for the feature.  | 
7406  |  |  *  | 
7407  |  |  * The native data is the representation in a "natural" form that comes from  | 
7408  |  |  * the driver that created this feature, or that is aimed at an output driver.  | 
7409  |  |  * The native data may be in different format, which is indicated by  | 
7410  |  |  * GetNativeMediaType().  | 
7411  |  |  *  | 
7412  |  |  * This function is the same as the C function  | 
7413  |  |  * OGR_F_SetNativeData().  | 
7414  |  |  *  | 
7415  |  |  * @param pszNativeData a string with the native data, or NULL if there is none.  | 
7416  |  |  * @since GDAL 2.1  | 
7417  |  |  *  | 
7418  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7419  |  |  */  | 
7420  |  |  | 
7421  |  | void OGRFeature::SetNativeData(const char *pszNativeData)  | 
7422  | 0  | { | 
7423  | 0  |     CPLFree(m_pszNativeData);  | 
7424  | 0  |     m_pszNativeData =  | 
7425  | 0  |         pszNativeData ? VSI_STRDUP_VERBOSE(pszNativeData) : nullptr;  | 
7426  | 0  | }  | 
7427  |  |  | 
7428  |  | /************************************************************************/  | 
7429  |  | /*                          OGR_F_SetNativeData()                       */  | 
7430  |  | /************************************************************************/  | 
7431  |  |  | 
7432  |  | /**  | 
7433  |  |  * \brief Sets the native data for the feature.  | 
7434  |  |  *  | 
7435  |  |  * The native data is the representation in a "natural" form that comes from  | 
7436  |  |  * the driver that created this feature, or that is aimed at an output driver.  | 
7437  |  |  * The native data may be in different format, which is indicated by  | 
7438  |  |  * OGR_F_GetNativeMediaType().  | 
7439  |  |  *  | 
7440  |  |  * This function is the same as the C++ method  | 
7441  |  |  * OGRFeature::SetNativeData().  | 
7442  |  |  *  | 
7443  |  |  * @param hFeat handle to the feature.  | 
7444  |  |  * @param pszNativeData a string with the native data, or NULL if there is none.  | 
7445  |  |  * @since GDAL 2.1  | 
7446  |  |  *  | 
7447  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7448  |  |  */  | 
7449  |  |  | 
7450  |  | void OGR_F_SetNativeData(OGRFeatureH hFeat, const char *pszNativeData)  | 
7451  | 0  | { | 
7452  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetNativeData");  | 
7453  |  |  | 
7454  | 0  |     OGRFeature::FromHandle(hFeat)->SetNativeData(pszNativeData);  | 
7455  | 0  | }  | 
7456  |  |  | 
7457  |  | /************************************************************************/  | 
7458  |  | /*                         SetNativeMediaType()                         */  | 
7459  |  | /************************************************************************/  | 
7460  |  |  | 
7461  |  | /**  | 
7462  |  |  * \brief Sets the native media type for the feature.  | 
7463  |  |  *  | 
7464  |  |  * The native media type is the identifier for the format of the native data.  | 
7465  |  |  * It follows the IANA RFC 2045 (see https://en.wikipedia.org/wiki/Media_type),  | 
7466  |  |  * e.g. "application/vnd.geo+json" for JSon.  | 
7467  |  |  *  | 
7468  |  |  * This function is the same as the C function  | 
7469  |  |  * OGR_F_SetNativeMediaType().  | 
7470  |  |  *  | 
7471  |  |  * @param pszNativeMediaType a string with the native media type, or NULL if  | 
7472  |  |  * there is none.  | 
7473  |  |  * @since GDAL 2.1  | 
7474  |  |  *  | 
7475  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7476  |  |  */  | 
7477  |  |  | 
7478  |  | void OGRFeature::SetNativeMediaType(const char *pszNativeMediaType)  | 
7479  | 0  | { | 
7480  | 0  |     CPLFree(m_pszNativeMediaType);  | 
7481  | 0  |     m_pszNativeMediaType =  | 
7482  | 0  |         pszNativeMediaType ? VSI_STRDUP_VERBOSE(pszNativeMediaType) : nullptr;  | 
7483  | 0  | }  | 
7484  |  |  | 
7485  |  | /************************************************************************/  | 
7486  |  | /*                          OGR_F_SetNativeMediaType()                  */  | 
7487  |  | /************************************************************************/  | 
7488  |  |  | 
7489  |  | /**  | 
7490  |  |  * \brief Sets the native media type for the feature.  | 
7491  |  |  *  | 
7492  |  |  * The native media type is the identifier for the format of the native data.  | 
7493  |  |  * It follows the IANA RFC 2045 (see https://en.wikipedia.org/wiki/Media_type),  | 
7494  |  |  * e.g. "application/vnd.geo+json" for JSon.  | 
7495  |  |  *  | 
7496  |  |  * This function is the same as the C++ method  | 
7497  |  |  * OGRFeature::SetNativeMediaType().  | 
7498  |  |  *  | 
7499  |  |  * @param hFeat handle to the feature.  | 
7500  |  |  * @param pszNativeMediaType a string with the native media type, or NULL if  | 
7501  |  |  * there is none.  | 
7502  |  |  * @since GDAL 2.1  | 
7503  |  |  *  | 
7504  |  |  * @see https://trac.osgeo.org/gdal/wiki/rfc60_improved_roundtripping_in_ogr  | 
7505  |  |  */  | 
7506  |  |  | 
7507  |  | void OGR_F_SetNativeMediaType(OGRFeatureH hFeat, const char *pszNativeMediaType)  | 
7508  | 0  | { | 
7509  | 0  |     VALIDATE_POINTER0(hFeat, "OGR_F_SetNativeMediaType");  | 
7510  |  |  | 
7511  | 0  |     OGRFeature::FromHandle(hFeat)->SetNativeMediaType(pszNativeMediaType);  | 
7512  | 0  | }  | 
7513  |  |  | 
7514  |  | /************************************************************************/  | 
7515  |  | /*                           OGR_RawField_IsUnset()                     */  | 
7516  |  | /************************************************************************/  | 
7517  |  |  | 
7518  |  | /**  | 
7519  |  |  * \brief Returns whether a raw field is unset.  | 
7520  |  |  *  | 
7521  |  |  * Note: this function is rather low-level and should be rarely used in client  | 
7522  |  |  * code. Use instead OGR_F_IsFieldSet().  | 
7523  |  |  *  | 
7524  |  |  * @param puField pointer to raw field.  | 
7525  |  |  * @since GDAL 2.2  | 
7526  |  |  */  | 
7527  |  |  | 
7528  |  | int OGR_RawField_IsUnset(const OGRField *puField)  | 
7529  | 0  | { | 
7530  | 0  |     return puField->Set.nMarker1 == OGRUnsetMarker &&  | 
7531  | 0  |            puField->Set.nMarker2 == OGRUnsetMarker &&  | 
7532  | 0  |            puField->Set.nMarker3 == OGRUnsetMarker;  | 
7533  | 0  | }  | 
7534  |  |  | 
7535  |  | /************************************************************************/  | 
7536  |  | /*                           OGR_RawField_IsNull()                      */  | 
7537  |  | /************************************************************************/  | 
7538  |  |  | 
7539  |  | /**  | 
7540  |  |  * \brief Returns whether a raw field is null.  | 
7541  |  |  *  | 
7542  |  |  * Note: this function is rather low-level and should be rarely used in client  | 
7543  |  |  * code. Use instead OGR_F_IsFieldNull().  | 
7544  |  |  *  | 
7545  |  |  * @param puField pointer to raw field.  | 
7546  |  |  * @since GDAL 2.2  | 
7547  |  |  */  | 
7548  |  |  | 
7549  |  | int OGR_RawField_IsNull(const OGRField *puField)  | 
7550  | 0  | { | 
7551  | 0  |     return puField->Set.nMarker1 == OGRNullMarker &&  | 
7552  | 0  |            puField->Set.nMarker2 == OGRNullMarker &&  | 
7553  | 0  |            puField->Set.nMarker3 == OGRNullMarker;  | 
7554  | 0  | }  | 
7555  |  |  | 
7556  |  | /************************************************************************/  | 
7557  |  | /*                          OGR_RawField_SetUnset()                     */  | 
7558  |  | /************************************************************************/  | 
7559  |  |  | 
7560  |  | /**  | 
7561  |  |  * \brief Mark a raw field as unset.  | 
7562  |  |  *  | 
7563  |  |  * This should be called on a un-initialized field. In particular this will not  | 
7564  |  |  * free any memory dynamically allocated.  | 
7565  |  |  *  | 
7566  |  |  * Note: this function is rather low-level and should be rarely used in client  | 
7567  |  |  * code. Use instead OGR_F_UnsetField().  | 
7568  |  |  *  | 
7569  |  |  * @param puField pointer to raw field.  | 
7570  |  |  * @since GDAL 2.2  | 
7571  |  |  */  | 
7572  |  |  | 
7573  |  | void OGR_RawField_SetUnset(OGRField *puField)  | 
7574  | 0  | { | 
7575  | 0  |     puField->Set.nMarker1 = OGRUnsetMarker;  | 
7576  | 0  |     puField->Set.nMarker2 = OGRUnsetMarker;  | 
7577  | 0  |     puField->Set.nMarker3 = OGRUnsetMarker;  | 
7578  | 0  | }  | 
7579  |  |  | 
7580  |  | /************************************************************************/  | 
7581  |  | /*                          OGR_RawField_SetNull()                      */  | 
7582  |  | /************************************************************************/  | 
7583  |  |  | 
7584  |  | /**  | 
7585  |  |  * \brief Mark a raw field as null.  | 
7586  |  |  *  | 
7587  |  |  * This should be called on a un-initialized field. In particular this will not  | 
7588  |  |  * free any memory dynamically allocated.  | 
7589  |  |  *  | 
7590  |  |  * Note: this function is rather low-level and should be rarely used in client  | 
7591  |  |  * code. Use instead OGR_F_SetFieldNull().  | 
7592  |  |  *  | 
7593  |  |  * @param puField pointer to raw field.  | 
7594  |  |  * @since GDAL 2.2  | 
7595  |  |  */  | 
7596  |  |  | 
7597  |  | void OGR_RawField_SetNull(OGRField *puField)  | 
7598  | 0  | { | 
7599  | 0  |     puField->Set.nMarker1 = OGRNullMarker;  | 
7600  | 0  |     puField->Set.nMarker2 = OGRNullMarker;  | 
7601  | 0  |     puField->Set.nMarker3 = OGRNullMarker;  | 
7602  | 0  | }  | 
7603  |  |  | 
7604  |  | /************************************************************************/  | 
7605  |  | /*                     OGRFeatureUniquePtrDeleter                       */  | 
7606  |  | /************************************************************************/  | 
7607  |  |  | 
7608  |  | //! @cond Doxygen_Suppress  | 
7609  |  | void OGRFeatureUniquePtrDeleter::operator()(OGRFeature *poFeature) const  | 
7610  | 0  | { | 
7611  | 0  |     delete poFeature;  | 
7612  | 0  | }  | 
7613  |  |  | 
7614  |  | //! @endcond  | 
7615  |  |  | 
7616  |  | namespace  | 
7617  |  | { | 
7618  |  | // Implementation borrowed to OpenFileGDB  | 
7619  |  |  | 
7620  |  | /************************************************************************/  | 
7621  |  | /*                            WriteUInt8()                              */  | 
7622  |  | /************************************************************************/  | 
7623  |  |  | 
7624  |  | inline void WriteUInt8(std::vector<GByte> &abyBuffer, uint8_t nVal)  | 
7625  | 0  | { | 
7626  | 0  |     abyBuffer.push_back(nVal);  | 
7627  | 0  | }  | 
7628  |  |  | 
7629  |  | /************************************************************************/  | 
7630  |  | /*                             WriteVarUInt()                           */  | 
7631  |  | /************************************************************************/  | 
7632  |  |  | 
7633  |  | inline void WriteVarUInt(std::vector<GByte> &abyBuffer, uint64_t nVal)  | 
7634  | 0  | { | 
7635  | 0  |     while (true)  | 
7636  | 0  |     { | 
7637  | 0  |         if (nVal >= 0x80)  | 
7638  | 0  |         { | 
7639  | 0  |             WriteUInt8(abyBuffer, static_cast<uint8_t>(0x80 | (nVal & 0x7F)));  | 
7640  | 0  |             nVal >>= 7;  | 
7641  | 0  |         }  | 
7642  | 0  |         else  | 
7643  | 0  |         { | 
7644  | 0  |             WriteUInt8(abyBuffer, static_cast<uint8_t>(nVal));  | 
7645  | 0  |             break;  | 
7646  | 0  |         }  | 
7647  | 0  |     }  | 
7648  | 0  | }  | 
7649  |  |  | 
7650  |  | /************************************************************************/  | 
7651  |  | /*                             WriteVarInt()                            */  | 
7652  |  | /************************************************************************/  | 
7653  |  |  | 
7654  |  | inline void WriteVarInt(std::vector<GByte> &abyBuffer, int64_t nVal)  | 
7655  | 0  | { | 
7656  | 0  |     uint64_t nUVal;  | 
7657  | 0  |     if (nVal < 0)  | 
7658  | 0  |     { | 
7659  | 0  |         if (nVal == std::numeric_limits<int64_t>::min())  | 
7660  | 0  |             nUVal = static_cast<uint64_t>(1) << 63;  | 
7661  | 0  |         else  | 
7662  | 0  |             nUVal = -nVal;  | 
7663  | 0  |         if (nUVal >= 0x40)  | 
7664  | 0  |         { | 
7665  | 0  |             WriteUInt8(abyBuffer,  | 
7666  | 0  |                        static_cast<uint8_t>(0x80 | 0x40 | (nUVal & 0x3F)));  | 
7667  | 0  |             nUVal >>= 6;  | 
7668  | 0  |         }  | 
7669  | 0  |         else  | 
7670  | 0  |         { | 
7671  | 0  |             WriteUInt8(abyBuffer, static_cast<uint8_t>(0x40 | (nUVal & 0x3F)));  | 
7672  | 0  |             return;  | 
7673  | 0  |         }  | 
7674  | 0  |     }  | 
7675  | 0  |     else  | 
7676  | 0  |     { | 
7677  | 0  |         nUVal = nVal;  | 
7678  | 0  |         if (nUVal >= 0x40)  | 
7679  | 0  |         { | 
7680  | 0  |             WriteUInt8(abyBuffer, static_cast<uint8_t>(0x80 | (nUVal & 0x3F)));  | 
7681  | 0  |             nUVal >>= 6;  | 
7682  | 0  |         }  | 
7683  | 0  |         else  | 
7684  | 0  |         { | 
7685  | 0  |             WriteUInt8(abyBuffer, static_cast<uint8_t>((nUVal & 0x3F)));  | 
7686  | 0  |             return;  | 
7687  | 0  |         }  | 
7688  | 0  |     }  | 
7689  |  |  | 
7690  | 0  |     WriteVarUInt(abyBuffer, nUVal);  | 
7691  | 0  | }  | 
7692  |  |  | 
7693  |  | /************************************************************************/  | 
7694  |  | /*                          WriteFloat32()                              */  | 
7695  |  | /************************************************************************/  | 
7696  |  |  | 
7697  |  | inline void WriteFloat32(std::vector<GByte> &abyBuffer, float fVal)  | 
7698  | 0  | { | 
7699  | 0  |     CPL_LSBPTR32(&fVal);  | 
7700  | 0  |     const GByte *pabyInput = reinterpret_cast<const GByte *>(&fVal);  | 
7701  | 0  |     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(fVal));  | 
7702  | 0  | }  | 
7703  |  |  | 
7704  |  | /************************************************************************/  | 
7705  |  | /*                          WriteFloat64()                              */  | 
7706  |  | /************************************************************************/  | 
7707  |  |  | 
7708  |  | inline void WriteFloat64(std::vector<GByte> &abyBuffer, double dfVal)  | 
7709  | 0  | { | 
7710  | 0  |     CPL_LSBPTR64(&dfVal);  | 
7711  | 0  |     const GByte *pabyInput = reinterpret_cast<const GByte *>(&dfVal);  | 
7712  | 0  |     abyBuffer.insert(abyBuffer.end(), pabyInput, pabyInput + sizeof(dfVal));  | 
7713  | 0  | }  | 
7714  |  |  | 
7715  |  | }  // namespace  | 
7716  |  |  | 
7717  |  | /************************************************************************/  | 
7718  |  | /*                    OGRFeature::SerializeToBinary()                   */  | 
7719  |  | /************************************************************************/  | 
7720  |  |  | 
7721  |  | /** Serialize the feature to a binary encoding.  | 
7722  |  |  *  | 
7723  |  |  * This saves the feature ID, attribute fields content and geometry fields  | 
7724  |  |  * content.  | 
7725  |  |  *  | 
7726  |  |  * This method is aimed at being paired with DeserializeFromBinary().  | 
7727  |  |  *  | 
7728  |  |  * The format of that encoding may vary across GDAL versions.  | 
7729  |  |  *  | 
7730  |  |  * Note that abyBuffer is cleared at the beginning of this function.  | 
7731  |  |  *  | 
7732  |  |  * @since 3.9  | 
7733  |  |  */  | 
7734  |  | bool OGRFeature::SerializeToBinary(std::vector<GByte> &abyBuffer) const  | 
7735  | 0  | { | 
7736  | 0  |     const int nFieldCount = poDefn->GetFieldCount();  | 
7737  | 0  |     const int nGeomFieldCount = poDefn->GetGeomFieldCount();  | 
7738  | 0  |     try  | 
7739  | 0  |     { | 
7740  | 0  |         abyBuffer.clear();  | 
7741  |  |         // Set field flags  | 
7742  |  |         // For attribute fields, we have 2 bits  | 
7743  |  |         // - first one set if the field is unset  | 
7744  |  |         // - second one set if the field is null  | 
7745  |  |         // For geometry fields, we have one bit set to indicate if the geometry  | 
7746  |  |         // is non-null.  | 
7747  | 0  |         const size_t nPresenceFlagsSize =  | 
7748  | 0  |             ((2 * nFieldCount + nGeomFieldCount) + 7) / 8;  | 
7749  | 0  |         abyBuffer.resize(nPresenceFlagsSize);  | 
7750  |  | 
  | 
7751  | 0  |         WriteVarInt(abyBuffer, GetFID());  | 
7752  |  | 
  | 
7753  | 0  |         const auto SetFlagBit = [&abyBuffer](int iBit)  | 
7754  | 0  |         { abyBuffer[iBit / 8] |= (1 << (iBit % 8)); }; | 
7755  |  | 
  | 
7756  | 0  |         for (int i = 0; i < nFieldCount; ++i)  | 
7757  | 0  |         { | 
7758  | 0  |             const OGRField &uField = pauFields[i];  | 
7759  | 0  |             if (OGR_RawField_IsUnset(&uField))  | 
7760  | 0  |             { | 
7761  | 0  |                 const int iBit = 2 * i;  | 
7762  | 0  |                 SetFlagBit(iBit);  | 
7763  | 0  |                 continue;  | 
7764  | 0  |             }  | 
7765  | 0  |             if (OGR_RawField_IsNull(&uField))  | 
7766  | 0  |             { | 
7767  | 0  |                 const int iBit = 2 * i + 1;  | 
7768  | 0  |                 SetFlagBit(iBit);  | 
7769  | 0  |                 continue;  | 
7770  | 0  |             }  | 
7771  | 0  |             const auto poFDefn = poDefn->GetFieldDefn(i);  | 
7772  | 0  |             switch (poFDefn->GetType())  | 
7773  | 0  |             { | 
7774  | 0  |                 case OFTInteger:  | 
7775  | 0  |                 { | 
7776  | 0  |                     WriteVarInt(abyBuffer, uField.Integer);  | 
7777  | 0  |                     break;  | 
7778  | 0  |                 }  | 
7779  | 0  |                 case OFTInteger64:  | 
7780  | 0  |                 { | 
7781  | 0  |                     WriteVarInt(abyBuffer, uField.Integer64);  | 
7782  | 0  |                     break;  | 
7783  | 0  |                 }  | 
7784  | 0  |                 case OFTReal:  | 
7785  | 0  |                 { | 
7786  | 0  |                     WriteFloat64(abyBuffer, uField.Real);  | 
7787  | 0  |                     break;  | 
7788  | 0  |                 }  | 
7789  | 0  |                 case OFTString:  | 
7790  | 0  |                 { | 
7791  | 0  |                     const size_t nStrSize = strlen(uField.String);  | 
7792  | 0  |                     WriteVarUInt(abyBuffer, nStrSize);  | 
7793  | 0  |                     const GByte *pabyStr =  | 
7794  | 0  |                         reinterpret_cast<const GByte *>(uField.String);  | 
7795  | 0  |                     abyBuffer.insert(abyBuffer.end(), pabyStr,  | 
7796  | 0  |                                      pabyStr + nStrSize);  | 
7797  | 0  |                     break;  | 
7798  | 0  |                 }  | 
7799  | 0  |                 case OFTIntegerList:  | 
7800  | 0  |                 { | 
7801  | 0  |                     WriteVarInt(abyBuffer, uField.IntegerList.nCount);  | 
7802  | 0  |                     for (int j = 0; j < uField.IntegerList.nCount; ++j)  | 
7803  | 0  |                         WriteVarInt(abyBuffer, uField.IntegerList.paList[j]);  | 
7804  | 0  |                     break;  | 
7805  | 0  |                 }  | 
7806  | 0  |                 case OFTInteger64List:  | 
7807  | 0  |                 { | 
7808  | 0  |                     WriteVarInt(abyBuffer, uField.Integer64List.nCount);  | 
7809  | 0  |                     for (int j = 0; j < uField.Integer64List.nCount; ++j)  | 
7810  | 0  |                         WriteVarInt(abyBuffer, uField.Integer64List.paList[j]);  | 
7811  | 0  |                     break;  | 
7812  | 0  |                 }  | 
7813  | 0  |                 case OFTRealList:  | 
7814  | 0  |                 { | 
7815  | 0  |                     WriteVarInt(abyBuffer, uField.RealList.nCount);  | 
7816  | 0  |                     for (int j = 0; j < uField.RealList.nCount; ++j)  | 
7817  | 0  |                         WriteFloat64(abyBuffer, uField.RealList.paList[j]);  | 
7818  | 0  |                     break;  | 
7819  | 0  |                 }  | 
7820  | 0  |                 case OFTStringList:  | 
7821  | 0  |                 { | 
7822  | 0  |                     WriteVarInt(abyBuffer, uField.StringList.nCount);  | 
7823  | 0  |                     for (int j = 0; j < uField.StringList.nCount; ++j)  | 
7824  | 0  |                     { | 
7825  | 0  |                         const char *pszStr = uField.StringList.paList[j];  | 
7826  | 0  |                         const size_t nStrSize = strlen(pszStr);  | 
7827  | 0  |                         WriteVarUInt(abyBuffer, nStrSize);  | 
7828  | 0  |                         const GByte *pabyStr =  | 
7829  | 0  |                             reinterpret_cast<const GByte *>(pszStr);  | 
7830  | 0  |                         abyBuffer.insert(abyBuffer.end(), pabyStr,  | 
7831  | 0  |                                          pabyStr + nStrSize);  | 
7832  | 0  |                     }  | 
7833  | 0  |                     break;  | 
7834  | 0  |                 }  | 
7835  | 0  |                 case OFTBinary:  | 
7836  | 0  |                 { | 
7837  | 0  |                     WriteVarInt(abyBuffer, uField.Binary.nCount);  | 
7838  | 0  |                     abyBuffer.insert(abyBuffer.end(), uField.Binary.paData,  | 
7839  | 0  |                                      uField.Binary.paData +  | 
7840  | 0  |                                          uField.Binary.nCount);  | 
7841  | 0  |                     break;  | 
7842  | 0  |                 }  | 
7843  | 0  |                 case OFTWideString:  | 
7844  | 0  |                 case OFTWideStringList:  | 
7845  | 0  |                     break;  | 
7846  | 0  |                 case OFTDate:  | 
7847  | 0  |                 { | 
7848  | 0  |                     WriteVarInt(abyBuffer, uField.Date.Year);  | 
7849  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Month);  | 
7850  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Day);  | 
7851  | 0  |                     break;  | 
7852  | 0  |                 }  | 
7853  | 0  |                 case OFTTime:  | 
7854  | 0  |                 { | 
7855  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Hour);  | 
7856  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Minute);  | 
7857  | 0  |                     WriteFloat32(abyBuffer, uField.Date.Second);  | 
7858  | 0  |                     WriteUInt8(abyBuffer, uField.Date.TZFlag);  | 
7859  | 0  |                     break;  | 
7860  | 0  |                 }  | 
7861  | 0  |                 case OFTDateTime:  | 
7862  | 0  |                 { | 
7863  | 0  |                     WriteVarInt(abyBuffer, uField.Date.Year);  | 
7864  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Month);  | 
7865  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Day);  | 
7866  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Hour);  | 
7867  | 0  |                     WriteUInt8(abyBuffer, uField.Date.Minute);  | 
7868  | 0  |                     WriteFloat32(abyBuffer, uField.Date.Second);  | 
7869  | 0  |                     WriteUInt8(abyBuffer, uField.Date.TZFlag);  | 
7870  | 0  |                     break;  | 
7871  | 0  |                 }  | 
7872  | 0  |             }  | 
7873  | 0  |         }  | 
7874  | 0  |         for (int i = 0; i < nGeomFieldCount; ++i)  | 
7875  | 0  |         { | 
7876  | 0  |             if (!papoGeometries[i])  | 
7877  | 0  |             { | 
7878  | 0  |                 const int iBit = 2 * nFieldCount + i;  | 
7879  | 0  |                 SetFlagBit(iBit);  | 
7880  | 0  |                 continue;  | 
7881  | 0  |             }  | 
7882  | 0  |             const size_t nSize = papoGeometries[i]->WkbSize();  | 
7883  | 0  |             WriteVarUInt(abyBuffer, nSize);  | 
7884  | 0  |             const size_t nBufSizeBefore = abyBuffer.size();  | 
7885  | 0  |             abyBuffer.resize(nBufSizeBefore + nSize);  | 
7886  | 0  |             papoGeometries[i]->exportToWkb(  | 
7887  | 0  |                 wkbNDR, abyBuffer.data() + nBufSizeBefore, wkbVariantIso);  | 
7888  | 0  |         }  | 
7889  | 0  |         return true;  | 
7890  | 0  |     }  | 
7891  | 0  |     catch (const std::bad_alloc &)  | 
7892  | 0  |     { | 
7893  | 0  |         CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");  | 
7894  | 0  |         return false;  | 
7895  | 0  |     }  | 
7896  | 0  | }  | 
7897  |  |  | 
7898  |  | namespace  | 
7899  |  | { | 
7900  |  | // Implementation borrowed to OpenFileGDB  | 
7901  |  |  | 
7902  |  | /************************************************************************/  | 
7903  |  | /*                          ReadVarUInt()                               */  | 
7904  |  | /************************************************************************/  | 
7905  |  |  | 
7906  |  | template <class OutType>  | 
7907  |  | static bool ReadVarUInt(const GByte *&pabyIter, const GByte *pabyEnd,  | 
7908  |  |                         OutType &nOutVal)  | 
7909  | 0  | { | 
7910  | 0  |     if (pabyIter >= pabyEnd)  | 
7911  | 0  |         return false;  | 
7912  | 0  |     OutType b = *pabyIter;  | 
7913  | 0  |     if ((b & 0x80) == 0)  | 
7914  | 0  |     { | 
7915  | 0  |         pabyIter++;  | 
7916  | 0  |         nOutVal = b;  | 
7917  | 0  |         return true;  | 
7918  | 0  |     }  | 
7919  | 0  |     const GByte *pabyLocalIter = pabyIter + 1;  | 
7920  | 0  |     int nShift = 7;  | 
7921  | 0  |     OutType nVal = (b & 0x7F);  | 
7922  | 0  |     while (true)  | 
7923  | 0  |     { | 
7924  | 0  |         if (pabyLocalIter >= pabyEnd)  | 
7925  | 0  |             return false;  | 
7926  | 0  |         b = *pabyLocalIter;  | 
7927  | 0  |         pabyLocalIter++;  | 
7928  | 0  |         nVal |= (b & 0x7F) << nShift;  | 
7929  | 0  |         if ((b & 0x80) == 0)  | 
7930  | 0  |         { | 
7931  | 0  |             pabyIter = pabyLocalIter;  | 
7932  | 0  |             nOutVal = nVal;  | 
7933  | 0  |             return true;  | 
7934  | 0  |         }  | 
7935  | 0  |         nShift += 7;  | 
7936  |  |         // To avoid undefined behavior later when doing << nShift  | 
7937  | 0  |         if (nShift >= static_cast<int>(sizeof(OutType)) * 8)  | 
7938  | 0  |         { | 
7939  | 0  |             return false;  | 
7940  | 0  |         }  | 
7941  | 0  |     }  | 
7942  | 0  | }  | 
7943  |  |  | 
7944  |  | /************************************************************************/  | 
7945  |  | /*                             ReadVarInt()                             */  | 
7946  |  | /************************************************************************/  | 
7947  |  |  | 
7948  |  | template <class OutType>  | 
7949  |  | CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW static bool  | 
7950  |  | ReadVarInt(const GByte *&pabyIter, const GByte *pabyEnd, OutType &nOutVal)  | 
7951  | 0  | { | 
7952  | 0  |     GUInt32 b;  | 
7953  |  | 
  | 
7954  | 0  |     if (pabyIter >= pabyEnd)  | 
7955  | 0  |         return false;  | 
7956  | 0  |     b = *pabyIter;  | 
7957  | 0  |     GUIntBig nVal = (b & 0x3F);  | 
7958  | 0  |     bool bNegative = (b & 0x40) != 0;  | 
7959  | 0  |     if ((b & 0x80) == 0)  | 
7960  | 0  |     { | 
7961  | 0  |         pabyIter++;  | 
7962  | 0  |         if (bNegative)  | 
7963  | 0  |             nOutVal = -static_cast<OutType>(nVal);  | 
7964  | 0  |         else  | 
7965  | 0  |             nOutVal = static_cast<OutType>(nVal);  | 
7966  | 0  |         return true;  | 
7967  | 0  |     }  | 
7968  |  |  | 
7969  | 0  |     const GByte *pabyLocalIter = pabyIter + 1;  | 
7970  | 0  |     int nShift = 6;  | 
7971  | 0  |     while (true)  | 
7972  | 0  |     { | 
7973  | 0  |         if (pabyLocalIter >= pabyEnd)  | 
7974  | 0  |             return false;  | 
7975  | 0  |         GUIntBig b64 = *pabyLocalIter;  | 
7976  | 0  |         pabyLocalIter++;  | 
7977  | 0  |         nVal |= (b64 & 0x7F) << nShift;  | 
7978  | 0  |         if ((b64 & 0x80) == 0)  | 
7979  | 0  |         { | 
7980  | 0  |             pabyIter = pabyLocalIter;  | 
7981  | 0  |             if (bNegative)  | 
7982  | 0  |                 nOutVal = -static_cast<OutType>(nVal);  | 
7983  | 0  |             else  | 
7984  | 0  |                 nOutVal = static_cast<OutType>(nVal);  | 
7985  | 0  |             return true;  | 
7986  | 0  |         }  | 
7987  | 0  |         nShift += 7;  | 
7988  |  |         // To avoid undefined behavior later when doing << nShift  | 
7989  | 0  |         if (nShift >= static_cast<int>(sizeof(GIntBig)) * 8)  | 
7990  | 0  |         { | 
7991  | 0  |             return false;  | 
7992  | 0  |         }  | 
7993  | 0  |     }  | 
7994  | 0  | } Unexecuted instantiation: ogrfeature.cpp:bool (anonymous namespace)::ReadVarInt<long long>(unsigned char const*&, unsigned char const*, long long&) Unexecuted instantiation: ogrfeature.cpp:bool (anonymous namespace)::ReadVarInt<int>(unsigned char const*&, unsigned char const*, int&) Unexecuted instantiation: ogrfeature.cpp:bool (anonymous namespace)::ReadVarInt<short>(unsigned char const*&, unsigned char const*, short&)  | 
7995  |  |  | 
7996  |  | /************************************************************************/  | 
7997  |  | /*                          ReadUInt8()                                 */  | 
7998  |  | /************************************************************************/  | 
7999  |  |  | 
8000  |  | inline bool ReadUInt8(const GByte *&pabyIter, const GByte *pabyEnd, GByte &nVal)  | 
8001  | 0  | { | 
8002  | 0  |     if (pabyIter + sizeof(nVal) > pabyEnd)  | 
8003  | 0  |         return false;  | 
8004  | 0  |     nVal = *pabyIter;  | 
8005  | 0  |     pabyIter += sizeof(nVal);  | 
8006  | 0  |     return true;  | 
8007  | 0  | }  | 
8008  |  |  | 
8009  |  | /************************************************************************/  | 
8010  |  | /*                          ReadFloat32()                               */  | 
8011  |  | /************************************************************************/  | 
8012  |  |  | 
8013  |  | inline bool ReadFloat32(const GByte *&pabyIter, const GByte *pabyEnd,  | 
8014  |  |                         float &fVal)  | 
8015  | 0  | { | 
8016  | 0  |     if (pabyIter + sizeof(fVal) > pabyEnd)  | 
8017  | 0  |         return false;  | 
8018  | 0  |     memcpy(&fVal, pabyIter, sizeof(fVal));  | 
8019  | 0  |     CPL_LSBPTR32(&fVal);  | 
8020  | 0  |     pabyIter += sizeof(fVal);  | 
8021  | 0  |     return true;  | 
8022  | 0  | }  | 
8023  |  |  | 
8024  |  | /************************************************************************/  | 
8025  |  | /*                          ReadFloat64()                               */  | 
8026  |  | /************************************************************************/  | 
8027  |  |  | 
8028  |  | inline bool ReadFloat64(const GByte *&pabyIter, const GByte *pabyEnd,  | 
8029  |  |                         double &dfVal)  | 
8030  | 0  | { | 
8031  | 0  |     if (pabyIter + sizeof(dfVal) > pabyEnd)  | 
8032  | 0  |         return false;  | 
8033  | 0  |     memcpy(&dfVal, pabyIter, sizeof(dfVal));  | 
8034  | 0  |     CPL_LSBPTR64(&dfVal);  | 
8035  | 0  |     pabyIter += sizeof(dfVal);  | 
8036  | 0  |     return true;  | 
8037  | 0  | }  | 
8038  |  |  | 
8039  |  | }  // namespace  | 
8040  |  |  | 
8041  |  | /************************************************************************/  | 
8042  |  | /*                    OGRFeature::DeserializeFromBinary()               */  | 
8043  |  | /************************************************************************/  | 
8044  |  |  | 
8045  |  | /** Instantiate a feature from a binary encoding produces by SerializeToBinary()  | 
8046  |  |  *  | 
8047  |  |  * This sets the feature ID, attribute fields content and geometry fields  | 
8048  |  |  * content.  | 
8049  |  |  *  | 
8050  |  |  * DeserializeFromBinary() should be called on a feature whose feature definition  | 
8051  |  |  * is exactly the same as the one on which SerializeToBinary() was called.  | 
8052  |  |  * (but there is no security issue if not doing that, or if feeding a "random"  | 
8053  |  |  * buffer to that method).  | 
8054  |  |  *  | 
8055  |  |  * The format of that encoding may vary across GDAL versions.  | 
8056  |  |  *  | 
8057  |  |  * @since 3.9  | 
8058  |  |  */  | 
8059  |  | bool OGRFeature::DeserializeFromBinary(const GByte *pabyBuffer, size_t nSize)  | 
8060  | 0  | { | 
8061  | 0  |     Reset();  | 
8062  |  | 
  | 
8063  | 0  |     const GByte *const pabyFlags = pabyBuffer;  | 
8064  | 0  |     const GByte *const pabyEnd = pabyBuffer + nSize;  | 
8065  | 0  |     const int nFieldCount = poDefn->GetFieldCount();  | 
8066  | 0  |     const int nGeomFieldCount = poDefn->GetGeomFieldCount();  | 
8067  | 0  |     const size_t nPresenceFlagsSize =  | 
8068  | 0  |         ((2 * nFieldCount + nGeomFieldCount) + 7) / 8;  | 
8069  | 0  |     if (nSize < nPresenceFlagsSize)  | 
8070  | 0  |         return false;  | 
8071  | 0  |     pabyBuffer += nPresenceFlagsSize;  | 
8072  |  | 
  | 
8073  | 0  |     if (!ReadVarInt(pabyBuffer, pabyEnd, nFID))  | 
8074  | 0  |         return false;  | 
8075  |  |  | 
8076  | 0  |     const auto IsFlagBitSet = [pabyFlags](int iBit) -> bool  | 
8077  | 0  |     { return (pabyFlags[iBit / 8] & (1 << (iBit % 8))) != 0; }; | 
8078  |  | 
  | 
8079  | 0  |     for (int i = 0; i < nFieldCount; ++i)  | 
8080  | 0  |     { | 
8081  | 0  |         OGRField &uField = pauFields[i];  | 
8082  | 0  |         { | 
8083  | 0  |             const int iBit = 2 * i;  | 
8084  | 0  |             if (IsFlagBitSet(iBit))  | 
8085  | 0  |             { | 
8086  |  |                 // OGR_RawField_SetUnset(&uField);  | 
8087  | 0  |                 continue;  | 
8088  | 0  |             }  | 
8089  | 0  |         }  | 
8090  | 0  |         { | 
8091  | 0  |             const int iBit = 2 * i + 1;  | 
8092  | 0  |             if (IsFlagBitSet(iBit))  | 
8093  | 0  |             { | 
8094  | 0  |                 OGR_RawField_SetNull(&uField);  | 
8095  | 0  |                 continue;  | 
8096  | 0  |             }  | 
8097  | 0  |         }  | 
8098  | 0  |         const auto poFDefn = poDefn->GetFieldDefn(i);  | 
8099  | 0  |         switch (poFDefn->GetType())  | 
8100  | 0  |         { | 
8101  | 0  |             case OFTInteger:  | 
8102  | 0  |             { | 
8103  | 0  |                 uField.Set.nMarker2 = 0;  | 
8104  | 0  |                 uField.Set.nMarker3 = 0;  | 
8105  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, uField.Integer))  | 
8106  | 0  |                     return false;  | 
8107  | 0  |                 break;  | 
8108  | 0  |             }  | 
8109  | 0  |             case OFTInteger64:  | 
8110  | 0  |             { | 
8111  | 0  |                 uField.Set.nMarker2 = 0;  | 
8112  | 0  |                 uField.Set.nMarker3 = 0;  | 
8113  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, uField.Integer64))  | 
8114  | 0  |                     return false;  | 
8115  | 0  |                 break;  | 
8116  | 0  |             }  | 
8117  | 0  |             case OFTReal:  | 
8118  | 0  |             { | 
8119  | 0  |                 uField.Set.nMarker2 = 0;  | 
8120  | 0  |                 uField.Set.nMarker3 = 0;  | 
8121  | 0  |                 if (!ReadFloat64(pabyBuffer, pabyEnd, uField.Real))  | 
8122  | 0  |                     return false;  | 
8123  | 0  |                 break;  | 
8124  | 0  |             }  | 
8125  | 0  |             case OFTString:  | 
8126  | 0  |             { | 
8127  | 0  |                 size_t nStrSize = 0;  | 
8128  | 0  |                 if (!ReadVarUInt(pabyBuffer, pabyEnd, nStrSize) ||  | 
8129  | 0  |                     nStrSize > std::numeric_limits<size_t>::max() - 1)  | 
8130  | 0  |                 { | 
8131  | 0  |                     return false;  | 
8132  | 0  |                 }  | 
8133  | 0  |                 if (nStrSize > static_cast<size_t>(pabyEnd - pabyBuffer))  | 
8134  | 0  |                     return false;  | 
8135  | 0  |                 auto ptr =  | 
8136  | 0  |                     static_cast<char *>(VSI_MALLOC_VERBOSE(nStrSize + 1));  | 
8137  | 0  |                 if (!ptr)  | 
8138  | 0  |                     return false;  | 
8139  | 0  |                 uField.Set.nMarker2 = 0;  | 
8140  | 0  |                 uField.Set.nMarker3 = 0;  | 
8141  | 0  |                 uField.String = ptr;  | 
8142  | 0  |                 memcpy(uField.String, pabyBuffer, nStrSize);  | 
8143  | 0  |                 uField.String[nStrSize] = 0;  | 
8144  | 0  |                 pabyBuffer += nStrSize;  | 
8145  | 0  |                 break;  | 
8146  | 0  |             }  | 
8147  | 0  |             case OFTIntegerList:  | 
8148  | 0  |             { | 
8149  | 0  |                 int nCount = 0;  | 
8150  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, nCount) || nCount < 0 ||  | 
8151  | 0  |                     nCount > pabyEnd - pabyBuffer)  | 
8152  | 0  |                 { | 
8153  | 0  |                     return false;  | 
8154  | 0  |                 }  | 
8155  | 0  |                 auto ptr = static_cast<int *>(  | 
8156  | 0  |                     VSI_MALLOC2_VERBOSE(nCount, sizeof(int)));  | 
8157  | 0  |                 if (!ptr)  | 
8158  | 0  |                     return false;  | 
8159  | 0  |                 uField.Set.nMarker2 = 0;  | 
8160  | 0  |                 uField.Set.nMarker3 = 0;  | 
8161  | 0  |                 uField.IntegerList.paList = ptr;  | 
8162  | 0  |                 uField.IntegerList.nCount = nCount;  | 
8163  | 0  |                 for (int j = 0; j < nCount; ++j)  | 
8164  | 0  |                 { | 
8165  | 0  |                     if (!ReadVarInt(pabyBuffer, pabyEnd,  | 
8166  | 0  |                                     uField.IntegerList.paList[j]))  | 
8167  | 0  |                         return false;  | 
8168  | 0  |                 }  | 
8169  | 0  |                 break;  | 
8170  | 0  |             }  | 
8171  | 0  |             case OFTInteger64List:  | 
8172  | 0  |             { | 
8173  | 0  |                 int nCount = 0;  | 
8174  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, nCount) || nCount < 0 ||  | 
8175  | 0  |                     nCount > pabyEnd - pabyBuffer)  | 
8176  | 0  |                 { | 
8177  | 0  |                     return false;  | 
8178  | 0  |                 }  | 
8179  | 0  |                 auto ptr = static_cast<GIntBig *>(  | 
8180  | 0  |                     VSI_MALLOC2_VERBOSE(nCount, sizeof(GIntBig)));  | 
8181  | 0  |                 if (!ptr)  | 
8182  | 0  |                     return false;  | 
8183  | 0  |                 uField.Set.nMarker2 = 0;  | 
8184  | 0  |                 uField.Set.nMarker3 = 0;  | 
8185  | 0  |                 uField.Integer64List.paList = ptr;  | 
8186  | 0  |                 uField.Integer64List.nCount = nCount;  | 
8187  | 0  |                 for (int j = 0; j < nCount; ++j)  | 
8188  | 0  |                 { | 
8189  | 0  |                     if (!ReadVarInt(pabyBuffer, pabyEnd,  | 
8190  | 0  |                                     uField.Integer64List.paList[j]))  | 
8191  | 0  |                         return false;  | 
8192  | 0  |                 }  | 
8193  | 0  |                 break;  | 
8194  | 0  |             }  | 
8195  | 0  |             case OFTRealList:  | 
8196  | 0  |             { | 
8197  | 0  |                 int nCount = 0;  | 
8198  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, nCount) || nCount < 0 ||  | 
8199  | 0  |                     nCount > pabyEnd - pabyBuffer)  | 
8200  | 0  |                 { | 
8201  | 0  |                     return false;  | 
8202  | 0  |                 }  | 
8203  | 0  |                 auto ptr = static_cast<double *>(  | 
8204  | 0  |                     VSI_MALLOC2_VERBOSE(nCount, sizeof(double)));  | 
8205  | 0  |                 if (!ptr)  | 
8206  | 0  |                     return false;  | 
8207  | 0  |                 uField.Set.nMarker2 = 0;  | 
8208  | 0  |                 uField.Set.nMarker3 = 0;  | 
8209  | 0  |                 uField.RealList.paList = ptr;  | 
8210  | 0  |                 uField.RealList.nCount = nCount;  | 
8211  | 0  |                 for (int j = 0; j < nCount; ++j)  | 
8212  | 0  |                 { | 
8213  | 0  |                     if (!ReadFloat64(pabyBuffer, pabyEnd,  | 
8214  | 0  |                                      uField.RealList.paList[j]))  | 
8215  | 0  |                         return false;  | 
8216  | 0  |                 }  | 
8217  | 0  |                 break;  | 
8218  | 0  |             }  | 
8219  | 0  |             case OFTStringList:  | 
8220  | 0  |             { | 
8221  | 0  |                 int nCount = 0;  | 
8222  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, nCount) || nCount < 0 ||  | 
8223  | 0  |                     nCount > std::numeric_limits<int>::max() - 1 ||  | 
8224  | 0  |                     nCount > pabyEnd - pabyBuffer)  | 
8225  | 0  |                 { | 
8226  | 0  |                     return false;  | 
8227  | 0  |                 }  | 
8228  | 0  |                 auto ptr = static_cast<char **>(  | 
8229  | 0  |                     VSI_CALLOC_VERBOSE(nCount + 1, sizeof(char *)));  | 
8230  | 0  |                 if (!ptr)  | 
8231  | 0  |                     return false;  | 
8232  | 0  |                 uField.Set.nMarker2 = 0;  | 
8233  | 0  |                 uField.Set.nMarker3 = 0;  | 
8234  | 0  |                 uField.StringList.paList = ptr;  | 
8235  | 0  |                 uField.StringList.nCount = nCount;  | 
8236  | 0  |                 for (int j = 0; j < nCount; ++j)  | 
8237  | 0  |                 { | 
8238  | 0  |                     size_t nStrSize = 0;  | 
8239  | 0  |                     if (!ReadVarUInt(pabyBuffer, pabyEnd, nStrSize) ||  | 
8240  | 0  |                         nStrSize > std::numeric_limits<size_t>::max() - 1)  | 
8241  | 0  |                     { | 
8242  | 0  |                         return false;  | 
8243  | 0  |                     }  | 
8244  | 0  |                     if (nStrSize > static_cast<size_t>(pabyEnd - pabyBuffer))  | 
8245  | 0  |                         return false;  | 
8246  | 0  |                     uField.StringList.paList[j] =  | 
8247  | 0  |                         static_cast<char *>(VSI_MALLOC_VERBOSE(nStrSize + 1));  | 
8248  | 0  |                     if (!uField.StringList.paList[j])  | 
8249  | 0  |                         return false;  | 
8250  | 0  |                     memcpy(uField.StringList.paList[j], pabyBuffer, nStrSize);  | 
8251  | 0  |                     uField.StringList.paList[j][nStrSize] = 0;  | 
8252  | 0  |                     pabyBuffer += nStrSize;  | 
8253  | 0  |                 }  | 
8254  | 0  |                 break;  | 
8255  | 0  |             }  | 
8256  | 0  |             case OFTBinary:  | 
8257  | 0  |             { | 
8258  | 0  |                 int nBinSize = 0;  | 
8259  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, nBinSize) || nBinSize < 0)  | 
8260  | 0  |                 { | 
8261  | 0  |                     return false;  | 
8262  | 0  |                 }  | 
8263  | 0  |                 if (nBinSize > pabyEnd - pabyBuffer)  | 
8264  | 0  |                     return false;  | 
8265  | 0  |                 auto ptr = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nBinSize));  | 
8266  | 0  |                 if (!ptr)  | 
8267  | 0  |                     return false;  | 
8268  | 0  |                 uField.Set.nMarker2 = 0;  | 
8269  | 0  |                 uField.Set.nMarker3 = 0;  | 
8270  | 0  |                 uField.Binary.paData = ptr;  | 
8271  | 0  |                 uField.Binary.nCount = nBinSize;  | 
8272  | 0  |                 memcpy(uField.Binary.paData, pabyBuffer, nBinSize);  | 
8273  | 0  |                 pabyBuffer += nBinSize;  | 
8274  | 0  |                 break;  | 
8275  | 0  |             }  | 
8276  | 0  |             case OFTWideString:  | 
8277  | 0  |             case OFTWideStringList:  | 
8278  | 0  |                 break;  | 
8279  | 0  |             case OFTDate:  | 
8280  | 0  |             { | 
8281  | 0  |                 memset(&uField, 0, sizeof(uField));  | 
8282  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, uField.Date.Year) ||  | 
8283  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Month) ||  | 
8284  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Day))  | 
8285  | 0  |                 { | 
8286  | 0  |                     return false;  | 
8287  | 0  |                 }  | 
8288  | 0  |                 break;  | 
8289  | 0  |             }  | 
8290  | 0  |             case OFTTime:  | 
8291  | 0  |             { | 
8292  | 0  |                 memset(&uField, 0, sizeof(uField));  | 
8293  | 0  |                 if (!ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Hour) ||  | 
8294  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Minute) ||  | 
8295  | 0  |                     !ReadFloat32(pabyBuffer, pabyEnd, uField.Date.Second) ||  | 
8296  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.TZFlag))  | 
8297  | 0  |                 { | 
8298  | 0  |                     return false;  | 
8299  | 0  |                 }  | 
8300  | 0  |                 break;  | 
8301  | 0  |             }  | 
8302  | 0  |             case OFTDateTime:  | 
8303  | 0  |             { | 
8304  | 0  |                 memset(&uField, 0, sizeof(uField));  | 
8305  | 0  |                 if (!ReadVarInt(pabyBuffer, pabyEnd, uField.Date.Year) ||  | 
8306  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Month) ||  | 
8307  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Day) ||  | 
8308  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Hour) ||  | 
8309  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.Minute) ||  | 
8310  | 0  |                     !ReadFloat32(pabyBuffer, pabyEnd, uField.Date.Second) ||  | 
8311  | 0  |                     !ReadUInt8(pabyBuffer, pabyEnd, uField.Date.TZFlag))  | 
8312  | 0  |                 { | 
8313  | 0  |                     return false;  | 
8314  | 0  |                 }  | 
8315  | 0  |                 break;  | 
8316  | 0  |             }  | 
8317  | 0  |         }  | 
8318  | 0  |     }  | 
8319  | 0  |     for (int i = 0; i < nGeomFieldCount; ++i)  | 
8320  | 0  |     { | 
8321  | 0  |         const int iBit = 2 * nFieldCount + i;  | 
8322  | 0  |         if (IsFlagBitSet(iBit))  | 
8323  | 0  |         { | 
8324  | 0  |             continue;  | 
8325  | 0  |         }  | 
8326  | 0  |         size_t nWkbSize = 0;  | 
8327  | 0  |         if (!ReadVarUInt(pabyBuffer, pabyEnd, nWkbSize))  | 
8328  | 0  |         { | 
8329  | 0  |             return false;  | 
8330  | 0  |         }  | 
8331  | 0  |         if (nWkbSize > static_cast<size_t>(pabyEnd - pabyBuffer))  | 
8332  | 0  |         { | 
8333  | 0  |             return false;  | 
8334  | 0  |         }  | 
8335  | 0  |         OGRGeometry *poGeom = nullptr;  | 
8336  | 0  |         if (OGRGeometryFactory::createFromWkb(  | 
8337  | 0  |                 pabyBuffer, poDefn->GetGeomFieldDefn(i)->GetSpatialRef(),  | 
8338  | 0  |                 &poGeom, nWkbSize, wkbVariantIso) != OGRERR_NONE ||  | 
8339  | 0  |             !poGeom)  | 
8340  | 0  |         { | 
8341  | 0  |             delete poGeom;  | 
8342  | 0  |             return false;  | 
8343  | 0  |         }  | 
8344  | 0  |         pabyBuffer += nWkbSize;  | 
8345  | 0  |         papoGeometries[i] = poGeom;  | 
8346  | 0  |     }  | 
8347  | 0  |     return true;  | 
8348  | 0  | }  | 
8349  |  |  | 
8350  |  | /************************************************************************/  | 
8351  |  | /*                    OGRFeature::ConstFieldIterator                    */  | 
8352  |  | /************************************************************************/  | 
8353  |  |  | 
8354  |  | struct OGRFeature::FieldValue::Private  | 
8355  |  | { | 
8356  |  |     CPL_DISALLOW_COPY_ASSIGN(Private)  | 
8357  |  |  | 
8358  |  |     OGRFeature *m_poSelf = nullptr;  | 
8359  |  |     int m_nPos = 0;  | 
8360  |  |     mutable std::vector<int> m_anList{}; | 
8361  |  |     mutable std::vector<GIntBig> m_anList64{}; | 
8362  |  |     mutable std::vector<double> m_adfList{}; | 
8363  |  |     mutable std::vector<std::string> m_aosList{}; | 
8364  |  |  | 
8365  |  |     Private(const OGRFeature *poSelf, int iFieldIndex)  | 
8366  | 0  |         : m_poSelf(const_cast<OGRFeature *>(poSelf)), m_nPos(iFieldIndex)  | 
8367  | 0  |     { | 
8368  | 0  |     }  | 
8369  |  |  | 
8370  |  |     Private(OGRFeature *poSelf, int iFieldIndex)  | 
8371  | 0  |         : m_poSelf(poSelf), m_nPos(iFieldIndex)  | 
8372  | 0  |     { | 
8373  | 0  |     }  | 
8374  |  | };  | 
8375  |  |  | 
8376  |  | struct OGRFeature::ConstFieldIterator::Private  | 
8377  |  | { | 
8378  |  |     CPL_DISALLOW_COPY_ASSIGN(Private)  | 
8379  |  |  | 
8380  |  |     OGRFeature::FieldValue m_oValue;  | 
8381  |  |     int m_nPos = 0;  | 
8382  |  |  | 
8383  |  |     Private(const OGRFeature *poSelf, int iFieldIndex)  | 
8384  | 0  |         : m_oValue(poSelf, iFieldIndex)  | 
8385  | 0  |     { | 
8386  | 0  |     }  | 
8387  |  | };  | 
8388  |  |  | 
8389  |  | //! @cond Doxygen_Suppress  | 
8390  |  | OGRFeature::ConstFieldIterator::ConstFieldIterator(const OGRFeature *poSelf,  | 
8391  |  |                                                    int nPos)  | 
8392  | 0  |     : m_poPrivate(new Private(poSelf, nPos))  | 
8393  | 0  | { | 
8394  | 0  |     m_poPrivate->m_nPos = nPos;  | 
8395  | 0  | }  | 
8396  |  |  | 
8397  | 0  | OGRFeature::ConstFieldIterator::~ConstFieldIterator() = default;  | 
8398  |  |  | 
8399  |  | const OGRFeature::FieldValue &OGRFeature::ConstFieldIterator::operator*() const  | 
8400  | 0  | { | 
8401  | 0  |     return m_poPrivate->m_oValue;  | 
8402  | 0  | }  | 
8403  |  |  | 
8404  |  | OGRFeature::ConstFieldIterator &OGRFeature::ConstFieldIterator::operator++()  | 
8405  | 0  | { | 
8406  | 0  |     ++m_poPrivate->m_nPos;  | 
8407  | 0  |     m_poPrivate->m_oValue.m_poPrivate->m_nPos = m_poPrivate->m_nPos;  | 
8408  | 0  |     return *this;  | 
8409  | 0  | }  | 
8410  |  |  | 
8411  |  | bool OGRFeature::ConstFieldIterator::operator!=(  | 
8412  |  |     const ConstFieldIterator &it) const  | 
8413  | 0  | { | 
8414  | 0  |     return m_poPrivate->m_nPos != it.m_poPrivate->m_nPos;  | 
8415  | 0  | }  | 
8416  |  |  | 
8417  |  | //! @endcond  | 
8418  |  |  | 
8419  |  | OGRFeature::ConstFieldIterator OGRFeature::begin() const  | 
8420  | 0  | { | 
8421  | 0  |     return {this, 0}; | 
8422  | 0  | }  | 
8423  |  |  | 
8424  |  | OGRFeature::ConstFieldIterator OGRFeature::end() const  | 
8425  | 0  | { | 
8426  | 0  |     return {this, GetFieldCount()}; | 
8427  | 0  | }  | 
8428  |  |  | 
8429  |  | /************************************************************************/  | 
8430  |  | /*                      OGRFeature::FieldValue                          */  | 
8431  |  | /************************************************************************/  | 
8432  |  |  | 
8433  |  | OGRFeature::FieldValue::FieldValue(const OGRFeature *poFeature, int iFieldIndex)  | 
8434  | 0  |     : m_poPrivate(new Private(poFeature, iFieldIndex))  | 
8435  | 0  | { | 
8436  | 0  | }  | 
8437  |  |  | 
8438  |  | OGRFeature::FieldValue::FieldValue(OGRFeature *poFeature, int iFieldIndex)  | 
8439  | 0  |     : m_poPrivate(new Private(poFeature, iFieldIndex))  | 
8440  | 0  | { | 
8441  | 0  | }  | 
8442  |  |  | 
8443  |  | OGRFeature::FieldValue &OGRFeature::FieldValue::Assign(const FieldValue &oOther)  | 
8444  | 0  | { | 
8445  | 0  |     if (&oOther != this &&  | 
8446  | 0  |         !(m_poPrivate->m_poSelf == oOther.m_poPrivate->m_poSelf &&  | 
8447  | 0  |           m_poPrivate->m_nPos == oOther.m_poPrivate->m_nPos))  | 
8448  | 0  |     { | 
8449  | 0  |         OGRFieldType eOtherType(oOther.GetType());  | 
8450  | 0  |         if (oOther.IsNull())  | 
8451  | 0  |             SetNull();  | 
8452  | 0  |         else if (oOther.IsUnset())  | 
8453  | 0  |             Unset();  | 
8454  | 0  |         else if (eOtherType == OFTInteger)  | 
8455  | 0  |             m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos,  | 
8456  | 0  |                                             oOther.GetInteger());  | 
8457  | 0  |         else if (eOtherType == OFTInteger64)  | 
8458  | 0  |             m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos,  | 
8459  | 0  |                                             oOther.GetInteger64());  | 
8460  | 0  |         else if (eOtherType == OFTReal)  | 
8461  | 0  |             m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos,  | 
8462  | 0  |                                             oOther.GetDouble());  | 
8463  | 0  |         else if (eOtherType == OFTString)  | 
8464  | 0  |             m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos,  | 
8465  | 0  |                                             oOther.GetString());  | 
8466  | 0  |         else if (eOtherType == OFTDate || eOtherType == OFTDateTime ||  | 
8467  | 0  |                  eOtherType == OFTTime)  | 
8468  | 0  |         { | 
8469  | 0  |             int nYear = 0;  | 
8470  | 0  |             int nMonth = 0;  | 
8471  | 0  |             int nDay = 0;  | 
8472  | 0  |             int nHour = 0;  | 
8473  | 0  |             int nMinute = 0;  | 
8474  | 0  |             float fSecond = 0.0f;  | 
8475  | 0  |             int nTZFlag = 0;  | 
8476  | 0  |             oOther.GetDateTime(&nYear, &nMonth, &nDay, &nHour, &nMinute,  | 
8477  | 0  |                                &fSecond, &nTZFlag);  | 
8478  | 0  |             m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, nYear, nMonth,  | 
8479  | 0  |                                             nDay, nHour, nMinute, fSecond,  | 
8480  | 0  |                                             nTZFlag);  | 
8481  | 0  |         }  | 
8482  | 0  |         else if (eOtherType == OFTStringList)  | 
8483  | 0  |         { | 
8484  | 0  |             m_poPrivate->m_poSelf->SetField(  | 
8485  | 0  |                 m_poPrivate->m_nPos,  | 
8486  | 0  |                 oOther.m_poPrivate->m_poSelf->GetFieldAsStringList(  | 
8487  | 0  |                     oOther.m_poPrivate->m_nPos));  | 
8488  | 0  |         }  | 
8489  | 0  |         else if (eOtherType == OFTIntegerList)  | 
8490  | 0  |         { | 
8491  | 0  |             operator=(oOther.GetAsIntegerList());  | 
8492  | 0  |         }  | 
8493  | 0  |         else if (eOtherType == OFTInteger64List)  | 
8494  | 0  |         { | 
8495  | 0  |             operator=(oOther.GetAsInteger64List());  | 
8496  | 0  |         }  | 
8497  | 0  |         else if (eOtherType == OFTRealList)  | 
8498  | 0  |         { | 
8499  | 0  |             operator=(oOther.GetAsDoubleList());  | 
8500  | 0  |         }  | 
8501  | 0  |     }  | 
8502  | 0  |     return *this;  | 
8503  | 0  | }  | 
8504  |  |  | 
8505  |  | OGRFeature::FieldValue &  | 
8506  |  | OGRFeature::FieldValue::operator=(const FieldValue &oOther)  | 
8507  | 0  | { | 
8508  | 0  |     return Assign(oOther);  | 
8509  | 0  | }  | 
8510  |  |  | 
8511  |  | //! @cond Doxygen_Suppress  | 
8512  |  | OGRFeature::FieldValue &OGRFeature::FieldValue::operator=(FieldValue &&oOther)  | 
8513  | 0  | { | 
8514  | 0  |     return Assign(oOther);  | 
8515  | 0  | }  | 
8516  |  |  | 
8517  |  | //! @endcond  | 
8518  |  |  | 
8519  |  | OGRFeature::FieldValue &OGRFeature::FieldValue::operator=(int nVal)  | 
8520  | 0  | { | 
8521  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, nVal);  | 
8522  | 0  |     return *this;  | 
8523  | 0  | }  | 
8524  |  |  | 
8525  |  | OGRFeature::FieldValue &OGRFeature::FieldValue::operator=(GIntBig nVal)  | 
8526  | 0  | { | 
8527  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, nVal);  | 
8528  | 0  |     return *this;  | 
8529  | 0  | }  | 
8530  |  |  | 
8531  |  | OGRFeature::FieldValue &OGRFeature::FieldValue::operator=(double dfVal)  | 
8532  | 0  | { | 
8533  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, dfVal);  | 
8534  | 0  |     return *this;  | 
8535  | 0  | }  | 
8536  |  |  | 
8537  |  | OGRFeature::FieldValue &OGRFeature::FieldValue::operator=(const char *pszVal)  | 
8538  | 0  | { | 
8539  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, pszVal);  | 
8540  | 0  |     return *this;  | 
8541  | 0  | }  | 
8542  |  |  | 
8543  |  | OGRFeature::FieldValue &  | 
8544  |  | OGRFeature::FieldValue::operator=(const std::string &osVal)  | 
8545  | 0  | { | 
8546  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, osVal.c_str());  | 
8547  | 0  |     return *this;  | 
8548  | 0  | }  | 
8549  |  |  | 
8550  |  | OGRFeature::FieldValue &  | 
8551  |  | OGRFeature::FieldValue::operator=(const std::vector<int> &oArray)  | 
8552  | 0  | { | 
8553  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos,  | 
8554  | 0  |                                     static_cast<int>(oArray.size()),  | 
8555  | 0  |                                     oArray.empty() ? nullptr : oArray.data());  | 
8556  | 0  |     return *this;  | 
8557  | 0  | }  | 
8558  |  |  | 
8559  |  | OGRFeature::FieldValue &  | 
8560  |  | OGRFeature::FieldValue::operator=(const std::vector<GIntBig> &oArray)  | 
8561  | 0  | { | 
8562  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos,  | 
8563  | 0  |                                     static_cast<int>(oArray.size()),  | 
8564  | 0  |                                     oArray.empty() ? nullptr : oArray.data());  | 
8565  | 0  |     return *this;  | 
8566  | 0  | }  | 
8567  |  |  | 
8568  |  | OGRFeature::FieldValue &  | 
8569  |  | OGRFeature::FieldValue::operator=(const std::vector<double> &oArray)  | 
8570  | 0  | { | 
8571  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos,  | 
8572  | 0  |                                     static_cast<int>(oArray.size()),  | 
8573  | 0  |                                     oArray.empty() ? nullptr : oArray.data());  | 
8574  | 0  |     return *this;  | 
8575  | 0  | }  | 
8576  |  |  | 
8577  |  | OGRFeature::FieldValue &  | 
8578  |  | OGRFeature::FieldValue::operator=(const std::vector<std::string> &oArray)  | 
8579  | 0  | { | 
8580  | 0  |     CPLStringList aosList;  | 
8581  | 0  |     for (auto &&oStr : oArray)  | 
8582  | 0  |         aosList.AddString(oStr.c_str());  | 
8583  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, aosList.List());  | 
8584  | 0  |     return *this;  | 
8585  | 0  | }  | 
8586  |  |  | 
8587  |  | OGRFeature::FieldValue &  | 
8588  |  | OGRFeature::FieldValue::operator=(CSLConstList papszValues)  | 
8589  | 0  | { | 
8590  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, papszValues);  | 
8591  | 0  |     return *this;  | 
8592  | 0  | }  | 
8593  |  |  | 
8594  |  | void OGRFeature::FieldValue::SetDateTime(int nYear, int nMonth, int nDay,  | 
8595  |  |                                          int nHour, int nMinute, float fSecond,  | 
8596  |  |                                          int nTZFlag)  | 
8597  | 0  | { | 
8598  | 0  |     m_poPrivate->m_poSelf->SetField(m_poPrivate->m_nPos, nYear, nMonth, nDay,  | 
8599  | 0  |                                     nHour, nMinute, fSecond, nTZFlag);  | 
8600  | 0  | }  | 
8601  |  |  | 
8602  |  | void OGRFeature::FieldValue::SetNull()  | 
8603  | 0  | { | 
8604  | 0  |     m_poPrivate->m_poSelf->SetFieldNull(m_poPrivate->m_nPos);  | 
8605  | 0  | }  | 
8606  |  |  | 
8607  |  | void OGRFeature::FieldValue::clear()  | 
8608  | 0  | { | 
8609  | 0  |     m_poPrivate->m_poSelf->UnsetField(m_poPrivate->m_nPos);  | 
8610  | 0  | }  | 
8611  |  |  | 
8612  |  | //! @cond Doxygen_Suppress  | 
8613  | 0  | OGRFeature::FieldValue::~FieldValue() = default;  | 
8614  |  |  | 
8615  |  | //! @endcond  | 
8616  |  |  | 
8617  |  | int OGRFeature::FieldValue::GetIndex() const  | 
8618  | 0  | { | 
8619  | 0  |     return m_poPrivate->m_nPos;  | 
8620  | 0  | }  | 
8621  |  |  | 
8622  |  | const OGRFieldDefn *OGRFeature::FieldValue::GetDefn() const  | 
8623  | 0  | { | 
8624  | 0  |     return m_poPrivate->m_poSelf->GetFieldDefnRef(GetIndex());  | 
8625  | 0  | }  | 
8626  |  |  | 
8627  |  | const OGRField *OGRFeature::FieldValue::GetRawValue() const  | 
8628  | 0  | { | 
8629  | 0  |     return &(m_poPrivate->m_poSelf->pauFields[GetIndex()]);  | 
8630  | 0  | }  | 
8631  |  |  | 
8632  |  | bool OGRFeature::FieldValue::IsUnset() const  | 
8633  | 0  | { | 
8634  | 0  |     return CPL_TO_BOOL(OGR_RawField_IsUnset(GetRawValue()));  | 
8635  | 0  | }  | 
8636  |  |  | 
8637  |  | bool OGRFeature::FieldValue::IsNull() const  | 
8638  | 0  | { | 
8639  | 0  |     return CPL_TO_BOOL(OGR_RawField_IsNull(GetRawValue()));  | 
8640  | 0  | }  | 
8641  |  |  | 
8642  |  | int OGRFeature::FieldValue::GetAsInteger() const  | 
8643  | 0  | { | 
8644  | 0  |     return const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8645  | 0  |         ->GetFieldAsInteger(GetIndex());  | 
8646  | 0  | }  | 
8647  |  |  | 
8648  |  | GIntBig OGRFeature::FieldValue::GetAsInteger64() const  | 
8649  | 0  | { | 
8650  | 0  |     return const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8651  | 0  |         ->GetFieldAsInteger64(GetIndex());  | 
8652  | 0  | }  | 
8653  |  |  | 
8654  |  | double OGRFeature::FieldValue::GetAsDouble() const  | 
8655  | 0  | { | 
8656  | 0  |     return const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8657  | 0  |         ->GetFieldAsDouble(GetIndex());  | 
8658  | 0  | }  | 
8659  |  |  | 
8660  |  | const char *OGRFeature::FieldValue::GetAsString() const  | 
8661  | 0  | { | 
8662  | 0  |     return const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8663  | 0  |         ->GetFieldAsString(GetIndex());  | 
8664  | 0  | }  | 
8665  |  |  | 
8666  |  | bool OGRFeature::FieldValue::GetDateTime(int *pnYear, int *pnMonth, int *pnDay,  | 
8667  |  |                                          int *pnHour, int *pnMinute,  | 
8668  |  |                                          float *pfSecond, int *pnTZFlag) const  | 
8669  | 0  | { | 
8670  | 0  |     return CPL_TO_BOOL(const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8671  | 0  |                            ->GetFieldAsDateTime(GetIndex(), pnYear, pnMonth,  | 
8672  | 0  |                                                 pnDay, pnHour, pnMinute,  | 
8673  | 0  |                                                 pfSecond, pnTZFlag));  | 
8674  | 0  | }  | 
8675  |  |  | 
8676  |  | const std::vector<int> &OGRFeature::FieldValue::GetAsIntegerList() const  | 
8677  | 0  | { | 
8678  | 0  |     int nCount = 0;  | 
8679  | 0  |     auto &&panList = const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8680  | 0  |                          ->GetFieldAsIntegerList(GetIndex(), &nCount);  | 
8681  | 0  |     m_poPrivate->m_anList.assign(panList, panList + nCount);  | 
8682  | 0  |     return m_poPrivate->m_anList;  | 
8683  | 0  | }  | 
8684  |  |  | 
8685  |  | const std::vector<GIntBig> &OGRFeature::FieldValue::GetAsInteger64List() const  | 
8686  | 0  | { | 
8687  | 0  |     int nCount = 0;  | 
8688  | 0  |     auto &&panList = const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8689  | 0  |                          ->GetFieldAsInteger64List(GetIndex(), &nCount);  | 
8690  | 0  |     m_poPrivate->m_anList64.assign(panList, panList + nCount);  | 
8691  | 0  |     return m_poPrivate->m_anList64;  | 
8692  | 0  | }  | 
8693  |  |  | 
8694  |  | const std::vector<double> &OGRFeature::FieldValue::GetAsDoubleList() const  | 
8695  | 0  | { | 
8696  | 0  |     int nCount = 0;  | 
8697  | 0  |     auto &&panList = const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8698  | 0  |                          ->GetFieldAsDoubleList(GetIndex(), &nCount);  | 
8699  | 0  |     m_poPrivate->m_adfList.assign(panList, panList + nCount);  | 
8700  | 0  |     return m_poPrivate->m_adfList;  | 
8701  | 0  | }  | 
8702  |  |  | 
8703  |  | const std::vector<std::string> &OGRFeature::FieldValue::GetAsStringList() const  | 
8704  | 0  | { | 
8705  | 0  |     auto &&papszList = const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8706  | 0  |                            ->GetFieldAsStringList(GetIndex());  | 
8707  | 0  |     m_poPrivate->m_aosList.clear();  | 
8708  | 0  |     if (papszList)  | 
8709  | 0  |     { | 
8710  | 0  |         for (char **papszIter = papszList; *papszIter; ++papszIter)  | 
8711  | 0  |         { | 
8712  | 0  |             m_poPrivate->m_aosList.emplace_back(*papszIter);  | 
8713  | 0  |         }  | 
8714  | 0  |     }  | 
8715  | 0  |     return m_poPrivate->m_aosList;  | 
8716  | 0  | }  | 
8717  |  |  | 
8718  |  | OGRFeature::FieldValue::operator CSLConstList() const  | 
8719  | 0  | { | 
8720  | 0  |     return const_cast<CSLConstList>(  | 
8721  | 0  |         const_cast<OGRFeature *>(m_poPrivate->m_poSelf)  | 
8722  | 0  |             ->GetFieldAsStringList(GetIndex()));  | 
8723  | 0  | }  | 
8724  |  |  | 
8725  |  | OGRRangeFieldDomain *OGRRangeFieldDomain::Clone() const  | 
8726  | 0  | { | 
8727  | 0  |     auto poDomain = new OGRRangeFieldDomain(  | 
8728  | 0  |         m_osName, m_osDescription, m_eFieldType, m_eFieldSubType, m_sMin,  | 
8729  | 0  |         m_bMinIsInclusive, m_sMax, m_bMaxIsInclusive);  | 
8730  | 0  |     poDomain->SetMergePolicy(m_eMergePolicy);  | 
8731  | 0  |     poDomain->SetSplitPolicy(m_eSplitPolicy);  | 
8732  | 0  |     return poDomain;  | 
8733  | 0  | }  | 
8734  |  |  | 
8735  |  | OGRGlobFieldDomain *OGRGlobFieldDomain::Clone() const  | 
8736  | 0  | { | 
8737  | 0  |     auto poDomain = new OGRGlobFieldDomain(  | 
8738  | 0  |         m_osName, m_osDescription, m_eFieldType, m_eFieldSubType, m_osGlob);  | 
8739  | 0  |     poDomain->SetMergePolicy(m_eMergePolicy);  | 
8740  | 0  |     poDomain->SetSplitPolicy(m_eSplitPolicy);  | 
8741  | 0  |     return poDomain;  | 
8742  | 0  | }  | 
8743  |  | #if defined(__GNUC__)  | 
8744  |  | #pragma GCC diagnostic pop  | 
8745  |  | #endif  |