1 #ifndef __TXMPMeta_hpp__
2 #define __TXMPMeta_hpp__    1
3 
4 #if ( ! __XMP_hpp__ )
5     #error "Do not directly include, use XMP.hpp"
6 #endif
7 
8 #include "XMPCore/XMPCoreDefines.h"
9 #if ENABLE_CPP_DOM_MODEL
10 	#include "XMPCore/XMPCoreFwdDeclarations.h"
11 #endif
12 
13 // =================================================================================================
14 // ADOBE SYSTEMS INCORPORATED
15 // Copyright 2002 Adobe Systems Incorporated
16 // All Rights Reserved
17 //
18 // NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
19 // of the Adobe license agreement accompanying it.
20 // =================================================================================================
21 
22 // =================================================================================================
23 /// \file TXMPMeta.hpp
24 /// \brief API for access to the XMP Toolkit core services.
25 ///
26 /// \c TXMPMeta is the template class providing the core services of the XMP Toolkit. It must be
27 /// instantiated with a string class such as \c std::string. Read the Toolkit Overview for
28 /// information about the overall architecture of the XMP API, and the documentation for \c XMP.hpp
29 /// for specific instantiation instructions. Please that you MUST NOT derive a class from this class,
30 /// consider this class FINAL, use it directly. [1279031]
31 ///
32 /// Access these functions through the concrete class, \c SXMPMeta.
33 // =================================================================================================
34 
35 // =================================================================================================
36 /// \class TXMPMeta TXMPMeta.hpp
37 /// \brief API for access to the XMP Toolkit core services.
38 ///
39 /// \c TXMPMeta is the template class providing the core services of the XMP Toolkit. It should be
40 /// instantiated with a string class such as \c std::string. Read the Toolkit Overview for
41 /// information about the overall architecture of the XMP API, and the documentation for \c XMP.hpp
42 /// for specific instantiation instructions.
43 ///
44 /// Access these functions through the concrete class, \c SXMPMeta.
45 ///
46 /// You can create \c TXMPMeta objects (also called XMP objects) from metadata that you construct,
47 /// or that you obtain from files using the XMP Toolkit's XMPFiles component; see \c TXMPFiles.hpp.
48 // =================================================================================================
49 
50 template <class tStringObj> class TXMPIterator;
51 template <class tStringObj> class TXMPUtils;
52 
53 // -------------------------------------------------------------------------------------------------
54 
55 template <class tStringObj> class TXMPMeta {
56 
57 public:
58 
59     // =============================================================================================
60     // Initialization and termination
61     // ==============================
62 
63     // ---------------------------------------------------------------------------------------------
64     /// \name Initialization and termination
65     ///
66     /// @{
67 
68     // ---------------------------------------------------------------------------------------------
69     /// @brief \c GetVersionInfo() retrieves runtime version information.
70     ///
71     /// The header \c XMPVersion.hpp defines a static version number for the XMP Toolkit, which
72     /// describes the version of the API used at client compile time. It is not necessarily the same
73     /// as the runtime version. Do not base runtime decisions on the static version alone; you can,
74     /// however, compare the runtime and static versions.
75     ///
76     /// This function is static; make the call directly from the concrete class (\c SXMPMeta). The
77     /// function can be called before calling \c TXMPMeta::Initialize().
78     ///
79     /// @param info [out] A buffer in which to return the version information.
80 
81     static void GetVersionInfo ( XMP_VersionInfo * info );
82 
83     // ---------------------------------------------------------------------------------------------
84     /// @brief \c Initialize() explicitly initializes the XMP Toolkit before use. */
85 
86     /// Initializes the XMP Toolkit.
87     ///
88     /// Call this function before making any other calls to the \c TXMPMeta functions, except
89     /// \c TXMPMeta::GetVersionInfo().
90     ///
91     /// This function is static; make the call directly from the concrete class (\c SXMPMeta).
92     ///
93     /// @return True on success. */
94     static bool Initialize();
95     // ---------------------------------------------------------------------------------------------
96     /// @brief \c Terminate() explicitly terminates usage of the XMP Toolkit.
97     ///
98     /// Frees structures created on initialization.
99     ///
100     /// This function is static; make the call directly from the concrete class (\c SXMPMeta).
101 
102     static void Terminate();
103 
104     /// @}
105 
106     // =============================================================================================
107     // Constuctors and destructor
108     // ==========================
109 
110     // ---------------------------------------------------------------------------------------------
111     /// \name Constructors and destructor
112     /// @{
113 
114     // ---------------------------------------------------------------------------------------------
115     /// @brief Default constructor, creates an empty object.
116     ///
117     /// The default constructor creates a new empty \c TXMPMeta object.
118     ///
119     /// @return The new object. */
120     TXMPMeta();
121 
122     // ---------------------------------------------------------------------------------------------
123     /// @brief Copy constructor, creates a client object refering to the same internal object.
124     ///
125     /// The copy constructor creates a new \c TXMPMeta object that refers to the same internal XMP
126     /// object. as an existing \c TXMPMeta object.
127     ///
128     /// @param original The object to copy.
129     ///
130     /// @return The new object. */
131 
132     TXMPMeta ( const TXMPMeta<tStringObj> & original );
133 
134     // ---------------------------------------------------------------------------------------------
135     /// @brief Assignment operator, assigns the internal reference and increments the reference count.
136     ///
137     /// The assignment operator assigns the internal ref from the rhs object and increments the
138     /// reference count on the underlying internal XMP object.
139 
140     void operator= ( const TXMPMeta<tStringObj> & rhs );
141 
142     // ---------------------------------------------------------------------------------------------
143     /// @brief Reconstructs an XMP object from an internal reference.
144     ///
145     /// This constructor creates a new \c TXMPMeta object that refers to the underlying reference object
146     /// of an existing \c TXMPMeta object. Use to safely pass XMP objects across DLL boundaries.
147     ///
148     /// @param xmpRef The underlying reference object, obtained from some other XMP object with
149     /// \c TXMPMeta::GetInternalRef().
150     ///
151     /// @return The new object.
152 
153     TXMPMeta ( XMPMetaRef xmpRef );
154 
155     // ---------------------------------------------------------------------------------------------
156     /// @brief Constructs an object and parse one buffer of RDF into it.
157     ///
158     /// This constructor creates a new \c TXMPMeta object and populates it with metadata from a
159     /// buffer containing serialized RDF. This buffer must be a complete RDF parse stream.
160     ///
161     /// The result of passing serialized data to this function is identical to creating an empty
162     /// object then calling \c TXMPMeta::ParseFromBuffer(). To use the constructor, however, the RDF
163     /// must be complete. If you need to parse data from multiple buffers, create an empty object
164     /// and use  \c TXMPMeta::ParseFromBuffer().
165     ///
166     /// @param buffer  A pointer to the buffer of RDF to be parsed. Can be null if the length is 0;
167     /// in this case, the function creates an empty object.
168     ///
169     /// @param xmpSize  The length in bytes of the buffer.
170     ///
171     /// @return The new object.
172 
173     TXMPMeta ( XMP_StringPtr buffer,
174                XMP_StringLen xmpSize );
175 
176     // ---------------------------------------------------------------------------------------------
177     /// @brief Destructor, typical virtual destructor. */
178     virtual ~TXMPMeta() throw();
179 
180     /// @}
181 
182     // =============================================================================================
183     // Global state functions
184     // ======================
185 
186     // ---------------------------------------------------------------------------------------------
187     /// \name Global option flags
188     /// @{
189     /// Global option flags affect the overall behavior of the XMP Toolkit. The available options
190     /// will be declared in \c XMP_Const.h. There are none in this version of the Toolkit.
191 
192     // ---------------------------------------------------------------------------------------------
193     /// @brief \c GetGlobalOptions() retrieves the set of global option flags. There are none in
194     /// this version of the Toolkit.
195     ///
196     /// This function is static; you can make the call from the class without instantiating it.
197     ///
198     /// @return A logical OR of global option bit-flag constants.
199 
200      static XMP_OptionBits GetGlobalOptions();
201 
202     // ---------------------------------------------------------------------------------------------
203     /// @brief \c SetGlobalOptions() updates the set of global option flags. There are none in this
204     /// version of the Toolkit.
205     ///
206     /// The entire set is replaced with the new values. If only one flag is to be modified, use
207     /// \c TXMPMeta::GetGlobalOptions() to obtain the current set, modify the desired flag, then use
208     /// this function to reset the value.
209     ///
210     /// This function is static; you can make the call from the class without instantiating it.
211     ///
212     /// @param options A logical OR of global option bit-flag constants.
213 
214     static void SetGlobalOptions ( XMP_OptionBits options );
215 
216     /// @}
217 
218     // ---------------------------------------------------------------------------------------------
219     /// \name Internal data structure dump utilities
220     /// @{
221     ///
222     /// These are debugging utilities that dump internal data structures, to be handled by
223     /// client-defined callback described in \c XMP_Const.h.
224 	///
225 	/// @see Member function \c TXMPMeta::DumpObject()
226 
227     // ---------------------------------------------------------------------------------------------
228     /// @brief \c DumpNamespaces() sends the list of registered namespace URIs and prefixes to a handler.
229     ///
230     /// For debugging. Invokes a client-defined callback for each line of output.
231     ///
232     /// This function is static; make the call directly from the concrete class (\c SXMPMeta).
233     ///
234     /// @param outProc The client-defined procedure to handle each line of output.
235     ///
236     /// @param clientData A pointer to client-defined data to pass to the handler.
237     ///
238     /// @return	A success-fail status value, returned from the handler. Zero is success, failure
239     /// values are client-defined.
240 
241     static XMP_Status DumpNamespaces ( XMP_TextOutputProc outProc,
242                      				   void *             clientData );
243 
244     /// @}
245 
246     // ---------------------------------------------------------------------------------------------
247     /// \name Namespace Functions
248     /// @{
249     ///
250     /// Namespaces must be registered before use in namespace URI parameters or path expressions.
251     /// Within the XMP Toolkit the registered namespace URIs and prefixes must be unique. Additional
252     /// namespaces encountered when parsing RDF are automatically registered.
253     ///
254     /// The namespace URI should always end in an XML name separator such as '/' or '#'. This is
255     /// because some forms of RDF shorthand catenate a namespace URI with an element name to form a
256     /// new URI.
257 
258     // ---------------------------------------------------------------------------------------------
259     /// @brief \c RegisterNamespace() registers a namespace URI with a suggested prefix.
260     ///
261     /// If the URI is not registered but the suggested prefix is in use, a unique prefix is created
262     /// from the suggested one. The actual registered prefix is returned. The function result tells
263     /// if the registered prefix is the suggested one. It is not an error if the URI is already
264     /// registered, regardless of the prefix.
265     ///
266     /// This function is static; make the call directly from the concrete class (\c SXMPMeta).
267     ///
268     /// @param namespaceURI The URI for the namespace. Must be a valid XML URI.
269     ///
270     /// @param suggestedPrefix The suggested prefix to be used if the URI is not yet registered.
271     /// Must be a valid XML name.
272     ///
273     /// @param registeredPrefix [out] A string object in which to return the prefix actually
274     /// registered for this URI.
275     ///
276     /// @return True if the registered prefix matches the suggested prefix.
277     ///
278     /// @note No checking is done on either the URI or the prefix.  */
279 
280     static bool RegisterNamespace ( XMP_StringPtr namespaceURI,
281                         			XMP_StringPtr suggestedPrefix,
282                        				tStringObj *  registeredPrefix );
283 
284     // ---------------------------------------------------------------------------------------------
285     /// @brief \c GetNamespacePrefix() obtains the prefix for a registered namespace URI, and
286     /// reports whether the URI is registered.
287     ///
288     /// This function is static; make the call directly from the concrete class (\c SXMPMeta).
289     ///
290     /// @param namespaceURI The URI for the namespace. Must not be null or the empty string. It is
291     /// not an error if the namespace URI is not registered.
292     ///
293     /// @param namespacePrefix [out] A string object in which to return the prefix registered for
294     /// this URI, with a terminating colon character, ':'. If the namespace is not registered, this
295     /// string is not modified.
296     ///
297     /// @return True if the namespace URI is registered.
298 
299     static bool GetNamespacePrefix ( XMP_StringPtr namespaceURI,
300                          			 tStringObj *  namespacePrefix );
301 
302     // ---------------------------------------------------------------------------------------------
303     /// @brief \c GetNamespaceURI() obtains the URI for a registered namespace prefix, and reports
304     /// whether the prefix is registered.
305     ///
306     /// This function is static; make the call directly from the concrete class (\c SXMPMeta).
307     ///
308     /// @param namespacePrefix The prefix for the namespace. Must not be null or the empty string.
309     /// It is not an error if the namespace prefix is not registered.
310     ///
311     /// @param namespaceURI [out] A string object in which to return the URI registered for this
312     /// prefix. If the prefix is not registered, this string is not modified.
313     ///
314     /// @return True if the namespace prefix is registered.
315 
316     static bool GetNamespaceURI ( XMP_StringPtr namespacePrefix,
317                       			  tStringObj *  namespaceURI );
318 
319     // ---------------------------------------------------------------------------------------------
320     /// @brief Not implemented.
321     ///
322     /// Deletes a namespace from the registry. Does nothing if the URI is not registered, or if the
323     /// parameter is null or the empty string.
324     ///
325     /// This function is static; make the call directly from the concrete class (\c SXMPMeta).
326     ///
327     /// @param namespaceURI The URI for the namespace.
328 
329     static void DeleteNamespace ( XMP_StringPtr namespaceURI );
330 
331     /// @}
332 
333     // =============================================================================================
334     // Basic property manipulation functions
335     // =====================================
336 
337     // *** Should add discussion of schemaNS and propName prefix usage.
338 
339     // ---------------------------------------------------------------------------------------------
340     /// \name Accessing property values
341     /// @{
342     ///
343     /// The property value accessors all take a property specification; the top level namespace URI
344     ///	(the "schema" namespace) and the basic name of the property being referenced. See the
345     ///	introductory discussion of path expression usage for more information.
346 	///
347     /// The accessor functions return true if the specified property exists. If it does, output
348     /// parameters return the value (if any) and option flags describing the property. The option
349     /// bit-flag constants that describe properties are \c kXMP_PropXx and
350 	/// \c kXMP_ArrayIsXx. See \c #kXMP_PropValueIsURI and following, and macros \c #XMP_PropIsSimple
351 	/// and following in \c XMP_Const.h. If the property exists and has a value, it is returned as a
352 	/// Unicode string in UTF-8 encoding. Arrays and the non-leaf levels of structs do not have
353 	/// values.
354 
355     // ---------------------------------------------------------------------------------------------
356     /// @brief \c GetProperty() reports whether a property exists, and retrieves its value.
357     ///
358     /// This is the simplest property accessor. Use this to retrieve the values of top-level simple
359     /// properties, or after using the path composition functions in \c TXMPUtils.
360     ///
361     /// When specifying a namespace and path (in this and all other accessors):
362     ///   \li If a namespace URI is specified, it must be for a registered namespace.
363     ///   \li If the namespace is specified only by a prefix in the property name path,
364     /// it must be a registered prefix.
365     ///   \li If both a URI and path prefix are present, they must be corresponding
366     /// parts of a registered namespace.
367     ///
368     /// @param schemaNS The namespace URI for the property. The URI must be for a registered
369     /// namespace. Must not be null or the empty string.
370     ///
371     /// @param propName The name of the property. Can be a general path expression, must not be null
372     /// or the empty string. The first component can be a namespace prefix; if present without a
373     /// \c schemaNS value, the prefix specifies the namespace. The prefix must be for a registered
374     /// namespace, and if a namespace URI is specified, must match the registered prefix for that
375     /// namespace.
376     ///
377     /// @param propValue [out] A string object in which to return the value of the property, if the
378     /// property exists and has a value. Arrays and non-leaf levels of structs do not have values.
379     /// Can be null if the value is not wanted.
380     ///
381     /// @param options A buffer in which to return option flags describing the property. Can be null
382     /// if the flags are not wanted.
383     ///
384     /// @return True if the property exists.
385 
386     bool GetProperty ( XMP_StringPtr    schemaNS,
387                  	   XMP_StringPtr    propName,
388                        tStringObj *     propValue,
389                   	   XMP_OptionBits * options ) const;
390 
391     // ---------------------------------------------------------------------------------------------
392     /// @brief \c GetArrayItem() provides access to items within an array.
393     ///
394     /// Reports whether the item exists; if it does, and if it has a value, the function retrieves
395     /// the value. Items are accessed by an integer index, where the first item has index 1.
396     ///
397     /// @param schemaNS The namespace URI for the array; see \c GetProperty().
398     ///
399     /// @param arrayName The name of the array. Can be a general path expression, must not be null
400     /// or the empty string; see \c GetProperty() for namespace prefix usage.
401     ///
402     /// @param itemIndex The 1-based index of the desired item. Use the macro \c #kXMP_ArrayLastItem
403     /// to specify the last existing array item.
404     ///
405     /// @param itemValue [out] A string object in which to return the value of the array item, if it
406     /// has a value. Arrays and non-leaf levels of structs do not have values. Can be null if the
407     /// value is not wanted.
408     ///
409     /// @param options [out] A buffer in which to return the option flags describing the array item.
410     /// Can be null if the flags are not wanted.
411     ///
412     /// @return True if the array item exists.
413 
414     bool GetArrayItem ( XMP_StringPtr    schemaNS,
415                    		XMP_StringPtr    arrayName,
416                    		XMP_Index        itemIndex,
417                    		tStringObj *     itemValue,
418                    		XMP_OptionBits * options ) const;
419 
420     // ---------------------------------------------------------------------------------------------
421     /// @brief \c GetStructField() provides access to fields within a nested structure.
422     ///
423     /// Reports whether the field exists; if it does, and if it has a value, the function retrieves
424     /// the value.
425     ///
426     /// @param schemaNS The namespace URI for the struct; see \c GetProperty().
427     ///
428     /// @param structName The name of the struct. Can be a general path expression, must not be null
429     /// or the empty string; see \c GetProperty() for namespace prefix usage.
430     ///
431     /// @param fieldNS The namespace URI for the field. Same URI and prefix usage as the \c schemaNS
432     /// and \c structName parameters.
433     ///
434     /// @param fieldName The name of the field. Must be a single XML name, must not be null or the
435     /// empty string. Same URI and prefix usage as the \c schemaNS and \c structName parameters.
436     ///
437     /// @param fieldValue [out] A string object in which to return the value of the field, if the
438     /// field has a value. Arrays and non-leaf levels of structs do not have values. Can be null if
439     /// the value is not wanted.
440     ///
441     /// @param options [out] A buffer in which to return the option flags describing the field. Can
442     /// be null if the flags are not wanted.
443     ///
444     /// @return True if the field exists.
445 
446     bool GetStructField ( XMP_StringPtr    schemaNS,
447                      	  XMP_StringPtr    structName,
448                      	  XMP_StringPtr    fieldNS,
449                      	  XMP_StringPtr    fieldName,
450                      	  tStringObj *     fieldValue,
451                      	  XMP_OptionBits * options ) const;
452 
453     // ---------------------------------------------------------------------------------------------
454     /// @brief \c GetQualifier() provides access to a qualifier attached to a property.
455     ///
456     /// @note In this version of the Toolkit, qualifiers are supported only for simple leaf properties.
457     ///
458     /// @param schemaNS The namespace URI; see \c GetProperty().
459     ///
460     /// @param propName The name of the property to which the qualifier is attached. Can be a
461     /// general path expression, must not be null or the empty string; see \c GetProperty() for
462     /// namespace prefix usage.
463     ///
464     /// @param qualNS The namespace URI for the qualifier. Same URI and prefix usage as the
465     /// \c schemaNS and \c propName parameters.
466     ///
467     /// @param qualName The name of the qualifier. Must be a single XML name, must not be null or
468     /// the empty string. Same URI and prefix usage as the \c schemaNS and \c propName parameters.
469     ///
470     /// @param qualValue [out] A string object in which to return the value of the qualifier, if the
471     /// qualifier has a value. Arrays and non-leaf levels of structs do not have values. Can be null
472     /// if the value is not wanted.
473     ///
474     /// @param options [out] A buffer in which to return the option flags describing the qualifier.
475     /// Can be null if the flags are not wanted.
476     ///
477     /// @return True if the qualifier exists.
478 
479     bool GetQualifier ( XMP_StringPtr    schemaNS,
480                    		XMP_StringPtr    propName,
481                   		XMP_StringPtr    qualNS,
482                   		XMP_StringPtr    qualName,
483                    		tStringObj *     qualValue,
484                    		XMP_OptionBits * options ) const;
485 
486     /// @}
487 
488     // =============================================================================================
489 
490     // ---------------------------------------------------------------------------------------------
491     /// \name Creating properties and setting their values
492  	/// @{
493  	///
494     /// These functions all take a property specification; the top level namespace URI (the "schema"
495     /// namespace) and the basic name of the property being referenced. See the introductory
496     /// discussion of path expression usage for more information.
497 	///
498     /// All of the functions take a UTF-8 encoded Unicode string for the property value. Arrays and
499     /// non-leaf levels of structs do not have values. The value can be passed as an
500     /// \c #XMP_StringPtr (a pointer to a null-terminated string), or as a string object
501     /// (\c tStringObj).
502 
503     /// Each function takes an options flag that describes the property. You can use these functions
504     /// to create empty arrays and structs by setting appropriate option flags. When you assign a
505     /// value, all levels of a struct that are implicit in the assignment are created if necessary.
506     /// \c TXMPMeta::AppendArrayItem() implicitly creates the named array if necessary.
507     ///
508     /// The allowed option bit-flags include:
509     ///   \li \c #kXMP_PropValueIsStruct - Can be used to create an empty struct.
510     ///		A struct is implicitly created when the first field is set.
511     ///   \li \c #kXMP_PropValueIsArray - By default, a general unordered array (bag).
512     ///   \li \c #kXMP_PropArrayIsOrdered - An ordered array.
513    	///   \li \c #kXMP_PropArrayIsAlternate - An alternative array.
514    	///   \li \c #kXMP_PropArrayIsAltText - An alt-text array. Each array element must
515     /// 	be a simple property with an \c xml:lang attribute.
516 
517     // ---------------------------------------------------------------------------------------------
518     /// @brief \c SetProperty() creates or sets a property value.
519     ///
520     /// This is the simplest property setter. Use it for top-level simple properties, or after using
521     /// the path composition functions in \c TXMPUtils.
522     ///
523     /// @param schemaNS The namespace URI; see \c GetProperty().
524     ///
525     /// @param propName The name of the property. Can be a general path expression, must not be null
526     /// or the empty string; see \c GetProperty() for namespace prefix usage.
527     ///
528     /// @param propValue The new value, a pointer to a null terminated UTF-8 string. Must be null
529     /// for arrays and non-leaf levels of structs that do not have values.
530     ///
531     /// @param options Option flags describing the property; a logical OR of allowed bit-flag
532     /// constants; see \c #kXMP_PropValueIsStruct and following. Must match the type of a property
533     /// that already exists.
534 
535     void SetProperty ( XMP_StringPtr  schemaNS,
536 					   XMP_StringPtr  propName,
537 					   XMP_StringPtr  propValue,
538 					   XMP_OptionBits options = 0 );
539 
540     // ---------------------------------------------------------------------------------------------
541     /// @brief \c SetProperty() creates or sets a property value using a string object.
542 	///
543     /// Overloads the basic form of the function, allowing you to pass a string object
544 	/// for the item value. It is otherwise identical; see details in the canonical form.
545 
546     void SetProperty ( XMP_StringPtr      schemaNS,
547 					   XMP_StringPtr      propName,
548 					   const tStringObj & propValue,
549 					   XMP_OptionBits     options = 0 );
550 
551     // ---------------------------------------------------------------------------------------------
552     /// @brief \c SetArrayItem() creates or sets the value of an item within an array.
553     ///
554     /// Items are accessed by an integer index, where the first item has index 1. This function
555     /// creates the item if necessary, but the array itself must already exist Use
556     /// \c AppendArrayItem() to create arrays. A new item is automatically appended if the index is the
557     /// array size plus 1. To insert a new item before or after an existing item, use option flags.
558     ///
559     /// Use \c TXMPUtils::ComposeArrayItemPath() to create a complex path.
560     ///
561     /// @param schemaNS The namespace URI; see \c GetProperty().
562     ///
563     /// @param arrayName The name of the array. Can be a general path expression, must not be null
564     /// or the empty string; see \c GetProperty() for namespace prefix usage.
565     ///
566     /// @param itemIndex The 1-based index of the desired item. Use the macro \c #kXMP_ArrayLastItem
567     /// to specify the last existing array item.
568     ///
569     /// @param itemValue The new item value, a null-terminated UTF-8 string, if the array item has a
570     /// value.
571     ///
572     /// @param options Option flags describing the array type and insertion location for a new item;
573     /// a logical OR of allowed bit-flag constants. The type, if specified, must match the existing
574     /// array type, \c #kXMP_PropArrayIsOrdered, \c #kXMP_PropArrayIsAlternate, or
575     /// \c #kXMP_PropArrayIsAltText. Default (0 or \c #kXMP_NoOptions) matches the  existing array type.
576     ///
577     /// To insert a new item before or after the specified index, set flag \c #kXMP_InsertBeforeItem
578     /// or \c #kXMP_InsertAfterItem.
579 
580     void SetArrayItem ( XMP_StringPtr  schemaNS,
581 					    XMP_StringPtr  arrayName,
582 					    XMP_Index      itemIndex,
583 					    XMP_StringPtr  itemValue,
584 					    XMP_OptionBits options = 0 );
585 
586     // ---------------------------------------------------------------------------------------------
587     /// @brief \c SetArrayItem() creates or sets the value of an item within an array using a string object.
588     ///
589     /// Overloads the basic form of the function, allowing you to pass a string object in which to
590 	/// return the item value. It is otherwise identical; see details in the canonical form.
591 
592     void SetArrayItem ( XMP_StringPtr      schemaNS,
593 					    XMP_StringPtr      arrayName,
594 					    XMP_Index          itemIndex,
595 					    const tStringObj & itemValue,
596 					    XMP_OptionBits     options = 0 );
597 
598     // ---------------------------------------------------------------------------------------------
599     /// @brief \c AppendArrayItem() adds an item to an array, creating the array if necessary.
600     ///
601     /// This function simplifies construction of an array by not requiring that you pre-create an
602     /// empty array. The array that is assigned is created automatically if it does not yet exist.
603     /// If the array exists, it must have the form specified by the options. Each call appends a new
604     /// item to the array.
605     ///
606     /// Use \c TXMPUtils::ComposeArrayItemPath() to create a complex path.
607     ///
608     /// @param schemaNS The namespace URI; see \c GetProperty().
609     ///
610     /// @param arrayName The name of the array. Can be a general path expression, must not be null
611     /// or the empty string; see \c GetProperty() for namespace prefix usage.
612     ///
613     /// @param arrayOptions Option flags describing the array type to create; a logical OR of
614     /// allowed bit-flag constants, \c #kXMP_PropArrayIsOrdered, \c #kXMP_PropArrayIsAlternate, or
615     /// \c #kXMP_PropArrayIsAltText. If the array exists, must match the existing array type or be
616     /// null (0 or \c #kXMP_NoOptions).
617     ///
618     /// @param itemValue The new item value, a null-terminated UTF-8 string, if the array item has a
619     /// value.
620     ///
621     /// @param itemOptions Option flags describing the item type to create; one of the bit-flag
622     /// constants \c #kXMP_PropValueIsArray or \c #kXMP_PropValueIsStruct to create a complex array
623     /// item.
624 
625     void AppendArrayItem ( XMP_StringPtr  schemaNS,
626 						   XMP_StringPtr  arrayName,
627 						   XMP_OptionBits arrayOptions,
628 						   XMP_StringPtr  itemValue,
629 						   XMP_OptionBits itemOptions = 0 );
630 
631     // ---------------------------------------------------------------------------------------------
632     /// @brief \c AppendArrayItem() adds an item to an array using a string object value, creating
633     /// the array if necessary.
634     ///
635     /// Overloads the basic form of the function, allowing you to pass a string object in which to
636 	/// return the item value. It is otherwise identical; see details in the canonical form.
637 
638     void AppendArrayItem ( XMP_StringPtr      schemaNS,
639 						   XMP_StringPtr      arrayName,
640 						   XMP_OptionBits     arrayOptions,
641 						   const tStringObj & itemValue,
642 						   XMP_OptionBits     itemOptions = 0 );
643 
644     // ---------------------------------------------------------------------------------------------
645     /// @brief \c SetStructField() creates or sets the value of a field within a nested structure.
646     ///
647     /// Use this to  set a value within an existing structure, create a new field within an existing
648     /// structure, or create an empty structure of any depth. If you set a field in a structure that
649     /// does not exist, the structure is automatically created.
650     ///
651     /// Use \c TXMPUtils::ComposeStructFieldPath() to create a complex path.
652     ///
653     /// @param schemaNS The namespace URI; see \c GetProperty().
654     ///
655     /// @param structName The name of the struct. Can be a general path expression, must not be null
656     /// or the empty string; see \c GetProperty() for namespace prefix usage.
657     ///
658     /// @param fieldNS The namespace URI for the field. Same namespace and prefix usage as
659     /// \c GetProperty().
660     ///
661     /// @param fieldName The name of the field. Must be a single XML name, must not be null or the
662     /// empty string. Same namespace and prefix usage as \c GetProperty().
663     ///
664     /// @param fieldValue The new value, a null-terminated UTF-8 string, if the field has a value.
665     /// Null to create a new, empty struct or empty field in an existing struct.
666     ///
667     /// @param options Option flags describing the property, in which the bit-flag
668     /// \c #kXMP_PropValueIsStruct must be set to create a struct.
669 
670     void SetStructField ( XMP_StringPtr   schemaNS,
671 						  XMP_StringPtr   structName,
672 						  XMP_StringPtr   fieldNS,
673 						  XMP_StringPtr   fieldName,
674 						  XMP_StringPtr   fieldValue,
675 						  XMP_OptionBits  options = 0 );
676 
677     // ---------------------------------------------------------------------------------------------
678     /// @brief \c SetStructField() creates or sets the value of a field within a nested structure,
679     /// using a string object.
680     ///
681     /// Overloads the basic form of the function, allowing you to pass a string object in which to
682 	/// return the field value. It is otherwise identical; see details in the canonical form.
683 
684     void SetStructField ( XMP_StringPtr      schemaNS,
685 						  XMP_StringPtr      structName,
686 						  XMP_StringPtr      fieldNS,
687 						  XMP_StringPtr      fieldName,
688 						  const tStringObj & fieldValue,
689 						  XMP_OptionBits     options = 0 );
690 
691     // ---------------------------------------------------------------------------------------------
692     /// @brief \c SetQualifier() creates or sets a qualifier attached to a property.
693     ///
694     /// Use this to  set a value for an existing qualifier, or create a new qualifier. <<how do
695     /// options work? macro vs bit-flag? interaction w/XMP_PropHasQualifier?>> Use
696     /// \c TXMPUtils::ComposeQualifierPath() to create a complex path.
697     ///
698     /// @param schemaNS The namespace URI; see \c GetProperty().
699     ///
700     /// @param propName The name of the property to which the qualifier is attached. Can be a
701     /// general path expression, must not be null or the empty string; see \c GetProperty() for
702     /// namespace prefix usage.
703     ///
704     /// @param qualNS The namespace URI for the qualifier. Same namespace and prefix usage as
705     /// \c GetProperty().
706     ///
707     /// @param qualName The name of the qualifier. Must be a single XML name, must not be null or
708     /// the empty string. Same namespace and prefix usage as \c GetProperty().
709     ///
710     /// @param qualValue The new value, a null-terminated UTF-8 string, if the qualifier has a
711     /// value. Null to create a new, empty qualifier.
712     ///
713     /// @param options Option flags describing the <<qualified property? qualifier?>>, a logical OR
714     /// of property-type bit-flag constants. Use the macro \c #XMP_PropIsQualifier to create a
715     /// qualifier.	 <<??>>
716 
717     void SetQualifier ( XMP_StringPtr  schemaNS,
718 					    XMP_StringPtr  propName,
719 					    XMP_StringPtr  qualNS,
720 					    XMP_StringPtr  qualName,
721 					    XMP_StringPtr  qualValue,
722 					    XMP_OptionBits options = 0 );
723 
724     // ---------------------------------------------------------------------------------------------
725     /// @brief \c SetQualifier() creates or sets a qualifier attached to a property using a string object.
726     ///
727     /// Overloads the basic form of the function, allowing you to pass a string object
728 	/// for the qualifier value. It is otherwise identical; see details in the canonical form.
729 
730     void SetQualifier ( XMP_StringPtr      schemaNS,
731 					    XMP_StringPtr      propName,
732 					    XMP_StringPtr      qualNS,
733 					    XMP_StringPtr      qualName,
734 					    const tStringObj & qualValue,
735 					    XMP_OptionBits     options = 0 );
736 
737     /// @}
738 
739     // =============================================================================================
740 
741     // ---------------------------------------------------------------------------------------------
742     /// \name Detecting and deleting properties.
743     /// @{
744     ///
745     /// The namespace URI and prefix usage for property specifiers in these functions is the same as
746     /// for \c TXMPMeta::GetProperty().
747 
748     // ---------------------------------------------------------------------------------------------
749     /// @brief \c DeleteProperty() deletes an XMP subtree rooted at a given property.
750     ///
751     /// It is not an error if the property does not exist.
752     ///
753     /// @param schemaNS The namespace URI for the property; see \c GetProperty().
754     ///
755     /// @param propName The name of the property; see \c GetProperty().
756 
757     void DeleteProperty ( XMP_StringPtr schemaNS,
758                      	  XMP_StringPtr propName );
759 
760     // ---------------------------------------------------------------------------------------------
761     /// @brief \c DeleteArrayItem() deletes an XMP subtree rooted at a given array item.
762     ///
763     /// It is not an error if the array item does not exist. Use
764     /// \c TXMPUtils::ComposeArrayItemPath() to create a complex path.
765     ///
766     /// @param schemaNS The namespace URI for the array; see \c GetProperty().
767     ///
768     /// @param arrayName The name of the array. Can be a general path expression, must not be null
769     /// or the empty string; see \c GetProperty() for namespace prefix usage.
770     ///
771     /// @param itemIndex The 1-based index of the desired item. Use the macro \c #kXMP_ArrayLastItem
772     /// to specify the last existing array item.
773 
774     void DeleteArrayItem ( XMP_StringPtr schemaNS,
775 						   XMP_StringPtr arrayName,
776 						   XMP_Index     itemIndex );
777 
778     // ---------------------------------------------------------------------------------------------
779     /// @brief \c DeleteStructField() deletes an XMP subtree rooted at a given struct field.
780     ///
781     /// It is not an error if the field does not exist.
782     ///
783     /// @param schemaNS The namespace URI for the struct; see \c GetProperty().
784     ///
785     /// @param structName The name of the struct. Can be a general path expression, must not be null
786     /// or the empty string; see \c GetProperty() for namespace prefix usage.
787     ///
788     /// @param fieldNS The namespace URI for the field. Same namespace and prefix usage as
789     /// \c GetProperty().
790     ///
791     /// @param fieldName The name of the field. Must be a single XML name, must not be null or the
792     /// empty string. Same namespace and prefix usage as \c GetProperty().
793 
794     void DeleteStructField ( XMP_StringPtr schemaNS,
795 							 XMP_StringPtr structName,
796 							 XMP_StringPtr fieldNS,
797 							 XMP_StringPtr fieldName );
798 
799     // ---------------------------------------------------------------------------------------------
800     /// @brief \c DeleteQualifier() deletes an XMP subtree rooted at a given qualifier.
801     ///
802     /// It is not an error if the qualifier does not exist.
803     ///
804     /// @param schemaNS The namespace URI; see \c GetProperty().
805     ///
806     /// @param propName The name of the property to which the qualifier is attached. Can be a
807     /// general path expression, must not be null or the empty string; see \c GetProperty() for
808     /// namespace prefix usage.
809     ///
810     /// @param qualNS The namespace URI for the qualifier. Same namespace and prefix usage as
811     /// \c GetProperty().
812     ///
813     /// @param qualName The name of the qualifier. Must be a single XML name, must not be null or
814     /// the empty string. Same namespace and prefix usage as \c GetProperty().
815 
816     void DeleteQualifier ( XMP_StringPtr schemaNS,
817 						   XMP_StringPtr propName,
818 						   XMP_StringPtr qualNS,
819 						   XMP_StringPtr qualName );
820 
821     // ---------------------------------------------------------------------------------------------
822     /// @brief \c DoesPropertyExist() reports whether a property currently exists.
823     ///
824     /// @param schemaNS The namespace URI for the property; see \c GetProperty().
825     ///
826     /// @param propName The name of the property; see \c GetProperty().
827     ///
828     /// @return True if the property exists.
829 
830     bool DoesPropertyExist ( XMP_StringPtr schemaNS,
831                         	 XMP_StringPtr propName ) const;
832 
833     // ---------------------------------------------------------------------------------------------
834     /// @brief \c DoesArrayItemExist() reports whether an array item currently exists.
835     ///
836     /// Use \c TXMPUtils::ComposeArrayItemPath() to create a complex path.
837     ///
838     /// @param schemaNS The namespace URI; see \c GetProperty().
839     ///
840     /// @param arrayName The name of the array. Can be a general path expression, must not be null
841     /// or the empty string; see \c GetProperty() for namespace prefix usage.
842     ///
843     /// @param itemIndex The 1-based index of the desired item. Use the macro \c #kXMP_ArrayLastItem
844     /// to specify the last existing array item.
845     ///
846     /// @return True if the array item exists.
847 
848     bool DoesArrayItemExist ( XMP_StringPtr schemaNS,
849 							  XMP_StringPtr arrayName,
850 							  XMP_Index     itemIndex ) const;
851 
852     // ---------------------------------------------------------------------------------------------
853     /// @brief \c DoesStructFieldExist() reports whether a struct field currently exists.
854     ///
855     /// Use \c TXMPUtils::ComposeStructFieldPath() to create a complex path.
856     ///
857     /// @param schemaNS The namespace URI; see \c GetProperty().
858     ///
859     /// @param structName The name of the struct. Can be a general path expression, must not be null
860     /// or the empty string; see \c GetProperty() for namespace prefix usage.
861     ///
862     /// @param fieldNS The namespace URI for the field. Same namespace and prefix usage as
863     /// \c GetProperty().
864     ///
865     /// @param fieldName The name of the field. Must be a single XML name, must not be null or the
866     /// empty string. Same namespace and prefix usage as \c GetProperty().
867     ///
868     /// @return True if the field exists.
869 
870     bool DoesStructFieldExist ( XMP_StringPtr schemaNS,
871 							    XMP_StringPtr structName,
872 							    XMP_StringPtr fieldNS,
873 							    XMP_StringPtr fieldName ) const;
874 
875     // ---------------------------------------------------------------------------------------------
876     /// @brief \c DoesQualifierExist() reports whether a qualifier currently exists.
877     ///
878     /// @param schemaNS The namespace URI; see \c GetProperty().
879     ///
880     /// @param propName The name of the property to which the qualifier is attached. Can be a
881     /// general path expression, must not be null or the empty string; see \c GetProperty() for
882     /// namespace prefix usage.
883     ///
884     /// @param qualNS The namespace URI for the qualifier. Same namespace and prefix usage as
885     /// \c GetProperty().
886     ///
887     /// @param qualName The name of the qualifier. Must be a single XML name, must not be null or
888     /// the empty string. Same namespace and prefix usage as \c GetProperty().
889     ///
890     /// @return True if the qualifier exists.
891 
892     bool DoesQualifierExist ( XMP_StringPtr schemaNS,
893 							  XMP_StringPtr propName,
894 							  XMP_StringPtr qualNS,
895 							  XMP_StringPtr qualName ) const;
896 
897     /// @}
898 
899     // =============================================================================================
900     // Specialized Get and Set functions
901     // =============================================================================================
902 
903     // ---------------------------------------------------------------------------------------------
904     /// \name Accessing properties as binary values.
905     /// @{
906     ///
907 	/// These are very similar to \c TXMPMeta::GetProperty() and \c TXMPMeta::SetProperty(), except
908 	/// that the value is returned or provided in binary form instead of as a UTF-8 string.
909 	/// \c TXMPUtils provides functions for converting between binary and string values.
910     /// Use the path composition functions in  \c TXMPUtils	to compose complex path expressions
911     /// for fields or items in nested structures or arrays, or for qualifiers.
912 
913     // ---------------------------------------------------------------------------------------------
914     /// @brief \c GetProperty_Bool() retrieves the value of a Boolean property as a C++ bool.
915     ///
916     /// Reports whether a property exists, and retrieves its binary value and property type information.
917     ///
918     /// @param schemaNS The namespace URI; see \c GetProperty().
919     ///
920     /// @param propName The name of the property. Can be a general path expression, must not be null
921     /// or the empty string; see \c GetProperty() for namespace prefix usage.
922     ///
923     /// @param propValue [out] A buffer in which to return the binary value. Can be null if the
924     /// value is not wanted. Must be null for arrays and non-leaf levels of structs that do not have
925     /// values.
926     ///
927     /// @param options [out] A buffer in which to return the option flags describing the property, a
928     /// logical OR of allowed bit-flag constants; see \c #kXMP_PropValueIsStruct and following. Can
929     /// be null if flags are not wanted.
930     ///
931     /// @return True if the property exists.
932 
933     bool GetProperty_Bool ( XMP_StringPtr    schemaNS,
934 						    XMP_StringPtr    propName,
935 						    bool *           propValue,
936 						    XMP_OptionBits * options ) const;
937 
938     // ---------------------------------------------------------------------------------------------
939     /// @brief \c GetProperty_Int() retrieves the value of an integer property as a C long integer.
940     ///
941     /// Reports whether a property exists, and retrieves its binary value and property type information.
942     ///
943     /// @param schemaNS The namespace URI; see \c GetProperty().
944     ///
945     /// @param propName The name of the property. Can be a general path expression, must not be null
946     /// or the empty string; see \c GetProperty() for namespace prefix usage.
947     ///
948     /// @param propValue [out] A buffer in which to return the binary value. Can be null if the
949     /// value is not wanted. Must be null for arrays and non-leaf levels of structs that do not have
950     /// values.
951     ///
952     /// @param options [out] A buffer in which to return the option flags describing the property, a
953     /// logical OR of allowed bit-flag constants; see \c #kXMP_PropValueIsStruct and following. Can
954     /// be null if flags are not wanted.
955     ///
956     /// @return True if the property exists.
957 
958     bool GetProperty_Int ( XMP_StringPtr    schemaNS,
959 						   XMP_StringPtr    propName,
960 						   XMP_Int32 *           propValue,
961 						   XMP_OptionBits * options ) const;
962 
963     // ---------------------------------------------------------------------------------------------
964     /// @brief \c GetProperty_Int64() retrieves the value of an integer property as a C long long integer.
965     ///
966     /// Reports whether a property exists, and retrieves its binary value and property type information.
967     ///
968     /// @param schemaNS The namespace URI; see \c GetProperty().
969     ///
970     /// @param propName The name of the property. Can be a general path expression, must not be null
971     /// or the empty string; see \c GetProperty() for namespace prefix usage.
972     ///
973     /// @param propValue [out] A buffer in which to return the binary value. Can be null if the
974     /// value is not wanted. Must be null for arrays and non-leaf levels of structs that do not have
975     /// values.
976     ///
977     /// @param options [out] A buffer in which to return the option flags describing the property, a
978     /// logical OR of allowed bit-flag constants; see \c #kXMP_PropValueIsStruct and following. Can
979     /// be null if flags are not wanted.
980     ///
981     /// @return True if the property exists.
982 
983     bool GetProperty_Int64 ( XMP_StringPtr    schemaNS,
984 							 XMP_StringPtr    propName,
985 							 XMP_Int64 *      propValue,
986 							 XMP_OptionBits * options ) const;
987 
988     // ---------------------------------------------------------------------------------------------
989     /// @brief \c GetProperty_Float() retrieves the value of a floating-point property as a C double float.
990     ///
991     /// Reports whether a property exists, and retrieves its binary value and property type information.
992     ///
993     /// @param schemaNS The namespace URI; see \c GetProperty().
994     ///
995     /// @param propName The name of the property. Can be a general path expression, must not be null
996     /// or the empty string; see \c GetProperty() for namespace prefix usage.
997     ///
998     /// @param propValue [out] A buffer in which to return the binary value. Can be null if the
999     /// value is not wanted. Must be null for arrays and non-leaf levels of structs that do not have
1000     /// values.
1001     ///
1002     /// @param options [out] A buffer in which to return the option flags describing the property, a
1003     /// logical OR of allowed bit-flag constants; see \c #kXMP_PropValueIsStruct and following. Can
1004     /// be null if flags are not wanted.
1005     ///
1006     /// @return True if the property exists.
1007 
1008     bool GetProperty_Float ( XMP_StringPtr    schemaNS,
1009 							 XMP_StringPtr    propName,
1010 							 double *         propValue,
1011 							 XMP_OptionBits * options ) const;
1012 
1013     // ---------------------------------------------------------------------------------------------
1014     /// @brief \c GetProperty_Date() retrieves the value of a date-time property as an \c #XMP_DateTime structure.
1015     ///
1016     /// Reports whether a property exists, and retrieves its binary value and property type information.
1017     ///
1018     /// @param schemaNS The namespace URI; see \c GetProperty().
1019     ///
1020     /// @param propName The name of the property. Can be a general path expression, must not be null
1021     /// or the empty string; see \c GetProperty() for namespace prefix usage.
1022     ///
1023     /// @param propValue [out] A buffer in which to return the binary value. Can be null if the
1024     /// value is not wanted. Must be null for arrays and non-leaf levels of structs that do not have
1025     /// values.
1026     ///
1027     /// @param options [out] A buffer in which to return the option flags describing the property, a
1028     /// logical OR of allowed bit-flag constants; see \c #kXMP_PropValueIsStruct and following. Can
1029     /// be null if flags are not wanted.
1030     ///
1031     /// @return True if the property exists.
1032 
1033     bool GetProperty_Date ( XMP_StringPtr    schemaNS,
1034 						    XMP_StringPtr    propName,
1035 						    XMP_DateTime *   propValue,
1036 						    XMP_OptionBits * options ) const;
1037 
1038     // ---------------------------------------------------------------------------------------------
1039     /// @brief \c SetProperty_Bool() sets the value of a Boolean property using a C++ bool.
1040     ///
1041     /// Sets a property with a binary value, creating it if necessary.
1042     ///
1043     /// @param schemaNS The namespace URI; see \c GetProperty().
1044     ///
1045     /// @param propName The name of the property. Can be a general path expression, must not be null
1046     /// or the empty string; see \c GetProperty() for namespace prefix usage.
1047     ///
1048     /// @param propValue The new binary value. Can be null if creating the property. Must be null
1049     /// for arrays and non-leaf levels of structs that do not have values.
1050     ///
1051     /// @param options Option flags describing the property; a logical OR of allowed bit-flag
1052     /// constants; see \c #kXMP_PropValueIsStruct and following. Must match the type of a property
1053     /// that already exists.
1054 
1055     void SetProperty_Bool ( XMP_StringPtr  schemaNS,
1056 						    XMP_StringPtr  propName,
1057 						    bool           propValue,
1058 						    XMP_OptionBits options = 0 );
1059 
1060     // ---------------------------------------------------------------------------------------------
1061     /// @brief \c SetProperty_Int() sets the value of an integer property using a C long integer.
1062     ///
1063     /// Sets a property with a binary value, creating it if necessary.
1064     ///
1065     /// @param schemaNS The namespace URI; see \c GetProperty().
1066     ///
1067     /// @param propName The name of the property. Can be a general path expression, must not be null
1068     /// or the empty string; see \c GetProperty() for namespace prefix usage.
1069     ///
1070     /// @param propValue The new binary value. Can be null if creating the property. Must be null
1071     /// for arrays and non-leaf levels of structs that do not have values.
1072     ///
1073     /// @param options Option flags describing the property; a logical OR of allowed bit-flag
1074     /// constants; see \c #kXMP_PropValueIsStruct and following. Must match the type of a property
1075     /// that already exists.
1076 
1077     void SetProperty_Int ( XMP_StringPtr  schemaNS,
1078 						   XMP_StringPtr  propName,
1079 						   XMP_Int32      propValue,
1080 						   XMP_OptionBits options = 0 );
1081 
1082     // ---------------------------------------------------------------------------------------------
1083     /// @brief \c SetProperty_Int64() sets the value of an integer property using a C long long integer.
1084     ///
1085     /// Sets a property with a binary value, creating it if necessary.
1086     ///
1087     /// @param schemaNS The namespace URI; see \c GetProperty().
1088     ///
1089     /// @param propName The name of the property. Can be a general path expression, must not be null
1090     /// or the empty string; see \c GetProperty() for namespace prefix usage.
1091     ///
1092     /// @param propValue The new binary value. Can be null if creating the property. Must be null
1093     /// for arrays and non-leaf levels of structs that do not have values.
1094     ///
1095     /// @param options Option flags describing the property; a logical OR of allowed bit-flag
1096     /// constants; see \c #kXMP_PropValueIsStruct and following. Must match the type of a property
1097     /// that already exists.
1098 
1099     void SetProperty_Int64 ( XMP_StringPtr  schemaNS,
1100 							 XMP_StringPtr  propName,
1101 							 XMP_Int64     propValue,
1102 							 XMP_OptionBits options = 0 );
1103 
1104     // ---------------------------------------------------------------------------------------------
1105     /// @brief \c SetProperty_Float() sets the value of a floating-point property using a C double float.
1106     ///
1107     /// Sets a property with a binary value, creating it if necessary.
1108     ///
1109     /// @param schemaNS The namespace URI; see \c GetProperty().
1110     ///
1111     /// @param propName The name of the property. Can be a general path expression, must not be null
1112     /// or the empty string; see \c GetProperty() for namespace prefix usage.
1113     ///
1114     /// @param propValue The new binary value. Can be null if creating the property. Must be null
1115     /// for arrays and non-leaf levels of structs that do not have values.
1116     ///
1117     /// @param options Option flags describing the property; a logical OR of allowed bit-flag
1118     /// constants; see \c #kXMP_PropValueIsStruct and following. Must match the type of a property
1119     /// that already exists.
1120 
1121     void SetProperty_Float ( XMP_StringPtr  schemaNS,
1122 							 XMP_StringPtr  propName,
1123 							 double         propValue,
1124 							 XMP_OptionBits options = 0 );
1125 
1126     // ---------------------------------------------------------------------------------------------
1127     /// @brief \c SetProperty_Date() sets the value of a date/time property using an \c #XMP_DateTime structure.
1128     ///
1129     /// Sets a property with a binary value, creating it if necessary.
1130     ///
1131     /// @param schemaNS The namespace URI; see \c GetProperty().
1132     ///
1133     /// @param propName The name of the property. Can be a general path expression, must not be null
1134     /// or the empty string; see \c GetProperty() for namespace prefix usage.
1135     ///
1136     /// @param propValue The new binary value. Can be null if creating the property. Must be null
1137     /// for arrays and non-leaf levels of structs that do not have values.
1138     ///
1139     /// @param options Option flags describing the property; a logical OR of allowed bit-flag
1140     /// constants; see \c #kXMP_PropValueIsStruct and following. Must match the type of a property
1141     /// that already exists.
1142 
1143     void SetProperty_Date ( XMP_StringPtr         schemaNS,
1144 						    XMP_StringPtr         propName,
1145 						    const XMP_DateTime &  propValue,
1146 						    XMP_OptionBits        options = 0 );
1147 
1148     /// @}
1149     // =============================================================================================
1150     /// \name Accessing localized text (alt-text) properties.
1151     /// @{
1152     ///
1153 	/// Localized text properties are stored in alt-text arrays. They allow multiple concurrent
1154 	/// localizations of a property value, for example a document title or copyright in several
1155 	/// languages.
1156     ///
1157     /// These functions provide convenient support for localized text properties, including a
1158     /// number of special and obscure aspects. The most important aspect of these functions is that
1159     /// they select an appropriate array item based on one or two RFC 3066 language tags. One of
1160     /// these languages, the "specific" language, is preferred and selected if there is an exact
1161     /// match. For many languages it is also possible to define a "generic" language that can be
1162     /// used if there is no specific language match. The generic language must be a valid RFC 3066
1163     /// primary subtag, or the empty string.
1164     ///
1165     /// For example, a specific language of "en-US" should be used in the US, and a specific
1166     /// language of "en-UK" should be used in England. It is also appropriate to use "en" as the
1167     /// generic language in each case. If a US document goes to England, the "en-US" title is
1168     /// selected by using the "en" generic language and the "en-UK" specific language.
1169     ///
1170     /// It is considered poor practice, but allowed, to pass a specific language that is just an
1171     /// RFC 3066 primary tag. For example "en" is not a good specific language, it should only be
1172     /// used as a generic language. Passing "i" or "x" as the generic language is also considered
1173     /// poor practice but allowed.
1174     ///
1175     /// Advice from the W3C about the use of RFC 3066 language tags can be found at:
1176     ///     \li http://www.w3.org/International/articles/language-tags/
1177     ///
1178     /// \note RFC 3066 language tags must be treated in a case insensitive manner. The XMP toolkit
1179     /// does this by normalizing their capitalization:
1180  	/// 	\li The primary subtag is lower case, the suggested practice of ISO 639.
1181 	/// 	\li All 2 letter secondary subtags are upper case, the suggested practice of ISO 3166.
1182 	/// 	\li All other subtags are lower case.
1183     ///
1184     /// The XMP specification defines an artificial language, "x-default", that is used to
1185     /// explicitly denote a default item in an alt-text array. The XMP toolkit normalizes alt-text
1186     /// arrays such that the x-default item is the first item. The \c SetLocalizedText() function
1187     /// has several special features related to the x-default item, see its description for details.
1188 
1189     // ---------------------------------------------------------------------------------------------
1190     /// @brief \c GetLocalizedText() retrieves information about a selected item in an alt-text array.
1191     ///
1192     /// The array item is selected according to these rules:
1193     ///   \li Look for an exact match with the specific language.
1194     ///   \li If a generic language is given, look for a partial match.
1195     ///   \li Look for an x-default item.
1196     ///   \li Choose the first item.
1197     ///
1198     /// A partial match with the generic language is where the start of the item's language matches
1199     /// the generic string and the next character is '-'. An exact match is also recognized as a
1200     /// degenerate case.
1201     ///
1202     /// You can pass "x-default" as the specific language. In this case, selection of an
1203     /// \c x-default item is an exact match by the first rule, not a selection by the 3rd rule. The
1204     /// last 2 rules are fallbacks used when the specific and generic languages fail to produce a
1205     /// match.
1206     ///
1207     /// The return value reports whether a match was successfully made.
1208     ///
1209     /// @param schemaNS The namespace URI for the alt-text array; see \c GetProperty().
1210     ///
1211     /// @param altTextName The name of the alt-text array. Can be a general path expression, must
1212     /// not be null or the empty string; see \c GetProperty() for namespace prefix usage.
1213     ///
1214     /// @param genericLang The name of the generic language as an RFC 3066 primary subtag. Can be
1215     /// null or the empty string if no generic language is wanted.
1216     ///
1217     /// @param specificLang The name of the specific language as an RFC 3066 tag, or "x-default".
1218     /// Must not be null or the empty string.
1219     ///
1220     /// @param actualLang [out] A string object in which to return the language of the selected
1221     /// array item, if an appropriate array item is found. Can be null if the language is not wanted.
1222     ///
1223     /// @param itemValue [out] A string object in which to return the value of the array item, if an
1224     /// appropriate array item is found. Can be null if the value is not wanted.
1225     ///
1226     /// @param options A buffer in which to return the option flags that describe the array item, if
1227     /// an appropriate array item is found. Can be null if the flags are not wanted.
1228     ///
1229     /// @return True if an appropriate array item exists.
1230 
1231     bool GetLocalizedText ( XMP_StringPtr    schemaNS,
1232 						    XMP_StringPtr    altTextName,
1233 						    XMP_StringPtr    genericLang,
1234 						    XMP_StringPtr    specificLang,
1235 						    tStringObj *     actualLang,
1236 						    tStringObj *     itemValue,
1237 						    XMP_OptionBits * options ) const;
1238 
1239     // ---------------------------------------------------------------------------------------------
1240     /// @brief \c SetLocalizedText() modifies the value of a selected item in an alt-text array.
1241     ///
1242     /// Creates an appropriate array item if necessary, and handles special cases for the x-default
1243     /// item.
1244     ///
1245     /// The array item is selected according to these rules:
1246     ///   \li Look for an exact match with the specific language.
1247     ///   \li If a generic language is given, look for a partial match.
1248     ///   \li Look for an x-default item.
1249     ///   \li Choose the first item.
1250     ///
1251     /// A partial match with the generic language is where the start of the item's language matches
1252     /// the generic string and the next character is '-'. An exact match is also recognized as a
1253     /// degenerate case.
1254     ///
1255     /// You can pass "x-default" as the specific language. In this case, selection of an
1256     /// \c x-default item is an exact match by the first rule, not a selection by the 3rd rule. The
1257     /// last 2 rules are fallbacks used when the specific and generic languages fail to produce a
1258     /// match.
1259     ///
1260     /// Item values are modified according to these rules:
1261     ///
1262     ///   \li If the selected item is from a match with the specific language, the value of that
1263     ///   item is modified. If the existing value of that item matches the existing value of the
1264     ///   x-default item, the x-default item is also modified. If the array only has 1 existing item
1265     ///   (which is not x-default), an x-default item is added with the given value.
1266     ///
1267     ///   \li If the selected item is from a match with the generic language and there are no other
1268     ///   generic matches, the value of that item is modified. If the existing value of that item
1269     ///   matches the existing value of the x-default item, the x-default item is also modified. If
1270     ///   the array only has 1 existing item (which is not x-default), an x-default item is added
1271     ///   with the given value.
1272     ///
1273     ///   \li If the selected item is from a partial match with the generic language and there are
1274     ///   other partial matches, a new item is created for the specific language. The x-default item
1275     ///   is not modified.
1276     ///
1277     ///   \li If the selected item is from the last 2 rules then a new item is created for the
1278     ///   specific language. If the array only had an x-default item, the x-default item is also
1279     ///   modified. If the array was empty, items are created for the specific language and
1280     ///   x-default.
1281     ///
1282     /// @param schemaNS The namespace URI for the alt-text array; see \c GetProperty().
1283     ///
1284     /// @param altTextName The name of the alt-text array. Can be a general path expression, must
1285     /// not be null or the empty string; see \c GetProperty() for namespace prefix usage.
1286     ///
1287     /// @param genericLang The name of the generic language as an RFC 3066 primary subtag. Can be
1288     /// null or the empty string if no generic language is wanted.
1289     ///
1290     /// @param specificLang The name of the specific language as an RFC 3066 tag, or "x-default".
1291     /// Must not be null or the empty string.
1292     ///
1293     /// @param itemValue The new value for the matching array item, specified as a null-terminated
1294     /// UTF-8 string.
1295     ///
1296     /// @param options Option flags, none currently defined.
1297 
1298     void SetLocalizedText ( XMP_StringPtr  schemaNS,
1299 						    XMP_StringPtr  altTextName,
1300 						    XMP_StringPtr  genericLang,
1301 						    XMP_StringPtr  specificLang,
1302 						    XMP_StringPtr  itemValue,
1303 						    XMP_OptionBits options = 0 );
1304 
1305     // ---------------------------------------------------------------------------------------------
1306     /// @brief \c SetLocalizedText() modifies the value of a selected item in an alt-text array using
1307     /// a string object.
1308     ///
1309     /// Creates an appropriate array item if necessary, and handles special cases for the x-default
1310     /// item.
1311     ///
1312     /// The array item is selected according to these rules:
1313     ///   \li Look for an exact match with the specific language.
1314     ///   \li If a generic language is given, look for a partial match.
1315     ///   \li Look for an x-default item.
1316     ///   \li Choose the first item.
1317     ///
1318     /// A partial match with the generic language is where the start of the item's language matches
1319     /// the generic string and the next character is '-'. An exact match is also recognized as a
1320     /// degenerate case.
1321     ///
1322     /// You can pass "x-default" as the specific language. In this case, selection of an \c x-default
1323     /// item is an exact match by the first rule, not a selection by the 3rd rule. The last 2 rules
1324     /// are fallbacks used when the specific and generic languages fail to produce a match.
1325     ///
1326     /// Item values are modified according to these rules:
1327     ///
1328     ///   \li If the selected item is from a match with the specific language, the value of that
1329     ///   item is modified. If the existing value of that item matches the existing value of the
1330     ///   x-default item, the x-default item is also modified. If the array only has 1 existing item
1331     ///   (which is not x-default), an x-default item is added with the given value.
1332     ///
1333     ///   \li If the selected item is from a match with the generic language and there are no other
1334     ///   generic matches, the value of that item is modified. If the existing value of that item
1335     ///   matches the existing value of the x-default item, the x-default item is also modified. If
1336     ///   the array only has 1 existing item (which is not x-default), an x-default item is added
1337     ///   with the given value.
1338     ///
1339     ///   \li If the selected item is from a partial match with the generic language and there are
1340     ///   other partial matches, a new item is created for the specific language. The x-default item
1341     ///   is not modified.
1342     ///
1343     ///   \li If the selected item is from the last 2 rules then a new item is created for the
1344     ///   specific language. If the array only had an x-default item, the x-default item is also
1345     ///   modified. If the array was empty, items are created for the specific language and
1346     ///   x-default.
1347     ///
1348     /// @param schemaNS The namespace URI for the alt-text array; see \c GetProperty().
1349     ///
1350     /// @param altTextName The name of the alt-text array. Can be a general path expression, must
1351     /// not be null or the empty string; see \c GetProperty() for namespace prefix usage.
1352     ///
1353     /// @param genericLang The name of the generic language as an RFC 3066 primary subtag. Can be
1354     /// null or the empty string if no generic language is wanted.
1355     ///
1356     /// @param specificLang The name of the specific language as an RFC 3066 tag, or "x-default".
1357     /// Must not be null or the empty string.
1358     ///
1359     /// @param itemValue The new value for the matching array item, specified as a string object.
1360     ///
1361     /// @param options Option flags, none currently defined.
1362 
1363     void SetLocalizedText ( XMP_StringPtr      schemaNS,
1364 						    XMP_StringPtr      altTextName,
1365 						    XMP_StringPtr      genericLang,
1366 						    XMP_StringPtr      specificLang,
1367 						    const tStringObj & itemValue,
1368 						    XMP_OptionBits     options = 0 );
1369 
1370     // ---------------------------------------------------------------------------------------------
1371 	/// @brief \c DeleteLocalizedText() deletes specific language alternatives from an alt-text array.
1372 	///
1373 	///	The rules for finding the language value to delete are similar to those for \c #SetLocalizedText().
1374 	///
1375 	/// @param schemaNS The namespace URI for the alt-text array; see \c #GetProperty().
1376 	///
1377 	/// @param altTextName The name of the alt-text array. Can be a general path expression, must
1378 	/// not be null or the empty string; see \c #GetProperty() for namespace prefix usage.
1379 	///
1380 	/// @param genericLang The name of the generic language as an RFC 3066 primary subtag. Can be
1381 	/// null or the empty string if no generic language is wanted.
1382 	///
1383 	/// @param specificLang The name of the specific language as an RFC 3066 tag, or "x-default".
1384 	/// Must not be null or the empty string.
1385     ///
1386 	void
1387 	DeleteLocalizedText ( XMP_StringPtr    schemaNS,
1388 							XMP_StringPtr    altTextName,
1389 							XMP_StringPtr    genericLang,
1390 							XMP_StringPtr    specificLang );
1391 
1392 	/// @}
1393 
1394    	// =============================================================================================
1395     /// \name Creating and reading serialized RDF.
1396     /// @{
1397     ///
1398 	/// The metadata contained in an XMP object must be serialized as RDF for storage in an XMP
1399 	/// packet and output to a file. Similarly, metadata in the form of serialized RDF (such as
1400 	/// metadata read from a file using \c TXMPFiles) must be parsed into an XMP object for
1401 	/// manipulation with the XMP Toolkit.
1402 	///
1403 	/// These functions support parsing serialized RDF into an XMP object, and serializing an XMP
1404     /// object into RDF. The input for parsing can be any valid Unicode encoding. ISO Latin-1 is
1405     /// also recognized, but its use is strongly discouraged. Serialization is always as UTF-8.
1406 
1407     // ---------------------------------------------------------------------------------------------
1408     /// @brief \c ParseFromBuffer() parses RDF from a series of input buffers into this XMP object.
1409     ///
1410     /// Use this to convert metadata from serialized RDF form (as, for example, read from an XMP
1411     /// packet embedded in a file) into an XMP object that you can manipulate with the XMP Toolkit.
1412     /// If this XMP object is empty and the input buffer contains a complete XMP packet, this is the
1413     /// same as creating a new XMP object from that buffer with the constructor.
1414     ///
1415     /// You can use this function to combine multiple buffers into a single metadata tree. To
1416     /// terminate an input loop conveniently, pass  the option \c #kXMP_ParseMoreBuffers for all
1417     /// real input, then make a final call with a zero length and \c #kXMP_NoOptions. The buffers
1418     /// can be any length. The buffer boundaries need not respect XML tokens or even Unicode
1419     /// characters.
1420     ///
1421     /// @param buffer A pointer to a buffer of input. Can be null if \c bufferSize is 0.
1422     ///
1423     /// @param bufferSize The length of the input buffer in bytes. Zero is a valid value.
1424     ///
1425     /// @param options An options flag that controls how the parse operation is performed. A logical
1426     /// OR of these bit-flag constants:
1427     ///   \li \c #kXMP_ParseMoreBuffers - This is not the last buffer of input, more calls follow.
1428     ///   \li \c #kXMP_RequireXMPMeta - The \c x:xmpmeta XML element is required around \c rdf:RDF.
1429     ///
1430     /// @see \c TXMPFiles::GetXMP()
1431 
1432     void ParseFromBuffer ( XMP_StringPtr  buffer,
1433 						   XMP_StringLen  bufferSize,
1434 						   XMP_OptionBits options = 0 );
1435 
1436     // ---------------------------------------------------------------------------------------------
1437     /// @brief \c SerializeToBuffer() serializes metadata in this XMP object into a string as RDF.
1438     ///
1439     /// Use this to prepare metadata for storage as an XMP packet embedded in a file. See \c TXMPFiles::PutXMP().
1440     ///
1441     /// @param rdfString [out] A string object in which to return the serialized RDF. Must not be null.
1442     ///
1443     /// @param options An options flag that controls how the serialization operation is performed.
1444     /// The specified options must be logically consistent; an exception is thrown if they are not.
1445     /// A logical OR of these bit-flag constants:
1446     ///   \li \c kXMP_OmitPacketWrapper - Do not include an XML packet wrapper. This cannot be
1447     ///   specified together with \c #kXMP_ReadOnlyPacket, \c #kXMP_IncludeThumbnailPad, or
1448     ///   \c #kXMP_ExactPacketLength.
1449     ///   \li \c kXMP_ReadOnlyPacket - Create a read-only XML packet wapper. Cannot be specified
1450     ///   together with \c kXMP_OmitPacketWrapper.
1451     ///   \li \c kXMP_UseCompactFormat - Use a highly compact RDF syntax and layout.
1452     ///   \li \c kXMP_IncludeThumbnailPad - Include typical space for a JPEG thumbnail in the
1453     ///   padding if no \c xmp:Thumbnails property is present. Cannot be specified together with
1454     ///   \c kXMP_OmitPacketWrapper.
1455     ///   \li \c kXMP_ExactPacketLength - The padding parameter provides the overall packet length.
1456     ///   The actual amount of padding is computed. An exception is thrown if the packet exceeds
1457     ///   this length with no padding.	Cannot be specified together with
1458     ///   \c kXMP_OmitPacketWrapper.
1459     ///
1460     /// In addition to the above options, you can include one of the following encoding options:
1461     ///   \li \c #kXMP_EncodeUTF8 - Encode as UTF-8, the default.
1462     ///   \li \c #kXMP_EncodeUTF16Big - Encode as big-endian UTF-16.
1463     ///   \li \c #kXMP_EncodeUTF16Little - Encode as little-endian UTF-16.
1464     ///   \li \c #kXMP_EncodeUTF32Big - Encode as big-endian UTF-32.
1465     ///   \li \c #kXMP_EncodeUTF32Little - Encode as little-endian UTF-32.
1466     ///
1467     /// @param padding The amount of padding to be added if a writeable XML packet is created. If
1468     /// zero (the default) an appropriate amount of padding is computed.
1469     ///
1470     /// @param newline The string to be used as a line terminator. If empty, defaults to linefeed,
1471     /// U+000A, the standard XML newline.
1472     ///
1473     /// @param indent The string to be used for each level of indentation in the serialized RDF. If
1474     /// empty, defaults to two ASCII spaces, U+0020.
1475     ///
1476     /// @param baseIndent The number of levels of indentation to be used for the outermost XML
1477     /// element in the serialized RDF. This is convenient when embedding the RDF in other text.
1478 
1479     void SerializeToBuffer ( tStringObj *   rdfString,
1480 							 XMP_OptionBits options,
1481 							 XMP_StringLen  padding,
1482 							 XMP_StringPtr  newline,
1483 							 XMP_StringPtr  indent = "",
1484 							 XMP_Index      baseIndent = 0 ) const;
1485 
1486     // ---------------------------------------------------------------------------------------------
1487     /// @brief \c SerializeToBuffer() serializes metadata in this XMP object into a string as RDF.
1488     ///
1489     /// This simpler form of the function uses default values for the \c newline, \c indent, and
1490     /// \c baseIndent parameters.
1491     ///
1492     /// @param rdfString [out] A string object in which to return the serialized RDF. Must not be null.
1493     ///
1494     /// @param options An options flag that controls how the serialization operation is performed.
1495     /// The specified options must be logically consistent; an exception is thrown if they are not.
1496     /// A logical OR of these bit-flag constants:
1497     ///   \li \c kXMP_OmitPacketWrapper - Do not include an XML packet wrapper. This cannot be
1498     ///   specified together with \c #kXMP_ReadOnlyPacket, \c #kXMP_IncludeThumbnailPad, or
1499     ///   \c #kXMP_ExactPacketLength.
1500     ///   \li \c kXMP_ReadOnlyPacket - Create a read-only XML packet wapper. Cannot be specified
1501     ///   together with \c kXMP_OmitPacketWrapper.
1502     ///   \li \c kXMP_UseCompactFormat - Use a highly compact RDF syntax and layout.
1503     ///   \li \c kXMP_IncludeThumbnailPad - Include typical space for a JPEG thumbnail in the
1504     ///   padding if no \c xmp:Thumbnails property is present. Cannot be specified together with
1505     ///   \c kXMP_OmitPacketWrapper.
1506     ///   \li \c kXMP_ExactPacketLength - The padding parameter provides the overall packet length.
1507     ///   The actual amount of padding is computed. An exception is thrown if the packet exceeds
1508     ///   this length with no padding.	Cannot be specified together with
1509     ///   \c kXMP_OmitPacketWrapper.
1510     ///
1511     /// In addition to the above options, you can include one of the following encoding options:
1512     ///   \li \c #kXMP_EncodeUTF8 - Encode as UTF-8, the default.
1513     ///   \li \c #kXMP_EncodeUTF16Big - Encode as big-endian UTF-16.
1514     ///   \li \c #kXMP_EncodeUTF16Little - Encode as little-endian UTF-16.
1515     ///   \li \c #kXMP_EncodeUTF32Big - Encode as big-endian UTF-32.
1516     ///   \li \c #kXMP_EncodeUTF32Little - Encode as little-endian UTF-32.
1517     ///
1518     /// @param padding The amount of padding to be added if a writeable XML packet is created.
1519     /// If zero (the default) an appropriate amount of padding is computed.
1520 
1521     void SerializeToBuffer ( tStringObj *   rdfString,
1522 							 XMP_OptionBits options = 0,
1523 							 XMP_StringLen  padding = 0 ) const;
1524 
1525     /// @}
1526     // =============================================================================================
1527     // Miscellaneous Member Functions
1528     // ==============================
1529 
1530     // ---------------------------------------------------------------------------------------------
1531     /// \name Helper functions.
1532     /// @{
1533 
1534     // ---------------------------------------------------------------------------------------------
1535     /// @brief Retrieves an internal reference that can be safely passed across DLL boundaries and
1536     /// reconstructed.
1537     ///
1538     /// The \c TXMPMeta class is a normal C++ template, it is instantiated and local to each client
1539     /// executable, as are the other \c TXMP* classes. Different clients might not use the same
1540     /// string type to instantiate \c TXMPMeta.
1541     ///
1542     /// Because of this you should not pass \c SXMPMeta objects, or pointers to \c SXMPMeta objects,
1543     /// across DLL boundaries. Use this function to obtain a safe internal reference that you can
1544     /// pass, then construct a local object on the callee side. This construction does not create a
1545     /// cloned XMP tree, it is the same underlying XMP object safely wrapped in each client's
1546     /// \c SXMPMeta object.
1547     ///
1548     /// Use this function and the associated constructor like this:
1549     ///   \li The callee's header contains:
1550     /// <pre>
1551     /// CalleeMethod ( XMPMetaRef xmpRef );
1552     /// </pre>
1553     ///
1554     ///   \li The caller's code contains:
1555     /// <pre>
1556     /// SXMPMeta callerXMP;
1557     /// CalleeMethod ( callerXMP.GetInternalRef() );
1558     /// </pre>
1559     ///
1560     ///   \li The callee's code contains:
1561     /// <pre>
1562     /// SXMPMeta calleeXMP ( xmpRef );
1563     /// </pre>
1564     ///
1565     /// @return The reference object.
1566 
1567     XMPMetaRef GetInternalRef() const;
1568 
1569     // ---------------------------------------------------------------------------------------------
1570     /// @brief \c GetObjectName() retrieves the client-assigned name of this XMP object.
1571     ///
1572     /// Assign this name with \c SetObjectName().
1573     ///
1574     /// @param name [out] A string object in which to return the name.
1575 
1576     void GetObjectName ( tStringObj * name ) const;
1577 
1578     // ---------------------------------------------------------------------------------------------
1579     /// @brief \c SetObjectName() assigns a name to this XMP object.
1580     ///
1581     /// Retrieve this client-assigned name with \c GetObjectName().
1582     ///
1583     /// @param name The name as a null-terminated UTF-8 string.
1584 
1585     void SetObjectName ( XMP_StringPtr name );
1586 
1587     // ---------------------------------------------------------------------------------------------
1588     /// @brief \c SetObjectName() assigns a name to this XMP object.
1589     ///
1590     /// Retrieve this client-assigned name with \c GetObjectName().
1591     ///
1592     /// @param name The name as a string object.
1593 
1594     void SetObjectName ( tStringObj name );
1595 
1596     // ---------------------------------------------------------------------------------------------
1597     /// @brief \c Sort() sorts the data model tree of an XMP object.
1598     ///
1599     /// Use this function to sort the data model of an XMP object into a canonical order. This can
1600     /// be convenient when comparing data models, (e.g. by text comparison of DumpObject output).
1601     ///
1602     /// At the top level the namespaces are sorted by their prefixes. Within a namespace, the top
1603     /// level properties are sorted by name. Within a struct, the fields are sorted by their
1604     /// qualified name, i.e. their XML prefix:local form. Unordered arrays of simple items are
1605     /// sorted by value. Language Alternative arrays are sorted by the xml:lang qualifiers, with
1606     /// the "x-default" item placed first.
1607 
1608     void Sort();
1609 
1610     // ---------------------------------------------------------------------------------------------
1611     /// @brief \c Erase() restores the object to a "just constructed" state.
1612 
1613     void Erase();
1614 
1615     // ---------------------------------------------------------------------------------------------
1616     /// @brief \c Clone() creates a deep copy of an XMP object.
1617     ///
1618     /// Use this function to copy an entire XMP metadata tree. Assignment and copy constructors only
1619     /// increment a reference count, they do not do a deep copy. This function returns an object,
1620     /// not a pointer. The following shows correct usage:
1621     ///
1622     /// <pre>
1623     /// SXMPMeta * clone1 = new SXMPMeta ( sourceXMP.Clone() );  // This works.
1624     /// SXMPMeta   clone2 ( sourceXMP.Clone );  	// This works also. (Not a pointer.)
1625     /// </pre>
1626     /// The \c clone2 example does not use an explicit pointer.
1627     /// This is good for local usage, protecting against memory leaks.
1628     ///
1629     /// This is an example of incorrect usage:
1630     /// <pre>
1631     /// SXMPMeta * clone3 = &sourceXMP.Clone();		// ! This does not work!
1632     /// </pre>
1633     /// The assignment to \c clone3 creates a temporary object, initializes it with the clone,
1634     /// assigns the address of the temporary to \c clone3, then deletes the temporary.
1635     ///
1636     /// @param options Option flags, not currently defined..
1637     ///
1638     /// @return An XMP object cloned from the original.
1639 
1640     TXMPMeta Clone ( XMP_OptionBits options = 0 ) const;
1641 
1642     // ---------------------------------------------------------------------------------------------
1643     /// @brief \c CountArrayItems() reports the number of items currently defined in an array.
1644     ///
1645     /// @param schemaNS The namespace URI; see \c GetProperty().
1646     ///
1647     /// @param arrayName The name of the array. Can be a general path expression, must not be null
1648     /// or the empty string; see \c GetProperty() for namespace prefix usage.
1649     ///
1650     /// @return The number of items.
1651 
1652     XMP_Index CountArrayItems ( XMP_StringPtr schemaNS,
1653                       			XMP_StringPtr arrayName ) const;
1654 
1655     // ---------------------------------------------------------------------------------------------
1656     /// @brief \c DumpObject() outputs the content of an XMP object to a callback handler for debugging.
1657     ///
1658     /// Invokes a client-defined callback for each line of output.
1659     ///
1660     /// @param outProc The client-defined procedure to handle each line of output.
1661     ///
1662     /// @param clientData A pointer to client-defined data to pass to the handler.
1663     ///
1664     /// @return	A success-fail status value, returned from the handler. Zero is success, failure
1665     /// values are client-defined.
1666     ///
1667     /// @see Static function \c DumpNamespaces()
1668 
1669     XMP_Status DumpObject ( XMP_TextOutputProc outProc,
1670                  			void *	           clientData ) const;
1671 
1672     // ---------------------------------------------------------------------------------------------
1673     /// @brief Not implemented
1674     XMP_OptionBits GetObjectOptions() const;
1675 
1676     // ---------------------------------------------------------------------------------------------
1677     /// \brief Not implemented
1678     void SetObjectOptions ( XMP_OptionBits options );
1679 
1680     /// @}
1681 
1682     // =============================================================================================
1683     // Error notifications
1684     // ===================
1685 
1686     // ---------------------------------------------------------------------------------------------
1687     /// \name Error notifications
1688     /// @{
1689 	///
1690 	/// From the beginning through version 5.5, XMP Tookit errors result in throwing an \c XMP_Error
1691 	/// exception. For the most part exceptions were thrown early and thus API calls aborted as soon
1692 	/// as an error was detected. Starting in version 5.5, support has been added for notifications
1693 	/// of errors arising in calls to \c TXMPMeta functions.
1694 	///
1695 	/// A client can register an error notification callback function for a \c TXMPMeta object. This
1696 	/// can be done as a global default or individually to each object. The global default applies
1697 	/// to all objects created after it is registered. Within the object there is no difference
1698 	/// between the global default or explicitly registered callback. The callback function returns
1699 	/// a \c bool value indicating if recovery should be attempted (true) or an exception thrown
1700 	/// (false). If no callback is registered, a best effort at recovery and continuation will be
1701 	/// made with an exception thrown if recovery is not possible.
1702 	///
1703 	/// The number of notifications delivered for a given TXMPMeta object can be limited. This is
1704 	/// intended to reduce chatter from multiple or cascading errors. The limit is set when the
1705 	/// callback function is registered. This limits the number of notifications of the highest
1706 	/// severity delivered or less. If a higher severity error occurs, the counting starts again.
1707 	/// The limit and counting can be reset at any time, see \c ResetErrorCallbackLimit.
1708 
1709 	//  --------------------------------------------------------------------------------------------
1710 	/// @brief SetDefaultErrorCallback() registers a global default error notification callback.
1711 	///
1712 	/// @param proc The client's callback function.
1713 	///
1714 	/// @param context Client-provided context for the callback.
1715 	///
1716 	/// @param limit A limit on the number of notifications to be delivered.
1717 
1718 	static void SetDefaultErrorCallback ( XMPMeta_ErrorCallbackProc proc, void* context = 0, XMP_Uns32 limit = 1 );
1719 
1720 	//  --------------------------------------------------------------------------------------------
1721 	/// @brief SetErrorCallback() registers an error notification callback.
1722 	///
1723 	/// @param proc The client's callback function.
1724 	///
1725 	/// @param context Client-provided context for the callback.
1726 	///
1727 	/// @param limit A limit on the number of notifications to be delivered.
1728 
1729 	void SetErrorCallback ( XMPMeta_ErrorCallbackProc proc, void* context = 0, XMP_Uns32 limit = 1 );
1730 
1731 	//  --------------------------------------------------------------------------------------------
1732 	/// @brief ResetErrorCallbackLimit() resets the error notification limit and counting. It has no
1733 	///        effect if an error notification callback function is not registered.
1734 	///
1735 	/// @param limit A limit on the number of notifications to be delivered.
1736 
1737 	void ResetErrorCallbackLimit ( XMP_Uns32 limit = 1 );
1738 
1739     /// @}
1740 
1741     // =============================================================================================
1742 
1743     XMPMetaRef xmpRef;  // *** Should be private, see below.
1744 
1745 private:
1746 
1747 #if 0	// *** VS.Net and gcc seem to not handle the friend declarations properly.
1748     friend class TXMPIterator <class tStringObj>;
1749     friend class TXMPUtils <class tStringObj>;
1750 #endif
1751 
1752 	static void SetClientString ( void * clientPtr, XMP_StringPtr valuePtr, XMP_StringLen valueLen );
1753 
1754 };  // class TXMPMeta
1755 
1756 #endif  // __TXMPMeta_hpp__
1757