1 /******************************************************************************
2  *
3  * Project:  OpenGIS Simple Features Reference Implementation
4  * Purpose:  The OGRSFDriverRegistrar class implementation.
5  * Author:   Frank Warmerdam, warmerdam@pobox.com
6  *
7  ******************************************************************************
8  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
9  * Copyright (c) 2008-2012, Even Rouault <even dot rouault at spatialys.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #include "ogrsf_frmts.h"
31 #include "ogr_api.h"
32 #include "ograpispy.h"
33 
34 CPL_CVSID("$Id: ogrsfdriverregistrar.cpp 428c6a6a0a81364b703d448b3baa74bb17ae2cbd 2020-10-21 15:43:49 +0200 Even Rouault $")
35 
36 /************************************************************************/
37 /*                         OGRSFDriverRegistrar                         */
38 /************************************************************************/
39 
40 /**
41  * \brief Constructor
42  *
43  * Normally the driver registrar is constructed by the
44  * OGRSFDriverRegistrar::GetRegistrar() accessor which ensures singleton
45  * status.
46  */
47 
OGRSFDriverRegistrar()48 OGRSFDriverRegistrar::OGRSFDriverRegistrar() {}
49 
50 /************************************************************************/
51 /*                       ~OGRSFDriverRegistrar()                        */
52 /************************************************************************/
53 
~OGRSFDriverRegistrar()54 OGRSFDriverRegistrar::~OGRSFDriverRegistrar() {}
55 
56 //! @cond Doxygen_Suppress
57 /************************************************************************/
58 /*                           GetRegistrar()                             */
59 /************************************************************************/
60 
GetRegistrar()61 OGRSFDriverRegistrar *OGRSFDriverRegistrar::GetRegistrar()
62 {
63     static      OGRSFDriverRegistrar oSingleton;
64     return &oSingleton;
65 }
66 
67 /************************************************************************/
68 /*                           OGRCleanupAll()                            */
69 /************************************************************************/
70 
71 #if defined(WIN32) && defined(_MSC_VER)
72 #include "ogremulatedtransaction.h"
73 void OGRRegisterMutexedDataSource();
74 void OGRRegisterMutexedLayer();
75 int OGRwillNeverBeTrue = FALSE;
76 #endif
77 
78 /**
79  * \brief Cleanup all OGR related resources.
80  *
81  * FIXME
82  */
OGRCleanupAll()83 void OGRCleanupAll()
84 
85 {
86     GDALDestroyDriverManager();
87 #if defined(WIN32) && defined(_MSC_VER)
88 // Horrible hack: for some reason MSVC doesn't export those classes&symbols
89 // if they are not referenced from the DLL itself
90     if(OGRwillNeverBeTrue)
91     {
92         OGRRegisterMutexedDataSource();
93         OGRRegisterMutexedLayer();
94         OGRCreateEmulatedTransactionDataSourceWrapper(nullptr,nullptr,FALSE,FALSE);
95     }
96 #endif
97 }
98 
99 /************************************************************************/
100 /*                              OGROpen()                               */
101 /************************************************************************/
102 
OGROpen(const char * pszName,int bUpdate,OGRSFDriverH * pahDriverList)103 OGRDataSourceH OGROpen( const char *pszName, int bUpdate,
104                         OGRSFDriverH *pahDriverList )
105 
106 {
107     VALIDATE_POINTER1( pszName, "OGROpen", nullptr );
108 
109     GDALDatasetH hDS = GDALOpenEx(pszName, GDAL_OF_VECTOR |
110                             ((bUpdate) ? GDAL_OF_UPDATE: 0), nullptr, nullptr, nullptr);
111     if( hDS != nullptr && pahDriverList != nullptr )
112         *pahDriverList = reinterpret_cast<OGRSFDriverH>(GDALGetDatasetDriver(hDS));
113 
114     return reinterpret_cast<OGRDataSourceH>(hDS);
115 }
116 
117 /************************************************************************/
118 /*                           OGROpenShared()                            */
119 /************************************************************************/
120 
OGROpenShared(const char * pszName,int bUpdate,OGRSFDriverH * pahDriverList)121 OGRDataSourceH OGROpenShared( const char *pszName, int bUpdate,
122                               OGRSFDriverH *pahDriverList )
123 
124 {
125     VALIDATE_POINTER1( pszName, "OGROpenShared", nullptr );
126 
127     GDALDatasetH hDS = GDALOpenEx(pszName, GDAL_OF_VECTOR |
128             ((bUpdate) ? GDAL_OF_UPDATE: 0) | GDAL_OF_SHARED, nullptr, nullptr, nullptr);
129     if( hDS != nullptr && pahDriverList != nullptr )
130         *pahDriverList = reinterpret_cast<OGRSFDriverH>(GDALGetDatasetDriver(hDS));
131     return reinterpret_cast<OGRDataSourceH>(hDS);
132 }
133 
134 /************************************************************************/
135 /*                        OGRReleaseDataSource()                        */
136 /************************************************************************/
137 
OGRReleaseDataSource(OGRDataSourceH hDS)138 OGRErr OGRReleaseDataSource( OGRDataSourceH hDS )
139 
140 {
141     VALIDATE_POINTER1( hDS, "OGRReleaseDataSource", OGRERR_INVALID_HANDLE );
142 
143     GDALClose( reinterpret_cast<GDALDatasetH>(hDS) );
144 
145     return OGRERR_NONE;
146 }
147 
148 /************************************************************************/
149 /*                           GetOpenDSCount()                           */
150 /************************************************************************/
151 
GetOpenDSCount()152 int OGRSFDriverRegistrar::GetOpenDSCount()
153 {
154     CPLError(CE_Failure, CPLE_AppDefined, "Stub implementation in GDAL 2.0");
155     return 0;
156 }
157 
158 /************************************************************************/
159 /*                         OGRGetOpenDSCount()                          */
160 /************************************************************************/
161 
OGRGetOpenDSCount()162 int OGRGetOpenDSCount()
163 
164 {
165     return OGRSFDriverRegistrar::GetRegistrar()->GetOpenDSCount();
166 }
167 
168 /************************************************************************/
169 /*                             GetOpenDS()                              */
170 /************************************************************************/
171 
GetOpenDS(CPL_UNUSED int iDS)172 OGRDataSource *OGRSFDriverRegistrar::GetOpenDS( CPL_UNUSED int iDS )
173 {
174     CPLError(CE_Failure, CPLE_AppDefined, "Stub implementation in GDAL 2.0");
175     return nullptr;
176 }
177 
178 /************************************************************************/
179 /*                            OGRGetOpenDS()                            */
180 /************************************************************************/
181 
OGRGetOpenDS(int iDS)182 OGRDataSourceH OGRGetOpenDS( int iDS )
183 
184 {
185     return reinterpret_cast<OGRDataSourceH>(
186         OGRSFDriverRegistrar::GetRegistrar()->GetOpenDS( iDS ));
187 }
188 
189 /************************************************************************/
190 /*                          OpenWithDriverArg()                         */
191 /************************************************************************/
192 
OpenWithDriverArg(GDALDriver * poDriver,GDALOpenInfo * poOpenInfo)193 GDALDataset* OGRSFDriverRegistrar::OpenWithDriverArg(GDALDriver* poDriver,
194                                                  GDALOpenInfo* poOpenInfo)
195 {
196     OGRDataSource* poDS = reinterpret_cast<OGRDataSource*>(
197         reinterpret_cast<OGRSFDriver*>(poDriver)->Open(poOpenInfo->pszFilename,
198                                         poOpenInfo->eAccess == GA_Update));
199     if( poDS != nullptr )
200         poDS->SetDescription( poDS->GetName() );
201     return poDS;
202 }
203 
204 /************************************************************************/
205 /*                          CreateVectorOnly()                          */
206 /************************************************************************/
207 
CreateVectorOnly(GDALDriver * poDriver,const char * pszName,char ** papszOptions)208 GDALDataset* OGRSFDriverRegistrar::CreateVectorOnly( GDALDriver* poDriver,
209                                                      const char * pszName,
210                                                      char ** papszOptions )
211 {
212     OGRDataSource* poDS = reinterpret_cast<OGRDataSource*>(
213         reinterpret_cast<OGRSFDriver*>(poDriver)->
214             CreateDataSource(pszName, papszOptions));
215     if( poDS != nullptr && poDS->GetName() != nullptr )
216         poDS->SetDescription( poDS->GetName() );
217     return poDS;
218 }
219 
220 /************************************************************************/
221 /*                          DeleteDataSource()                          */
222 /************************************************************************/
223 
DeleteDataSource(GDALDriver * poDriver,const char * pszName)224 CPLErr OGRSFDriverRegistrar::DeleteDataSource( GDALDriver* poDriver,
225                                               const char * pszName )
226 {
227     if( reinterpret_cast<OGRSFDriver*>(poDriver)->
228             DeleteDataSource(pszName) == OGRERR_NONE )
229         return CE_None;
230     else
231         return CE_Failure;
232 }
233 
234 /************************************************************************/
235 /*                           RegisterDriver()                           */
236 /************************************************************************/
237 
RegisterDriver(OGRSFDriver * poDriver)238 void OGRSFDriverRegistrar::RegisterDriver( OGRSFDriver * poDriver )
239 
240 {
241     GDALDriver* poGDALDriver = GDALDriver::FromHandle(
242         GDALGetDriverByName( poDriver->GetName() ));
243     if( poGDALDriver == nullptr)
244     {
245         poDriver->SetDescription( poDriver->GetName() );
246         poDriver->SetMetadataItem("OGR_DRIVER", "YES");
247 
248         if( poDriver->GetMetadataItem(GDAL_DMD_LONGNAME) == nullptr )
249             poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, poDriver->GetName() );
250 
251         poDriver->pfnOpenWithDriverArg = OpenWithDriverArg;
252 
253         if( poDriver->TestCapability(ODrCCreateDataSource) )
254         {
255             poDriver->SetMetadataItem( GDAL_DCAP_CREATE, "YES" );
256             poDriver->pfnCreateVectorOnly = CreateVectorOnly;
257         }
258         if( poDriver->TestCapability(ODrCDeleteDataSource) )
259         {
260             poDriver->pfnDeleteDataSource = DeleteDataSource;
261         }
262 
263         poDriver->SetMetadataItem( GDAL_DCAP_VECTOR, "YES" );
264 
265         GetGDALDriverManager()->RegisterDriver( poDriver );
266     }
267     else
268     {
269         if( poGDALDriver->GetMetadataItem("OGR_DRIVER") == nullptr)
270         {
271             CPLError(CE_Failure, CPLE_AppDefined,
272                     "A non OGR driver is registered with the same name: %s", poDriver->GetName());
273         }
274         delete poDriver;
275     }
276 }
277 
278 /************************************************************************/
279 /*                         OGRRegisterDriver()                          */
280 /************************************************************************/
281 
OGRRegisterDriver(OGRSFDriverH hDriver)282 void OGRRegisterDriver( OGRSFDriverH hDriver )
283 
284 {
285     VALIDATE_POINTER0( hDriver, "OGRRegisterDriver" );
286 
287     GetGDALDriverManager()->RegisterDriver( GDALDriver::FromHandle(hDriver) );
288 }
289 
290 /************************************************************************/
291 /*                        OGRDeregisterDriver()                         */
292 /************************************************************************/
293 
OGRDeregisterDriver(OGRSFDriverH hDriver)294 void OGRDeregisterDriver( OGRSFDriverH hDriver )
295 
296 {
297     VALIDATE_POINTER0( hDriver, "OGRDeregisterDriver" );
298 
299     GetGDALDriverManager()->DeregisterDriver( GDALDriver::FromHandle(hDriver) );
300 }
301 
302 /************************************************************************/
303 /*                           GetDriverCount()                           */
304 /************************************************************************/
305 
GetDriverCount()306 int OGRSFDriverRegistrar::GetDriverCount()
307 
308 {
309     /* We must be careful only to return drivers that are actual OGRSFDriver* */
310     GDALDriverManager* poDriverManager = GetGDALDriverManager();
311     int nTotal = poDriverManager->GetDriverCount();
312     int nOGRDriverCount = 0;
313     for(int i=0;i<nTotal;i++)
314     {
315         GDALDriver* poDriver = poDriverManager->GetDriver(i);
316         if( poDriver->GetMetadataItem(GDAL_DCAP_VECTOR) != nullptr )
317             nOGRDriverCount ++;
318     }
319     return nOGRDriverCount;
320 }
321 
322 /************************************************************************/
323 /*                         OGRGetDriverCount()                          */
324 /************************************************************************/
325 
OGRGetDriverCount()326 int OGRGetDriverCount()
327 
328 {
329     return OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
330 }
331 
332 /************************************************************************/
333 /*                             GetDriver()                              */
334 /************************************************************************/
335 
GetDriver(int iDriver)336 GDALDriver *OGRSFDriverRegistrar::GetDriver( int iDriver )
337 
338 {
339     /* We must be careful only to return drivers that are actual OGRSFDriver* */
340     GDALDriverManager* poDriverManager = GetGDALDriverManager();
341     int nTotal = poDriverManager->GetDriverCount();
342     int nOGRDriverCount = 0;
343     for(int i=0;i<nTotal;i++)
344     {
345         GDALDriver* poDriver = poDriverManager->GetDriver(i);
346         if( poDriver->GetMetadataItem(GDAL_DCAP_VECTOR) != nullptr )
347         {
348             if( nOGRDriverCount == iDriver )
349                 return poDriver;
350             nOGRDriverCount ++;
351         }
352     }
353     return nullptr;
354 }
355 
356 /************************************************************************/
357 /*                            OGRGetDriver()                            */
358 /************************************************************************/
359 
OGRGetDriver(int iDriver)360 OGRSFDriverH OGRGetDriver( int iDriver )
361 
362 {
363     return reinterpret_cast<OGRSFDriverH>(
364         OGRSFDriverRegistrar::GetRegistrar()->GetDriver( iDriver ));
365 }
366 
367 /************************************************************************/
368 /*                          GetDriverByName()                           */
369 /************************************************************************/
370 
GetDriverByName(const char * pszName)371 GDALDriver *OGRSFDriverRegistrar::GetDriverByName( const char * pszName )
372 
373 {
374     GDALDriverManager* poDriverManager = GetGDALDriverManager();
375     GDALDriver* poGDALDriver =
376         poDriverManager->GetDriverByName(CPLSPrintf("OGR_%s", pszName));
377     if( poGDALDriver == nullptr )
378         poGDALDriver = poDriverManager->GetDriverByName(pszName);
379     if( poGDALDriver == nullptr ||
380         poGDALDriver->GetMetadataItem(GDAL_DCAP_VECTOR) == nullptr )
381         return nullptr;
382     return poGDALDriver;
383 }
384 
385 /************************************************************************/
386 /*                         OGRGetDriverByName()                         */
387 /************************************************************************/
388 
OGRGetDriverByName(const char * pszName)389 OGRSFDriverH OGRGetDriverByName( const char *pszName )
390 
391 {
392     VALIDATE_POINTER1( pszName, "OGRGetDriverByName", nullptr );
393 
394     return reinterpret_cast<OGRSFDriverH>(
395         OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName( pszName ));
396 }
397 //! @endcond
398