Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: XLSX Translator
4 : * Purpose: Definition of classes for OGR OpenOfficeSpreadsheet .xlsx 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_XLSX_H_INCLUDED
14 : #define OGR_XLSX_H_INCLUDED
15 :
16 : #include "ogrsf_frmts.h"
17 :
18 : #include "ogr_expat.h"
19 : #include "memdataset.h"
20 :
21 : #include <vector>
22 : #include <set>
23 : #include <string>
24 : #include <map>
25 :
26 : namespace OGRXLSX
27 : {
28 :
29 : /************************************************************************/
30 : /* OGRXLSXLayer */
31 : /************************************************************************/
32 :
33 : class OGRXLSXDataSource;
34 :
35 : class OGRXLSXLayer final : public OGRMemLayer
36 : {
37 : friend class OGRXLSXDataSource;
38 :
39 : bool bInit;
40 : OGRXLSXDataSource *poDS;
41 : CPLString osFilename;
42 : void Init();
43 : bool bUpdated;
44 : bool bHasHeaderLine;
45 : std::string m_osCols{};
46 : std::set<int> oSetFieldsOfUnknownType{};
47 :
48 : GIntBig TranslateFIDFromMemLayer(GIntBig nFID) const;
49 : GIntBig TranslateFIDToMemLayer(GIntBig nFID) const;
50 :
51 : public:
52 : OGRXLSXLayer(OGRXLSXDataSource *poDSIn, const char *pszFilename,
53 : const char *pszName, int bUpdateIn = FALSE);
54 :
55 : bool HasBeenUpdated() const
56 : {
57 : return bUpdated;
58 : }
59 :
60 : void SetUpdated(bool bUpdatedIn = true);
61 :
62 : bool GetHasHeaderLine() const
63 : {
64 : return bHasHeaderLine;
65 : }
66 :
67 60 : void SetHasHeaderLine(bool bIn)
68 : {
69 60 : bHasHeaderLine = bIn;
70 60 : }
71 :
72 1160 : const char *GetName() const override
73 : {
74 1160 : return OGRMemLayer::GetLayerDefn()->GetName();
75 : }
76 :
77 29 : OGRwkbGeometryType GetGeomType() const override
78 : {
79 29 : return wkbNone;
80 : }
81 :
82 10 : const OGRSpatialReference *GetSpatialRef() const override
83 : {
84 10 : return nullptr;
85 : }
86 :
87 459 : void ResetReading() override
88 : {
89 459 : Init();
90 459 : OGRMemLayer::ResetReading();
91 459 : }
92 :
93 : int TestCapability(const char *pszCap) const override;
94 :
95 84 : const CPLString &GetFilename() const
96 : {
97 84 : return osFilename;
98 : }
99 :
100 : /* For external usage. Mess with FID */
101 : OGRFeature *GetNextFeature() override;
102 : OGRFeature *GetFeature(GIntBig nFeatureId) override;
103 : OGRErr ISetFeature(OGRFeature *poFeature) override;
104 : OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount,
105 : const int *panUpdatedFieldsIdx,
106 : int nUpdatedGeomFieldsCount,
107 : const int *panUpdatedGeomFieldsIdx,
108 : bool bUpdateStyleString) override;
109 : OGRErr DeleteFeature(GIntBig nFID) override;
110 :
111 23 : OGRErr SetNextByIndex(GIntBig nIndex) override
112 : {
113 23 : Init();
114 23 : return OGRMemLayer::SetNextByIndex(nIndex);
115 : }
116 :
117 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
118 :
119 5241 : const OGRFeatureDefn *GetLayerDefn() const override
120 : {
121 5241 : const_cast<OGRXLSXLayer *>(this)->Init();
122 5241 : return OGRMemLayer::GetLayerDefn();
123 : }
124 :
125 164 : GIntBig GetFeatureCount(int bForce) override
126 : {
127 164 : Init();
128 164 : return OGRMemLayer::GetFeatureCount(bForce);
129 : }
130 :
131 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
132 : int bApproxOK = TRUE) override;
133 :
134 0 : OGRErr DeleteField(int iField) override
135 : {
136 0 : Init();
137 0 : SetUpdated();
138 0 : return OGRMemLayer::DeleteField(iField);
139 : }
140 :
141 0 : OGRErr ReorderFields(int *panMap) override
142 : {
143 0 : Init();
144 0 : SetUpdated();
145 0 : return OGRMemLayer::ReorderFields(panMap);
146 : }
147 :
148 18 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
149 : int nFlagsIn) override
150 : {
151 18 : Init();
152 18 : SetUpdated();
153 18 : return OGRMemLayer::AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
154 : }
155 :
156 4 : const std::string &GetCols() const
157 : {
158 4 : return m_osCols;
159 : }
160 :
161 : OGRErr SyncToDisk() override;
162 :
163 : GDALDataset *GetDataset() override;
164 : };
165 :
166 : /************************************************************************/
167 : /* OGRXLSXDataSource */
168 : /************************************************************************/
169 : #define STACK_SIZE 5
170 :
171 : typedef enum
172 : {
173 : STATE_DEFAULT,
174 :
175 : /* for sharedString.xml */
176 : STATE_SI,
177 : STATE_T,
178 :
179 : /* for sheet?.xml */
180 : STATE_COLS,
181 : STATE_SHEETDATA,
182 : STATE_ROW,
183 : STATE_CELL,
184 : STATE_TEXTV,
185 : } HandlerStateEnum;
186 :
187 : typedef struct
188 : {
189 : HandlerStateEnum eVal;
190 : int nBeginDepth;
191 : } HandlerState;
192 :
193 : class XLSXFieldTypeExtended
194 : {
195 : public:
196 : OGRFieldType eType;
197 : bool bHasMS;
198 :
199 176 : XLSXFieldTypeExtended() : eType(OFTMaxType), bHasMS(false)
200 : {
201 176 : }
202 :
203 395 : explicit XLSXFieldTypeExtended(OGRFieldType eTypeIn, bool bHasMSIn = false)
204 395 : : eType(eTypeIn), bHasMS(bHasMSIn)
205 : {
206 395 : }
207 : };
208 :
209 : class OGRXLSXDataSource final : public GDALDataset
210 : {
211 : char *pszName;
212 : CPLString osPrefixedFilename;
213 : bool bUpdatable;
214 : bool bUpdated;
215 :
216 : int nLayers;
217 : OGRXLSXLayer **papoLayers;
218 : std::map<CPLString, CPLString> oMapRelsIdToTarget;
219 : std::set<std::string> m_oSetSheetId;
220 :
221 : void AnalyseSharedStrings(VSILFILE *fpSharedStrings);
222 : void AnalyseWorkbook(VSILFILE *fpWorkbook);
223 : void AnalyseWorkbookRels(VSILFILE *fpWorkbookRels);
224 : void AnalyseStyles(VSILFILE *fpStyles);
225 :
226 : std::vector<std::string> apoSharedStrings;
227 : std::string osCurrentString;
228 :
229 : bool bFirstLineIsHeaders;
230 : int bAutodetectTypes;
231 :
232 : XML_Parser oParser;
233 : bool bStopParsing;
234 : int nWithoutEventCounter;
235 : int nDataHandlerCounter;
236 : int nCurLine;
237 : int nCurCol;
238 :
239 : OGRXLSXLayer *poCurLayer;
240 : std::string m_osCols{};
241 :
242 : int nStackDepth;
243 : int nDepth;
244 : HandlerState stateStack[STACK_SIZE];
245 :
246 : CPLString osValueType;
247 : CPLString osValue;
248 :
249 : std::vector<std::string> apoFirstLineValues;
250 : std::vector<std::string> apoFirstLineTypes;
251 : std::vector<std::string> apoCurLineValues;
252 : std::vector<std::string> apoCurLineTypes;
253 :
254 : bool bInCellXFS;
255 : std::map<int, XLSXFieldTypeExtended> apoMapStyleFormats;
256 : std::vector<XLSXFieldTypeExtended> apoStyles;
257 :
258 : void PushState(HandlerStateEnum eVal);
259 : void startElementDefault(const char *pszName, const char **ppszAttr);
260 : void startElementTable(const char *pszName, const char **ppszAttr);
261 : void endElementTable(const char *pszName);
262 : void startElementCols(const char *pszName, const char **ppszAttr);
263 : void endElementCols(const char *pszName);
264 : void startElementRow(const char *pszName, const char **ppszAttr);
265 : void endElementRow(const char *pszName);
266 : void startElementCell(const char *pszName, const char **ppszAttr);
267 : void endElementCell(const char *pszName);
268 : void dataHandlerTextV(const char *data, int nLen);
269 :
270 : void DetectHeaderLine();
271 :
272 : OGRFieldType GetOGRFieldType(const char *pszValue, const char *pszValueType,
273 : OGRFieldSubType &eSubType);
274 :
275 : void DeleteLayer(const char *pszLayerName);
276 :
277 : public:
278 : explicit OGRXLSXDataSource(CSLConstList papszOpenOptionsIn);
279 : ~OGRXLSXDataSource() override;
280 : CPLErr Close() override;
281 :
282 : int Open(const char *pszFilename, const char *pszPrefixedFilename,
283 : VSILFILE *fpWorkbook, VSILFILE *fpWorkbookRels,
284 : VSILFILE *fpSharedStrings, VSILFILE *fpStyles, int bUpdate);
285 : int Create(const char *pszName, char **papszOptions);
286 :
287 : int GetLayerCount() const override;
288 : const OGRLayer *GetLayer(int) const override;
289 :
290 : int TestCapability(const char *) const override;
291 :
292 : OGRLayer *ICreateLayer(const char *pszName,
293 : const OGRGeomFieldDefn *poGeomFieldDefn,
294 : CSLConstList papszOptions) override;
295 :
296 : OGRErr DeleteLayer(int iLayer) override;
297 :
298 : CPLErr FlushCache(bool bAtClosing) override;
299 :
300 : void startElementCbk(const char *pszName, const char **ppszAttr);
301 : void endElementCbk(const char *pszName);
302 : void dataHandlerCbk(const char *data, int nLen);
303 :
304 : void startElementSSCbk(const char *pszName, const char **ppszAttr);
305 : void endElementSSCbk(const char *pszName);
306 : void dataHandlerSSCbk(const char *data, int nLen);
307 :
308 : void startElementWBRelsCbk(const char *pszName, const char **ppszAttr);
309 :
310 : void startElementWBCbk(const char *pszName, const char **ppszAttr);
311 :
312 : void startElementStylesCbk(const char *pszName, const char **ppszAttr);
313 : void endElementStylesCbk(const char *pszName);
314 :
315 : void BuildLayer(OGRXLSXLayer *poLayer);
316 :
317 1202 : bool GetUpdatable()
318 : {
319 1202 : return bUpdatable;
320 : }
321 :
322 12 : void SetUpdated()
323 : {
324 12 : bUpdated = true;
325 12 : }
326 : };
327 :
328 : } // namespace OGRXLSX
329 :
330 : #endif /* ndef OGR_XLSX_H_INCLUDED */
|