1 /******************************************************************************
2  *
3  * Project:  LV BAG Translator
4  * Purpose:  Definition of classes for OGR LVBAG driver.
5  * Author:   Laixer B.V., info at laixer dot com
6  *
7  ******************************************************************************
8  * Copyright (c) 2020, Laixer B.V. <info at laixer dot com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28 
29 #ifndef OGR_LVBAG_H_INCLUDED
30 #define OGR_LVBAG_H_INCLUDED
31 
32 #include "ogrsf_frmts.h"
33 #include "ogr_expat.h"
34 #include "ogrlayerpool.h"
35 
36 namespace OGRLVBAG {
37 
38 typedef enum
39 {
40     LYR_RAW,
41     LYR_UNION
42 } LayerType;
43 
44 /**
45  * Layer pool unique pointer.
46  */
47 using LayerPoolUniquePtr = std::unique_ptr<OGRLayerPool>;
48 
49 /**
50  * Vector holding pointers to OGRLayer.
51  */
52 using LayerVector = std::vector<std::pair<LayerType, OGRLayerUniquePtr>>;
53 
54 }
55 
56 /************************************************************************/
57 /*                           OGRLVBAGLayer                              */
58 /************************************************************************/
59 
60 class OGRLVBAGLayer final: public OGRAbstractProxiedLayer, public OGRGetNextFeatureThroughRaw<OGRLVBAGLayer>
61 {
62     CPL_DISALLOW_COPY_ASSIGN(OGRLVBAGLayer)
63 
64     OGRFeatureDefn     *poFeatureDefn;
65     OGRFeature         *m_poFeature = nullptr;
66     VSILFILE           *fp;
67     CPLString           osFilename;
68 
69     typedef enum
70     {
71         FD_OPENED,
72         FD_CLOSED,
73         FD_CANNOT_REOPEN
74     } FileDescriptorState;
75 
76     FileDescriptorState eFileDescriptorsState;
77 
78     OGRExpatUniquePtr   oParser;
79 
80     bool                bSchemaOnly;
81     bool                bHasReadSchema;
82     bool                bFixInvalidData;
83     bool                bLegacyId;
84 
85     typedef enum
86     {
87         ADDRESS_PRIMARY,
88         ADDRESS_SECONDARY,
89     } AddressRefState;
90 
91     int                 nNextFID;
92     int                 nCurrentDepth;
93     int                 nGeometryElementDepth;
94     int                 nFeatureCollectionDepth;
95     int                 nFeatureElementDepth;
96     int                 nAttributeElementDepth;
97 
98     AddressRefState     eAddressRefState;
99 
100     CPLString           osElementString;
101     CPLString           osAttributeString;
102     bool                bCollectData;
103 
104     char                aBuf[BUFSIZ];
105 
106     void                AddSpatialRef(OGRwkbGeometryType eTypeIn);
107     void                AddOccurrenceFieldDefn();
108     void                AddIdentifierFieldDefn();
109     void                AddDocumentFieldDefn();
110     void                CreateFeatureDefn(const char *);
111 
112     void                ConfigureParser();
113     void                ParseDocument();
114     bool                IsParserFinished(XML_Status status);
115 
116     void                StartElementCbk(const char *, const char **);
117     void                EndElementCbk(const char *);
118     void                DataHandlerCbk(const char *, int);
119 
120     void                StartDataCollect();
121     void                StopDataCollect();
122 
123     bool                TouchLayer();
124     void                CloseUnderlyingLayer() override;
125 
126     OGRFeature*         GetNextRawFeature();
127 
128     friend class OGRGetNextFeatureThroughRaw<OGRLVBAGLayer>;
129     friend class OGRLVBAGDataSource;
130 
131 public:
132     explicit OGRLVBAGLayer( const char *pszFilename, OGRLayerPool* poPoolIn, char **papszOpenOptions );
133     ~OGRLVBAGLayer();
134 
135     void                ResetReading() override;
136     OGRFeature*         GetNextFeature() override;
137 
138     OGRFeatureDefn*     GetLayerDefn() override;
139 
140     int                 TestCapability( const char * ) override;
141 };
142 
143 /************************************************************************/
144 /*                          OGRLVBAGDataSource                          */
145 /************************************************************************/
146 
147 class OGRLVBAGDataSource final: public GDALDataset
148 {
149     OGRLVBAG::LayerPoolUniquePtr poPool;
150     OGRLVBAG::LayerVector papoLayers;
151 
152     void                TryCoalesceLayers();
153 
154     friend GDALDataset *OGRLVBAGDriverOpen( GDALOpenInfo* poOpenInfo );
155 
156 public:
157                         OGRLVBAGDataSource();
158 
159     int                 Open( const char* pszFilename, char **papszOpenOptions );
160 
161     int                 GetLayerCount() override;
162     OGRLayer*           GetLayer( int ) override;
163 
164     int                 TestCapability( const char * ) override;
165 };
166 
167 #endif  // ndef OGR_LVBAG_H_INCLUDED
168