/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 | } |