Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: XLSX Translator
5 : * Purpose: Definition of classes for OGR OpenOfficeSpreadsheet .xlsx 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 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #ifndef OGR_XLSX_H_INCLUDED
31 : #define OGR_XLSX_H_INCLUDED
32 :
33 : #include "ogrsf_frmts.h"
34 :
35 : #include "ogr_expat.h"
36 : #include "ogr_mem.h"
37 :
38 : #include <vector>
39 : #include <set>
40 : #include <string>
41 : #include <map>
42 :
43 : namespace OGRXLSX
44 : {
45 :
46 : /************************************************************************/
47 : /* OGRXLSXLayer */
48 : /************************************************************************/
49 :
50 : class OGRXLSXDataSource;
51 :
52 : class OGRXLSXLayer final : public OGRMemLayer
53 : {
54 : friend class OGRXLSXDataSource;
55 :
56 : bool bInit;
57 : OGRXLSXDataSource *poDS;
58 : CPLString osFilename;
59 : void Init();
60 : bool bUpdated;
61 : bool bHasHeaderLine;
62 : std::string m_osCols{};
63 : std::set<int> oSetFieldsOfUnknownType{};
64 :
65 : public:
66 : OGRXLSXLayer(OGRXLSXDataSource *poDSIn, const char *pszFilename,
67 : const char *pszName, int bUpdateIn = FALSE);
68 :
69 : bool HasBeenUpdated() const
70 : {
71 : return bUpdated;
72 : }
73 :
74 : void SetUpdated(bool bUpdatedIn = true);
75 :
76 : bool GetHasHeaderLine() const
77 : {
78 : return bHasHeaderLine;
79 : }
80 :
81 57 : void SetHasHeaderLine(bool bIn)
82 : {
83 57 : bHasHeaderLine = bIn;
84 57 : }
85 :
86 1121 : const char *GetName() override
87 : {
88 1121 : return OGRMemLayer::GetLayerDefn()->GetName();
89 : }
90 :
91 27 : OGRwkbGeometryType GetGeomType() override
92 : {
93 27 : return wkbNone;
94 : }
95 :
96 10 : virtual OGRSpatialReference *GetSpatialRef() override
97 : {
98 10 : return nullptr;
99 : }
100 :
101 393 : void ResetReading() override
102 : {
103 393 : Init();
104 393 : OGRMemLayer::ResetReading();
105 393 : }
106 :
107 80 : const CPLString &GetFilename() const
108 : {
109 80 : return osFilename;
110 : }
111 :
112 : /* For external usage. Mess with FID */
113 : virtual OGRFeature *GetNextFeature() override;
114 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
115 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
116 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
117 :
118 18 : virtual OGRErr SetNextByIndex(GIntBig nIndex) override
119 : {
120 18 : Init();
121 18 : return OGRMemLayer::SetNextByIndex(nIndex);
122 : }
123 :
124 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
125 :
126 5130 : OGRFeatureDefn *GetLayerDefn() override
127 : {
128 5130 : Init();
129 5130 : return OGRMemLayer::GetLayerDefn();
130 : }
131 :
132 150 : GIntBig GetFeatureCount(int bForce) override
133 : {
134 150 : Init();
135 150 : return OGRMemLayer::GetFeatureCount(bForce);
136 : }
137 :
138 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
139 : int bApproxOK = TRUE) override;
140 :
141 0 : virtual OGRErr DeleteField(int iField) override
142 : {
143 0 : Init();
144 0 : SetUpdated();
145 0 : return OGRMemLayer::DeleteField(iField);
146 : }
147 :
148 0 : virtual OGRErr ReorderFields(int *panMap) override
149 : {
150 0 : Init();
151 0 : SetUpdated();
152 0 : return OGRMemLayer::ReorderFields(panMap);
153 : }
154 :
155 18 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
156 : int nFlagsIn) override
157 : {
158 18 : Init();
159 18 : SetUpdated();
160 18 : return OGRMemLayer::AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
161 : }
162 :
163 397 : int TestCapability(const char *pszCap) override
164 : {
165 397 : Init();
166 397 : return OGRMemLayer::TestCapability(pszCap);
167 : }
168 :
169 4 : const std::string &GetCols() const
170 : {
171 4 : return m_osCols;
172 : }
173 :
174 : virtual OGRErr SyncToDisk() override;
175 :
176 : GDALDataset *GetDataset() override;
177 : };
178 :
179 : /************************************************************************/
180 : /* OGRXLSXDataSource */
181 : /************************************************************************/
182 : #define STACK_SIZE 5
183 :
184 : typedef enum
185 : {
186 : STATE_DEFAULT,
187 :
188 : /* for sharedString.xml */
189 : STATE_SI,
190 : STATE_T,
191 :
192 : /* for sheet?.xml */
193 : STATE_COLS,
194 : STATE_SHEETDATA,
195 : STATE_ROW,
196 : STATE_CELL,
197 : STATE_TEXTV,
198 : } HandlerStateEnum;
199 :
200 : typedef struct
201 : {
202 : HandlerStateEnum eVal;
203 : int nBeginDepth;
204 : } HandlerState;
205 :
206 : class XLSXFieldTypeExtended
207 : {
208 : public:
209 : OGRFieldType eType;
210 : bool bHasMS;
211 :
212 164 : XLSXFieldTypeExtended() : eType(OFTMaxType), bHasMS(false)
213 : {
214 164 : }
215 :
216 371 : explicit XLSXFieldTypeExtended(OGRFieldType eTypeIn, bool bHasMSIn = false)
217 371 : : eType(eTypeIn), bHasMS(bHasMSIn)
218 : {
219 371 : }
220 : };
221 :
222 : class OGRXLSXDataSource final : public GDALDataset
223 : {
224 : char *pszName;
225 : CPLString osPrefixedFilename;
226 : bool bUpdatable;
227 : bool bUpdated;
228 :
229 : int nLayers;
230 : OGRXLSXLayer **papoLayers;
231 : std::map<CPLString, CPLString> oMapRelsIdToTarget;
232 : std::set<std::string> m_oSetSheetId;
233 :
234 : void AnalyseSharedStrings(VSILFILE *fpSharedStrings);
235 : void AnalyseWorkbook(VSILFILE *fpWorkbook);
236 : void AnalyseWorkbookRels(VSILFILE *fpWorkbookRels);
237 : void AnalyseStyles(VSILFILE *fpStyles);
238 :
239 : std::vector<std::string> apoSharedStrings;
240 : std::string osCurrentString;
241 :
242 : bool bFirstLineIsHeaders;
243 : int bAutodetectTypes;
244 :
245 : XML_Parser oParser;
246 : bool bStopParsing;
247 : int nWithoutEventCounter;
248 : int nDataHandlerCounter;
249 : int nCurLine;
250 : int nCurCol;
251 :
252 : OGRXLSXLayer *poCurLayer;
253 : std::string m_osCols{};
254 :
255 : int nStackDepth;
256 : int nDepth;
257 : HandlerState stateStack[STACK_SIZE];
258 :
259 : CPLString osValueType;
260 : CPLString osValue;
261 :
262 : std::vector<std::string> apoFirstLineValues;
263 : std::vector<std::string> apoFirstLineTypes;
264 : std::vector<std::string> apoCurLineValues;
265 : std::vector<std::string> apoCurLineTypes;
266 :
267 : bool bInCellXFS;
268 : std::map<int, XLSXFieldTypeExtended> apoMapStyleFormats;
269 : std::vector<XLSXFieldTypeExtended> apoStyles;
270 :
271 : void PushState(HandlerStateEnum eVal);
272 : void startElementDefault(const char *pszName, const char **ppszAttr);
273 : void startElementTable(const char *pszName, const char **ppszAttr);
274 : void endElementTable(const char *pszName);
275 : void startElementCols(const char *pszName, const char **ppszAttr);
276 : void endElementCols(const char *pszName);
277 : void startElementRow(const char *pszName, const char **ppszAttr);
278 : void endElementRow(const char *pszName);
279 : void startElementCell(const char *pszName, const char **ppszAttr);
280 : void endElementCell(const char *pszName);
281 : void dataHandlerTextV(const char *data, int nLen);
282 :
283 : void DetectHeaderLine();
284 :
285 : OGRFieldType GetOGRFieldType(const char *pszValue, const char *pszValueType,
286 : OGRFieldSubType &eSubType);
287 :
288 : void DeleteLayer(const char *pszLayerName);
289 :
290 : public:
291 : explicit OGRXLSXDataSource(CSLConstList papszOpenOptionsIn);
292 : virtual ~OGRXLSXDataSource();
293 : CPLErr Close() override;
294 :
295 : int Open(const char *pszFilename, const char *pszPrefixedFilename,
296 : VSILFILE *fpWorkbook, VSILFILE *fpWorkbookRels,
297 : VSILFILE *fpSharedStrings, VSILFILE *fpStyles, int bUpdate);
298 : int Create(const char *pszName, char **papszOptions);
299 :
300 : virtual int GetLayerCount() override;
301 : virtual OGRLayer *GetLayer(int) override;
302 :
303 : virtual int TestCapability(const char *) override;
304 :
305 : OGRLayer *ICreateLayer(const char *pszName,
306 : const OGRGeomFieldDefn *poGeomFieldDefn,
307 : CSLConstList papszOptions) override;
308 :
309 : virtual OGRErr DeleteLayer(int iLayer) override;
310 :
311 : virtual CPLErr FlushCache(bool bAtClosing) override;
312 :
313 : void startElementCbk(const char *pszName, const char **ppszAttr);
314 : void endElementCbk(const char *pszName);
315 : void dataHandlerCbk(const char *data, int nLen);
316 :
317 : void startElementSSCbk(const char *pszName, const char **ppszAttr);
318 : void endElementSSCbk(const char *pszName);
319 : void dataHandlerSSCbk(const char *data, int nLen);
320 :
321 : void startElementWBRelsCbk(const char *pszName, const char **ppszAttr);
322 :
323 : void startElementWBCbk(const char *pszName, const char **ppszAttr);
324 :
325 : void startElementStylesCbk(const char *pszName, const char **ppszAttr);
326 : void endElementStylesCbk(const char *pszName);
327 :
328 : void BuildLayer(OGRXLSXLayer *poLayer);
329 :
330 2031 : bool GetUpdatable()
331 : {
332 2031 : return bUpdatable;
333 : }
334 :
335 10 : void SetUpdated()
336 : {
337 10 : bUpdated = true;
338 10 : }
339 : };
340 :
341 : } // namespace OGRXLSX
342 :
343 : #endif /* ndef OGR_XLSX_H_INCLUDED */
|