Coverage Report

Created: 2025-08-11 09:23

/src/gdal/ogr/ogrsf_frmts/csv/ogr_csv.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  CSV Translator
4
 * Purpose:  Definition of classes for OGR .csv driver.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2004,  Frank Warmerdam
9
 * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#ifndef OGR_CSV_H_INCLUDED
15
#define OGR_CSV_H_INCLUDED
16
17
#include "ogrsf_frmts.h"
18
19
#include <set>
20
21
typedef enum
22
{
23
    OGR_CSV_GEOM_NONE,
24
    OGR_CSV_GEOM_AS_WKT,
25
    OGR_CSV_GEOM_AS_SOME_GEOM_FORMAT,
26
    OGR_CSV_GEOM_AS_XYZ,
27
    OGR_CSV_GEOM_AS_XY,
28
    OGR_CSV_GEOM_AS_YX,
29
} OGRCSVGeometryFormat;
30
31
class OGRCSVDataSource;
32
33
typedef enum
34
{
35
    CREATE_FIELD_DO_NOTHING,
36
    CREATE_FIELD_PROCEED,
37
    CREATE_FIELD_ERROR
38
} OGRCSVCreateFieldAction;
39
40
void OGRCSVDriverRemoveFromMap(const char *pszName, GDALDataset *poDS);
41
42
// Must be kept as a macro with the value fully resolved, as it is used
43
// by STRINGIFY(x) to generate open option description.
44
85.3k
#define OGR_CSV_DEFAULT_MAX_LINE_SIZE 10000000
45
46
/************************************************************************/
47
/*                             OGRCSVLayer                              */
48
/************************************************************************/
49
50
class IOGRCSVLayer CPL_NON_FINAL
51
{
52
  public:
53
86.6k
    IOGRCSVLayer() = default;
54
    virtual ~IOGRCSVLayer();
55
56
    virtual OGRLayer *GetLayer() = 0;
57
58
    virtual std::vector<std::string> GetFileList() = 0;
59
};
60
61
class OGRCSVLayer final : public IOGRCSVLayer, public OGRLayer
62
{
63
  public:
64
    enum class StringQuoting
65
    {
66
        IF_NEEDED,
67
        IF_AMBIGUOUS,
68
        ALWAYS
69
    };
70
71
  private:
72
    GDALDataset *m_poDS = nullptr;
73
    OGRFeatureDefn *poFeatureDefn = nullptr;
74
    std::set<CPLString> m_oSetFields{};
75
76
    VSILFILE *fpCSV = nullptr;
77
    const int m_nMaxLineSize = -1;
78
79
    static constexpr int64_t FID_INITIAL_VALUE = 1;
80
    int64_t m_nNextFID = FID_INITIAL_VALUE;
81
82
    bool bHasFieldNames = false;
83
84
    OGRFeature *GetNextUnfilteredFeature();
85
86
    bool bNew = false;
87
    bool bInWriteMode = false;
88
    bool bUseCRLF = false;
89
    bool bNeedRewindBeforeRead = false;
90
    OGRCSVGeometryFormat eGeometryFormat = OGR_CSV_GEOM_NONE;
91
92
    char *pszFilename = nullptr;
93
    std::string m_osCSVTFilename{};
94
    bool bCreateCSVT = false;
95
    bool bWriteBOM = false;
96
    char szDelimiter[2] = {0};
97
98
    int nCSVFieldCount = 0;
99
    int *panGeomFieldIndex = nullptr;
100
    bool bFirstFeatureAppendedDuringSession = true;
101
    bool bHiddenWKTColumn = false;
102
103
    // http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm
104
    // specific
105
    int iNfdcLongitudeS = -1;
106
    int iNfdcLatitudeS = 1;
107
    bool bHonourStrings = true;
108
109
    // https://www.usgs.gov/u.s.-board-on-geographic-names/download-gnis-data
110
    bool m_bIsGNIS = false;
111
    int iLongitudeField = -1;
112
    int iLatitudeField = -1;
113
    int iZField = -1;
114
    CPLString osXField{};
115
    CPLString osYField{};
116
    CPLString osZField{};
117
118
    bool bIsEurostatTSV = false;
119
    int nEurostatDims = 0;
120
121
    GIntBig nTotalFeatures = 0;
122
123
    char **AutodetectFieldTypes(CSLConstList papszOpenOptions, int nFieldCount);
124
125
    bool bWarningBadTypeOrWidth = false;
126
    bool bKeepSourceColumns = false;
127
    bool bKeepGeomColumns = true;
128
129
    bool bMergeDelimiter = false;
130
131
    bool bEmptyStringNull = false;
132
133
    bool m_bWriteHeader = true;
134
135
    StringQuoting m_eStringQuoting = StringQuoting::IF_AMBIGUOUS;
136
137
    char **GetNextLineTokens();
138
139
    static bool Matches(const char *pszFieldName, char **papszPossibleNames);
140
141
    CPL_DISALLOW_COPY_ASSIGN(OGRCSVLayer)
142
143
  public:
144
    OGRCSVLayer(GDALDataset *poDS, const char *pszName, VSILFILE *fp,
145
                int nMaxLineSize, const char *pszFilename, int bNew,
146
                int bInWriteMode, char chDelimiter);
147
    virtual ~OGRCSVLayer() override;
148
149
    OGRLayer *GetLayer() override
150
118k
    {
151
118k
        return this;
152
118k
    }
153
154
    const char *GetFilename() const
155
44
    {
156
44
        return pszFilename;
157
44
    }
158
159
    std::vector<std::string> GetFileList() override;
160
161
    char GetDelimiter() const
162
44
    {
163
44
        return szDelimiter[0];
164
44
    }
165
166
    bool GetCRLF() const
167
44
    {
168
44
        return bUseCRLF;
169
44
    }
170
171
    bool GetCreateCSVT() const
172
44
    {
173
44
        return bCreateCSVT;
174
44
    }
175
176
    bool GetWriteBOM() const
177
44
    {
178
44
        return bWriteBOM;
179
44
    }
180
181
    OGRCSVGeometryFormat GetGeometryFormat() const
182
44
    {
183
44
        return eGeometryFormat;
184
44
    }
185
186
    bool HasHiddenWKTColumn() const
187
44
    {
188
44
        return bHiddenWKTColumn;
189
44
    }
190
191
    GIntBig GetTotalFeatureCount() const
192
0
    {
193
0
        return nTotalFeatures;
194
0
    }
195
196
    const CPLString &GetXField() const
197
44
    {
198
44
        return osXField;
199
44
    }
200
201
    const CPLString &GetYField() const
202
0
    {
203
0
        return osYField;
204
0
    }
205
206
    const CPLString &GetZField() const
207
44
    {
208
44
        return osZField;
209
44
    }
210
211
    void BuildFeatureDefn(const char *pszNfdcGeomField = nullptr,
212
                          const char *pszGeonamesGeomFieldPrefix = nullptr,
213
                          CSLConstList papszOpenOptions = nullptr);
214
215
    void ResetReading() override;
216
    OGRFeature *GetNextFeature() override;
217
    virtual OGRFeature *GetFeature(GIntBig nFID) override;
218
219
    OGRFeatureDefn *GetLayerDefn() override
220
1.26M
    {
221
1.26M
        return poFeatureDefn;
222
1.26M
    }
223
224
    int TestCapability(const char *) override;
225
226
    virtual OGRErr CreateField(const OGRFieldDefn *poField,
227
                               int bApproxOK = TRUE) override;
228
229
    static OGRCSVCreateFieldAction
230
    PreCreateField(OGRFeatureDefn *poFeatureDefn,
231
                   const std::set<CPLString> &oSetFields,
232
                   const OGRFieldDefn *poNewField, int bApproxOK);
233
    virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
234
                                   int bApproxOK = TRUE) override;
