Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/gcore/gdalmajorobject.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL Core
4
 * Purpose:  Base class for objects with metadata, etc.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2000, Frank Warmerdam
9
 * Copyright (c) 2009-2013, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#include "cpl_port.h"
15
#include "gdal_priv.h"
16
17
#include <cstdarg>
18
#include <cstddef>
19
20
#include "cpl_error.h"
21
#include "cpl_string.h"
22
#include "gdal.h"
23
24
/************************************************************************/
25
/*                          GDALMajorObject()                           */
26
/************************************************************************/
27
28
0
GDALMajorObject::GDALMajorObject() : nFlags(GMO_VALID)
29
0
{
30
0
}
31
32
/************************************************************************/
33
/*                          ~GDALMajorObject()                          */
34
/************************************************************************/
35
36
GDALMajorObject::~GDALMajorObject()
37
38
0
{
39
0
    if ((nFlags & GMO_VALID) == 0)
40
0
        CPLDebug("GDAL", "In ~GDALMajorObject on invalid object");
41
42
0
    nFlags &= ~GMO_VALID;
43
0
}
44
45
/************************************************************************/
46
/*                           GetDescription()                           */
47
/************************************************************************/
48
49
/**
50
 * \brief Fetch object description.
51
 *
52
 * The semantics of the returned description are specific to the derived
53
 * type.  For GDALDatasets it is the dataset name.  For GDALRasterBands
54
 * it is actually a description (if supported) or "".
55
 *
56
 * This method is the same as the C function GDALGetDescription().
57
 *
58
 * @return non-null pointer to internal description string.
59
 */
60
61
const char *GDALMajorObject::GetDescription() const
62
63
0
{
64
0
    return sDescription.c_str();
65
0
}
66
67
/************************************************************************/
68
/*                         GDALGetDescription()                         */
69
/************************************************************************/
70
71
/**
72
 * \brief Fetch object description.
73
 *
74
 * @see GDALMajorObject::GetDescription()
75
 */
76
77
const char *CPL_STDCALL GDALGetDescription(GDALMajorObjectH hObject)
78
79
0
{
80
0
    VALIDATE_POINTER1(hObject, "GDALGetDescription", nullptr);
81
82
0
    return GDALMajorObject::FromHandle(hObject)->GetDescription();
83
0
}
84
85
/************************************************************************/
86
/*                           SetDescription()                           */
87
/************************************************************************/
88
89
/**
90
 * \brief Set object description.
91
 *
92
 * The semantics of the description are specific to the derived
93
 * type.  For GDALDatasets it is the dataset name.  For GDALRasterBands
94
 * it is actually a description (if supported) or "".
95
 *
96
 * Normally application code should not set the "description" for
97
 * GDALDatasets.  It is handled internally.
98
 *
99
 * This method is the same as the C function GDALSetDescription().
100
 */
101
102
void GDALMajorObject::SetDescription(const char *pszNewDesc)
103
104
0
{
105
0
    sDescription = pszNewDesc;
106
0
}
107
108
/************************************************************************/
109
/*                         GDALSetDescription()                         */
110
/************************************************************************/
111
112
/**
113
 * \brief Set object description.
114
 *
115
 * @see GDALMajorObject::SetDescription()
116
 */
117
118
void CPL_STDCALL GDALSetDescription(GDALMajorObjectH hObject,
119
                                    const char *pszNewDesc)
120
121
0
{
122
0
    VALIDATE_POINTER0(hObject, "GDALSetDescription");
123
124
0
    GDALMajorObject::FromHandle(hObject)->SetDescription(pszNewDesc);
125
0
}
126
127
/************************************************************************/
128
/*                      GetMetadataDomainList()                         */
129
/************************************************************************/
130
131
/**
132
 * \brief Fetch list of metadata domains.
133
 *
134
 * The returned string list is the list of (non-empty) metadata domains.
135
 *
136
 * This method does the same thing as the C function
137
 * GDALGetMetadataDomainList().
138
 *
139
 * @return NULL or a string list. Must be freed with CSLDestroy()
140
 *
141
 */
142
143
char **GDALMajorObject::GetMetadataDomainList()
144
0
{
145
0
    return CSLDuplicate(oMDMD.GetDomainList());
146
0
}
147
148
/************************************************************************/
149
/*                      BuildMetadataDomainList()                       */
150
/************************************************************************/
151
152
/**
153
 * \brief Helper function for custom implementations of GetMetadataDomainList()
154
 *
155
 *
156
 * @param papszList initial list of domains. May be NULL. Will become invalid
157
 *                  after function call (use return value)
158
 * @param bCheckNonEmpty if TRUE, each candidate domain will be tested to be non
159
 *                       empty
160
 * @param ... NULL terminated variadic list of candidate domains.
161
 *
162
 * @return NULL or a string list. Must be freed with CSLDestroy()
163
 *
164
 */
