/src/gdal/gcore/gdalmajorobject.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | * @since GDAL 1.11 |
142 | | */ |
143 | | |
144 | | char **GDALMajorObject::GetMetadataDomainList() |
145 | 0 | { |
146 | 0 | return CSLDuplicate(oMDMD.GetDomainList()); |
147 | 0 | } |
148 | | |
149 | | /************************************************************************/ |
150 | | /* BuildMetadataDomainList() */ |
151 | | /************************************************************************/ |
152 | | |
153 | | /** |
154 | | * \brief Helper function for custom implementations of GetMetadataDomainList() |
155 | | * |
156 | | * |
157 | | * @param papszList initial list of domains. May be NULL. Will become invalid |
158 | | * after function call (use return value) |
159 | | * @param bCheckNonEmpty if TRUE, each candidate domain will be tested to be non |
160 | | * empty |
161 | | * @param ... NULL terminated variadic list of candidate domains. |
162 | | * |
163 | | * @return NULL or a string list. Must be freed with CSLDestroy() |
164 | | * |
165 | | * @since GDAL 1.11 |
166 | | */ |
167 | | |
168 | | char **GDALMajorObject::BuildMetadataDomainList(char **papszList, |
169 | | int bCheckNonEmpty, ...) |
170 | 0 | { |
171 | 0 | va_list args; |
172 | 0 | const char *pszDomain = nullptr; |
173 | 0 | va_start(args, bCheckNonEmpty); |
174 | |
|
175 | 0 | while ((pszDomain = va_arg(args, const char *)) != nullptr) |
176 | 0 | { |
177 | 0 | if (CSLFindString(papszList, pszDomain) < 0 && |
178 | 0 | (!bCheckNonEmpty || GetMetadata(pszDomain) != nullptr)) |
179 | 0 | { |
180 | 0 | papszList = CSLAddString(papszList, pszDomain); |
181 | 0 | } |
182 | 0 | } |
183 | |
|
184 | 0 | va_end(args); |
185 | |
|
186 | 0 | return papszList; |
187 | 0 | } |
188 | | |
189 | | /************************************************************************/ |
190 | | /* GDALGetMetadataDomainList() */ |
191 | | /************************************************************************/ |
192 | | |
193 | | /** |
194 | | * \brief Fetch list of metadata domains. |
195 | | * |
196 | | * @see GDALMajorObject::GetMetadataDomainList() |
197 | | * |
198 | | * @since GDAL 1.11 |
199 | | */ |
200 | | |
201 | | char **CPL_STDCALL GDALGetMetadataDomainList(GDALMajorObjectH hObject) |
202 | | |
203 | 0 | { |
204 | 0 | VALIDATE_POINTER1(hObject, "GetMetadataDomainList", nullptr); |
205 | | |
206 | 0 | return GDALMajorObject::FromHandle(hObject)->GetMetadataDomainList(); |
207 | 0 | } |
208 | | |
209 | | /************************************************************************/ |
210 | | /* GetMetadata() */ |
211 | | /************************************************************************/ |
212 | | |
213 | | /** |
214 | | * \brief Fetch metadata. |
215 | | * |
216 | | * The returned string list is owned by the object, and may change at |
217 | | * any time. It is formatted as a "Name=value" list with the last pointer |
218 | | * value being NULL. Use the CPL StringList functions such as |
219 | | * CSLFetchNameValue() to manipulate it. |
220 | | * |
221 | | * Note that relatively few formats return any metadata at this time. |
222 | | * |
223 | | * This method does the same thing as the C function GDALGetMetadata(). |
224 | | * |
225 | | * @param pszDomain the domain of interest. Use "" or NULL for the default |
226 | | * domain. |
227 | | * |
228 | | * @return NULL or a string list. |
229 | | */ |
230 | | |
231 | | char **GDALMajorObject::GetMetadata(const char *pszDomain) |
232 | | |
233 | 0 | { |
234 | 0 | return oMDMD.GetMetadata(pszDomain); |
235 | 0 | } |
236 | | |
237 | | /************************************************************************/ |
238 | | /* GDALGetMetadata() */ |
239 | | /************************************************************************/ |
240 | | |
241 | | /** |
242 | | * \brief Fetch metadata. |
243 | | * |
244 | | * @see GDALMajorObject::GetMetadata() |
245 | | */ |
246 | | |
247 | | char **CPL_STDCALL GDALGetMetadata(GDALMajorObjectH hObject, |
248 | | const char *pszDomain) |
249 | | |
250 | 0 | { |
251 | 0 | VALIDATE_POINTER1(hObject, "GDALGetMetadata", nullptr); |
252 | | |
253 | 0 | return GDALMajorObject::FromHandle(hObject)->GetMetadata(pszDomain); |
254 | 0 | } |
255 | | |
256 | | /************************************************************************/ |
257 | | /* SetMetadata() */ |
258 | | /************************************************************************/ |
259 | | |
260 | | /** |
261 | | * \brief Set metadata. |
262 | | * |
263 | | * The C function GDALSetMetadata() does the same thing as this method. |
264 | | * |
265 | | * @param papszMetadataIn the metadata in name=value string list format to |
266 | | * apply. |
267 | | * @param pszDomain the domain of interest. Use "" or NULL for the default |
268 | | * domain. |
269 | | * @return CE_None on success, CE_Failure on failure and CE_Warning if the |
270 | | * metadata has been accepted, but is likely not maintained persistently |
271 | | * by the underlying object between sessions. |
272 | | */ |
273 | | |
274 | | CPLErr GDALMajorObject::SetMetadata(char **papszMetadataIn, |
275 | | const char *pszDomain) |
276 | | |
277 | 0 | { |
278 | 0 | nFlags |= GMO_MD_DIRTY; |
279 | 0 | return oMDMD.SetMetadata(papszMetadataIn, pszDomain); |
280 | 0 | } |
281 | | |
282 | | /************************************************************************/ |
283 | | /* GDALSetMetadata() */ |
284 | | /************************************************************************/ |
285 | | |
286 | | /** |
287 | | * \brief Set metadata. |
288 | | * |
289 | | * CAUTION: when using this function on a GDALDatasetH or GDALRasterBandH, |
290 | | * depending on the format, older values of the updated information might |
291 | | * still be found in the file in a "ghost" state, even if no longer accessible |
292 | | * through the GDAL API. This is for example the case of the GTiff format (this |
293 | | * is not a exhaustive list) |
294 | | * |
295 | | * @see GDALMajorObject::SetMetadata(), GDALDataset::SetMetadata(), |
296 | | * GDALRasterBand::SetMetadata() |
297 | | */ |
298 | | |
299 | | CPLErr CPL_STDCALL GDALSetMetadata(GDALMajorObjectH hObject, |
300 | | CSLConstList papszMD, const char *pszDomain) |
301 | | |
302 | 0 | { |
303 | 0 | VALIDATE_POINTER1(hObject, "GDALSetMetadata", CE_Failure); |
304 | | |
305 | 0 | return GDALMajorObject::FromHandle(hObject)->SetMetadata( |
306 | 0 | const_cast<char **>(papszMD), pszDomain); |
307 | 0 | } |
308 | | |
309 | | /************************************************************************/ |
310 | | /* GetMetadataItem() */ |
311 | | /************************************************************************/ |
312 | | |
313 | | /** |
314 | | * \brief Fetch single metadata item. |
315 | | * |
316 | | * The C function GDALGetMetadataItem() does the same thing as this method. |
317 | | * |
318 | | * @param pszName the key for the metadata item to fetch. |
319 | | * @param pszDomain the domain to fetch for, use NULL for the default domain. |
320 | | * |
321 | | * @return NULL on failure to find the key, or a pointer to an internal |
322 | | * copy of the value string on success. |
323 | | */ |
324 | | |
325 | | const char *GDALMajorObject::GetMetadataItem(const char *pszName, |
326 | | const char *pszDomain) |
327 | | |
328 | 0 | { |
329 | 0 | return oMDMD.GetMetadataItem(pszName, pszDomain); |
330 | 0 | } |
331 | | |
332 | | /************************************************************************/ |
333 | | /* GDALGetMetadataItem() */ |
334 | | /************************************************************************/ |
335 | | |
336 | | /** |
337 | | * \brief Fetch single metadata item. |
338 | | * |
339 | | * @see GDALMajorObject::GetMetadataItem() |
340 | | */ |
341 | | |
342 | | const char *CPL_STDCALL GDALGetMetadataItem(GDALMajorObjectH hObject, |
343 | | const char *pszName, |
344 | | const char *pszDomain) |
345 | | |
346 | 0 | { |
347 | 0 | VALIDATE_POINTER1(hObject, "GDALGetMetadataItem", nullptr); |
348 | | |
349 | 0 | return GDALMajorObject::FromHandle(hObject)->GetMetadataItem(pszName, |
350 | 0 | pszDomain); |
351 | 0 | } |
352 | | |
353 | | /************************************************************************/ |
354 | | /* SetMetadataItem() */ |
355 | | /************************************************************************/ |
356 | | |
357 | | /** |
358 | | * \brief Set single metadata item. |
359 | | * |
360 | | * The C function GDALSetMetadataItem() does the same thing as this method. |
361 | | * |
362 | | * @param pszName the key for the metadata item to fetch. |
363 | | * @param pszValue the value to assign to the key. |
364 | | * @param pszDomain the domain to set within, use NULL for the default domain. |
365 | | * |
366 | | * @return CE_None on success, or an error code on failure. |
367 | | */ |
368 | | |
369 | | CPLErr GDALMajorObject::SetMetadataItem(const char *pszName, |
370 | | const char *pszValue, |
371 | | const char *pszDomain) |
372 | | |
373 | 0 | { |
374 | 0 | nFlags |= GMO_MD_DIRTY; |
375 | 0 | return oMDMD.SetMetadataItem(pszName, pszValue, pszDomain); |
376 | 0 | } |
377 | | |
378 | | /************************************************************************/ |
379 | | /* GDALSetMetadataItem() */ |
380 | | /************************************************************************/ |
381 | | |
382 | | /** |
383 | | * \brief Set single metadata item. |
384 | | * |
385 | | * CAUTION: when using this function on a GDALDatasetH or GDALRasterBandH, |
386 | | * depending on the format, older values of the updated information might |
387 | | * still be found in the file in a "ghost" state, even if no longer accessible |
388 | | * through the GDAL API. This is for example the case of the GTiff format (this |
389 | | * is not a exhaustive list) |
390 | | * |
391 | | * @see GDALMajorObject::SetMetadataItem(), GDALDataset::SetMetadataItem(), |
392 | | * GDALRasterBand::SetMetadataItem() |
393 | | */ |
394 | | |
395 | | CPLErr CPL_STDCALL GDALSetMetadataItem(GDALMajorObjectH hObject, |
396 | | const char *pszName, |
397 | | const char *pszValue, |
398 | | const char *pszDomain) |
399 | | |
400 | 0 | { |
401 | 0 | VALIDATE_POINTER1(hObject, "GDALSetMetadataItem", CE_Failure); |
402 | | |
403 | 0 | return GDALMajorObject::FromHandle(hObject)->SetMetadataItem( |
404 | 0 | pszName, pszValue, pszDomain); |
405 | 0 | } |
406 | | |
407 | | /************************************************************************/ |
408 | | /* GetMOFlags() */ |
409 | | /************************************************************************/ |
410 | | |
411 | | /** Returns the GMO_ flags. |
412 | | * @return flags |
413 | | */ |
414 | | int GDALMajorObject::GetMOFlags() const |
415 | | |
416 | 0 | { |
417 | 0 | return nFlags; |
418 | 0 | } |
419 | | |
420 | | /************************************************************************/ |
421 | | /* SetMOFlags() */ |
422 | | /************************************************************************/ |
423 | | |
424 | | /** Assign GMO_flags. |
425 | | * @param nNewFlags new flags. |
426 | | */ |
427 | | void GDALMajorObject::SetMOFlags(int nNewFlags) |
428 | | |
429 | 0 | { |
430 | 0 | nFlags = nNewFlags; |
431 | 0 | } |