Coverage Report

Created: 2025-06-09 08:44

/src/gdal/ogr/ogrsf_frmts/ods/ogr_ods.h
Line
Count
Source (jump to first uncovered line)
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();
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
7.16k
    {
58
7.16k
        bHasHeaderLine = bIn;
59
7.16k
    }
60
61
    const char *GetName() override
62
21.7k
    {
63
21.7k
        return OGRMemLayer::GetLayerDefn()->GetName();
64
21.7k
    }
65
66
    OGRwkbGeometryType GetGeomType() override
67
11.3k
    {
68
11.3k
        return wkbNone;
69
11.3k
    }
70
71
    virtual OGRSpatialReference *GetSpatialRef() override
72
11.3k
    {
73
11.3k
        return nullptr;
74
11.3k
    }
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
    OGRFeature *GetNextFeatureWithoutFIDHack()
95
6.12M
    {
96
6.12M
        return OGRMemLayer::GetNextFeature();
97
6.12M
    }
98
99
    OGRErr SetFeatureWithoutFIDHack(OGRFeature *poFeature)
100
693k
    {
101
693k
        SetUpdated();
102
693k
        return OGRMemLayer::ISetFeature(poFeature);
103
693k
    }
104
105
    OGRErr ICreateFeature(OGRFeature *poFeature) override;
106
107
    virtual OGRErr CreateField(const OGRFieldDefn *poField,
108
                               int bApproxOK = TRUE) override
109
380k
    {
110
380k
        SetUpdated();
111
380k
        return OGRMemLayer::CreateField(poField, bApproxOK);
112
380k
    }
113
114
    virtual OGRErr DeleteField(int iField) override
115
0
    {
116
0
        SetUpdated();
117
0
        return OGRMemLayer::DeleteField(iField);
118
0
    }
119
120
    virtual OGRErr ReorderFields(int *panMap) override
121
0
    {
122
0
        SetUpdated();
123
0
        return OGRMemLayer::ReorderFields(panMap);
124
0
    }
125
126
    virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
127
                                  int nFlagsIn) override
128
10.4k
    {
129
10.4k
        SetUpdated();
130
10.4k
        return OGRMemLayer::AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
131
10.4k
    }
132
133
    virtual OGRErr SyncToDisk() override;
134
135
    GDALDataset *GetDataset() override;
136
};
137
138
/************************************************************************/
139
/*                           OGRODSDataSource                           */
140
/************************************************************************/
141
114k
#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
    bool GetUpdatable()
260
19.8M
    {
261
19.8M
        return bUpdatable;
262
19.8M
    }
263
264
    void SetUpdated()
265
0
    {
266
0
        bUpdated = true;
267
0
    }
268
};
269
270
}  // namespace OGRODS
271
272
#endif /* ndef OGR_ODS_H_INCLUDED */