165
166
char **GDALMajorObject::BuildMetadataDomainList(char **papszList,
167
                                                int bCheckNonEmpty, ...)
168
0
{
169
0
    va_list args;
170
0
    const char *pszDomain = nullptr;
171
0
    va_start(args, bCheckNonEmpty);
172
173
0
    while ((pszDomain = va_arg(args, const char *)) != nullptr)
174
0
    {
175
0
        if (CSLFindString(papszList, pszDomain) < 0 &&
176
0
            (!bCheckNonEmpty || GetMetadata(pszDomain) != nullptr))
177
0
        {
178
0
            papszList = CSLAddString(papszList, pszDomain);
179
0
        }
180
0
    }
181
182
0
    va_end(args);
183
184
0
    return papszList;
185
0
}
186
187
/************************************************************************/
188
/*                    GDALGetMetadataDomainList()                       */
189
/************************************************************************/
190
191
/**
192
 * \brief Fetch list of metadata domains.
193
 *
194
 * @see GDALMajorObject::GetMetadataDomainList()
195
 *
196
 */
197
198
char **CPL_STDCALL GDALGetMetadataDomainList(GDALMajorObjectH hObject)
199
200
0
{
201
0
    VALIDATE_POINTER1(hObject, "GetMetadataDomainList", nullptr);
202
203
0
    return GDALMajorObject::FromHandle(hObject)->GetMetadataDomainList();
204
0
}
205
206
/************************************************************************/
207
/*                            GetMetadata()                             */
208
/************************************************************************/
209
210
/**
211
 * \brief Fetch metadata.
212
 *
213
 * The returned string list is owned by the object, and may change at
214
 * any time.  It is formatted as a "Name=value" list with the last pointer
215
 * value being NULL.  Use the CPL StringList functions such as
216
 * CSLFetchNameValue() to manipulate it.
217
 *
218
 * Note that relatively few formats return any metadata at this time.
219
 *
220
 * This method does the same thing as the C function GDALGetMetadata().
221
 *
222
 * @param pszDomain the domain of interest.  Use "" or NULL for the default
223
 * domain.
224
 *
225
 * @return NULL or a string list.
226
 */
227
228
char **GDALMajorObject::GetMetadata(const char *pszDomain)
229
230
0
{
231
0
    return oMDMD.GetMetadata(pszDomain);
232
0
}
233
234
/************************************************************************/
235
/*                          GDALGetMetadata()                           */
236
/************************************************************************/
237
238
/**
239
 * \brief Fetch metadata.
240
 *
241
 * @see GDALMajorObject::GetMetadata()
242
 */
243
244
char **CPL_STDCALL GDALGetMetadata(GDALMajorObjectH hObject,
245
                                   const char *pszDomain)
246
247
0
{
248
0
    VALIDATE_POINTER1(hObject, "GDALGetMetadata", nullptr);
249
250
0
    return GDALMajorObject::FromHandle(hObject)->GetMetadata(pszDomain);
251
0
}
252
253
/************************************************************************/
254
/*                            SetMetadata()                             */
255
/************************************************************************/
256
257
/**
258
 * \brief Set metadata.
259
 *
260
 * The C function GDALSetMetadata() does the same thing as this method.
261
 *
262
 * @param papszMetadataIn the metadata in name=value string list format to
263
 * apply.
264
 * @param pszDomain the domain of interest.  Use "" or NULL for the default
265
 * domain.
266
 * @return CE_None on success, CE_Failure on failure and CE_Warning if the
267
 * metadata has been accepted, but is likely not maintained persistently
268
 * by the underlying object between sessions.
269
 */
270
271
CPLErr GDALMajorObject::SetMetadata(char **papszMetadataIn,
272
                                    const char *pszDomain)
273
274
0
{
275
0
    nFlags |= GMO_MD_DIRTY;
276
0
    return oMDMD.SetMetadata(papszMetadataIn, pszDomain);
277
0
}
278
279
/************************************************************************/
280
/*                          GDALSetMetadata()                           */
281
/************************************************************************/
282
283
/**
284
 * \brief Set metadata.
285
 *
286
 * CAUTION: when using this function on a GDALDatasetH or GDALRasterBandH,
287
 * depending on the format, older values of the updated information might
288
 * still be found in the file in a "ghost" state, even if no longer accessible
289
 * through the GDAL API. This is for example the case of the GTiff format (this
290
 * is not a exhaustive list)
291
 *
292
 * @see GDALMajorObject::SetMetadata(), GDALDataset::SetMetadata(),
293
 *      GDALRasterBand::SetMetadata()
294
 */
