LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/xlsx - ogr_xlsx.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 43 51 84.3 %
Date: 2025-01-18 12:42:00 Functions: 16 18 88.9 %

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

Generated by: LCOV version 1.14