Coverage Report

Created: 2026-08-14 09:29

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