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 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 ****************************************************************************/
29
30 #include "cpl_port.h"
31 #include "gdal_priv.h"
32
33 #include <cstdarg>
34 #include <cstddef>
35
36 #include "cpl_error.h"
37 #include "cpl_string.h"
38 #include "gdal.h"
39
40 CPL_CVSID("$Id: gdalmajorobject.cpp b1c9c12ad373e40b955162b45d704070d4ebf7b0 2019-06-19 16:50:15 +0200 Even Rouault $")
41
42 /************************************************************************/
43 /* GDALMajorObject() */
44 /************************************************************************/
45
GDALMajorObject()46 GDALMajorObject::GDALMajorObject() :
47 nFlags(GMO_VALID)
48 {}
49
50 /************************************************************************/
51 /* ~GDALMajorObject() */
52 /************************************************************************/
53
~GDALMajorObject()54 GDALMajorObject::~GDALMajorObject()
55
56 {
57 if( (nFlags & GMO_VALID) == 0 )
58 CPLDebug( "GDAL", "In ~GDALMajorObject on invalid object" );
59
60 nFlags &= ~GMO_VALID;
61 }
62
63 /************************************************************************/
64 /* GetDescription() */
65 /************************************************************************/
66
67 /**
68 * \brief Fetch object description.
69 *
70 * The semantics of the returned description are specific to the derived
71 * type. For GDALDatasets it is the dataset name. For GDALRasterBands
72 * it is actually a description (if supported) or "".
73 *
74 * This method is the same as the C function GDALGetDescription().
75 *
76 * @return non-null pointer to internal description string.
77 */
78
GetDescription() const79 const char *GDALMajorObject::GetDescription() const
80
81 {
82 return sDescription.c_str();
83 }
84
85 /************************************************************************/
86 /* GDALGetDescription() */
87 /************************************************************************/
88
89 /**
90 * \brief Fetch object description.
91 *
92 * @see GDALMajorObject::GetDescription()
93 */
94
GDALGetDescription(GDALMajorObjectH hObject)95 const char * CPL_STDCALL GDALGetDescription( GDALMajorObjectH hObject )
96
97 {
98 VALIDATE_POINTER1( hObject, "GDALGetDescription", nullptr );
99
100 return GDALMajorObject::FromHandle(hObject)->GetDescription();
101 }
102
103 /************************************************************************/
104 /* SetDescription() */
105 /************************************************************************/
106
107 /**
108 * \brief Set object description.
109 *
110 * The semantics of the description are specific to the derived
111 * type. For GDALDatasets it is the dataset name. For GDALRasterBands
112 * it is actually a description (if supported) or "".
113 *
114 * Normally application code should not set the "description" for
115 * GDALDatasets. It is handled internally.
116 *
117 * This method is the same as the C function GDALSetDescription().
118 */
119
SetDescription(const char * pszNewDesc)120 void GDALMajorObject::SetDescription( const char * pszNewDesc )
121
122 {
123 sDescription = pszNewDesc;
124 }
125
126 /************************************************************************/
127 /* GDALSetDescription() */
128 /************************************************************************/
129
130 /**
131 * \brief Set object description.
132 *
133 * @see GDALMajorObject::SetDescription()
134 */
135
GDALSetDescription(GDALMajorObjectH hObject,const char * pszNewDesc)136 void CPL_STDCALL GDALSetDescription( GDALMajorObjectH hObject,
137 const char *pszNewDesc )
138
139 {
140 VALIDATE_POINTER0( hObject, "GDALSetDescription" );
141
142 GDALMajorObject::FromHandle(hObject)->SetDescription( pszNewDesc );
143 }
144
145 /************************************************************************/
146 /* GetMetadataDomainList() */
147 /************************************************************************/
148
149 /**
150 * \brief Fetch list of metadata domains.
151 *
152 * The returned string list is the list of (non-empty) metadata domains.
153 *
154 * This method does the same thing as the C function GDALGetMetadataDomainList().
155 *
156 * @return NULL or a string list. Must be freed with CSLDestroy()
157 *
158 * @since GDAL 1.11
159 */
160
GetMetadataDomainList()161 char **GDALMajorObject::GetMetadataDomainList()
162 {
163 return CSLDuplicate(oMDMD.GetDomainList());
164 }
165
166 /************************************************************************/
167 /* BuildMetadataDomainList() */
168 /************************************************************************/
169
170 /**
171 * \brief Helper function for custom implementations of GetMetadataDomainList()
172 *
173 *
174 * @param papszList initial list of domains. May be NULL. Will become invalid
175 * after function call (use return value)
176 * @param bCheckNonEmpty if TRUE, each candidate domain will be tested to be non
177 * empty
178 * @param ... NULL terminated variadic list of candidate domains.
179 *
180 * @return NULL or a string list. Must be freed with CSLDestroy()
181 *
182 * @since GDAL 1.11
183 */
184
BuildMetadataDomainList(char ** papszList,int bCheckNonEmpty,...)185 char **GDALMajorObject::BuildMetadataDomainList( char** papszList,
186 int bCheckNonEmpty, ... )
187 {
188 va_list args;
189 const char* pszDomain = nullptr;
190 va_start(args, bCheckNonEmpty);
191
192 while( (pszDomain = va_arg(args, const char*)) != nullptr )
193 {
194 if( CSLFindString(papszList, pszDomain) < 0 &&
195 (!bCheckNonEmpty || GetMetadata(pszDomain) != nullptr) )
196 {
197 papszList = CSLAddString(papszList, pszDomain);
198 }
199 }
200
201 va_end(args);
202
203 return papszList;
204 }
205
206 /************************************************************************/
207 /* GDALGetMetadataDomainList() */
208 /************************************************************************/
209
210 /**
211 * \brief Fetch list of metadata domains.
212 *
213 * @see GDALMajorObject::GetMetadataDomainList()
214 *
215 * @since GDAL 1.11
216 */
217
218 char ** CPL_STDCALL
GDALGetMetadataDomainList(GDALMajorObjectH hObject)219 GDALGetMetadataDomainList( GDALMajorObjectH hObject )
220
221 {
222 VALIDATE_POINTER1( hObject, "GetMetadataDomainList", nullptr );
223
224 return GDALMajorObject::FromHandle(hObject)->GetMetadataDomainList();
225 }
226
227 /************************************************************************/
228 /* GetMetadata() */
229 /************************************************************************/
230
231 /**
232 * \brief Fetch metadata.
233 *
234 * The returned string list is owned by the object, and may change at
235 * any time. It is formatted as a "Name=value" list with the last pointer
236 * value being NULL. Use the CPL StringList functions such as
237 * CSLFetchNameValue() to manipulate it.
238 *
239 * Note that relatively few formats return any metadata at this time.
240 *
241 * This method does the same thing as the C function GDALGetMetadata().
242 *
243 * @param pszDomain the domain of interest. Use "" or NULL for the default
244 * domain.
245 *
246 * @return NULL or a string list.
247 */
248
GetMetadata(const char * pszDomain)249 char **GDALMajorObject::GetMetadata( const char * pszDomain )
250
251 {
252 return oMDMD.GetMetadata( pszDomain );
253 }
254
255 /************************************************************************/
256 /* GDALGetMetadata() */
257 /************************************************************************/
258
259 /**
260 * \brief Fetch metadata.
261 *
262 * @see GDALMajorObject::GetMetadata()
263 */
264
265 char ** CPL_STDCALL
GDALGetMetadata(GDALMajorObjectH hObject,const char * pszDomain)266 GDALGetMetadata( GDALMajorObjectH hObject, const char * pszDomain )
267
268 {
269 VALIDATE_POINTER1( hObject, "GDALGetMetadata", nullptr );
270
271 return GDALMajorObject::FromHandle(hObject)->GetMetadata(pszDomain);
272 }
273
274 /************************************************************************/
275 /* SetMetadata() */
276 /************************************************************************/
277
278 /**
279 * \brief Set metadata.
280 *
281 * The C function GDALSetMetadata() does the same thing as this method.
282 *
283 * @param papszMetadataIn the metadata in name=value string list format to
284 * apply.
285 * @param pszDomain the domain of interest. Use "" or NULL for the default
286 * domain.
287 * @return CE_None on success, CE_Failure on failure and CE_Warning if the
288 * metadata has been accepted, but is likely not maintained persistently
289 * by the underlying object between sessions.
290 */
291
SetMetadata(char ** papszMetadataIn,const char * pszDomain)292 CPLErr GDALMajorObject::SetMetadata( char ** papszMetadataIn,
293 const char * pszDomain )
294
295 {
296 nFlags |= GMO_MD_DIRTY;
297 return oMDMD.SetMetadata( papszMetadataIn, pszDomain );
298 }
299
300 /************************************************************************/
301 /* GDALSetMetadata() */
302 /************************************************************************/
303
304 /**
305 * \brief Set metadata.
306 *
307 * CAUTION: when using this function on a GDALDatasetH or GDALRasterBandH,
308 * depending on the format, older values of the updated information might
309 * still be found in the file in a "ghost" state, even if no longer accessible
310 * through the GDAL API. This is for example the case of the GTiff format (this is
311 * not a exhaustive list)
312 *
313 * @see GDALMajorObject::SetMetadata(), GDALDataset::SetMetadata(),
314 * GDALRasterBand::SetMetadata()
315 */
316
317 CPLErr CPL_STDCALL
GDALSetMetadata(GDALMajorObjectH hObject,CSLConstList papszMD,const char * pszDomain)318 GDALSetMetadata( GDALMajorObjectH hObject, CSLConstList papszMD,
319 const char *pszDomain )
320
321 {
322 VALIDATE_POINTER1( hObject, "GDALSetMetadata", CE_Failure );
323
324 return GDALMajorObject::FromHandle(hObject)->
325 SetMetadata( const_cast<char**>(papszMD), pszDomain );
326 }
327
328 /************************************************************************/
329 /* GetMetadataItem() */
330 /************************************************************************/
331
332 /**
333 * \brief Fetch single metadata item.
334 *
335 * The C function GDALGetMetadataItem() does the same thing as this method.
336 *
337 * @param pszName the key for the metadata item to fetch.
338 * @param pszDomain the domain to fetch for, use NULL for the default domain.
339 *
340 * @return NULL on failure to find the key, or a pointer to an internal
341 * copy of the value string on success.
342 */
343
GetMetadataItem(const char * pszName,const char * pszDomain)344 const char *GDALMajorObject::GetMetadataItem( const char * pszName,
345 const char * pszDomain )
346
347 {
348 return oMDMD.GetMetadataItem( pszName, pszDomain );
349 }
350
351 /************************************************************************/
352 /* GDALGetMetadataItem() */
353 /************************************************************************/
354
355 /**
356 * \brief Fetch single metadata item.
357 *
358 * @see GDALMajorObject::GetMetadataItem()
359 */
360
GDALGetMetadataItem(GDALMajorObjectH hObject,const char * pszName,const char * pszDomain)361 const char * CPL_STDCALL GDALGetMetadataItem( GDALMajorObjectH hObject,
362 const char *pszName,
363 const char *pszDomain )
364
365 {
366 VALIDATE_POINTER1( hObject, "GDALGetMetadataItem", nullptr );
367
368 return GDALMajorObject::FromHandle(hObject)->
369 GetMetadataItem( pszName, pszDomain);
370 }
371
372 /************************************************************************/
373 /* SetMetadataItem() */
374 /************************************************************************/
375
376 /**
377 * \brief Set single metadata item.
378 *
379 * The C function GDALSetMetadataItem() does the same thing as this method.
380 *
381 * @param pszName the key for the metadata item to fetch.
382 * @param pszValue the value to assign to the key.
383 * @param pszDomain the domain to set within, use NULL for the default domain.
384 *
385 * @return CE_None on success, or an error code on failure.
386 */
387
SetMetadataItem(const char * pszName,const char * pszValue,const char * pszDomain)388 CPLErr GDALMajorObject::SetMetadataItem( const char * pszName,
389 const char * pszValue,
390 const char * pszDomain )
391
392 {
393 nFlags |= GMO_MD_DIRTY;
394 return oMDMD.SetMetadataItem( pszName, pszValue, pszDomain );
395 }
396
397 /************************************************************************/
398 /* GDALSetMetadataItem() */
399 /************************************************************************/
400
401 /**
402 * \brief Set single metadata item.
403 *
404 * CAUTION: when using this function on a GDALDatasetH or GDALRasterBandH,
405 * depending on the format, older values of the updated information might
406 * still be found in the file in a "ghost" state, even if no longer accessible
407 * through the GDAL API. This is for example the case of the GTiff format (this is
408 * not a exhaustive list)
409 *
410 * @see GDALMajorObject::SetMetadataItem(), GDALDataset::SetMetadataItem(),
411 * GDALRasterBand::SetMetadataItem()
412 */
413
414 CPLErr CPL_STDCALL
GDALSetMetadataItem(GDALMajorObjectH hObject,const char * pszName,const char * pszValue,const char * pszDomain)415 GDALSetMetadataItem( GDALMajorObjectH hObject,
416 const char *pszName, const char *pszValue,
417 const char *pszDomain )
418
419 {
420 VALIDATE_POINTER1( hObject, "GDALSetMetadataItem", CE_Failure );
421
422 return GDALMajorObject::FromHandle(hObject)->
423 SetMetadataItem( pszName, pszValue, pszDomain );
424 }
425
426 /************************************************************************/
427 /* GetMOFlags() */
428 /************************************************************************/
429
430 /** Returns the GMO_ flags.
431 * @return flags
432 */
GetMOFlags() const433 int GDALMajorObject::GetMOFlags() const
434
435 {
436 return nFlags;
437 }
438
439 /************************************************************************/
440 /* SetMOFlags() */
441 /************************************************************************/
442
443 /** Assign GMO_flags.
444 * @param nNewFlags new flags.
445 */
SetMOFlags(int nNewFlags)446 void GDALMajorObject::SetMOFlags( int nNewFlags )
447
448 {
449 nFlags = nNewFlags;
450 }
451