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: 2024-11-21 22:18:42 Functions: 16 18 88.9 %

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

Generated by: LCOV version 1.14