Line data Source code
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 2477890 : GDALMajorObject::GDALMajorObject() : nFlags(GMO_VALID)
29 : {
30 2477720 : }
31 :
32 : /************************************************************************/
33 : /* ~GDALMajorObject() */
34 : /************************************************************************/
35 :
36 2334670 : GDALMajorObject::~GDALMajorObject()
37 :
38 : {
39 2334670 : if ((nFlags & GMO_VALID) == 0)
40 0 : CPLDebug("GDAL", "In ~GDALMajorObject on invalid object");
41 :
42 2334670 : nFlags &= ~GMO_VALID;
43 2334670 : }
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 8164000 : const char *GDALMajorObject::GetDescription() const
62 :
63 : {
64 8164000 : return sDescription.c_str();
65 : }
66 :
67 : /************************************************************************/
68 : /* GDALGetDescription() */
69 : /************************************************************************/
70 :
71 : /**
72 : * \brief Fetch object description.
73 : *
74 : * @see GDALMajorObject::GetDescription()
75 : */
76 :
77 24306 : const char *CPL_STDCALL GDALGetDescription(GDALMajorObjectH hObject)
78 :
79 : {
80 24306 : VALIDATE_POINTER1(hObject, "GDALGetDescription", nullptr);
81 :
82 24306 : return GDALMajorObject::FromHandle(hObject)->GetDescription();
83 : }
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 589121 : void GDALMajorObject::SetDescription(const char *pszNewDesc)
103 :
104 : {
105 589121 : sDescription = pszNewDesc;
106 588932 : }
107 :
108 : /************************************************************************/
109 : /* GDALSetDescription() */
110 : /************************************************************************/
111 :
112 : /**
113 : * \brief Set object description.
114 : *
115 : * @see GDALMajorObject::SetDescription()
116 : */
117 :
118 76 : void CPL_STDCALL GDALSetDescription(GDALMajorObjectH hObject,
119 : const char *pszNewDesc)
120 :
121 : {
122 76 : VALIDATE_POINTER0(hObject, "GDALSetDescription");
123 :
124 76 : GDALMajorObject::FromHandle(hObject)->SetDescription(pszNewDesc);
125 : }
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 1357 : char **GDALMajorObject::GetMetadataDomainList()
144 : {
145 1357 : return CSLDuplicate(oMDMD.GetDomainList());
146 : }
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 124 : char **GDALMajorObject::BuildMetadataDomainList(char **papszList,
167 : int bCheckNonEmpty, ...)
168 : {
169 : va_list args;
170 124 : const char *pszDomain = nullptr;
171 124 : va_start(args, bCheckNonEmpty);
172 :
173 505 : while ((pszDomain = va_arg(args, const char *)) != nullptr)
174 : {
175 702 : if (CSLFindString(papszList, pszDomain) < 0 &&
176 321 : (!bCheckNonEmpty || GetMetadata(pszDomain) != nullptr))
177 : {
178 17 : papszList = CSLAddString(papszList, pszDomain);
179 : }
180 : }
181 :
182 124 : va_end(args);
183 :
184 124 : return papszList;
185 : }
186 :
187 : /************************************************************************/
188 : /* GDALGetMetadataDomainList() */
189 : /************************************************************************/
190 :
191 : /**
192 : * \brief Fetch list of metadata domains.
193 : *
194 : * @see GDALMajorObject::GetMetadataDomainList()
195 : *
196 : */
197 :
198 192 : char **CPL_STDCALL GDALGetMetadataDomainList(GDALMajorObjectH hObject)
199 :
200 : {
201 192 : VALIDATE_POINTER1(hObject, "GetMetadataDomainList", nullptr);
202 :
203 192 : return GDALMajorObject::FromHandle(hObject)->GetMetadataDomainList();
204 : }
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 240003 : char **GDALMajorObject::GetMetadata(const char *pszDomain)
229 :
230 : {
231 240003 : return oMDMD.GetMetadata(pszDomain);
232 : }
233 :
234 : /************************************************************************/
235 : /* GDALGetMetadata() */
236 : /************************************************************************/
237 :
238 : /**
239 : * \brief Fetch metadata.
240 : *
241 : * @see GDALMajorObject::GetMetadata()
242 : */
243 :
244 19355 : char **CPL_STDCALL GDALGetMetadata(GDALMajorObjectH hObject,
245 : const char *pszDomain)
246 :
247 : {
248 19355 : VALIDATE_POINTER1(hObject, "GDALGetMetadata", nullptr);
249 :
250 19355 : return GDALMajorObject::FromHandle(hObject)->GetMetadata(pszDomain);
251 : }
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 84588 : CPLErr GDALMajorObject::SetMetadata(char **papszMetadataIn,
272 : const char *pszDomain)
273 :
274 : {
275 84588 : nFlags |= GMO_MD_DIRTY;
276 84588 : return oMDMD.SetMetadata(papszMetadataIn, pszDomain);
277 : }
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 1019 : CPLErr CPL_STDCALL GDALSetMetadata(GDALMajorObjectH hObject,
297 : CSLConstList papszMD, const char *pszDomain)
298 :
299 : {
300 1019 : VALIDATE_POINTER1(hObject, "GDALSetMetadata", CE_Failure);
301 :
302 2038 : return GDALMajorObject::FromHandle(hObject)->SetMetadata(
303 1019 : const_cast<char **>(papszMD), pszDomain);
304 : }
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 13066000 : const char *GDALMajorObject::GetMetadataItem(const char *pszName,
323 : const char *pszDomain)
324 :
325 : {
326 13066000 : return oMDMD.GetMetadataItem(pszName, pszDomain);
327 : }
328 :
329 : /************************************************************************/
330 : /* GDALGetMetadataItem() */
331 : /************************************************************************/
332 :
333 : /**
334 : * \brief Fetch single metadata item.
335 : *
336 : * @see GDALMajorObject::GetMetadataItem()
337 : */
338 :
339 264188 : const char *CPL_STDCALL GDALGetMetadataItem(GDALMajorObjectH hObject,
340 : const char *pszName,
341 : const char *pszDomain)
342 :
343 : {
344 264188 : VALIDATE_POINTER1(hObject, "GDALGetMetadataItem", nullptr);
345 :
346 528376 : return GDALMajorObject::FromHandle(hObject)->GetMetadataItem(pszName,
347 264188 : pszDomain);
348 : }
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 4939600 : CPLErr GDALMajorObject::SetMetadataItem(const char *pszName,
367 : const char *pszValue,
368 : const char *pszDomain)
369 :
370 : {
371 4939600 : nFlags |= GMO_MD_DIRTY;
372 4939600 : return oMDMD.SetMetadataItem(pszName, pszValue, pszDomain);
373 : }
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 937 : CPLErr CPL_STDCALL GDALSetMetadataItem(GDALMajorObjectH hObject,
393 : const char *pszName,
394 : const char *pszValue,
395 : const char *pszDomain)
396 :
397 : {
398 937 : VALIDATE_POINTER1(hObject, "GDALSetMetadataItem", CE_Failure);
399 :
400 1874 : return GDALMajorObject::FromHandle(hObject)->SetMetadataItem(
401 937 : pszName, pszValue, pszDomain);
402 : }
403 :
404 : /************************************************************************/
405 : /* GetMOFlags() */
406 : /************************************************************************/
407 :
408 : /** Returns the GMO_ flags.
409 : * @return flags
410 : */
411 3403540 : int GDALMajorObject::GetMOFlags() const
412 :
413 : {
414 3403540 : return nFlags;
415 : }
416 :
417 : /************************************************************************/
418 : /* SetMOFlags() */
419 : /************************************************************************/
420 :
421 : /** Assign GMO_flags.
422 : * @param nNewFlags new flags.
423 : */
424 1556480 : void GDALMajorObject::SetMOFlags(int nNewFlags)
425 :
426 : {
427 1556480 : nFlags = nNewFlags;
428 1556480 : }
|