/src/gdal/ogr/ogrsf_frmts/generic/ogrsfdriver.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: OpenGIS Simple Features Reference Implementation |
4 | | * Purpose: The generic portions of the OGRSFDriver class. |
5 | | * Author: Frank Warmerdam, warmerdam@pobox.com |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 1999, Les Technologies SoftMap Inc. |
9 | | * Copyright (c) 2009-2011, 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 "ogr_p.h" |
17 | | #include "ograpispy.h" |
18 | | |
19 | | //! @cond Doxygen_Suppress |
20 | | |
21 | | /************************************************************************/ |
22 | | /* ~OGRSFDriver() */ |
23 | | /************************************************************************/ |
24 | | |
25 | | OGRSFDriver::~OGRSFDriver() |
26 | | |
27 | 0 | { |
28 | 0 | } |
29 | | |
30 | | /************************************************************************/ |
31 | | /* CreateDataSource() */ |
32 | | /************************************************************************/ |
33 | | |
34 | | OGRDataSource *OGRSFDriver::CreateDataSource(const char *, char **) |
35 | | |
36 | 0 | { |
37 | 0 | CPLError(CE_Failure, CPLE_NotSupported, |
38 | 0 | "CreateDataSource() not supported by this driver.\n"); |
39 | |
|
40 | 0 | return nullptr; |
41 | 0 | } |
42 | | |
43 | | //! @endcond |
44 | | |
45 | | /************************************************************************/ |
46 | | /* OGR_Dr_CreateDataSource() */ |
47 | | /************************************************************************/ |
48 | | |
49 | | /** |
50 | | \brief This function attempts to create a new data source based on the passed driver. |
51 | | |
52 | | The papszOptions argument can be used to control driver specific |
53 | | creation options. These options are normally documented in the format |
54 | | specific documentation. |
55 | | |
56 | | It is important to call OGR_DS_Destroy() when the datasource is no longer |
57 | | used to ensure that all data has been properly flushed to disk. |
58 | | |
59 | | @deprecated Use GDALCreate() |
60 | | |
61 | | @param hDriver handle to the driver on which data source creation is |
62 | | based. |
63 | | @param pszName the name for the new data source. UTF-8 encoded. |
64 | | @param papszOptions a StringList of name=value options. Options are driver |
65 | | specific. |
66 | | |
67 | | @return NULL is returned on failure, or a new OGRDataSource handle on |
68 | | success. |
69 | | */ |
70 | | |
71 | | OGRDataSourceH OGR_Dr_CreateDataSource(OGRSFDriverH hDriver, |
72 | | const char *pszName, char **papszOptions) |
73 | | |
74 | 0 | { |
75 | 0 | VALIDATE_POINTER1(hDriver, "OGR_Dr_CreateDataSource", nullptr); |
76 | | |
77 | 0 | GDALDriver *poDriver = reinterpret_cast<GDALDriver *>(hDriver); |
78 | | |
79 | | /* MapServer had the bad habit of calling with NULL name for a memory |
80 | | * datasource */ |
81 | 0 | if (pszName == nullptr) |
82 | 0 | pszName = ""; |
83 | |
|
84 | 0 | OGRDataSourceH hDS = reinterpret_cast<OGRDataSourceH>( |
85 | 0 | poDriver->Create(pszName, 0, 0, 0, GDT_Unknown, papszOptions)); |
86 | |
|
87 | 0 | #ifdef OGRAPISPY_ENABLED |
88 | 0 | OGRAPISpyCreateDataSource(hDriver, pszName, papszOptions, |
89 | 0 | reinterpret_cast<OGRDataSourceH>(hDS)); |
90 | 0 | #endif |
91 | |
|
92 | 0 | return hDS; |
93 | 0 | } |
94 | | |
95 | | /************************************************************************/ |
96 | | /* DeleteDataSource() */ |
97 | | /************************************************************************/ |
98 | | |
99 | | //! @cond Doxygen_Suppress |
100 | | |
101 | | OGRErr OGRSFDriver::DeleteDataSource(const char *pszDataSource) |
102 | | |
103 | 0 | { |
104 | 0 | (void)pszDataSource; |
105 | 0 | CPLError(CE_Failure, CPLE_NotSupported, |
106 | 0 | "DeleteDataSource() not supported by this driver."); |
107 | |
|
108 | 0 | return OGRERR_UNSUPPORTED_OPERATION; |
109 | 0 | } |
110 | | |
111 | | //! @endcond |
112 | | |
113 | | /************************************************************************/ |
114 | | /* OGR_Dr_DeleteDataSource() */ |
115 | | /************************************************************************/ |
116 | | |
117 | | /** |
118 | | \brief Delete a datasource. |
119 | | |
120 | | Delete (from the disk, in the database, ...) the named datasource. |
121 | | Normally it would be safest if the datasource was not open at the time. |
122 | | |
123 | | Whether this is a supported operation on this driver case be tested |
124 | | using TestCapability() on ODrCDeleteDataSource. |
125 | | |
126 | | @deprecated Use GDALDeleteDataset() |
127 | | |
128 | | @param hDriver handle to the driver on which data source deletion is |
129 | | based. |
130 | | |
131 | | @param pszDataSource the name of the datasource to delete. |
132 | | |
133 | | @return OGRERR_NONE on success, and OGRERR_UNSUPPORTED_OPERATION if this |
134 | | is not supported by this driver. |
135 | | */ |
136 | | |
137 | | OGRErr OGR_Dr_DeleteDataSource(OGRSFDriverH hDriver, const char *pszDataSource) |
138 | | |
139 | 0 | { |
140 | 0 | VALIDATE_POINTER1(hDriver, "OGR_Dr_DeleteDataSource", |
141 | 0 | OGRERR_INVALID_HANDLE); |
142 | | |
143 | 0 | #ifdef OGRAPISPY_ENABLED |
144 | 0 | OGRAPISpyDeleteDataSource(hDriver, pszDataSource); |
145 | 0 | #endif |
146 | |
|
147 | 0 | CPLErr eErr = |
148 | 0 | reinterpret_cast<GDALDriver *>(hDriver)->Delete(pszDataSource); |
149 | 0 | if (eErr == CE_None) |
150 | 0 | return OGRERR_NONE; |
151 | 0 | else |
152 | 0 | return OGRERR_FAILURE; |
153 | 0 | } |
154 | | |
155 | | /************************************************************************/ |
156 | | /* OGR_Dr_GetName() */ |
157 | | /************************************************************************/ |
158 | | |
159 | | /** |
160 | | \brief Fetch name of driver (file format). |
161 | | |
162 | | This name should be relatively short |
163 | | (10-40 characters), and should reflect the underlying file format. For |
164 | | instance "ESRI Shapefile". |
165 | | |
166 | | This function is the same as the C++ method OGRSFDriver::GetName(). |
167 | | |
168 | | @param hDriver handle to the driver to get the name from. |
169 | | @return driver name. This is an internal string and should not be modified |
170 | | or freed. |
171 | | */ |
172 | | |
173 | | const char *OGR_Dr_GetName(OGRSFDriverH hDriver) |
174 | | |
175 | 0 | { |
176 | 0 | VALIDATE_POINTER1(hDriver, "OGR_Dr_GetName", nullptr); |
177 | | |
178 | 0 | return reinterpret_cast<GDALDriver *>(hDriver)->GetDescription(); |
179 | 0 | } |
180 | | |
181 | | /************************************************************************/ |
182 | | /* OGR_Dr_Open() */ |
183 | | /************************************************************************/ |
184 | | |
185 | | /** |
186 | | \brief Attempt to open file with this driver. |
187 | | |
188 | | NOTE: It is *NOT* safe to cast the returned handle to |
189 | | OGRDataSource*. If a C++ object is needed, the handle should be cast to GDALDataset*. |
190 | | Similarly, the returned OGRSFDriverH handle should be cast to GDALDriver*, and |
191 | | *NOT* OGRSFDriver*. |
192 | | |
193 | | @deprecated Use GDALOpenEx() |
194 | | |
195 | | @param hDriver handle to the driver that is used to open file. |
196 | | @param pszName the name of the file, or data source to try and open. |
197 | | @param bUpdate TRUE if update access is required, otherwise FALSE (the |
198 | | default). |
199 | | |
200 | | @return NULL on error or if the pass name is not supported by this driver, |
201 | | otherwise a handle to a GDALDataset. This GDALDataset should be |
202 | | closed by deleting the object when it is no longer needed. |
203 | | */ |
204 | | |
205 | | OGRDataSourceH OGR_Dr_Open(OGRSFDriverH hDriver, const char *pszName, |
206 | | int bUpdate) |
207 | | |
208 | 0 | { |
209 | 0 | VALIDATE_POINTER1(hDriver, "OGR_Dr_Open", nullptr); |
210 | | |
211 | 0 | const char *const apszDrivers[] = { |
212 | 0 | reinterpret_cast<GDALDriver *>(hDriver)->GetDescription(), nullptr}; |
213 | |
|
214 | 0 | #ifdef OGRAPISPY_ENABLED |
215 | 0 | int iSnapshot = OGRAPISpyOpenTakeSnapshot(pszName, bUpdate); |
216 | 0 | #endif |
217 | |
|
218 | 0 | GDALDatasetH hDS = |
219 | 0 | GDALOpenEx(pszName, GDAL_OF_VECTOR | ((bUpdate) ? GDAL_OF_UPDATE : 0), |
220 | 0 | apszDrivers, nullptr, nullptr); |
221 | |
|
222 | 0 | #ifdef OGRAPISPY_ENABLED |
223 | 0 | OGRAPISpyOpen(pszName, bUpdate, iSnapshot, &hDS); |
224 | 0 | #endif |
225 | |
|
226 | 0 | return reinterpret_cast<OGRDataSourceH>(hDS); |
227 | 0 | } |
228 | | |
229 | | /************************************************************************/ |
230 | | /* OGR_Dr_TestCapability() */ |
231 | | /************************************************************************/ |
232 | | |
233 | | /** |
234 | | \brief Test if capability is available. |
235 | | |
236 | | One of the following data source capability names can be passed into this |
237 | | function, and a TRUE or FALSE value will be returned indicating whether |
238 | | or not the capability is available for this object. |
239 | | |
240 | | <ul> |
241 | | <li> <b>ODrCCreateDataSource</b>: True if this driver can support creating data sources.<p> |
242 | | <li> <b>ODrCDeleteDataSource</b>: True if this driver supports deleting data sources.<p> |
243 | | </ul> |
244 | | |
245 | | The \#define macro forms of the capability names should be used in preference |
246 | | to the strings themselves to avoid misspelling. |
247 | | |
248 | | @deprecated Use GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE) |
249 | | |
250 | | @param hDriver handle to the driver to test the capability against. |
251 | | @param pszCap the capability to test. |
252 | | |
253 | | @return TRUE if capability available otherwise FALSE. |
254 | | |
255 | | */ |
256 | | |
257 | | int OGR_Dr_TestCapability(OGRSFDriverH hDriver, const char *pszCap) |
258 | | |
259 | 0 | { |
260 | 0 | VALIDATE_POINTER1(hDriver, "OGR_Dr_TestCapability", 0); |
261 | 0 | VALIDATE_POINTER1(pszCap, "OGR_Dr_TestCapability", 0); |
262 | | |
263 | 0 | GDALDriver *poDriver = reinterpret_cast<GDALDriver *>(hDriver); |
264 | 0 | if (EQUAL(pszCap, ODrCCreateDataSource)) |
265 | 0 | { |
266 | 0 | return poDriver->GetMetadataItem(GDAL_DCAP_CREATE) || |
267 | 0 | poDriver->pfnCreate != nullptr || |
268 | 0 | poDriver->pfnCreateVectorOnly != nullptr; |
269 | 0 | } |
270 | 0 | else if (EQUAL(pszCap, ODrCDeleteDataSource)) |
271 | 0 | { |
272 | 0 | return poDriver->pfnDelete != nullptr || |
273 | 0 | poDriver->pfnDeleteDataSource != nullptr; |
274 | 0 | } |
275 | 0 | else |
276 | 0 | return FALSE; |
277 | 0 | } |
278 | | |
279 | | /************************************************************************/ |
280 | | /* OGR_Dr_CopyDataSource() */ |
281 | | /************************************************************************/ |
282 | | |
283 | | /** |
284 | | \brief This function creates a new datasource by copying all the layers from the source datasource. |
285 | | |
286 | | It is important to call OGR_DS_Destroy() when the datasource is no longer |
287 | | used to ensure that all data has been properly flushed to disk. |
288 | | |
289 | | @deprecated Use GDALCreateCopy() |
290 | | |
291 | | @param hDriver handle to the driver on which data source creation is |
292 | | based. |
293 | | @param hSrcDS source datasource |
294 | | @param pszNewName the name for the new data source. |
295 | | @param papszOptions a StringList of name=value options. Options are driver |
296 | | specific. |
297 | | |
298 | | @return NULL is returned on failure, or a new OGRDataSource handle on |
299 | | success. |
300 | | */ |
301 | | |
302 | | OGRDataSourceH OGR_Dr_CopyDataSource(OGRSFDriverH hDriver, |
303 | | OGRDataSourceH hSrcDS, |
304 | | const char *pszNewName, |
305 | | char **papszOptions) |
306 | | |
307 | 0 | { |
308 | 0 | VALIDATE_POINTER1(hDriver, "OGR_Dr_CopyDataSource", nullptr); |
309 | 0 | VALIDATE_POINTER1(hSrcDS, "OGR_Dr_CopyDataSource", nullptr); |
310 | 0 | VALIDATE_POINTER1(pszNewName, "OGR_Dr_CopyDataSource", nullptr); |
311 | | |
312 | 0 | GDALDriver *poDriver = reinterpret_cast<GDALDriver *>(hDriver); |
313 | 0 | if (!poDriver->GetMetadataItem(GDAL_DCAP_CREATE)) |
314 | 0 | { |
315 | 0 | CPLError(CE_Failure, CPLE_NotSupported, |
316 | 0 | "%s driver does not support data source creation.", |
317 | 0 | poDriver->GetDescription()); |
318 | 0 | return nullptr; |
319 | 0 | } |
320 | | |
321 | 0 | GDALDataset *poSrcDS = GDALDataset::FromHandle(hSrcDS); |
322 | 0 | GDALDataset *poODS = |
323 | 0 | poDriver->Create(pszNewName, 0, 0, 0, GDT_Unknown, papszOptions); |
324 | 0 | if (poODS == nullptr) |
325 | 0 | return nullptr; |
326 | | |
327 | | /* -------------------------------------------------------------------- */ |
328 | | /* Process each data source layer. */ |
329 | | /* -------------------------------------------------------------------- */ |
330 | 0 | for (int iLayer = 0; iLayer < poSrcDS->GetLayerCount(); iLayer++) |
331 | 0 | { |
332 | 0 | OGRLayer *poLayer = poSrcDS->GetLayer(iLayer); |
333 | |
|
334 | 0 | if (poLayer == nullptr) |
335 | 0 | continue; |
336 | | |
337 | 0 | poODS->CopyLayer(poLayer, poLayer->GetLayerDefn()->GetName(), |
338 | 0 | papszOptions); |
339 | 0 | } |
340 | |
|
341 | 0 | return reinterpret_cast<OGRDataSourceH>(poODS); |
342 | 0 | } |