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 "ogr_mem.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();
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() override
62 : {
63 1362 : return OGRMemLayer::GetLayerDefn()->GetName();
64 : }
65 :
66 121 : OGRwkbGeometryType GetGeomType() override
67 : {
68 121 : return wkbNone;
69 : }
70 :
71 12 : virtual OGRSpatialReference *GetSpatialRef() override
72 : {
73 12 : return nullptr;
74 : }
75 :
76 : /* For external usage. Mess with FID */
77 : virtual OGRFeature *GetNextFeature() override;
78 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
79 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
80 : OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount,
81 : const int *panUpdatedFieldsIdx,
82 : int nUpdatedGeomFieldsCount,
83 : const int *panUpdatedGeomFieldsIdx,
84 : bool bUpdateStyleString) override;
85 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
86 :
87 : virtual GIntBig GetFeatureCount(int) override;
88 :
89 : virtual OGRErr SetAttributeFilter(const char *pszQuery) override;
90 :
91 : virtual int TestCapability(const char *pszCap) override;
92 :
93 : /* For internal usage, for cell resolver */
94 243 : OGRFeature *GetNextFeatureWithoutFIDHack()
95 : {
96 243 : return OGRMemLayer::GetNextFeature();
97 : }
98 :
99 106 : OGRErr SetFeatureWithoutFIDHack(OGRFeature *poFeature)
100 : {
101 106 : SetUpdated();
102 106 : return OGRMemLayer::ISetFeature(poFeature);
103 : }
104 :
105 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
106 :
107 654 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
108 : int bApproxOK = TRUE) override
109 : {
110 654 : SetUpdated();
111 654 : return OGRMemLayer::CreateField(poField, bApproxOK);
112 : }
113 :
114 0 : virtual OGRErr DeleteField(int iField) override
115 : {
116 0 : SetUpdated();
117 0 : return OGRMemLayer::DeleteField(iField);
118 : }
119 :
120 0 : virtual OGRErr ReorderFields(int *panMap) override
121 : {
122 0 : SetUpdated();
123 0 : return OGRMemLayer::ReorderFields(panMap);
124 : }
125 :
126 31 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
127 : int nFlagsIn) override
128 : {
129 31 : SetUpdated();
130 31 : return OGRMemLayer::AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
131 : }
132 :
133 : virtual OGRErr SyncToDisk() override;
134 :
135 : GDALDataset *GetDataset() override;
136 : };
137 :
138 : /************************************************************************/
139 : /* OGRODSDataSource */
140 : /************************************************************************/
141 : #define STACK_SIZE 5
142 :
143 : typedef enum
144 : {
145 : STATE_DEFAULT,
146 : STATE_TABLE,
147 : STATE_ROW,
148 : STATE_CELL,
149 : STATE_TEXTP,
150 : } HandlerStateEnum;
151 :
152 : typedef struct
153 : {
154 : HandlerStateEnum eVal;
155 : int nBeginDepth;
156 : } HandlerState;
157 :
158 : class OGRODSDataSource final : public GDALDataset
159 : {
160 : char *pszName;
161 : bool bUpdatable;
162 : bool bUpdated;
163 : bool bAnalysedFile;
164 :
165 : int nLayers;
166 : OGRLayer **papoLayers;
167 :
168 : VSILFILE *fpSettings;
169 : std::string osCurrentConfigTableName;
170 : std::string osConfigName;
171 : int nVerticalSplitFlags;
172 : std::set<std::string> osSetLayerHasSplitter;
173 : void AnalyseSettings();
174 :
175 : VSILFILE *fpContent;
176 : void AnalyseFile();
177 :
178 : bool bFirstLineIsHeaders;
179 : int bAutodetectTypes;
180 :
181 : XML_Parser oParser;
182 : bool bStopParsing;
183 : int nWithoutEventCounter;
184 : int nDataHandlerCounter;
185 : int nCurLine;
186 : int nEmptyRowsAccumulated;
187 : int nRowsRepeated;
188 : int nCurCol;
189 : int nCellsRepeated;
190 : // Accumulated memory allocations related to repeated cells.
191 : size_t m_nAccRepeatedMemory = 0;
192 : bool bEndTableParsing;
193 :
194 : OGRODSLayer *poCurLayer;
195 :
196 : int nStackDepth;
197 : int nDepth;
198 : HandlerState stateStack[STACK_SIZE];
199 :
200 : CPLString osValueType;
201 : CPLString osValue;
202 : bool m_bValueFromTableCellAttribute = false;
203 : std::string osFormula;
204 :
205 : std::vector<std::string> apoFirstLineValues;
206 : std::vector<std::string> apoFirstLineTypes;
207 : std::vector<std::string> apoCurLineValues;
208 : std::vector<std::string> apoCurLineTypes;
209 :
210 : void PushState(HandlerStateEnum eVal);
211 : void startElementDefault(const char *pszName, const char **ppszAttr);
212 : void startElementTable(const char *pszName, const char **ppszAttr);
213 : void endElementTable(const char *pszName);
214 : void startElementRow(const char *pszName, const char **ppszAttr);
215 : void endElementRow(const char *pszName);
216 : void startElementCell(const char *pszName, const char **ppszAttr);
217 : void endElementCell(const char *pszName);
218 : void dataHandlerTextP(const char *data, int nLen);
219 :
220 : void DetectHeaderLine();
221 :
222 : OGRFieldType GetOGRFieldType(const char *pszValue, const char *pszValueType,
223 : OGRFieldSubType &eSubType);
224 :
225 : void DeleteLayer(const char *pszLayerName);
226 :
227 : void FillRepeatedCells(bool wasLastCell);
228 :
229 : public:
230 : explicit OGRODSDataSource(CSLConstList papszOpenOptionsIn);
231 : virtual ~OGRODSDataSource();
232 : CPLErr Close() override;
233 :
234 : int Open(const char *pszFilename, VSILFILE *fpContentIn,
235 : VSILFILE *fpSettingsIn, int bUpdatableIn);
236 : int Create(const char *pszName, char **papszOptions);
237 :
238 : virtual int GetLayerCount() override;
239 : virtual OGRLayer *GetLayer(int) override;
240 :
241 : virtual int TestCapability(const char *) override;
242 :
243 : OGRLayer *ICreateLayer(const char *pszName,
244 : const OGRGeomFieldDefn *poGeomFieldDefn,
245 : CSLConstList papszOptions) override;
246 :
247 : virtual OGRErr DeleteLayer(int iLayer) override;
248 :
249 : virtual CPLErr FlushCache(bool bAtClosing) override;
250 :
251 : void startElementCbk(const char *pszName, const char **ppszAttr);
252 : void endElementCbk(const char *pszName);
253 : void dataHandlerCbk(const char *data, int nLen);
254 :
255 : void startElementStylesCbk(const char *pszName, const char **ppszAttr);
256 : void endElementStylesCbk(const char *pszName);
257 : void dataHandlerStylesCbk(const char *data, int nLen);
258 :
259 1298 : bool GetUpdatable()
260 : {
261 1298 : return bUpdatable;
262 : }
263 :
264 11 : void SetUpdated()
265 : {
266 11 : bUpdated = true;
267 11 : }
268 : };
269 :
270 : } // namespace OGRODS
271 :
272 : #endif /* ndef OGR_ODS_H_INCLUDED */
|