LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/s101 - ogr_s101.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 57 58 98.3 %
Date: 2026-05-08 18:52:02 Functions: 34 35 97.1 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  S-101 driver
       4             :  * Purpose:  Header file
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef OGR_S101_H_INCLUDED
      14             : #define OGR_S101_H_INCLUDED
      15             : 
      16             : #include "ogrsf_frmts.h"
      17             : #include "iso8211.h"
      18             : #include "ddfrecordindex.h"
      19             : 
      20             : #include "cpl_int_wrapper.h"
      21             : #include "cpl_string.h"
      22             : 
      23             : #include <map>
      24             : #include <set>
      25             : #include <string_view>
      26             : 
      27             : /************************************************************************/
      28             : /*                            OGRS101Reader                             */
      29             : /************************************************************************/
      30             : 
      31             : class OGRS101FeatureCatalog;
      32             : 
      33             : namespace OGRS101FeatureCatalogTypes
      34             : {
      35             : struct InformationType;
      36             : struct FeatureType;
      37             : }  // namespace OGRS101FeatureCatalogTypes
      38             : 
      39         710 : class OGRS101Reader
      40             : {
      41             :   public:
      42             :     struct CRSIdTag
      43             :     {
      44             :     };
      45             : 
      46             :     using CRSId = cpl::IntWrapper<CRSIdTag>;
      47             : 
      48             :     static constexpr CRSId INVALID_CRS_ID{-1};
      49             :     static constexpr CRSId HORIZONTAL_CRS_ID{1};
      50             : 
      51             :     struct RecordNameTag
      52             :     {
      53             :     };
      54             : 
      55             :     // Record "name" is a poor naming from the S100 spec. It is actually
      56             :     // a numeric value
      57             :     using RecordName = cpl::IntWrapper<RecordNameTag>;
      58             : 
      59             :   private:
      60             :     /////////////////////////////////////////////////////////////////////////
      61             :     // Members
      62             :     /////////////////////////////////////////////////////////////////////////
      63             : 
      64             :     bool m_bStrict = true;
      65             :     std::string m_osFilename{};
      66             :     std::unique_ptr<DDFModule> m_poModule{};
      67             : 
      68             :     CPLStringList m_aosMetadata{};
      69             : 
      70             :     // DSSI field
      71             :     static constexpr double S101_SHIFT = 0;
      72             :     double m_dfXShift = S101_SHIFT;  // DCOX
      73             :     double m_dfYShift = S101_SHIFT;  // DCOY
      74             :     double m_dfZShift = S101_SHIFT;  // DCOZ
      75             :     static constexpr int S101_XSCALE = 10000000;
      76             :     int m_nXScale = S101_XSCALE;  // CMFX
      77             :     static constexpr int S101_YSCALE = 10000000;
      78             :     int m_nYScale = S101_YSCALE;  // CMFY
      79             :     static constexpr int S101_ZSCALE = 10;
      80             :     int m_nZScale = S101_ZSCALE;           // CMFZ
      81             :     int m_nCountInformationRecord = 0;     // NOIR
      82             :     int m_nCountPointRecord = 0;           // NOPN
      83             :     int m_nCountMultiPointRecord = 0;      // NOMN
      84             :     int m_nCountCurveRecord = 0;           // NOCN
      85             :     int m_nCountCompositeCurveRecord = 0;  // NOXN
      86             :     int m_nCountSurfaceRecord = 0;         // NOSN
      87             :     int m_nCountFeatureTypeRecord = 0;     // NOFR
      88             : 
      89             :     struct AttrCodeTag
      90             :     {
      91             :     };
      92             : 
      93             :     using AttrCode = cpl::IntWrapper<AttrCodeTag>;
      94             :     // from ATCS field
      95             :     std::map<AttrCode, std::string> m_attributeCodes{};
      96             : 
      97             :     struct InfoTypeCodeTag
      98             :     {
      99             :     };
     100             : 
     101             :     using InfoTypeCode = cpl::IntWrapper<InfoTypeCodeTag>;
     102             :     // from ITCS field
     103             :     std::map<InfoTypeCode, std::string> m_informationTypeCodes{};
     104             : 
     105             :     struct FeatureTypeCodeTag
     106             :     {
     107             :     };
     108             : 
     109             :     using FeatureTypeCode = cpl::IntWrapper<FeatureTypeCodeTag>;
     110             :     // from FTCS field
     111             :     std::map<FeatureTypeCode, std::string> m_featureTypeCodes{};
     112             : 
     113             :     struct InfoAssocCodeTag
     114             :     {
     115             :     };
     116             : 
     117             :     using InfoAssocCode = cpl::IntWrapper<InfoAssocCodeTag>;
     118             :     // from IACS field
     119             :     std::map<InfoAssocCode, std::string> m_informationAssociationCodes{};
     120             : 
     121             :     struct FeatureAssocCodeTag
     122             :     {
     123             :     };
     124             : 
     125             :     using FeatureAssocCode = cpl::IntWrapper<FeatureAssocCodeTag>;
     126             :     // from FACS field
     127             :     std::map<FeatureAssocCode, std::string> m_featureAssociationCodes{};
     128             : 
     129             :     struct AssocRoleCodeTag
     130             :     {
     131             :     };
     132             : 
     133             :     using AssocRoleCode = cpl::IntWrapper<AssocRoleCodeTag>;
     134             :     // from ARCS field
     135             :     std::map<AssocRoleCode, std::string> m_associationRoleCodes{};
     136             : 
     137             :     static constexpr RecordName PSEUDO_RECORD_NAME_NO_GEOM{-1111111111};
     138             : 
     139             :     /** Triple (feature type code, geometry type, CRS Id) */
     140             :     struct FeatureTypeKey
     141             :     {
     142             :         FeatureTypeCode nFeatureTypeCode{0};
     143             :         RecordName nGeometryType{PSEUDO_RECORD_NAME_NO_GEOM};
     144             :         CRSId nCRSId{INVALID_CRS_ID};
     145             : 
     146             :         // I'd wish I could use C++20
     147        2946 :         inline bool operator<(const FeatureTypeKey &other) const
     148             :         {
     149        2946 :             return toTuple() < other.toTuple();
     150             :         }
     151             : 
     152             :       private:
     153        5892 :         inline std::tuple<int, int, int> toTuple() const
     154             :         {
     155           0 :             return std::make_tuple(static_cast<int>(nFeatureTypeCode),
     156        5892 :                                    static_cast<int>(nGeometryType),
     157       17676 :                                    static_cast<int>(nCRSId));
     158             :         }
     159             :     };
     160             : 
     161             :     // key is the crs index (CRIX). 1: Horizontal CRS. >= 2: CompoundCRS
     162             :     std::map<CRSId, OGRSpatialReference> m_oMapSRS{};
     163             : 
     164             :     DDFRecordIndex m_oInformationTypeRecordIndex{};
     165             :     DDFRecordIndex m_oPointRecordIndex{};
     166             :     DDFRecordIndex m_oMultiPointRecordIndex{};
     167             :     DDFRecordIndex m_oCurveRecordIndex{};
     168             :     DDFRecordIndex m_oCompositeCurveRecordIndex{};
     169             :     DDFRecordIndex m_oSurfaceRecordIndex{};
     170             :     DDFRecordIndex m_oFeatureTypeRecordIndex{};
     171             : 
     172             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnInformationType{};
     173             : 
     174             :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> m_oMapPointFeatureDefn{};
     175             :     std::map<CRSId, std::vector<int>> m_oMapCRSIdToPointRecordIdx{};
     176             : 
     177             :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> m_oMapMultiPointFeatureDefn{};
     178             :     std::map<CRSId, std::vector<int>> m_oMapCRSIdToMultiPointRecordIdx{};
     179             : 
     180             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnCurve{};
     181             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnCompositeCurve{};
     182             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnSurface{};
     183             : 
     184             :     struct LayerDef
     185             :     {
     186             :         OGRFeatureDefnRefCountedPtr poFeatureDefn{};
     187             :         std::string osName{};
     188             :         std::string osDefinition{};
     189             :         std::string osAlias{};
     190             :         std::vector<int> anRecordIndices{};
     191             :     };
     192             : 
     193             :     std::map<FeatureTypeKey, LayerDef> m_oMapFeatureKeyToLayerDef{};
     194             :     std::map<int, const OGRFeatureDefn *> m_oMapFeatureTypeIdToFDefn{};
     195             : 
     196             :     std::map<std::string, std::unique_ptr<OGRFieldDomain>> m_oMapFieldDomains{};
     197             : 
     198             :     const OGRS101FeatureCatalog *m_poFeatureCatalog = nullptr;
     199             : 
     200             :     /////////////////////////////////////////////////////////////////////////
     201             :     // Methods
     202             :     /////////////////////////////////////////////////////////////////////////
     203             : 
     204             :     bool CheckFieldDefinitions() const;
     205             :     bool CheckField0000Definition() const;
     206             : 
     207             :     bool ReadDatasetGeneralInformationRecord(const DDFRecord *poRecord);
     208             :     bool ReadDSID(const DDFRecord *poRecord);
     209             :     bool ReadDSSI(const DDFRecord *poRecord);
     210             : 
     211             :     template <class CodeType>
     212             :     bool ReadGenericCodeAssociation(const DDFRecord *poRecord,
     213             :                                     const char *pszFieldName,
     214             :                                     const char *pszSubField0Name,
     215             :                                     const char *pszSubField1Name,
     216             :                                     std::map<CodeType, std::string> &map) const;
     217             : 
     218             :     bool ReadATCS(const DDFRecord *poRecord);
     219             :     bool ReadITCS(const DDFRecord *poRecord);
     220             :     bool ReadFTCS(const DDFRecord *poRecord);
     221             :     bool ReadIACS(const DDFRecord *poRecord);
     222             :     bool ReadFACS(const DDFRecord *poRecord);
     223             :     bool ReadARCS(const DDFRecord *poRecord);
     224             : 
     225             :     bool ReadCSID(const DDFRecord *poRecord);
     226             : 
     227             :     bool IngestRecords(const DDFRecord *poRecordIn);
     228             : 
     229             :     // Type for PAIX subfield (parent index)
     230             :     struct AttrIndexTag
     231             :     {
     232             :     };
     233             : 
     234             :     using AttrIndex = cpl::IntWrapper<AttrIndexTag>;
     235             : 
     236             :     // Type for ATIX subfield (attribute index)
     237             :     struct AttrRepeatTag
     238             :     {
     239             :     };
     240             : 
     241             :     using AttrRepeat = cpl::IntWrapper<AttrRepeatTag>;
     242             : 
     243             :     using PathElement = std::pair<AttrCode, AttrRepeat>;
     244             :     using PathVector = std::vector<PathElement>;
     245             : 
     246             :     // Capture essential information for a repetition of the ATTR field
     247             :     struct S101AttrDef
     248             :     {
     249             :         PathVector oReversedPath{};  // ordered from child to root
     250             :         std::string osVal{};
     251             :         int iField = 0;
     252             :         bool bMultipleFields = false;
     253             :         bool bIsParent = false;
     254             :     };
     255             : 
     256             :     bool ReadFeatureCatalog();
     257             : 
     258             :     std::string BuildFieldName(const PathVector &oReversedPath,
     259             :                                const char *pszAttrFieldName, int iField,
     260             :                                bool bMultipleFields,
     261             :                                const char *pszIDFieldName) const;
     262             : 
     263             :     bool CreateInformationTypeFeatureDefn();
     264             :     bool CreatePointFeatureDefns();
     265             :     bool CreateMultiPointFeatureDefns();
     266             :     bool CreateCurveFeatureDefn();
     267             :     bool CreateCompositeCurveFeatureDefn();
     268             :     bool CreateSurfaceFeatureDefn();
     269             :     bool CreateFeatureTypeFeatureDefns();
     270             : 
     271             :     bool InferFeatureDefn(
     272             :         const DDFRecordIndex &oIndex, const char *pszIDFieldName,
     273             :         const char *pszAttrFieldName, const std::vector<int> &anRecordIndices,
     274             :         OGRFeatureDefn &oFeatureDefn,
     275             :         std::map<std::string, std::unique_ptr<OGRFieldDomain>>
     276             :             &oMapFieldDomains,
     277             :         const OGRS101FeatureCatalogTypes::InformationType *psInformationType =
     278             :             nullptr,
     279             :         const OGRS101FeatureCatalogTypes::FeatureType *psFeatureType =
     280             :             nullptr) const;
     281             : 
     282             :     bool IngestAttributes(const DDFRecord *poRecord, int iRecord,
     283             :                           const char *pszIDFieldName,
     284             :                           const char *pszAttrFieldName,
     285             :                           const DDFField *poATTRField, int iField,
     286             :                           bool bMultipleFields,
     287             :                           std::vector<S101AttrDef> &asS101AttrDefs) const;
     288             : 
     289             :     bool IngestAttributes(const DDFRecord *poRecord, int iRecord,
     290             :                           const char *pszIDFieldName,
     291             :                           const char *pszAttrFieldName,
     292             :                           std::vector<S101AttrDef> &asS101AttrDefs) const;
     293             : 
     294             :     bool FillFeatureAttributes(const DDFRecordIndex &oIndex, int iRecord,
     295             :                                const char *pszAttrFieldName,
     296             :                                OGRFeature &oFeature) const;
     297             : 
     298             :     CRSId GetCRSIdForPointRecord(const DDFRecord *poRecord, int iRecord,
     299             :                                  int nRecordID) const;
     300             : 
     301             :     std::map<OGRS101Reader::CRSId, std::vector<int>>
     302             :     CreateMapCRSIdToRecordIdxForPoints(bool &bError) const;
     303             : 
     304             :     CRSId GetCRSIdForMultiPointRecord(const DDFRecord *poRecord, int iRecord,
     305             :                                       int nRecordID) const;
     306             : 
     307             :     std::map<OGRS101Reader::CRSId, std::vector<int>>
     308             :     CreateMapCRSIdToRecordIdxForMultiPoints(bool &bError) const;
     309             : 
     310             :     bool FillFeatureWithNonAttrAssocSubfields(const DDFRecord *poRecord,
     311             :                                               int iRecord,
     312             :                                               const char *pszAttrFieldName,
     313             :                                               OGRFeature &oFeature) const;
     314             : 
     315             :     std::unique_ptr<OGRPoint> ReadPointGeometryInternal(
     316             :         const DDFRecord *poRecord, int iRecord, int nRecordID, int iPnt,
     317             :         const OGRSpatialReference *poSRS, const bool bIs3D,
     318             :         const DDFField *poCoordField, const char *pszRecordFieldName) const;
     319             : 
     320             :     std::unique_ptr<OGRPoint>
     321             :     ReadPointGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
     322             :                       const OGRSpatialReference *poSRS) const;
     323             : 
     324             :     std::unique_ptr<OGRMultiPoint>
     325             :     ReadMultiPointGeometry(const DDFRecord *poRecord, int iRecord,
     326             :                            int nRecordID,
     327             :                            const OGRSpatialReference *poSRS) const;
     328             : 
     329             :     std::unique_ptr<OGRLineString>
     330             :     ReadCurveGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
     331             :                       const OGRSpatialReference *poSRS) const;
     332             : 
     333             :     std::unique_ptr<OGRLineString> ReadCompositeCurveGeometryInternal(
     334             :         const DDFRecord *poRecord, int iRecord, int nRecordID,
     335             :         const OGRSpatialReference *poSRS,
     336             :         std::set<int> &oSetAlreadyVisitedCompositeCurveRecords) const;
     337             : 
     338             :     std::unique_ptr<OGRLineString>
     339             :     ReadCompositeCurveGeometry(const DDFRecord *poRecord, int iRecord,
     340             :                                int nRecordID,
     341             :                                const OGRSpatialReference *poSRS) const;
     342             : 
     343             :     std::unique_ptr<OGRPolygon>
     344             :     ReadSurfaceGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
     345             :                         const OGRSpatialReference *poSRS) const;
     346             : 
     347             :     template <typename T, typename GeomReaderMethodType>
     348             :     bool ReadGeometry(const DDFRecordIndex &oIndex, const char *pszErrorContext,
     349             :                       int nGeomRecordID, const char *pszGeomType, bool bReverse,
     350             :                       OGRFeature &oFeature,
     351             :                       std::unique_ptr<OGRGeometryCollection> &poMultiGeom,
     352             :                       GeomReaderMethodType geomReaderMethod,
     353             :                       int iGeomField = 0) const;
     354             : 
     355             :     bool FillFeatureTypeGeometry(const DDFRecord *poRecord, int iRecord,
     356             :                                  OGRFeature &oFeature) const;
     357             : 
     358             :     bool FillFeatureTypeMask(const DDFRecord *poRecord, int iRecord,
     359             :                              OGRFeature &oFeature) const;
     360             : 
     361             :     static std::string LaunderCRSName(const OGRSpatialReference &oSRS);
     362             :     static std::string GetPointLayerName(const OGRSpatialReference &oSRS);
     363             :     static std::string GetMultiPointLayerName(const OGRSpatialReference &oSRS);
     364             : 
     365             :     OGRS101Reader(const OGRS101Reader &) = delete;
     366             :     OGRS101Reader &operator=(const OGRS101Reader &) = delete;
     367             : 
     368             :   protected:
     369             :     friend class OGRS101FeatureCatalog;
     370             :     static bool EmitErrorOrWarning(const char *pszFile, const char *pszFunc,
     371             :                                    int nLine, const char *pszMsg, bool bError,
     372             :                                    bool bRecoverable);
     373             : 
     374             :   public:
     375             :     OGRS101Reader();
     376             :     ~OGRS101Reader();
     377             : 
     378             :     bool Load(GDALOpenInfo *poOpenInfo);
     379             : 
     380             :     /** Return feature catalog, or null. */
     381           2 :     const OGRS101FeatureCatalog *GetFeatureCatalog() const
     382             :     {
     383           2 :         return m_poFeatureCatalog;
     384             :     }
     385             : 
     386             :     /** Return dataset metadata from the DSID field. */
     387         242 :     const CPLStringList &GetMetadata() const
     388             :     {
     389         242 :         return m_aosMetadata;
     390             :     }
     391             : 
     392             :     /** Return InformationType records */
     393         156 :     const DDFRecordIndex &GetInformationTypeRecords() const
     394             :     {
     395         156 :         return m_oInformationTypeRecordIndex;
     396             :     }
     397             : 
     398             :     /** Return Point records */
     399         150 :     const DDFRecordIndex &GetPointRecords() const
     400             :     {
     401         150 :         return m_oPointRecordIndex;
     402             :     }
     403             : 
     404             :     /** Return MultiPoint records */
     405          56 :     const DDFRecordIndex &GetMultiPointRecords() const
     406             :     {
     407          56 :         return m_oMultiPointRecordIndex;
     408             :     }
     409             : 
     410             :     /** Return Curve records */
     411         106 :     const DDFRecordIndex &GetCurveRecords() const
     412             :     {
     413         106 :         return m_oCurveRecordIndex;
     414             :     }
     415             : 
     416             :     /** Return CompositeCurve records */
     417          81 :     const DDFRecordIndex &GetCompositeCurveRecords() const
     418             :     {
     419          81 :         return m_oCompositeCurveRecordIndex;
     420             :     }
     421             : 
     422             :     /** Return Surface records */
     423          63 :     const DDFRecordIndex &GetSurfaceRecords() const
     424             :     {
     425          63 :         return m_oSurfaceRecordIndex;
     426             :     }
     427             : 
     428             :     /** Return FeatureType records */
     429         282 :     const DDFRecordIndex &GetFeatureTypeRecords() const
     430             :     {
     431         282 :         return m_oFeatureTypeRecordIndex;
     432             :     }
     433             : 
     434             :     /** Return (and steal) the layer definition for InformationType features */
     435         242 :     OGRFeatureDefnRefCountedPtr StealInformationTypeFeatureDefn()
     436             :     {
     437         242 :         return std::move(m_poFeatureDefnInformationType);
     438             :     }
     439             : 
     440             :     /** Return a map from a CRSId to the layer definition for Point features */
     441         242 :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> &StealPointFeatureDefns()
     442             :     {
     443         242 :         return m_oMapPointFeatureDefn;
     444             :     }
     445             : 
     446             :     /** Return a map from a CRSId to the layer definition for MultiPoint features */
     447         242 :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> &StealMultiPointFeatureDefns()
     448             :     {
     449         242 :         return m_oMapMultiPointFeatureDefn;
     450             :     }
     451             : 
     452             :     /** Return (and steal) a map from a feature type key to the layer definition */
     453         242 :     std::map<FeatureTypeKey, LayerDef> &StealFeatureTypeLayerDefs()
     454             :     {
     455         242 :         return m_oMapFeatureKeyToLayerDef;
     456             :     }
     457             : 
     458             :     /** Return (and steal) the layer definition for curve records */
     459         242 :     OGRFeatureDefnRefCountedPtr StealCurveFeatureDefn()
     460             :     {
     461         242 :         return std::move(m_poFeatureDefnCurve);
     462             :     }
     463             : 
     464             :     /** Return (and steal) the layer definition for composite curve records */
     465         242 :     OGRFeatureDefnRefCountedPtr StealCompositeCurveFeatureDefn()
     466             :     {
     467         242 :         return std::move(m_poFeatureDefnCompositeCurve);
     468             :     }
     469             : 
     470             :     /** Return (and steal) the layer definition for surface records */
     471         242 :     OGRFeatureDefnRefCountedPtr StealSurfaceFeatureDefn()
     472             :     {
     473         242 :         return std::move(m_poFeatureDefnSurface);
     474             :     }
     475             : 
     476             :     /** Return the map from CRS id to indexes of Point records */
     477             :     const std::map<OGRS101Reader::CRSId, std::vector<int>> &
     478         150 :     GetMapCRSIdToRecordIdxForPoints() const
     479             :     {
     480         150 :         return m_oMapCRSIdToPointRecordIdx;
     481             :     }
     482             : 
     483             :     /** Return the map from CRS id to indexes of MultiPoint records */
     484             :     const std::map<OGRS101Reader::CRSId, std::vector<int>> &
     485          56 :     GetMapCRSIdToRecordIdxForMultiPoints() const
     486             :     {
     487          56 :         return m_oMapCRSIdToMultiPointRecordIdx;
     488             :     }
     489             : 
     490             :     /** Return (and steal) the field domains */
     491         242 :     std::map<std::string, std::unique_ptr<OGRFieldDomain>> &StealFieldDomains()
     492             :     {
     493         242 :         return m_oMapFieldDomains;
     494             :     }
     495             : 
     496             :     bool FillFeatureInformationType(const DDFRecordIndex &oIndex, int iRecord,
     497             :                                     OGRFeature &oFeature) const;
     498             : 
     499             :     bool FillFeaturePoint(const DDFRecordIndex &oIndex, int iRecord,
     500             :                           OGRFeature &oFeature) const;
     501             : 
     502             :     bool FillFeatureMultiPoint(const DDFRecordIndex &oIndex, int iRecord,
     503             :                                OGRFeature &oFeature) const;
     504             : 
     505             :     bool FillFeatureCurve(const DDFRecordIndex &oIndex, int iRecord,
     506             :                           OGRFeature &oFeature) const;
     507             : 
     508             :     bool FillFeatureCompositeCurve(const DDFRecordIndex &oIndex, int iRecord,
     509             :                                    OGRFeature &oFeature) const;
     510             : 
     511             :     bool FillFeatureSurface(const DDFRecordIndex &oIndex, int iRecord,
     512             :                             OGRFeature &oFeature) const;
     513             : 
     514             :     bool FillFeatureFeatureType(const DDFRecordIndex &oIndex, int iRecord,
     515             :                                 OGRFeature &oFeature) const;
     516             : };
     517             : 
     518             : /** Emit an error in strict mode (and return false),
     519             :  * or an error in non-strict mode (and return true) */
     520             : #define EMIT_ERROR_OR_WARNING(msg)                                             \
     521             :     EmitErrorOrWarning(__FILE__, __FUNCTION__, __LINE__, msg, m_bStrict, true)
     522             : 
     523             : /** Emit an error */
     524             : #define EMIT_ERROR(msg)                                                        \
     525             :     EmitErrorOrWarning(__FILE__, __FUNCTION__, __LINE__, msg, true, false)
     526             : 
     527             : /************************************************************************/
     528             : /*                            OGRS101Dataset                            */
     529             : /************************************************************************/
     530             : 
     531             : class OGRS101Dataset final : public GDALDataset
     532             : {
     533             :     std::unique_ptr<OGRS101Reader> m_poReader{};
     534             :     std::vector<std::unique_ptr<OGRLayer>> m_apoLayers{};
     535             : 
     536             :   public:
     537         355 :     OGRS101Dataset() = default;
     538             : 
     539             :     int GetLayerCount() const override;
     540             :     OGRLayer *GetLayer(int) const override;
     541             : 
     542        3002 :     const OGRS101Reader &GetReader() const
     543             :     {
     544        3002 :         return *m_poReader;
     545             :     }
     546             : 
     547             :     int TestCapability(const char *) const override;
     548             : 
     549             :     static GDALDataset *Open(GDALOpenInfo *poOpenInfo);
     550             :     static void UnloadDriver(GDALDriver *);
     551             : };
     552             : 
     553             : /************************************************************************/
     554             : /*                            OGRS101Layer()                            */
     555             : /************************************************************************/
     556             : 
     557         894 : class OGRS101Layer /* non final */ : public OGRLayer
     558             : {
     559             :   public:
     560             :     OGRS101Layer(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     561             :                  OGRFeatureDefnRefCountedPtr poFeatureDefn);
     562             :     ~OGRS101Layer() override;
     563             : 
     564       13932 :     const OGRFeatureDefn *GetLayerDefn() const override
     565             :     {
     566       13932 :         return m_poFeatureDefn.get();
     567             :     }
     568             : 
     569             :     void ResetReading() override;
     570             : 
     571             :     int TestCapability(const char *) const override;
     572             : 
     573             :     GIntBig GetFeatureCount(int bForce) override;
     574             : 
     575             :   protected:
     576             :     const OGRS101Dataset &m_oDS;
     577             :     const DDFRecordIndex &m_oIndex;
     578             :     const OGRFeatureDefnRefCountedPtr m_poFeatureDefn{};
     579             :     int m_nRecordIdx = 0;
     580             : 
     581             :   private:
     582             :     CPL_DISALLOW_COPY_ASSIGN(OGRS101Layer)
     583             : };
     584             : 
     585             : /************************************************************************/
     586             : /*                    OGRS101LayerInformationType()                     */
     587             : /************************************************************************/
     588             : 
     589             : class OGRS101LayerInformationType final
     590             :     : public OGRS101Layer,
     591             :       OGRGetNextFeatureThroughRaw<OGRS101LayerInformationType>
     592             : {
     593             :   public:
     594             :     OGRS101LayerInformationType(OGRS101Dataset &oDS,
     595             :                                 const DDFRecordIndex &oIndex,
     596             :                                 OGRFeatureDefnRefCountedPtr poFeatureDefn);
     597             : 
     598             :     OGRFeature *GetNextRawFeature();
     599             : 
     600             :     OGRFeature *GetFeature(GIntBig nFID) override;
     601             : 
     602         569 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerInformationType)
     603             : };
     604             : 
     605             : /************************************************************************/
     606             : /*                         OGRS101LayerPoint()                          */
     607             : /************************************************************************/
     608             : 
     609             : class OGRS101LayerPoint final : public OGRS101Layer,
     610             :                                 OGRGetNextFeatureThroughRaw<OGRS101LayerPoint>
     611             : {
     612             :   public:
     613             :     OGRS101LayerPoint(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     614             :                       const std::vector<int> &anRecordIndices,
     615             :                       OGRFeatureDefnRefCountedPtr poFeatureDefn);
     616             : 
     617             :     OGRFeature *GetNextRawFeature();
     618             : 
     619             :     GIntBig GetFeatureCount(int bForce) override;
     620             : 
     621             :     OGRFeature *GetFeature(GIntBig nFID) override;
     622             : 
     623         891 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerPoint)
     624             : 
     625             :   private:
     626             :     const std::vector<int> &m_anRecordIndices;
     627             : };
     628             : 
     629             : /************************************************************************/
     630             : /*                       OGRS101LayerMultiPoint()                       */
     631             : /************************************************************************/
     632             : 
     633             : class OGRS101LayerMultiPoint final
     634             :     : public OGRS101Layer,
     635             :       OGRGetNextFeatureThroughRaw<OGRS101LayerMultiPoint>
     636             : {
     637             :   public:
     638             :     OGRS101LayerMultiPoint(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     639             :                            const std::vector<int> &anRecordIndices,
     640             :                            OGRFeatureDefnRefCountedPtr poFeatureDefn);
     641             : 
     642             :     OGRFeature *GetNextRawFeature();
     643             : 
     644             :     GIntBig GetFeatureCount(int bForce) override;
     645             : 
     646             :     OGRFeature *GetFeature(GIntBig nFID) override;
     647             : 
     648         309 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerMultiPoint)
     649             : 
     650             :   private:
     651             :     const std::vector<int> &m_anRecordIndices;
     652             : };
     653             : 
     654             : /************************************************************************/
     655             : /*                         OGRS101LayerCurve()                          */
     656             : /************************************************************************/
     657             : 
     658             : class OGRS101LayerCurve final : public OGRS101Layer,
     659             :                                 OGRGetNextFeatureThroughRaw<OGRS101LayerCurve>
     660             : {
     661             :   public:
     662             :     OGRS101LayerCurve(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     663             :                       OGRFeatureDefnRefCountedPtr poFeatureDefn);
     664             : 
     665             :     OGRFeature *GetNextRawFeature();
     666             : 
     667             :     OGRFeature *GetFeature(GIntBig nFID) override;
     668             : 
     669         625 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerCurve)
     670             : };
     671             : 
     672             : /************************************************************************/
     673             : /*                     OGRS101LayerCompositeCurve()                     */
     674             : /************************************************************************/
     675             : 
     676             : class OGRS101LayerCompositeCurve final
     677             :     : public OGRS101Layer,
     678             :       OGRGetNextFeatureThroughRaw<OGRS101LayerCompositeCurve>
     679             : {
     680             :   public:
     681             :     OGRS101LayerCompositeCurve(OGRS101Dataset &oDS,
     682             :                                const DDFRecordIndex &oIndex,
     683             :                                OGRFeatureDefnRefCountedPtr poFeatureDefn);
     684             : 
     685             :     OGRFeature *GetNextRawFeature();
     686             : 
     687             :     OGRFeature *GetFeature(GIntBig nFID) override;
     688             : 
     689         379 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerCompositeCurve)
     690             : };
     691             : 
     692             : /************************************************************************/
     693             : /*                        OGRS101LayerSurface()                         */
     694             : /************************************************************************/
     695             : 
     696             : class OGRS101LayerSurface final
     697             :     : public OGRS101Layer,
     698             :       OGRGetNextFeatureThroughRaw<OGRS101LayerSurface>
     699             : {
     700             :   public:
     701             :     OGRS101LayerSurface(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     702             :                         OGRFeatureDefnRefCountedPtr poFeatureDefn);
     703             : 
     704             :     OGRFeature *GetNextRawFeature();
     705             : 
     706             :     OGRFeature *GetFeature(GIntBig nFID) override;
     707             : 
     708         213 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerSurface)
     709             : };
     710             : 
     711             : /************************************************************************/
     712             : /*                      OGRS101LayerFeatureType()                       */
     713             : /************************************************************************/
     714             : 
     715             : class OGRS101LayerFeatureType final
     716             :     : public OGRS101Layer,
     717             :       OGRGetNextFeatureThroughRaw<OGRS101LayerFeatureType>
     718             : {
     719             :   public:
     720             :     OGRS101LayerFeatureType(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     721             :                             const std::vector<int> &anRecordIndices,
     722             :                             OGRFeatureDefnRefCountedPtr poFeatureDefn);
     723             : 
     724             :     OGRFeature *GetNextRawFeature();
     725             : 
     726             :     GIntBig GetFeatureCount(int bForce) override;
     727             : 
     728             :     OGRFeature *GetFeature(GIntBig nFID) override;
     729             : 
     730         999 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerFeatureType)
     731             : 
     732             :   private:
     733             :     const std::vector<int> &m_anRecordIndices;
     734             : };
     735             : 
     736             : #endif  // OGR_S101_H_INCLUDED

Generated by: LCOV version 1.14