/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 |