235
236
    virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
237
238
    void SetCRLF(bool bNewValue);
239
    void SetWriteGeometry(OGRwkbGeometryType eGType,
240
                          OGRCSVGeometryFormat eGeometryFormat,
241
                          const char *pszGeomCol = nullptr);
242
    void SetCreateCSVT(bool bCreateCSVT);
243
    void SetWriteBOM(bool bWriteBOM);
244
245
    void SetWriteHeader(bool b)
246
584
    {
247
584
        m_bWriteHeader = b;
248
584
    }
249
250
    void SetStringQuoting(StringQuoting eVal)
251
628
    {
252
628
        m_eStringQuoting = eVal;
253
628
    }
254
255
    StringQuoting GetStringQuoting() const
256
44
    {
257
44
        return m_eStringQuoting;
258
44
    }
259
260
    virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
261
    virtual OGRErr SyncToDisk() override;
262
263
    GDALDataset *GetDataset() override
264
44
    {
265
44
        return m_poDS;
266
44
    }
267
268
    OGRErr WriteHeader();
269
};
270
271
/************************************************************************/
272
/*                           OGRCSVDataSource                           */
273
/************************************************************************/
274
275
class OGRCSVDataSource final : public GDALDataset
276
{
277
    char *pszName = nullptr;
278
279
    std::vector<std::unique_ptr<IOGRCSVLayer>> m_apoLayers{};
280
281
    bool bUpdate = false;
282
283
    CPLString osDefaultCSVName{};
284
285
    bool bEnableGeometryFields = false;
286
287
    bool DealWithOgrSchemaOpenOption(CSLConstList papszOpenOptions);
288
289
    /* When OGR_SCHEMA and schemaType=Full, this will contain the list
290
     * of removed field (if any).
291
     */
292
    std::vector<int> m_oDeletedFieldIndexes{};
293
294
    CPL_DISALLOW_COPY_ASSIGN(OGRCSVDataSource)
295
296
  public:
297
    OGRCSVDataSource();
298
    virtual ~OGRCSVDataSource() override;
299
300
    bool Open(const char *pszFilename, bool bUpdate, bool bForceOpen,
301
              CSLConstList papszOpenOptions, bool bSingleDriver);
302
    bool OpenTable(const char *pszFilename, CSLConstList papszOpenOptions,
303
                   const char *pszNfdcRunwaysGeomField = nullptr,
304
                   const char *pszGeonamesGeomFieldPrefix = nullptr);
305
306
    int GetLayerCount() override
307
68.9k
    {
308
68.9k
        return static_cast<int>(m_apoLayers.size());
309
68.9k
    }
310
311
    OGRLayer *GetLayer(int) override;
312
313
    char **GetFileList() override;
314
315
    virtual OGRLayer *ICreateLayer(const char *pszName,
316
                                   const OGRGeomFieldDefn *poGeomFieldDefn,
317
                                   CSLConstList papszOptions) override;
318
319
    virtual OGRErr DeleteLayer(int) override;
320
321
    int TestCapability(const char *) override;
322
323
    void CreateForSingleFile(const char *pszDirname, const char *pszFilename);
324
325
    void EnableGeometryFields()
326
0
    {
327
0
        bEnableGeometryFields = true;
328
0
    }
329
330
    static CPLString GetRealExtension(CPLString osFilename);
331
    const std::vector<int> &DeletedFieldIndexes() const;
332
};
333
334
#endif  // ndef OGR_CSV_H_INCLUDED