/src/gdal/ogr/ogrsf_frmts/ods/ogr_ods.h
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: ODS Translator |
4 | | * Purpose: Definition of classes for OGR OpenOfficeSpreadsheet .ods driver. |
5 | | * Author: Even Rouault, even dot rouault at spatialys.com |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2012, Even Rouault <even dot rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #ifndef OGR_ODS_H_INCLUDED |
14 | | #define OGR_ODS_H_INCLUDED |
15 | | |
16 | | #include "ogrsf_frmts.h" |
17 | | #include "memdataset.h" |
18 | | |
19 | | #include "ogr_expat.h" |
20 | | |
21 | | #include <vector> |
22 | | #include <string> |
23 | | #include <set> |
24 | | |
25 | | namespace OGRODS |
26 | | { |
27 | | |
28 | | /************************************************************************/ |
29 | | /* OGRODSLayer */ |
30 | | /************************************************************************/ |
31 | | |
32 | | class OGRODSDataSource; |
33 | | |
34 | | class OGRODSLayer final : public OGRMemLayer |
35 | | { |
36 | | OGRODSDataSource *poDS; |
37 | | bool bUpdated; |
38 | | bool bHasHeaderLine; |
39 | | OGRFeatureQuery *m_poAttrQueryODS; |
40 | | |
41 | | GIntBig TranslateFIDFromMemLayer(GIntBig nFID) const; |
42 | | GIntBig TranslateFIDToMemLayer(GIntBig nFID) const; |
43 | | |
44 | | public: |
45 | | OGRODSLayer(OGRODSDataSource *poDSIn, const char *pszName, |
46 | | bool bUpdateIn = FALSE); |
47 | | ~OGRODSLayer() override; |
48 | | |
49 | | void SetUpdated(bool bUpdatedIn = true); |
50 | | |
51 | | bool GetHasHeaderLine() |
52 | 0 | { |
53 | 0 | return bHasHeaderLine; |
54 | 0 | } |
55 | | |
56 | | void SetHasHeaderLine(bool bIn) |
57 | 0 | { |
58 | 0 | bHasHeaderLine = bIn; |
59 | 0 | } |
60 | | |
61 | | const char *GetName() const override |
62 | 12.6k | { |
63 | 12.6k | return OGRMemLayer::GetLayerDefn()->GetName(); |
64 | 12.6k | } |
65 | | |
66 | | OGRwkbGeometryType GetGeomType() const override |
67 | 0 | { |
68 | 0 | return wkbNone; |
69 | 0 | } |
70 | | |
71 | | const OGRSpatialReference *GetSpatialRef() const override |
72 | 313 | { |
73 | 313 | return nullptr; |
74 | 313 | } |
75 | | |
76 | | /* For external usage. Mess with FID */ |
77 | | OGRFeature *GetNextFeature() override; |
78 | | OGRFeature *GetFeature(GIntBig nFeatureId) override; |
79 | | OGRErr ISetFeature(OGRFeature *poFeature) override; |
80 | | OGRErr ISetFeatureUniqPtr(std::unique_ptr<OGRFeature> poFeature) override; |
81 | | OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount, |
82 | | const int *panUpdatedFieldsIdx, |
83 | | int nUpdatedGeomFieldsCount, |
84 | | const int *panUpdatedGeomFieldsIdx, |
85 | | bool bUpdateStyleString) override; |
86 | | OGRErr DeleteFeature(GIntBig nFID) override; |
87 | | |
88 | | GIntBig GetFeatureCount(int) override; |
89 | | |
90 | | OGRErr SetAttributeFilter(const char *pszQuery) override; |
91 | | |
92 | | int TestCapability(const char *pszCap) const override; |
93 | | |
94 | | /* For internal usage, for cell resolver */ |
95 | | OGRFeature *GetNextFeatureWithoutFIDHack() |
96 | 0 | { |
97 | 0 | return OGRMemLayer::GetNextFeature(); |
98 | 0 | } |
99 | | |
100 | | OGRErr SetFeatureWithoutFIDHack(OGRFeature *poFeature) |
101 | 0 | { |
102 | 0 | SetUpdated(); |
103 | 0 | return OGRMemLayer::ISetFeature(poFeature); |
104 | 0 | } |
105 | | |
106 | | OGRErr ICreateFeature(OGRFeature *poFeature) override; |
107 | | OGRErr ICreateFeatureUniqPtr(std::unique_ptr<OGRFeature> poFeature, |
108 | | GIntBig *pnFID) override; |
109 | | |
110 | | virtual OGRErr CreateField(const OGRFieldDefn *poField, |
111 | | int bApproxOK = TRUE) override |
112 | 1.24k | { |
113 | 1.24k | SetUpdated(); |
114 | 1.24k | return OGRMemLayer::CreateField(poField, bApproxOK); |
115 | 1.24k | } |
116 | | |
117 | | OGRErr DeleteField(int iField) override |
118 | 0 | { |
119 | 0 | SetUpdated(); |
120 | 0 | return OGRMemLayer::DeleteField(iField); |
121 | 0 | } |
122 | | |
123 | | OGRErr ReorderFields(int *panMap) override |
124 | 0 | { |
125 | 0 | SetUpdated(); |
126 | 0 | return OGRMemLayer::ReorderFields(panMap); |
127 | 0 | } |
128 | | |
129 | | virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn, |
130 | | int nFlagsIn) override |
131 | 0 | { |
132 | 0 | SetUpdated(); |
133 | 0 | return OGRMemLayer::AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn); |
134 | 0 | } |
135 | | |
136 | | OGRErr SyncToDisk() override; |
137 | | |
138 | | GDALDataset *GetDataset() override; |
139 | | }; |
140 | | |
141 | | /************************************************************************/ |
142 | | /* OGRODSDataSource */ |
143 | | /************************************************************************/ |
144 | 0 | #define STACK_SIZE 5 |
145 | | |
146 | | typedef enum |
147 | | { |
148 | | STATE_DEFAULT, |
149 | | STATE_TABLE, |
150 | | STATE_ROW, |
151 | | STATE_CELL, |
152 | | STATE_TEXTP, |
153 | | } HandlerStateEnum; |
154 | | |
155 | | typedef struct |
156 | | { |
157 | | HandlerStateEnum eVal; |
158 | | int nBeginDepth; |
159 | | } HandlerState; |
160 | | |
161 | | class OGRODSDataSource final : public GDALDataset |
162 | | { |
163 | | char *pszName; |
164 | | bool bUpdatable; |
165 | | bool bUpdated; |
166 | | bool bAnalysedFile; |
167 | | |
168 | | int nLayers; |
169 | | OGRLayer **papoLayers; |
170 | | |
171 | | VSILFILE *fpSettings; |
172 | | std::string osCurrentConfigTableName; |
173 | | std::string osConfigName; |
174 | | int nVerticalSplitFlags; |
175 | | std::set<std::string> osSetLayerHasSplitter; |
176 | | void AnalyseSettings(); |
177 | | |
178 | | VSILFILE *fpContent; |
179 | | void AnalyseFile(); |
180 | | |
181 | | bool bFirstLineIsHeaders; |
182 | | int bAutodetectTypes; |
183 | | |
184 | | XML_Parser oParser; |
185 | | bool bStopParsing; |
186 | | int nWithoutEventCounter; |
187 | | int nDataHandlerCounter; |
188 | | int nCurLine; |
189 | | int nEmptyRowsAccumulated; |
190 | | int nRowsRepeated; |
191 | | int nCurCol; |
192 | | int nCellsRepeated; |
193 | | // Accumulated memory allocations related to repeated cells. |
194 | | size_t m_nAccRepeatedMemory = 0; |
195 | | bool bEndTableParsing; |
196 | | |
197 | | OGRODSLayer *poCurLayer; |
198 | | |
199 | | int nStackDepth; |
200 | | int nDepth; |
201 | | HandlerState stateStack[STACK_SIZE]; |
202 | | |
203 | | CPLString osValueType; |
204 | | CPLString osValue; |
205 | | bool m_bValueFromTableCellAttribute = false; |
206 | | std::string osFormula; |
207 | | |
208 | | std::vector<std::string> apoFirstLineValues; |
209 | | std::vector<std::string> apoFirstLineTypes; |
210 | | std::vector<std::string> apoCurLineValues; |
211 | | std::vector<std::string> apoCurLineTypes; |
212 | | |
213 | | void PushState(HandlerStateEnum eVal); |
214 | | void startElementDefault(const char *pszName, const char **ppszAttr); |
215 | | void startElementTable(const char *pszName, const char **ppszAttr); |
216 | | void endElementTable(const char *pszName); |
217 | | void startElementRow(const char *pszName, const char **ppszAttr); |
218 | | void endElementRow(const char *pszName); |
219 | | void startElementCell(const char *pszName, const char **ppszAttr); |
220 | | void endElementCell(const char *pszName); |
221 | | void dataHandlerTextP(const char *data, int nLen); |
222 | | |
223 | | void DetectHeaderLine(); |
224 | | |
225 | | OGRFieldType GetOGRFieldType(const char *pszValue, const char *pszValueType, |
226 | | OGRFieldSubType &eSubType); |
227 | | |
228 | | void DeleteLayer(const char *pszLayerName); |
229 | | |
230 | | void FillRepeatedCells(bool wasLastCell); |
231 | | |
232 | | public: |
233 | | explicit OGRODSDataSource(CSLConstList papszOpenOptionsIn); |
234 | | ~OGRODSDataSource() override; |
235 | | CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override; |
236 | | |
237 | | int Open(const char *pszFilename, VSILFILE *fpContentIn, |
238 | | VSILFILE *fpSettingsIn, int bUpdatableIn); |
239 | | int Create(const char *pszName, CSLConstList papszOptions); |
240 | | |
241 | | int GetLayerCount() const override; |
242 | | const OGRLayer *GetLayer(int) const override; |
243 | | |
244 | | int TestCapability(const char *) const override; |
245 | | |
246 | | OGRLayer *ICreateLayer(const char *pszName, |
247 | | const OGRGeomFieldDefn *poGeomFieldDefn, |
248 | | CSLConstList papszOptions) override; |
249 | | |
250 | | OGRErr DeleteLayer(int iLayer) override; |
251 | | |
252 | | CPLErr FlushCache(bool bAtClosing) override; |
253 | | |
254 | | void startElementCbk(const char *pszName, const char **ppszAttr); |
255 | | void endElementCbk(const char *pszName); |
256 | | void dataHandlerCbk(const char *data, int nLen); |
257 | | |
258 | | void startElementStylesCbk(const char *pszName, const char **ppszAttr); |
259 | | void endElementStylesCbk(const char *pszName); |
260 | | void dataHandlerStylesCbk(const char *data, int nLen); |
261 | | |
262 | | bool GetUpdatable() |
263 | 0 | { |
264 | 0 | return bUpdatable; |
265 | 0 | } |
266 | | |
267 | | void SetUpdated() |
268 | 0 | { |
269 | 0 | bUpdated = true; |
270 | 0 | } |
271 | | }; |
272 | | |
273 | | } // namespace OGRODS |
274 | | |
275 | | #endif /* ndef OGR_ODS_H_INCLUDED */ |