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