295
296
CPLErr CPL_STDCALL GDALSetMetadata(GDALMajorObjectH hObject,
297
                                   CSLConstList papszMD, const char *pszDomain)
298
299
0
{
300
0
    VALIDATE_POINTER1(hObject, "GDALSetMetadata", CE_Failure);
301
302
0
    return GDALMajorObject::FromHandle(hObject)->SetMetadata(
303
0
        const_cast<char **>(papszMD), pszDomain);
304
0
}
305
306
/************************************************************************/
307
/*                          GetMetadataItem()                           */
308
/************************************************************************/
309
310
/**
311
 * \brief Fetch single metadata item.
312
 *
313
 * The C function GDALGetMetadataItem() does the same thing as this method.
314
 *
315
 * @param pszName the key for the metadata item to fetch.
316
 * @param pszDomain the domain to fetch for, use NULL for the default domain.
317
 *
318
 * @return NULL on failure to find the key, or a pointer to an internal
319
 * copy of the value string on success.
320
 */
321
322
const char *GDALMajorObject::GetMetadataItem(const char *pszName,
323
                                             const char *pszDomain)
324
325
0
{
326
0
    return oMDMD.GetMetadataItem(pszName, pszDomain);
327
0
}
328
329
/************************************************************************/
330
/*                        GDALGetMetadataItem()                         */
331
/************************************************************************/
332
333
/**
334
 * \brief Fetch single metadata item.
335
 *
336
 * @see GDALMajorObject::GetMetadataItem()
337
 */
338
339
const char *CPL_STDCALL GDALGetMetadataItem(GDALMajorObjectH hObject,
340
                                            const char *pszName,
341
                                            const char *pszDomain)
342
343
0
{
344
0
    VALIDATE_POINTER1(hObject, "GDALGetMetadataItem", nullptr);
345
346
0
    return GDALMajorObject::FromHandle(hObject)->GetMetadataItem(pszName,
347
0
                                                                 pszDomain);
348
0
}
349
350
/************************************************************************/
351
/*                          SetMetadataItem()                           */
352
/************************************************************************/
353
354
/**
355
 * \brief Set single metadata item.
356
 *
357
 * The C function GDALSetMetadataItem() does the same thing as this method.
358
 *
359
 * @param pszName the key for the metadata item to fetch.
360
 * @param pszValue the value to assign to the key.
361
 * @param pszDomain the domain to set within, use NULL for the default domain.
362
 *
363
 * @return CE_None on success, or an error code on failure.
364
 */
365
366
CPLErr GDALMajorObject::SetMetadataItem(const char *pszName,
367
                                        const char *pszValue,
368
                                        const char *pszDomain)
369
370
0
{
371
0
    nFlags |= GMO_MD_DIRTY;
372
0
    return oMDMD.SetMetadataItem(pszName, pszValue, pszDomain);
373
0
}
374
375
/************************************************************************/
376
/*                        GDALSetMetadataItem()                         */
377
/************************************************************************/
378
379
/**
380
 * \brief Set single metadata item.
381
 *
382
 * CAUTION: when using this function on a GDALDatasetH or GDALRasterBandH,
383
 * depending on the format, older values of the updated information might
384
 * still be found in the file in a "ghost" state, even if no longer accessible
385
 * through the GDAL API. This is for example the case of the GTiff format (this
386
 * is not a exhaustive list)
387
 *
388
 * @see GDALMajorObject::SetMetadataItem(), GDALDataset::SetMetadataItem(),
389
 *      GDALRasterBand::SetMetadataItem()
390
 */
391
392
CPLErr CPL_STDCALL GDALSetMetadataItem(GDALMajorObjectH hObject,
393
                                       const char *pszName,
394
                                       const char *pszValue,
395
                                       const char *pszDomain)
396
397
0
{
398
0
    VALIDATE_POINTER1(hObject, "GDALSetMetadataItem", CE_Failure);
399
400
0
    return GDALMajorObject::FromHandle(hObject)->SetMetadataItem(
401
0
        pszName, pszValue, pszDomain);
402
0
}
403
404
/************************************************************************/
405
/*                             GetMOFlags()                             */
406
/************************************************************************/
407
408
/** Returns the GMO_ flags.
409
 * @return flags
410
 */
411
int GDALMajorObject::GetMOFlags() const
412
413
0
{
414
0
    return nFlags;
415
0
}
416
417
/************************************************************************/
418
/*                             SetMOFlags()                             */
419
/************************************************************************/
420
421
/** Assign GMO_flags.
422
 * @param nNewFlags new flags.
423
 */
424
void GDALMajorObject::SetMOFlags(int nNewFlags)
425
426
0
{
427
0
    nFlags = nNewFlags;
428
0
}