Line data Source code
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 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "ogrsf_frmts.h"
15 : #include "ogr_api.h"
16 : #include "ograpispy.h"
17 :
18 : /************************************************************************/
19 : /* OGRSFDriverRegistrar */
20 : /************************************************************************/
21 :
22 : /**
23 : * \brief Constructor
24 : *
25 : * Normally the driver registrar is constructed by the
26 : * OGRSFDriverRegistrar::GetRegistrar() accessor which ensures singleton
27 : * status.
28 : */
29 :
30 307 : OGRSFDriverRegistrar::OGRSFDriverRegistrar()
31 : {
32 307 : }
33 :
34 : /************************************************************************/
35 : /* ~OGRSFDriverRegistrar() */
36 : /************************************************************************/
37 :
38 307 : OGRSFDriverRegistrar::~OGRSFDriverRegistrar()
39 : {
40 307 : }
41 :
42 : //! @cond Doxygen_Suppress
43 : /************************************************************************/
44 : /* GetRegistrar() */
45 : /************************************************************************/
46 :
47 3113 : OGRSFDriverRegistrar *OGRSFDriverRegistrar::GetRegistrar()
48 : {
49 3113 : static OGRSFDriverRegistrar oSingleton;
50 3113 : return &oSingleton;
51 : }
52 :
53 : //! @endcond
54 :
55 : /************************************************************************/
56 : /* OGRCleanupAll() */
57 : /************************************************************************/
58 :
59 : /**
60 : * \brief Cleanup all OGR related resources.
61 : *
62 : * \see GDALDestroy()
63 : * \deprecated Use GDALDestroy() instead
64 : */
65 783 : void OGRCleanupAll()
66 :
67 : {
68 783 : GDALDestroyDriverManager();
69 783 : }
70 :
71 : /************************************************************************/
72 : /* OGROpen() */
73 : /************************************************************************/
74 :
75 : /**
76 : \brief Open a file / data source with one of the registered drivers.
77 :
78 : This function loops through all the drivers registered with the driver
79 : manager trying each until one succeeds with the given data source.
80 :
81 : If this function fails, CPLGetLastErrorMsg() can be used to check if there
82 : is an error message explaining why.
83 :
84 : For drivers supporting the VSI virtual file API, it is possible to open
85 : a file in a .zip archive (see VSIInstallZipFileHandler()), in a .tar/.tar.gz/.tgz archive
86 : (see VSIInstallTarFileHandler()) or on a HTTP / FTP server (see VSIInstallCurlFileHandler())
87 :
88 : NOTE: It is *NOT* safe to cast the returned handle to
89 : OGRDataSource*. If a C++ object is needed, the handle should be cast to GDALDataset*.
90 : Similarly, the returned OGRSFDriverH handle should be cast to GDALDriver*, and
91 : *NOT* OGRSFDriver*.
92 :
93 : @deprecated Use GDALOpenEx()
94 :
95 : @param pszName the name of the file, or data source to open.
96 : @param bUpdate FALSE for read-only access (the default) or TRUE for
97 : read-write access.
98 : @param pahDriverList if non-NULL, this argument will be updated with a
99 : pointer to the driver which was used to open the data source.
100 :
101 : @return NULL on error or if the pass name is not supported by this driver,
102 : otherwise a handle to a GDALDataset. This GDALDataset should be
103 : closed by deleting the object when it is no longer needed.
104 :
105 : Example:
106 :
107 : \code{.cpp}
108 : OGRDataSourceH hDS;
109 : OGRSFDriverH *pahDriver;
110 :
111 : hDS = OGROpen( "polygon.shp", 0, pahDriver );
112 : if( hDS == NULL )
113 : {
114 : return;
115 : }
116 :
117 : ... use the data source ...
118 :
119 : OGRReleaseDataSource( hDS );
120 : \endcode
121 :
122 : */
123 :
124 178 : OGRDataSourceH OGROpen(const char *pszName, int bUpdate,
125 : OGRSFDriverH *pahDriverList)
126 :
127 : {
128 178 : VALIDATE_POINTER1(pszName, "OGROpen", nullptr);
129 :
130 : GDALDatasetH hDS =
131 178 : GDALOpenEx(pszName, GDAL_OF_VECTOR | ((bUpdate) ? GDAL_OF_UPDATE : 0),
132 : nullptr, nullptr, nullptr);
133 178 : if (hDS != nullptr && pahDriverList != nullptr)
134 0 : *pahDriverList =
135 0 : reinterpret_cast<OGRSFDriverH>(GDALGetDatasetDriver(hDS));
136 :
137 178 : return reinterpret_cast<OGRDataSourceH>(hDS);
138 : }
139 :
140 : /************************************************************************/
141 : /* OGROpenShared() */
142 : /************************************************************************/
143 :
144 : /**
145 : \brief Open a file / data source with one of the registered drivers if not
146 : already opened, or increment reference count of already opened data source
147 : previously opened with OGROpenShared()
148 :
149 : This function loops through all the drivers registered with the driver
150 : manager trying each until one succeeds with the given data source.
151 :
152 : If this function fails, CPLGetLastErrorMsg() can be used to check if there
153 : is an error message explaining why.
154 :
155 : NOTE: It is *NOT* safe to cast the returned handle to
156 : OGRDataSource*. If a C++ object is needed, the handle should be cast to GDALDataset*.
157 : Similarly, the returned OGRSFDriverH handle should be cast to GDALDriver*, and
158 : *NOT* OGRSFDriver*.
159 :
160 : @deprecated Use GDALOpenEx()
161 :
162 : @param pszName the name of the file, or data source to open.
163 : @param bUpdate FALSE for read-only access (the default) or TRUE for
164 : read-write access.
165 : @param pahDriverList if non-NULL, this argument will be updated with a
166 : pointer to the driver which was used to open the data source.
167 :
168 : @return NULL on error or if the pass name is not supported by this driver,
169 : otherwise a handle to a GDALDataset. This GDALDataset should be
170 : closed by deleting the object when it is no longer needed.
171 :
172 : Example:
173 :
174 : \code{.cpp}
175 : OGRDataSourceH hDS;
176 : OGRSFDriverH *pahDriver;
177 :
178 : hDS = OGROpenShared( "polygon.shp", 0, pahDriver );
179 : if( hDS == NULL )
180 : {
181 : return;
182 : }
183 :
184 : ... use the data source ...
185 :
186 : OGRReleaseDataSource( hDS );
187 : \endcode
188 :
189 : */
190 21 : OGRDataSourceH OGROpenShared(const char *pszName, int bUpdate,
191 : OGRSFDriverH *pahDriverList)
192 :
193 : {
194 21 : VALIDATE_POINTER1(pszName, "OGROpenShared", nullptr);
195 :
196 21 : GDALDatasetH hDS = GDALOpenEx(
197 : pszName,
198 : GDAL_OF_VECTOR | ((bUpdate) ? GDAL_OF_UPDATE : 0) | GDAL_OF_SHARED,
199 : nullptr, nullptr, nullptr);
200 21 : if (hDS != nullptr && pahDriverList != nullptr)
201 0 : *pahDriverList =
202 0 : reinterpret_cast<OGRSFDriverH>(GDALGetDatasetDriver(hDS));
203 21 : return reinterpret_cast<OGRDataSourceH>(hDS);
204 : }
205 :
206 : /************************************************************************/
207 : /* OGRReleaseDataSource() */
208 : /************************************************************************/
209 :
210 : /**
211 : \brief Drop a reference to this datasource, and if the reference count drops to zero close (destroy) the datasource.
212 :
213 : Internally this actually calls
214 : the OGRSFDriverRegistrar::ReleaseDataSource() method. This method is
215 : essentially a convenient alias.
216 :
217 : @deprecated Use GDALClose()
218 :
219 : @param hDS handle to the data source to release
220 :
221 : @return OGRERR_NONE on success or an error code.
222 : */
223 :
224 12 : OGRErr OGRReleaseDataSource(OGRDataSourceH hDS)
225 :
226 : {
227 12 : VALIDATE_POINTER1(hDS, "OGRReleaseDataSource", OGRERR_INVALID_HANDLE);
228 :
229 12 : GDALClose(reinterpret_cast<GDALDatasetH>(hDS));
230 :
231 12 : return OGRERR_NONE;
232 : }
233 :
234 : //! @cond Doxygen_Suppress
235 : /************************************************************************/
236 : /* GetOpenDSCount() */
237 : /************************************************************************/
238 :
239 0 : int OGRSFDriverRegistrar::GetOpenDSCount()
240 : {
241 0 : CPLError(CE_Failure, CPLE_AppDefined, "Stub implementation");
242 0 : return 0;
243 : }
244 :
245 : /************************************************************************/
246 : /* OGRGetOpenDSCount() */
247 : /************************************************************************/
248 :
249 0 : int OGRGetOpenDSCount()
250 :
251 : {
252 0 : return OGRSFDriverRegistrar::GetRegistrar()->GetOpenDSCount();
253 : }
254 :
255 : /************************************************************************/
256 : /* GetOpenDS() */
257 : /************************************************************************/
258 :
259 1 : OGRDataSource *OGRSFDriverRegistrar::GetOpenDS(CPL_UNUSED int iDS)
260 : {
261 1 : CPLError(CE_Failure, CPLE_AppDefined, "Stub implementation");
262 1 : return nullptr;
263 : }
264 :
265 : /************************************************************************/
266 : /* OGRGetOpenDS() */
267 : /************************************************************************/
268 :
269 1 : OGRDataSourceH OGRGetOpenDS(int iDS)
270 :
271 : {
272 : return reinterpret_cast<OGRDataSourceH>(
273 1 : OGRSFDriverRegistrar::GetRegistrar()->GetOpenDS(iDS));
274 : }
275 :
276 : /************************************************************************/
277 : /* OpenWithDriverArg() */
278 : /************************************************************************/
279 :
280 0 : GDALDataset *OGRSFDriverRegistrar::OpenWithDriverArg(GDALDriver *poDriver,
281 : GDALOpenInfo *poOpenInfo)
282 : {
283 0 : OGRDataSource *poDS = reinterpret_cast<OGRDataSource *>(
284 : reinterpret_cast<OGRSFDriver *>(poDriver)->Open(
285 0 : poOpenInfo->pszFilename, poOpenInfo->eAccess == GA_Update));
286 0 : if (poDS != nullptr)
287 0 : poDS->SetDescription(poDS->GetName());
288 0 : return poDS;
289 : }
290 :
291 : /************************************************************************/
292 : /* CreateVectorOnly() */
293 : /************************************************************************/
294 :
295 0 : GDALDataset *OGRSFDriverRegistrar::CreateVectorOnly(GDALDriver *poDriver,
296 : const char *pszName,
297 : char **papszOptions)
298 : {
299 0 : OGRDataSource *poDS = reinterpret_cast<OGRDataSource *>(
300 : reinterpret_cast<OGRSFDriver *>(poDriver)->CreateDataSource(
301 0 : pszName, papszOptions));
302 0 : if (poDS != nullptr && poDS->GetName() != nullptr)
303 0 : poDS->SetDescription(poDS->GetName());
304 0 : return poDS;
305 : }
306 :
307 : /************************************************************************/
308 : /* DeleteDataSource() */
309 : /************************************************************************/
310 :
311 0 : CPLErr OGRSFDriverRegistrar::DeleteDataSource(GDALDriver *poDriver,
312 : const char *pszName)
313 : {
314 0 : if (reinterpret_cast<OGRSFDriver *>(poDriver)->DeleteDataSource(pszName) ==
315 : OGRERR_NONE)
316 0 : return CE_None;
317 : else
318 0 : return CE_Failure;
319 : }
320 :
321 : /************************************************************************/
322 : /* RegisterDriver() */
323 : /************************************************************************/
324 :
325 0 : void OGRSFDriverRegistrar::RegisterDriver(OGRSFDriver *poDriver)
326 :
327 : {
328 : GDALDriver *poGDALDriver =
329 0 : GDALDriver::FromHandle(GDALGetDriverByName(poDriver->GetName()));
330 0 : if (poGDALDriver == nullptr)
331 : {
332 0 : poDriver->SetDescription(poDriver->GetName());
333 0 : poDriver->SetMetadataItem("OGR_DRIVER", "YES");
334 :
335 0 : if (poDriver->GetMetadataItem(GDAL_DMD_LONGNAME) == nullptr)
336 0 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, poDriver->GetName());
337 :
338 0 : poDriver->pfnOpenWithDriverArg = OpenWithDriverArg;
339 :
340 0 : if (poDriver->TestCapability(ODrCCreateDataSource))
341 : {
342 0 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
343 0 : poDriver->pfnCreateVectorOnly = CreateVectorOnly;
344 : }
345 0 : if (poDriver->TestCapability(ODrCDeleteDataSource))
346 : {
347 0 : poDriver->pfnDeleteDataSource = DeleteDataSource;
348 : }
349 :
350 0 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
351 :
352 0 : GetGDALDriverManager()->RegisterDriver(poDriver);
353 : }
354 : else
355 : {
356 0 : if (poGDALDriver->GetMetadataItem("OGR_DRIVER") == nullptr)
357 : {
358 0 : CPLError(CE_Failure, CPLE_AppDefined,
359 : "A non OGR driver is registered with the same name: %s",
360 0 : poDriver->GetName());
361 : }
362 0 : delete poDriver;
363 : }
364 0 : }
365 :
366 : /************************************************************************/
367 : /* OGRRegisterDriver() */
368 : /************************************************************************/
369 :
370 0 : void OGRRegisterDriver(OGRSFDriverH hDriver)
371 :
372 : {
373 0 : VALIDATE_POINTER0(hDriver, "OGRRegisterDriver");
374 :
375 0 : GetGDALDriverManager()->RegisterDriver(GDALDriver::FromHandle(hDriver));
376 : }
377 :
378 : /************************************************************************/
379 : /* OGRDeregisterDriver() */
380 : /************************************************************************/
381 :
382 0 : void OGRDeregisterDriver(OGRSFDriverH hDriver)
383 :
384 : {
385 0 : VALIDATE_POINTER0(hDriver, "OGRDeregisterDriver");
386 :
387 0 : GetGDALDriverManager()->DeregisterDriver(GDALDriver::FromHandle(hDriver));
388 : }
389 :
390 : /************************************************************************/
391 : /* GetDriverCount() */
392 : /************************************************************************/
393 :
394 313 : int OGRSFDriverRegistrar::GetDriverCount()
395 :
396 : {
397 : /* We must be careful only to return drivers that are actual OGRSFDriver* */
398 313 : GDALDriverManager *poDriverManager = GetGDALDriverManager();
399 313 : int nTotal = poDriverManager->GetDriverCount();
400 313 : int nOGRDriverCount = 0;
401 69026 : for (int i = 0; i < nTotal; i++)
402 : {
403 68713 : GDALDriver *poDriver = poDriverManager->GetDriver(i);
404 68713 : if (poDriver->GetMetadataItem(GDAL_DCAP_VECTOR) != nullptr)
405 27104 : nOGRDriverCount++;
406 : }
407 313 : return nOGRDriverCount;
408 : }
409 :
410 : //! @endcond
411 :
412 : /************************************************************************/
413 : /* OGRGetDriverCount() */
414 : /************************************************************************/
415 :
416 : /**
417 : \brief Fetch the number of registered drivers.
418 :
419 : @deprecated Use GDALGetDriverCount()
420 :
421 : @return the drivers count.
422 :
423 : */
424 313 : int OGRGetDriverCount()
425 :
426 : {
427 313 : return OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
428 : }
429 :
430 : /************************************************************************/
431 : /* GetDriver() */
432 : /************************************************************************/
433 :
434 : //! @cond Doxygen_Suppress
435 0 : GDALDriver *OGRSFDriverRegistrar::GetDriver(int iDriver)
436 :
437 : {
438 : /* We must be careful only to return drivers that are actual OGRSFDriver* */
439 0 : GDALDriverManager *poDriverManager = GetGDALDriverManager();
440 0 : int nTotal = poDriverManager->GetDriverCount();
441 0 : int nOGRDriverCount = 0;
442 0 : for (int i = 0; i < nTotal; i++)
443 : {
444 0 : GDALDriver *poDriver = poDriverManager->GetDriver(i);
445 0 : if (poDriver->GetMetadataItem(GDAL_DCAP_VECTOR) != nullptr)
446 : {
447 0 : if (nOGRDriverCount == iDriver)
448 0 : return poDriver;
449 0 : nOGRDriverCount++;
450 : }
451 : }
452 0 : return nullptr;
453 : }
454 :
455 : //! @endcond
456 :
457 : /************************************************************************/
458 : /* OGRGetDriver() */
459 : /************************************************************************/
460 :
461 : /**
462 : \brief Fetch the indicated driver.
463 :
464 : NOTE: It is *NOT* safe to cast the returned handle to
465 : OGRSFDriver*. If a C++ object is needed, the handle should be cast to GDALDriver*.
466 :
467 : @deprecated Use GDALGetDriver()
468 :
469 : @param iDriver the driver index, from 0 to GetDriverCount()-1.
470 :
471 : @return handle to the driver, or NULL if iDriver is out of range.
472 :
473 : */
474 :
475 0 : OGRSFDriverH OGRGetDriver(int iDriver)
476 :
477 : {
478 : return reinterpret_cast<OGRSFDriverH>(
479 0 : OGRSFDriverRegistrar::GetRegistrar()->GetDriver(iDriver));
480 : }
481 :
482 : /************************************************************************/
483 : /* GetDriverByName() */
484 : /************************************************************************/
485 :
486 : //! @cond Doxygen_Suppress
487 2799 : GDALDriver *OGRSFDriverRegistrar::GetDriverByName(const char *pszName)
488 :
489 : {
490 2799 : GDALDriverManager *poDriverManager = GetGDALDriverManager();
491 : GDALDriver *poGDALDriver =
492 2799 : poDriverManager->GetDriverByName(CPLSPrintf("OGR_%s", pszName));
493 2799 : if (poGDALDriver == nullptr)
494 2797 : poGDALDriver = poDriverManager->GetDriverByName(pszName);
495 5585 : if (poGDALDriver == nullptr ||
496 2786 : poGDALDriver->GetMetadataItem(GDAL_DCAP_VECTOR) == nullptr)
497 13 : return nullptr;
498 2786 : return poGDALDriver;
499 : }
500 :
501 : //! @endcond
502 :
503 : /************************************************************************/
504 : /* OGRGetDriverByName() */
505 : /************************************************************************/
506 :
507 : /**
508 : \brief Fetch the indicated driver.
509 :
510 : NOTE: It is *NOT* safe to cast the returned handle to
511 : OGRSFDriver*. If a C++ object is needed, the handle should be cast to GDALDriver*.
512 :
513 : @deprecated Use GDALGetDriverByName()
514 :
515 : @param pszName the driver name
516 :
517 : @return the driver, or NULL if no driver with that name is found
518 : */
519 :
520 2793 : OGRSFDriverH OGRGetDriverByName(const char *pszName)
521 :
522 : {
523 2793 : VALIDATE_POINTER1(pszName, "OGRGetDriverByName", nullptr);
524 :
525 : return reinterpret_cast<OGRSFDriverH>(
526 2793 : OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszName));
527 : }
|