Line data Source code
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 : {
53 : return bHasHeaderLine;
54 : }
55 :
56 115 : void SetHasHeaderLine(bool bIn)
57 : {
58 115 : bHasHeaderLine = bIn;
59 115 : }
60 :
61 1362 : const char *GetName() const override
62 : {
63 1362 : return OGRMemLayer::GetLayerDefn()->GetName();
64 : }
65 :
66 121 : OGRwkbGeometryType GetGeomType() const override
67 : {
68 121 : return wkbNone;
69 : }
70 :
71 12 : const OGRSpatialReference *GetSpatialRef() const override
72 : {
73 12 : return nullptr;
74 : }
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 243 : OGRFeature *GetNextFeatureWithoutFIDHack()
96 : {
97 243 : return OGRMemLayer::GetNextFeature();
98 : }
99 :
100 106 : OGRErr SetFeatureWithoutFIDHack(OGRFeature *poFeature)
101 : {
102 106 : SetUpdated();
103 106 : return OGRMemLayer::ISetFeature(poFeature);
104 : }
105 :
106 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
107 : OGRErr ICreateFeatureUniqPtr(std::unique_ptr<OGRFeature> poFeature,
108 : GIntBig *pnFID) override;
109 :
110 654 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
111 : int bApproxOK = TRUE) override
112 : {
113 654 : SetUpdated();
114 654 : return OGRMemLayer::CreateField(poField, bApproxOK);
115 : }
116 :
117 0 : OGRErr DeleteField(int iField) override
118 : {
119 0 : SetUpdated();
120 0 : return OGRMemLayer::DeleteField(iField);
121 : }
122 :
123 0 : OGRErr ReorderFields(int *panMap) override
124 : {
125 0 : SetUpdated();
126 0 : return OGRMemLayer::ReorderFields(panMap);
127 : }
128 :
129 31 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
130 : int nFlagsIn) override
131 : {
132 31 : SetUpdated();
133 31 : return OGRMemLayer::AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
134 : }
135 :
136 : OGRErr SyncToDisk() override;
137 :
138 : GDALDataset *GetDataset() override;
139 : };
140 :
141 : /************************************************************************/
142 : /* OGRODSDataSource */
143 : /************************************************************************/
144 : #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, char **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 1298 : bool GetUpdatable()
263 : {
264 1298 : return bUpdatable;
265 : }
266 :
267 11 : void SetUpdated()
268 : {
269 11 : bUpdated = true;
270 11 : }
271 : };
272 :
273 : } // namespace OGRODS
274 :
275 : #endif /* ndef OGR_ODS_H_INCLUDED */
|