Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}