1 /*! \file	mdobject.h
2  *	\brief	Definition of classes that define metadata objects
3  *
4  *			Class MDObject holds info about a specific metadata object
5  *<br><br>
6  *			Class MDOType holds the definition of MDObjects derived from
7  *			the XML dictionary.
8  *<br><br>
9  *
10  *	\version $Id: mdobject.h,v 1.22 2007/03/31 14:41:00 matt-beard Exp $
11  *
12  */
13 /*
14  *	Copyright (c) 2004, Matt Beard
15  *  Portions copyright (c) 2002, BBC R&D
16  *
17  *	This software is provided 'as-is', without any express or implied warranty.
18  *	In no event will the authors be held liable for any damages arising from
19  *	the use of this software.
20  *
21  *	Permission is granted to anyone to use this software for any purpose,
22  *	including commercial applications, and to alter it and redistribute it
23  *	freely, subject to the following restrictions:
24  *
25  *	  1. The origin of this software must not be misrepresented; you must
26  *	     not claim that you wrote the original software. If you use this
27  *	     software in a product, an acknowledgment in the product
28  *	     documentation would be appreciated but is not required.
29  *
30  *	  2. Altered source versions must be plainly marked as such, and must
31  *	     not be misrepresented as being the original software.
32  *
33  *	  3. This notice may not be removed or altered from any source
34  *	     distribution.
35  */
36 #ifndef MXFLIB__MDOBJECT_H
37 #define MXFLIB__MDOBJECT_H
38 
39 
40 // STL Includes
41 #include <string>
42 #include <list>
43 #include <map>
44 
45 
46 // mxflib includes
47 #include <mxflib/primer.h>
48 
49 
50 namespace mxflib
51 {
52 	//! SymbolSpace used to translate a symbolic name to a UL
53 	class SymbolSpace : public std::map<std::string, ULPtr>, public RefCount<SymbolSpace>
54 	{
55 	protected:
56 		static SymbolSpaceMap AllSymbolSpaces;					//!< Map of all existing symbol spaces by name to allow full searching
57 
58 		std::string SymName;									//!< The name of this symbol space
59 
60 	private:
61  		//! Prevent copy construction by NOT having an implementation to this copy constructor
62 		SymbolSpace(const SymbolSpace &rhs);
63 
64 	public:
65 		//! Construct a new symbol space
SymbolSpace(std::string Name)66 		SymbolSpace(std::string Name) : SymName(Name)
67 		{
68 			SymbolSpaceMap::iterator it = AllSymbolSpaces.find(Name);
69 
70 			if(it != AllSymbolSpaces.end())
71 			{
72 				error("Duplicate symbol space name \"%s\"\n");
73 			}
74 
75 			AllSymbolSpaces.insert(SymbolSpaceMap::value_type(Name, this));
76 		};
77 
78 
79 		//! Add a new symbol to this symbol space
80 		/*! \return true if added OK, else false (most likely a duplicate symbol name)
81 		 */
AddSymbol(std::string Symbol,ULPtr & UL)82 		bool AddSymbol(std::string Symbol, ULPtr &UL)
83 		{
84 			iterator it = find(Symbol);
85 			if(it != end()) return false;
86 
87 			insert(value_type(Symbol, UL));
88 
89 			return true;
90 		}
91 
92 
93 		//! Locate the given symbol in this symbol space, optionally check all other spaces too
94 		ULPtr Find(std::string Symbol, bool SearchAll = false)
95 		{
96 			iterator it = find(Symbol);
97 
98 			if(it != end()) return (*it).second;
99 
100 			if(SearchAll)
101 			{
102 				SymbolSpaceMap::iterator map_it = AllSymbolSpaces.begin();
103 				while(map_it != AllSymbolSpaces.end())
104 				{
105 					it = (*map_it).second->find(Symbol);
106 					if(it != end()) return (*it).second;
107 
108 					map_it++;
109 				}
110 			}
111 
112 			return NULL;
113 		}
114 
115 		//! Find the symbol space with a given name
FindSymbolSpace(std::string Name)116 		static SymbolSpacePtr FindSymbolSpace(std::string Name)
117 		{
118 			SymbolSpaceMap::iterator it = AllSymbolSpaces.find(Name);
119 
120 			if(it != AllSymbolSpaces.end()) return (*it).second;
121 
122 			return NULL;
123 		}
124 
125 		//! Get the name of this symbol space
Name(void)126 		const std::string &Name(void) const { return SymName; }
127 	};
128 }
129 
130 
131 namespace mxflib
132 {
133 	// Forward declare so the class can include pointers to itself
134 	class MDOType;
135 
136 	//! A smart pointer to an MDOType object
137 	typedef SmartPtr<MDOType> MDOTypePtr;
138 
139 	//! A parent pointer to an MDOType object
140 	typedef ParentPtr<MDOType> MDOTypeParent;
141 
142 	//! A list of smart pointers to MDOType objects
143 	typedef std::list<MDOTypePtr> MDOTypeList;
144 
145 	//! A map of object type names to MDOType objects
146 	typedef std::map<std::string, MDOTypePtr> MDOTypeMap;
147 
148 	// Forward declare the ObjectInterface
149 	class ObjectInterface;
150 }
151 
152 
153 
154 namespace mxflib
155 {
156 #define MXFLIB_MAXDICTDEPTH 32
157 
158 	//! Define version with old name for backwards compatibility
159 	typedef ClassUsage DictUse;
160 
161 	//! Make old enum values work for backwards compatibility
162 	const ClassUsage DICT_USE_NONE = ClassUsageNULL;
163 
164 	//! Make old enum values work for backwards compatibility
165 	const ClassUsage DICT_USE_REQUIRED = ClassUsageRequired;
166 
167 	//! Make old enum values work for backwards compatibility
168 	const ClassUsage DICT_USE_ENCODER_REQUIRED = ClassUsageEncoderRequired;
169 
170 	//! Make old enum values work for backwards compatibility
171 	const ClassUsage DICT_USE_DECODER_REQUIRED = ClassUsageDecoderRequired;
172 
173 	//! Make old enum values work for backwards compatibility
174 	const ClassUsage DICT_USE_OPTIONAL = ClassUsageOptional;
175 
176 	//! Make old enum values work for backwards compatibility
177 	const ClassUsage DICT_USE_DARK = ClassUsageDark;
178 
179 	//! Make old enum values work for backwards compatibility
180 	const ClassUsage DICT_USE_TOXIC = ClassUsageToxic;
181 
182 	//! Make old enum values work for backwards compatibility
183 	const ClassUsage DICT_USE_BEST_EFFORT = ClassUsageBestEffort;
184 
185 	/*
186 	** Enumeration type for key formats
187 	*/
188 	typedef enum
189 	{
190 		DICT_KEY_NONE = 0,
191 		DICT_KEY_1_BYTE = 1,
192 		DICT_KEY_2_BYTE = 2,
193 		DICT_KEY_4_BYTE = 4,
194 		DICT_KEY_AUTO = 3
195 	} DictKeyFormat;
196 
197 
198 	/*
199 	** Enumeration type for length formats
200 	*/
201 	typedef enum
202 	{
203 		DICT_LEN_NONE = 0,
204 		DICT_LEN_1_BYTE = 1,
205 		DICT_LEN_2_BYTE = 2,
206 		DICT_LEN_4_BYTE = 4,
207 		DICT_LEN_BER = 3
208 	} DictLenFormat;
209 
210 
211 	//! Define version with old name for backwards compatibility
212 	typedef ClassRef DictRefType;
213 
214 	//! Make old enum values work for backwards compatibility
215 	const ClassRef DICT_REF_NONE = ClassRefNone;
216 
217 	//! Make old enum values work for backwards compatibility
218 	const ClassRef DICT_REF_STRONG = ClassRefStrong;
219 
220 	//! Make old enum values work for backwards compatibility
221 	const ClassRef DICT_REF_WEAK = ClassRefWeak;
222 
223 	//! Make old enum values work for backwards compatibility
224 	const ClassRef DICT_REF_TARGET = ClassRefTarget;
225 
226 
227 /* Notes about the structure of dictionaries...
228    ============================================
229 
230    The dictionary is held as a list of MDOType objects, each of
231    which holds information about a 'type' held in the dictionary.
232 
233    The dictionary is generally tree structured, with some types
234    being children of others (this matches the sets with child items
235    of an MXF file) When an item is a child it contains a pointer to
236    its parent.  Each parent item contain pointers to each child item
237    through derivation from MDOTypeMap (maps child name to pointer to
238    child item). Care should be taken iterating this map as the
239    order is likely to be alphabetical rather than dictionary order
240    so where dictionary order is important (such as packs) iterate
241    through the ChildList property.
242 
243    Inheritance is supported where a type is regarded as a modified
244    version of another (base) type. The mechanism for inheritance is
245    that a derived MDOType will be a copy of the base MDOType
246    with a link back to the base in 'Base'. The 'Children' lists is
247    copied and new child types are added to these lists.
248    If a child of a derived type has the same name as a child of
249    the base it is regarded as a replacement.
250 */
251 }
252 
253 
254 namespace mxflib
255 {
256 	//! Holds the definition of a metadata object type
257 	class MDOType : public RefCount<MDOType>, public MDOTypeMap
258 	{
259 	protected:
260 		MDContainerType ContainerType;
261 
262 		std::string RootName;			//!< Base name of this type
263 
264 	protected:
265 		MDTypePtr ValueType;			//!< Value type if this is an actual data item, else NULL
266 
267 	public:
268 		MDOTypeParent Base;				//!< Base class if this is a derived class, else NULL
269 
270 	protected:
271 		StringList ChildOrder;			//!< Child names in order, for packs	## DEPRECATED - Use ChildList ##
272 		MDOTypeList ChildList;			//!< Child types in order, for packs
273 		MDOTypeParent Parent;			//!< Parent type if this is a child
274 		ULPtr TypeUL;					//!< The UL for this type, or NULL
275 
276 		/* Dictionary data */
277 		DataChunk		Key;			//!< Main key field
278 		DataChunk		GlobalKey;		//!< Global key field (may be a copy of Key)
279 		std::string		DictName;		//!< Short (XML tag) name
280 		std::string		Detail;			//!< Full descriptive name
281 		std::string		TypeName;		//!< Data type name from dictionary (or built from UL found in file?)
282 		DictKeyFormat	KeyFormat;		//!< Format of key of sub-items
283 		DictLenFormat	LenFormat;		//!< Format of length of sub-items
284 		unsigned int	minLength;		//!< Minimum length of value field
285 		unsigned int	maxLength;		//!< Maximum length of value field
286 		DictUse			Use;			//!< Usage requirements
287 		DataChunk		Default;		//!< Default value (if one exists)
288 		DataChunk		DValue;			//!< Distinguished value (if one is defined)
289 		ClassRef		RefType;		//!< Reference type if this is a reference
290 		MDOTypeParent	RefTarget;		//!< Type (or base type) of item this ref source must target
291 		std::string		RefTargetName;	//!< Name of the type (or base type) of item this ref source must target
292 										/*!< \note This must only be used during dictionary parsing or for error reporting,
293 										 *         not for actual reference linking where RefTarget must be used
294 										 */
295 
296 		//! Protected constructor so we can control creation of types
297 		MDOType();
298 
299 	public:
300 		//! Public constructor - build a full type
MDOType(MDContainerType ContainerType,std::string RootName,std::string Name,std::string Detail,MDTypePtr Type,DictKeyFormat KeyFormat,DictLenFormat LenFormat,unsigned int minLen,unsigned int maxLen,DictUse Use)301 		MDOType(MDContainerType ContainerType, std::string RootName, std::string Name, std::string Detail, MDTypePtr Type,
302 				DictKeyFormat KeyFormat, DictLenFormat LenFormat, unsigned int minLen, unsigned int maxLen, DictUse Use)
303 			: ContainerType(ContainerType), RootName(RootName), ValueType(Type), DictName(Name), Detail(Detail),
304 			  KeyFormat(KeyFormat), LenFormat(LenFormat), minLength(minLen), maxLength(maxLen), Use(Use)
305 		{
306 			// MaxLength = 0 is used for maxlength = unbounded
307 			if(maxLength == 0) maxLength = (unsigned int)-1;
308 
309 			if(Type) TypeName = Type->Name();
310 			else TypeName = Name;
311 
312 			// Set the name lookup - UL lookup set when key set
313 			NameLookup[RootName + Name] = this;
314 
315 			// Start of with no referencing details
316 			RefType = ClassRefNone;
317 		};
318 
319 		//! Set the referencing details for this type
320 		void SetRef(ClassRef Type, ULPtr &Target, std::string TargetName = "")
321 		{
322 			ASSERT(Target);
323 
324 			RefType = Type;
325 			RefTarget = Find(Target);
326 
327 			if(!RefTarget)
328 			{
329 				error("Unknown type UL:%s in MDOType::SetRef()\n", Target->GetString().c_str());
330 				return;
331 			}
332 
333 			if(TargetName != "") RefTargetName = TargetName;
334 			else RefTargetName = RefTarget->Name();
335 		}
336 
337 		//! Set the referencing details for this type
338 		void SetRef(ClassRef Type, MDOTypePtr Target, std::string TargetName = "")
339 		{
340 			RefType = Type;
341 			RefTarget = Target;
342 
343 			if(TargetName != "") RefTargetName = TargetName;
344 			else RefTargetName = Target->Name();
345 		}
346 
347 		//! Derive this new entry from a base entry
348 		void Derive(MDOTypePtr &BaseEntry);
349 
350 		//! Re-Derive sub-items from a base entry
351 		/*! Used when the base entry is being extended
352 		 */
353 		void ReDerive(MDOTypePtr &BaseEntry);
354 
355 		//! Access function for ContainerType
GetContainerType(void)356 		const MDContainerType &GetContainerType(void) const { return (const MDContainerType &)ContainerType; };
357 
358 		//! Ref access function
GetRefType(void)359 		ClassRef GetRefType(void) const { return RefType; };
360 
361 		//! Accessor for Reference Target
GetRefTarget(void)362 		MDOTypePtr GetRefTarget(void) const { return RefTarget; };
363 
364 		//! Accessor for Reference Target Name
365 		/*!< \note This must only be used during dictionary parsing or for error reporting,
366 		 *         not for actual reference linking where RefTarget must be used
367 		 */
GetRefTargetName(void)368 		std::string GetRefTargetName(void) const { return RefTargetName; };
369 
370 		//! Get the type name
Name(void)371 		std::string Name(void) const
372 		{
373 			return DictName;
374 		}
375 
376 		//! Get the full type name, including all parents
FullName(void)377 		std::string FullName(void) const
378 		{
379 			return RootName + DictName;
380 		}
381 
382 		//! Read-only access to default value
GetDefault(void)383 		const DataChunk &GetDefault(void) const { return Default; }
384 
385 		//! Read-only access to distinguished value
GetDValue(void)386 		const DataChunk &GetDValue(void) const { return DValue; }
387 
388 		//! Read-only access to the type UL
GetTypeUL(void)389 		const ULPtr &GetTypeUL(void) const { return TypeUL; }
390 
391 		//! Read-only access to the minLength value
GetMinLength(void)392 		unsigned int GetMinLength(void) const { return minLength; }
393 
394 		//! Read-only access to the maxnLength value
GetMaxLength(void)395 		unsigned int GetMaxLength(void) const { return maxLength; }
396 
397 		//! Read-only access to ValueType
GetValueType(void)398 		const MDTypePtr &GetValueType(void) const { return ValueType; }
399 
400 		//! Read-only access to ChildOrder
401 		/*! \note DEPRECATED - Use GetChildList() instead
402 		 */
GetChildOrder(void)403 		const StringList &GetChildOrder(void) const { return ChildOrder; }
404 
405 		//! Read-only access to ChildList
GetChildList(void)406 		const MDOTypeList &GetChildList(void) const { return ChildList; }
407 
408 		//! Locate a named child
Child(std::string Name)409 		MDOTypePtr Child(std::string Name)
410 		{
411 			MDOTypeMap::iterator it = find(Name);
412 			if(it != end()) return (*it).second;
413 			return NULL;
414 		}
415 
416 		//! Locate a child by UL
Child(ULPtr & ChildType)417 		MDOTypePtr Child(ULPtr &ChildType)
418 		{
419 			MDOTypeMap::iterator it = begin();
420 			while(it != end())
421 			{
422 				if(((*it).second->TypeUL) && (*((*it).second->TypeUL) == *ChildType)) return (*it).second;
423 				it++;
424 			}
425 			return NULL;
426 		}
427 
428 		//! Read-only access to KeyFormat
GetKeyFormat(void)429 		const DictKeyFormat &GetKeyFormat(void) const { return KeyFormat; }
430 
431 		//! Read-only access to LenFormat
GetLenFormat(void)432 		const DictLenFormat &GetLenFormat(void) const { return LenFormat; }
433 
434 		//! Insert a new child type
insert(MDOTypePtr NewType)435 		std::pair<iterator, bool> insert(MDOTypePtr NewType)
436 		{
437 			std::string NewName = NewType->Name();
438 			std::pair<iterator, bool> Ret = MDOTypeMap::insert(MDOTypeMap::value_type(NewName, NewType));
439 			ChildList.push_back(NewType);
440 			ChildOrder.push_back(NewName);
441 			return Ret;
442 		}
443 
444 		//! Get the UL for this type
GetUL(void)445 		ULPtr &GetUL(void) { return TypeUL; }
446 
447 		//! Read-only access to the key
GetKey(void)448 		const DataChunk &GetKey(void) { return Key; }
449 
450 		//! Read-only access to the global key
GetGlobalKey(void)451 		const DataChunk &GetGlobalKey(void) { return GlobalKey; }
452 
453 		//! Get the usage for this type
GetUse(void)454 		ClassUsage GetUse(void) { return (ClassUsage)Use; }
455 
456 		//! Determine if this type is derived from a specified type (directly or indirectly)
457 		bool IsA(std::string BaseType);
458 
459 		//! Determine if this type is derived from a specified type (directly or indirectly)
460 		bool IsA(MDOTypePtr &BaseType);
461 
462 		//! Determine if this type is derived from a specified type (directly or indirectly)
463 		bool IsA(const UL &BaseType);
464 
465 		//! Determine if this type is derived from a specified type (directly or indirectly)
IsA(ULPtr & BaseType)466 		bool IsA(ULPtr &BaseType) { return IsA(*BaseType); }
467 
468 		//! Redefine a sub-item in a container
469 		void ReDefine(std::string NewDetail, std::string NewBase, unsigned int NewMinSize, unsigned int NewMaxSize);
470 
471 		//! Redefine a container
ReDefine(std::string NewDetail)472 		void ReDefine(std::string NewDetail)
473 		{
474 			if(NewDetail.length()) Detail = NewDetail;
475 		}
476 
477 	//** Static Dictionary Handling data and functions **
478 	//***************************************************
479 	protected:
480 		static MDOTypeList	AllTypes;	//!< All types managed by this object
481 		static MDOTypeList	TopTypes;	//!< The top-level types managed by this object
482 
483 		//! Map for UL lookups
484 		static std::map<UL, MDOTypePtr> ULLookup;
485 
486 		//! Map for UL lookups - ignoring the version number (all entries use version = 1)
487 		static std::map<UL, MDOTypePtr> ULLookupVer1;
488 
489 		//! Map for reverse lookups based on type name
490 		static MDOTypeMap NameLookup;
491 
492 	public:
493 		//! Bit masks for items that are to be set for this definition in BuildTypeFromDict
494 		/*! This allows some values to be inherited from the base class,
495 		 *  but some to be overridden by this definition.
496 		 *  \note The bits are actually passed in a UInt32.
497 		 *  \note Not all items need a bit as they can be validated.
498 		 */
499 		enum DictionaryItems
500 		{
501 			DICT_ITEM_USE = 1,
502 			DICT_ITEM_REFTYPE = 2,
503 			DICT_ITEM_CONTAINERTYPE = 4,
504 			DICT_ITEM_MINLENGTH = 8,
505 			DICT_ITEM_MAXLENGTH = 16,
506 			DICT_ITEM_KEYFORMAT = 32,
507 			DICT_ITEM_LENFORMAT = 64,
508 			DICT_ITEM_DVALUE = 128
509 		};
510 
511 	protected:
512 		//! Basic primer for use when parsing non-primer partitions
513 		static PrimerPtr StaticPrimer;
514 
515 	public:
516 		//! Load the dictionary
517 		static void LoadDict(const char *DictFile, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols)
518 		{
519 			LoadDictionary(DictFile, DefaultSymbolSpace);
520 		}
521 
522 		//! Locate reference target types for any types not yet located
523 		static void LocateRefTypes(void);
524 
525 		//! Build a primer
526 		static PrimerPtr MakePrimer(bool SetStatic = false);
527 
528 		//! Get the static primer (make one if required)
GetStaticPrimer(void)529 		static PrimerPtr GetStaticPrimer(void)
530 		{
531 			if( !StaticPrimer) MakePrimer(true);
532 			return StaticPrimer;
533 		}
534 
535 		//! Find a type in the default symbol space, optionally searching all others
536 		static MDOTypePtr Find(std::string BaseType, bool SearchAll = false) { return Find(BaseType, MXFLibSymbols, SearchAll); }
537 
538 		//! Find a type in a specified symbol space, optionally searching all others
539 		static MDOTypePtr Find(std::string BaseType, SymbolSpacePtr &SymSpace, bool SearchAll = false);
540 
541 		static MDOTypePtr Find(const UL& BaseUL);
542 		static MDOTypePtr Find(Tag BaseTag, PrimerPtr BasePrimer);
543 
544 		static MDOTypePtr DefineClass(ClassRecordPtr &ThisClass, SymbolSpacePtr DefaultSymbolSpace, MDOTypePtr Parent = NULL);
545 
546 		static MDOTypePtr DefineClass(ClassRecordPtr &ThisClass, MDOTypePtr Parent = NULL, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols)
547 		{
548 			return DefineClass(ThisClass, DefaultSymbolSpace, Parent);
549 		}
550 
551 	protected:
552 		static void XML_startElement(void *user_data, const char *name, const char **attrs);
553 		static void XML_endElement(void *user_data, const char *name);
554 		static void XML_warning(void *user_data, const char *msg, ...);
555 		static void XML_error(void *user_data, const char *msg, ...);
556 		static void XML_fatalError(void *user_data, const char *msg, ...);
557 	};
558 }
559 
560 
561 namespace mxflib
562 {
563 	// Forward declare so the class can include pointers to itself
564 	class MDObject;
565 	class MDObjectPtr;
566 	class MDObjectParent;
567 
568 	//! A smart pointer to an MDObject object (with operator[] overloads)
569 	class MDObjectPtr : public SmartPtr<MDObject>
570 	{
571 	public:
MDObjectPtr()572 		MDObjectPtr() : SmartPtr<MDObject>() {};
573 //		MDObjectPtr(MDObject * ptr) : SmartPtr<MDObject>(ptr) {};
MDObjectPtr(IRefCount<MDObject> * ptr)574 		MDObjectPtr(IRefCount<MDObject> * ptr) : SmartPtr<MDObject>(ptr) {};
575 
576 		//! Child access operators that overcome dereferencing problems with SmartPtrs
577 		MDObjectPtr operator[](const char *ChildName);
578 		MDObjectPtr operator[](MDOTypePtr &ChildType);
579 		MDObjectPtr operator[](const UL &ChildType);
580 		MDObjectPtr operator[](ULPtr &ChildType);
581 	};
582 
583 	//! A parent pointer to an MDObject object (with operator[] overloads)
584 	class MDObjectParent : public ParentPtr<MDObject>
585 	{
586 	public:
MDObjectParent()587 		MDObjectParent() : ParentPtr<MDObject>() {};
MDObjectParent(IRefCount<MDObject> * ptr)588 		MDObjectParent(IRefCount<MDObject> * ptr) : ParentPtr<MDObject>(ptr) {};
589 
590 		//! Set value from a smart pointer
591 		/*! \note Not a perfect operator= as no return value is created (too inefficient) */
592 		void operator=(const MDObjectPtr &sp) { SmartPtr<MDObject>::operator=(sp); }
593 
594 		//! Set value from a pointer
595 		/*! \note Not a perfect operator= as no return value is created (too inefficient) */
596 		void operator=(RefCount<MDObject> *Ptr) { SmartPtr<MDObject>::operator=(Ptr); }
597 
598 		//! Child access operators that overcome dereferencing problems with SmartPtrs
599 		MDObjectPtr operator[](const char *ChildName);
600 		MDObjectPtr operator[](MDOTypePtr &ChildType);
601 		MDObjectPtr operator[](const UL &ChildType);
602 		MDObjectPtr operator[](ULPtr &ChildType);
603 	};
604 
605 	//! A list of smart pointers to MDObject objects
606 	class MDObjectList : public RefCount<MDObjectList>, public std::list<MDObjectPtr> {};
607 	typedef SmartPtr<MDObjectList> MDObjectListPtr;
608 
609 	//! A list of smart pointers to MDObject objects with names
610 	typedef std::pair<std::string,MDObjectPtr> MDObjectNamedListItem;
611 	typedef std::list<MDObjectNamedListItem> MDObjectNamedList;
612 
613 	//! A list of smart pointers to MDObject objects with ULs
614 	typedef std::pair<UL,MDObjectPtr> MDObjectULListItem;
615 	typedef std::list<MDObjectULListItem> MDObjectULList;
616 }
617 
618 
619 namespace mxflib
620 {
621 	//! Metadata Object class
622 	class MDObject : public RefCount<MDObject>, public MDObjectULList
623 	{
624 	protected:
625 		MDOTypePtr Type;
626 
627 		MDObjectPtr Link;
628 
629 		bool IsConstructed;				//!< True if this object is constructed, false if read from a file or a parent object
630 		UInt64 ParentOffset;			//!< Offset from start of parent object if read from file or object
631 		UInt32 KLSize;					//!< Size of this objects KL if read from file or parent object
632 		MDObjectParent Parent;			//!< Pointer to parent if read from inside another object
633 		MXFFileParent ParentFile;		//!< Pointer to parent file if read from a file
634 		ULPtr TheUL;					//!< The UL for this object (if known)
635 		Tag TheTag;						//!< The local tag used for this object (if known)
636 
637 		std::string ObjectName;			//!< The name of this object (normally the name of the type)
638 
639 		bool Modified;					//!< True if this object has been modified since being "read"
640 										/*!< This is used to automatically update the GenerationUID when writing the object */
641 
642 		ObjectInterface *Outer;			//!< Pointer to outer object if this is a sub-object of an ObjectInterface derived object
643 
644 	public:
645 		//! Pointer to a translator function to translate unknown ULs to object names
646 		typedef std::string (*ULTranslator)(ULPtr,const Tag *);
647 
648 	protected:
649 		//! Translator function to translate unknown ULs to object names
650 		static ULTranslator UL2NameFunc;
651 
652 		//! Static flag to say if dark metadata sets that appear to be valid KLV 2x2 sets should be parsed
653 		static bool ParseDark;
654 
655 	public:
656 		MDValuePtr Value;
657 
658 	protected:
659 		//! MDObject UL based constructor body
660 		/*! Builds a "blank" metadata object of a specified type
661 		 *	\note packs are built with default values
662 		 *
663 		 *  \note TheUL must be set before calling
664 		 */
665 		void ULCtor(void);
666 
667 	public:
668 		//! Construct a new MDObject of the specified type
669 		/*! BaseType is a symbol to be located in the given SymbolSpace - if no SymbolSpace is specifed the default MXFLib space is used
670 		 */
671 		MDObject(std::string BaseType, SymbolSpacePtr &SymSpace = MXFLibSymbols );
672 
673 		//! Construct a new MDObject of the specified type
674 		MDObject(MDOTypePtr BaseType);
675 
676 		//! Construct a new MDObject of the type with the specified UL
MDObject(const UL & BaseUL)677 		MDObject(const UL &BaseUL) { TheUL = new UL(BaseUL); ULCtor(); }
678 
679 		//! Construct a new MDObject of the type with the specified UL
MDObject(const ULPtr & BaseUL)680 		MDObject(const ULPtr &BaseUL) { TheUL = BaseUL; ULCtor(); }
681 
682 		//! Construct a new MDObject of the type with the specified UL
683 		MDObject(Tag BaseTag, PrimerPtr BasePrimer);
684 
685 		//! Generic constructor - called after each specific constructor has done its specific bits
686 		void Init(void);
687 
688 		//! Destroy an MDObject
689 		~MDObject();
690 
691 		//! Add a new child MDObject of the specified type
692 		/*! ChildName is a symbol to be located in default MXFLib SymbolSpace
693 		 */
AddChild(std::string ChildName,bool Replace)694 		MDObjectPtr AddChild(std::string ChildName, bool Replace) { return AddChild(ChildName, MXFLibSymbols, Replace); }
695 
696 		//! Add a new child MDObject of the specified type
697 		/*! ChildName is a symbol to be located in the given SymbolSpace - if no SymbolSpace is specifed the default MXFLib space is used
698 		 */
699 		MDObjectPtr AddChild(std::string ChildName, SymbolSpacePtr &SymSpace = MXFLibSymbols, bool Replace = true);
700 
701 
702 		//! Add a new child MDObject of the specified type
703 		MDObjectPtr AddChild(MDOTypePtr ChildType, bool Replace = true);
704 
705 		//! Add a new child MDObject to a vector
706 		/*! \note The type of the object added is automatic.
707 		 *        If the vector is of multiple members the next type will be chosen by the number of members currently
708 		 *        in the array, so if there are 3 sub member types the 7th entry will be type 1 [ 7 = (2*3) + 1 ]
709 		 *
710 		 *  \note This version of AddChild will <b>not</b> replace duplicates, it always appends
711 		 */
712 		MDObjectPtr AddChild(void);
713 
714 		//! Add a new child MDObject of the specified type
715 		MDObjectPtr AddChild(const UL &ChildType, bool Replace = true);
716 
717 		//! Add a new child MDObject of the specified type
718 		MDObjectPtr AddChild(ULPtr &ChildType, bool Replace = true) { return AddChild(*ChildType, Replace); }
719 
720 		//! Add a new child MDObject of the specified type
721 		MDObjectPtr AddChild(MDObjectPtr &ChildObject, bool Replace = false);
722 
723 	protected:
724 		//! Add a new child MDObject of the specified type
725 		/*! Same as AddChild(), but does not set "Modified"
726 		 */
727 		MDObjectPtr AddChildInternal(MDObjectPtr ChildObject, bool Replace = false);
728 
729 	public:
730 
731 		//! Remove the (first) child of the specified type
732 		void RemoveChild(std::string ChildName);
733 
734 		//! Remove the (first) child of the specified type
735 		void RemoveChild(MDOTypePtr &ChildType);
736 
737 		//! Remove the (first) child of the specified type
738 		void RemoveChild(ULPtr &ChildType);
739 
740 		//! Remove the specified child
741 		void RemoveChild(MDObjectPtr ChildObject);
742 
743 		//! Access function for child values of compound items
744 		MDObjectPtr operator[](std::string ChildName);
Child(std::string ChildName)745 		MDObjectPtr Child(std::string ChildName) { return operator[](ChildName); };
746 		MDObjectListPtr ChildList(std::string ChildName);
747 		MDObjectListPtr ChildList(const UL &ChildType);
ChildList(const ULPtr & ChildType)748 		MDObjectListPtr ChildList(const ULPtr &ChildType) { return ChildList(*ChildType); };
749 		MDObjectPtr operator[](MDOTypePtr ChildType);
Child(MDOTypePtr ChildType)750 		MDObjectPtr Child(MDOTypePtr ChildType) { return operator[](ChildType); };
751 		MDObjectListPtr ChildList(MDOTypePtr ChildType);
752 		MDObjectPtr operator[](const UL &ChildType);
753 		MDObjectPtr operator[](ULPtr &ChildType) { return operator[](*ChildType); };
Child(const UL & ChildType)754 		MDObjectPtr Child(const UL &ChildType) { return operator[](ChildType); };
Child(ULPtr & ChildType)755 		MDObjectPtr Child(ULPtr &ChildType) { return operator[](*ChildType); };
756 		MDObjectListPtr ChildList(ULPtr &ChildType);
757 
SetInt(Int32 Val)758 		void SetInt(Int32 Val) { SetModified(true); if (Value) Value->SetInt(Val); };
SetInt64(Int64 Val)759 		void SetInt64(Int64 Val) { SetModified(true); if (Value) Value->SetInt64(Val); };
SetUInt(UInt32 Val)760 		void SetUInt(UInt32 Val) { SetModified(true); if (Value) Value->SetUInt(Val); };
SetUInt64(UInt64 Val)761 		void SetUInt64(UInt64 Val) { SetModified(true); if (Value) Value->SetUInt64(Val); };
SetUint(UInt32 Val)762 		void SetUint(UInt32 Val) { SetUInt(Val); }
SetUint64(UInt64 Val)763 		void SetUint64(UInt64 Val) { SetUInt64(Val); }
SetString(std::string Val)764 		void SetString(std::string Val)	{ SetModified(true); if (Value) Value->SetString(Val); };
765 		bool SetDValue(void);
SetValue(const DataChunk & Source)766 		void SetValue(const DataChunk &Source) { ReadValue(Source); }
SetValue(MDObjectPtr Source)767 		void SetValue(MDObjectPtr Source) { ReadValue(Source->Value->PutData()); }
768 		Int32 GetInt(Int32 Default = 0) { if (Value) return Value->GetInt(); else return Default; };
769 		Int64 GetInt64(Int64 Default = 0) { if (Value) return Value->GetInt64(); else return Default; };
770 		UInt32 GetUInt(UInt32 Default = 0) { if (Value) return Value->GetUInt(); else return Default; };
771 		UInt64 GetUInt64(UInt64 Default = 0) { if(Value) return Value->GetUInt64(); else return Default; };
772 		UInt32 GetUint(UInt32 Default = 0) { return GetUInt(Default); }
773 		UInt64 GetUint64(UInt64 Default = 0) { return GetUInt64(Default); }
774 		std::string GetString(std::string Default = "")	{ if(Value) return Value->GetString(); else return Default; };
775 		bool IsDValue(void);
776 
777 		//! Set the default value for this object
778 		/*! \return true is a default value is set, else false */
SetDefault(void)779 		bool SetDefault(void)
780 		{
781 			if(!Value) return false;
782 
783 			ASSERT(Type);
784 
785 			if(Type->GetDefault().Size == 0) return false;
786 
787 			Value->ReadValue(Type->GetDefault());
788 
789 			return true;
790 		}
791 
792 
793 		/* Child value access */
794 		// For set functions AddChild is used (without replace option)
795 		// to ensure that the child exists and to set the modified flag
SetInt(const char * ChildName,Int32 Val)796 		void SetInt(const char *ChildName, Int32 Val)
797 		{
798 			MDObjectPtr Ptr = AddChild(ChildName);
799 			if (Ptr) Ptr->SetInt(Val);
800 			else if(Value) { SetModified(true); Value->SetInt(ChildName, Val); }
801 		};
SetInt64(const char * ChildName,Int64 Val)802 		void SetInt64(const char *ChildName, Int64 Val)
803 		{
804 			MDObjectPtr Ptr = AddChild(ChildName);
805 			if (Ptr) Ptr->SetInt64(Val);
806 			else if(Value) { SetModified(true); Value->SetInt64(ChildName, Val); }
807 		};
SetUInt(const char * ChildName,UInt32 Val)808 		void SetUInt(const char *ChildName, UInt32 Val)
809 		{
810 			MDObjectPtr Ptr = AddChild(ChildName);
811 			if (Ptr) Ptr->SetUInt(Val);
812 			else if(Value) { SetModified(true); Value->SetUInt(ChildName, Val); }
813 		};
SetUInt64(const char * ChildName,UInt64 Val)814 		void SetUInt64(const char *ChildName, UInt64 Val)
815 		{
816 			MDObjectPtr Ptr = AddChild(ChildName);
817 			if (Ptr) Ptr->SetUInt64(Val);
818 			else if(Value) { SetModified(true); Value->SetUInt64(ChildName, Val); }
819 		};
SetUint(const char * ChildName,UInt32 Val)820 		void SetUint(const char *ChildName, UInt32 Val) { SetUInt(ChildName, Val); }
SetUint64(const char * ChildName,UInt64 Val)821 		void SetUint64(const char *ChildName, UInt64 Val) { SetUInt64(ChildName, Val); }
822 
SetString(const char * ChildName,std::string Val)823 		void SetString(const char *ChildName, std::string Val)
824 		{
825 			MDObjectPtr Ptr = AddChild(ChildName);
826 			if (Ptr) Ptr->SetString(Val);
827 			else if(Value) { SetModified(true); Value->SetString(ChildName, Val); }
828 		};
829 
SetDValue(const char * ChildName)830 		bool SetDValue(const char *ChildName)
831 		{
832 			MDObjectPtr Ptr = AddChild(ChildName);
833 			if (Ptr) return Ptr->SetDValue(); else return false;
834 		};
835 
SetValue(const char * ChildName,const DataChunk & Source)836 		void SetValue(const char *ChildName, const DataChunk &Source)
837 		{
838 			MDObjectPtr Ptr = AddChild(ChildName);
839 			if (Ptr) Ptr->ReadValue(Source);
840 			else if(Value) { SetModified(true); Value->ReadValue(ChildName, Source); }
841 		};
842 
SetValue(const char * ChildName,MDObjectPtr Source)843 		void SetValue(const char *ChildName, MDObjectPtr Source)
844 		{
845 			MDObjectPtr Ptr = AddChild(ChildName);
846 			if (Ptr) Ptr->ReadValue(Source->Value->PutData());
847 			else if(Value) { SetModified(true); Value->ReadValue(ChildName, Source->Value->PutData()); }
848 		};
849 
850 		Int32 GetInt(const char *ChildName, Int32 Default = 0)
851 		{
852 			MDObjectPtr Ptr = operator[](ChildName);
853 			if (Ptr) return Ptr->GetInt(); else if(Value) return Value->GetInt(ChildName, Default); else return Default;
854 		};
855 
856 		Int64 GetInt64(const char *ChildName, Int64 Default = 0)
857 		{
858 			MDObjectPtr Ptr = operator[](ChildName);
859 			if (Ptr) return Ptr->GetInt64(); else if(Value) return Value->GetInt64(ChildName, Default); else return Default;
860 		};
861 
862 		UInt32 GetUInt(const char *ChildName, UInt32 Default = 0)
863 		{
864 			MDObjectPtr Ptr = operator[](ChildName);
865 			if (Ptr) return Ptr->GetUInt(); else if(Value) return Value->GetUInt(ChildName, Default); else return Default;
866 		};
867 
868 		UInt64 GetUInt64(const char *ChildName, UInt64 Default = 0)
869 		{
870 			MDObjectPtr Ptr = operator[](ChildName);
871 			if (Ptr) return Ptr->GetUInt64(); else if(Value) return Value->GetUInt64(ChildName, Default); else return Default;
872 		};
873 
874 		UInt32 GetUint(const char *ChildName, UInt32 Default = 0) { return GetUInt(ChildName, Default); }
875 		UInt64 GetUint64(const char *ChildName, UInt64 Default = 0)  { return GetUInt64(ChildName, Default); }
876 
877 		std::string GetString(const char *ChildName, std::string Default = "")
878 		{
879 			MDObjectPtr Ptr = operator[](ChildName);
880 			if (Ptr) return Ptr->GetString(); else if(Value) return Value->GetString(ChildName, Default); else return Default;
881 		};
882 
IsDValue(const char * ChildName)883 		bool IsDValue(const char *ChildName)
884 		{
885 			MDObjectPtr Ptr = operator[](ChildName);
886 			if (Ptr) return Ptr->IsDValue(); else return false;
887 		};
888 
SetInt(const UL & ChildType,Int32 Val)889 		void SetInt(const UL &ChildType, Int32 Val)
890 		{
891 			MDObjectPtr Ptr = AddChild(ChildType);
892 			if (Ptr) Ptr->SetInt(Val);
893 		};
SetInt(ULPtr & ChildType,Int32 Val)894 		void SetInt(ULPtr &ChildType, Int32 Val) { SetInt(*ChildType, Val); }
895 
SetInt64(const UL & ChildType,Int64 Val)896 		void SetInt64(const UL &ChildType, Int64 Val)
897 		{
898 			MDObjectPtr Ptr = AddChild(ChildType);
899 			if (Ptr) Ptr->SetInt64(Val);
900 		};
SetInt64(ULPtr & ChildType,Int64 Val)901 		void SetInt64(ULPtr &ChildType, Int64 Val) { SetInt64(*ChildType, Val); }
902 
SetUInt(const UL & ChildType,UInt32 Val)903 		void SetUInt(const UL &ChildType, UInt32 Val)
904 		{
905 			MDObjectPtr Ptr = AddChild(ChildType);
906 			if (Ptr) Ptr->SetUInt(Val);
907 		};
SetUInt(ULPtr & ChildType,UInt32 Val)908 		void SetUInt(ULPtr &ChildType, UInt32 Val) { SetUInt(*ChildType, Val); }
909 
SetUInt64(const UL & ChildType,UInt64 Val)910 		void SetUInt64(const UL &ChildType, UInt64 Val)
911 		{
912 			MDObjectPtr Ptr = AddChild(ChildType);
913 			if (Ptr) Ptr->SetUInt64(Val);
914 		};
SetUInt64(ULPtr & ChildType,UInt64 Val)915 		void SetUInt64(ULPtr &ChildType, UInt64 Val) { SetUInt64(*ChildType, Val); }
916 
SetString(const UL & ChildType,std::string Val)917 		void SetString(const UL &ChildType, std::string Val)
918 		{
919 			MDObjectPtr Ptr = AddChild(ChildType);
920 			if (Ptr) Ptr->SetString(Val);
921 		};
SetString(ULPtr & ChildType,std::string Val)922 		void SetString(ULPtr &ChildType, std::string Val) { SetString(*ChildType, Val); }
923 
SetDValue(const UL & ChildType)924 		bool SetDValue(const UL &ChildType)
925 		{
926 			MDObjectPtr Ptr = AddChild(ChildType);
927 			if (Ptr) return Ptr->SetDValue(); else return false;
928 		};
SetDValue(ULPtr & ChildType)929 		bool SetDValue(ULPtr &ChildType) { return SetDValue(*ChildType); }
930 
SetValue(const UL & ChildType,const DataChunk & Source)931 		void SetValue(const UL &ChildType, const DataChunk &Source)
932 		{
933 			MDObjectPtr Ptr = AddChild(ChildType);
934 			if (Ptr) Ptr->ReadValue(Source);
935 		};
SetValue(ULPtr & ChildType,const DataChunk & Source)936 		void SetValue(ULPtr &ChildType, const DataChunk &Source) { SetValue(*ChildType, Source); }
937 
SetValue(const UL & ChildType,MDObjectPtr Source)938 		void SetValue(const UL &ChildType, MDObjectPtr Source)
939 		{
940 			MDObjectPtr Ptr = AddChild(ChildType);
941 			if (Ptr) Ptr->ReadValue(Source->Value->PutData());
942 		};
SetValue(ULPtr & ChildType,MDObjectPtr Source)943 		void SetValue(ULPtr &ChildType, MDObjectPtr Source) { SetValue(*ChildType, Source); }
944 
945 		Int32 GetInt(const UL &ChildType, Int32 Default = 0)
946 		{
947 			MDObjectPtr Ptr = operator[](ChildType);
948 			if (Ptr) return Ptr->GetInt(); else return Default;
949 		};
950 		Int32 GetInt(ULPtr &ChildType, Int32 Default = 0) { return GetInt(*ChildType, Default); }
951 
952 		Int64 GetInt64(const UL &ChildType, Int64 Default = 0)
953 		{
954 			MDObjectPtr Ptr = operator[](ChildType);
955 			if (Ptr) return Ptr->GetInt64(); else return Default;
956 		};
957 		Int64 GetInt64(ULPtr &ChildType, Int64 Default = 0) { return GetInt64(*ChildType, Default); }
958 
959 		UInt32 GetUInt(const UL &ChildType, UInt32 Default = 0)
960 		{
961 			MDObjectPtr Ptr = operator[](ChildType);
962 			if (Ptr) return Ptr->GetUInt(); else return Default;
963 		};
964 		UInt32 GetUInt(ULPtr &ChildType, UInt32 Default = 0) { return GetUInt(*ChildType, Default); }
965 
966 		UInt64 GetUInt64(const UL &ChildType, UInt64 Default = 0)
967 		{
968 			MDObjectPtr Ptr = operator[](ChildType);
969 			if (Ptr) return Ptr->GetUInt64(); else return Default;
970 		};
971 		UInt64 GetUInt64(ULPtr &ChildType, UInt64 Default = 0) { return GetUInt64(*ChildType, Default); }
972 
973 		std::string GetString(const UL &ChildType, std::string Default = "")
974 		{
975 			MDObjectPtr Ptr = operator[](ChildType);
976 			if (Ptr) return Ptr->GetString(); else return Default;
977 		};
978 		std::string GetString(ULPtr &ChildType, std::string Default = "") { return GetString(*ChildType, Default); }
979 
IsDValue(const UL & ChildType)980 		bool IsDValue(const UL &ChildType) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->IsDValue(); else return false; };
IsDValue(ULPtr & ChildType)981 		bool IsDValue(ULPtr &ChildType) { return IsDValue(*ChildType); }
982 
SetInt(MDOTypePtr ChildType,Int32 Val)983 		void SetInt(MDOTypePtr ChildType, Int32 Val) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->SetInt(Val); };
SetInt64(MDOTypePtr ChildType,Int64 Val)984 		void SetInt64(MDOTypePtr ChildType, Int64 Val) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->SetInt64(Val); };
SetUInt(MDOTypePtr ChildType,UInt32 Val)985 		void SetUInt(MDOTypePtr ChildType, UInt32 Val) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->SetUInt(Val); };
SetUInt64(MDOTypePtr ChildType,UInt64 Val)986 		void SetUInt64(MDOTypePtr ChildType, UInt64 Val) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->SetUInt64(Val); };
SetUint(MDOTypePtr ChildType,UInt32 Val)987 		void SetUint(MDOTypePtr ChildType, UInt32 Val) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->SetUInt(Val); };
SetUint64(MDOTypePtr ChildType,UInt64 Val)988 		void SetUint64(MDOTypePtr ChildType, UInt64 Val) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->SetUInt64(Val); };
SetString(MDOTypePtr ChildType,std::string Val)989 		void SetString(MDOTypePtr ChildType, std::string Val) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->SetString(Val); };
SetDValue(MDOTypePtr ChildType)990 		bool SetDValue(MDOTypePtr ChildType) { MDObjectPtr Ptr = AddChild(ChildType); if (Ptr) return Ptr->SetDValue(); else return false; };
SetValue(MDOTypePtr ChildType,MDObjectPtr Source)991 		void SetValue(MDOTypePtr ChildType, MDObjectPtr Source) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->ReadValue(Source->Value->PutData()); }
SetValue(MDOTypePtr ChildType,const DataChunk & Source)992 		void SetValue(MDOTypePtr ChildType, const DataChunk &Source) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) Ptr->ReadValue(Source); }
993 		Int32 GetInt(MDOTypePtr ChildType, Int32 Default = 0) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->GetInt(); else return Default; };
994 		Int64 GetInt64(MDOTypePtr ChildType, Int64 Default = 0) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->GetInt64(); else return Default; };
995 		UInt32 GetUInt(MDOTypePtr ChildType, UInt32 Default = 0) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->GetUInt(); else return Default; };
996 		UInt64 GetUInt64(MDOTypePtr ChildType, UInt64 Default = 0) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->GetUInt64(); else return Default; };
997 		UInt32 GetUint(MDOTypePtr ChildType, UInt32 Default = 0) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->GetUInt(); else return Default; };
998 		UInt64 GetUint64(MDOTypePtr ChildType, UInt64 Default = 0) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->GetUInt64(); else return Default; };
999 		std::string GetString(MDOTypePtr ChildType, std::string Default = "") { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->GetString(); else return Default; };
IsDValue(MDOTypePtr ChildType)1000 		bool IsDValue(MDOTypePtr ChildType) { MDObjectPtr Ptr = operator[](ChildType); if (Ptr) return Ptr->IsDValue(); else return false; };
1001 
1002 		/* Child raw data access */
1003 		//! Get a reference to the data chunk (const to prevent setting!!)
GetData(void)1004 		const DataChunk& GetData(void) { ASSERT(Value); return Value->GetData(); };
1005 
1006 		//! Build a data chunk with all this item's data (including child data)
1007 		const DataChunkPtr PutData(PrimerPtr UsePrimer = NULL);
1008 
1009 		//! Read the object's value from a data chunk
ReadValue(const DataChunk & Chunk)1010 		size_t ReadValue(const DataChunk &Chunk) { return ReadValue(Chunk.Data, Chunk.Size); };
1011 
1012 		//! Read the object's value from a data chunk pointer
ReadValue(DataChunkPtr & Chunk)1013 		size_t ReadValue(DataChunkPtr &Chunk) { return ReadValue(Chunk->Data, Chunk->Size); };
1014 
1015 		//! Read the object's value from a memory buffer
1016 		size_t ReadValue(const UInt8 *Buffer, size_t Size, PrimerPtr UsePrimer = NULL);
1017 
1018 		//! Write this object to a new memory buffer
1019 		DataChunkPtr WriteObject(MDObjectPtr ParentObject, PrimerPtr UsePrimer, UInt32 BERSize = 0)
1020 		{
1021 			DataChunkPtr Ret = new DataChunk;
1022 			WriteObject(Ret, ParentObject, UsePrimer, BERSize);
1023 			return Ret;
1024 		}
1025 
1026 		//! Write this object to a memory buffer
1027 		size_t WriteObject(DataChunkPtr &Buffer, MDObjectPtr ParentObject, PrimerPtr UsePrimer, UInt32 BERSize = 0);
1028 
1029 		//! Write this top level object to a new memory buffer
1030 		/*! The object must be at the outer or top KLV level
1031 		 *	\return The new buffer
1032 		 */
1033 		DataChunkPtr WriteObject(PrimerPtr UsePrimer = NULL, UInt32 BERSize = 0)
1034 		{
1035 			DataChunkPtr Ret = new DataChunk;
1036 			WriteObject(Ret, NULL, UsePrimer, BERSize);
1037 			return Ret;
1038 		}
1039 
1040 		//! Write this top level object to a memory buffer
1041 		/*! The object must be at the outer or top KLV level. The object is appended to the buffer
1042 		 *	\return The number of bytes written
1043 		 */
1044 		size_t WriteObject(DataChunkPtr &Buffer, PrimerPtr UsePrimer = NULL, UInt32 BERSize = 0)
1045 		{
1046 			return WriteObject(Buffer, NULL, UsePrimer, BERSize);
1047 		}
1048 
1049 		//! Write this object, and any strongly linked sub-objects, to a memory buffer
1050 		size_t WriteLinkedObjects(DataChunkPtr &Buffer, PrimerPtr UsePrimer = NULL);
1051 
1052 		//! Report the name of this item (the name of its type)
Name(void)1053 		std::string Name(void) const { return ObjectName; };
1054 
1055 		//! Report the full name of this item (the full name of its type)
FullName(void)1056 		std::string FullName(void) const
1057 		{
1058 			if(Parent) return Parent->FullName() + "/" + ObjectName;
1059 			else return ObjectName;
1060 		};
1061 
1062 		//! Inset a new child object - overloads the existing MDObjectList version
insert(MDObjectPtr NewObject)1063 		void insert(MDObjectPtr NewObject)
1064 		{
1065 			if(NewObject->TheUL)
1066 				push_back(MDObjectULList::value_type(*(NewObject->TheUL), NewObject));
1067 			else
1068 				ASSERT(0);
1069 //				push_back(MDObjectULList::value_type(Null_UL, NewObject));
1070 		}
1071 
1072 		//! Type access function
GetType(void)1073 		const MDOTypePtr &GetType(void) const { return Type; };
1074 
1075 		//! Determine if this object is derived from a specified type (directly or indirectly)
1076 		bool IsA(std::string BaseType);
1077 
1078 		//! Determine if this object is derived from a specified type (directly or indirectly)
1079 		bool IsA(MDOTypePtr &BaseType);
1080 
1081 		//! Determine if this object is derived from a specified type (directly or indirectly)
1082 		bool IsA(const UL &BaseType);
1083 
1084 		//! Determine if this object is derived from a specified type (directly or indirectly)
IsA(ULPtr & BaseType)1085 		bool IsA(ULPtr &BaseType) { return IsA(*BaseType); }
1086 
1087 		//! Link access functions
GetLink(void)1088 		MDObjectPtr GetLink(void) const { return Link; };
1089 
1090 		//! Make a link from this reference source to the specified target set
1091 		bool MakeRef(MDObjectPtr &TargetSet, bool ForceLink = false);
1092 
1093 		//! DEPRECATED: Make a link from this reference source to the specified target set
1094 		/*! \note This method is deprecated - use MakeRef() instead */
1095 		bool MakeLink(MDObjectPtr &TargetSet, bool ForceLink = false) { return MakeRef(TargetSet, ForceLink); }
1096 
1097 		//! Record that a link exists (not the same as making a link - see MakeRef)
SetLink(MDObjectPtr NewLink)1098 		void SetLink(MDObjectPtr NewLink) { Link = NewLink; };
1099 
1100 		//! Ref access function
GetRefType(void)1101 		ClassRef GetRefType(void) const { ASSERT(Type); return Type->GetRefType(); };
1102 
1103 		//! Accessor for Reference Target
GetRefTarget(void)1104 		MDOTypePtr GetRefTarget(void) const { if(Type) return Type->GetRefTarget(); else return NULL; };
1105 
1106 		//! Set the parent details when an object has been read from a file
SetParent(MXFFilePtr & File,UInt64 Location,UInt32 NewKLSize)1107 		void SetParent(MXFFilePtr &File, UInt64 Location, UInt32 NewKLSize)
1108 		{
1109 			IsConstructed = false;
1110 			ParentOffset = Location;
1111 			KLSize = NewKLSize;
1112 			Parent = NULL;
1113 			ParentFile = File;
1114 		}
1115 
1116 		//! Set the parent details when an object has been read from memory
SetParent(MDObjectPtr & Object,UInt64 Location,UInt32 NewKLSize)1117 		void SetParent(MDObjectPtr &Object, UInt64 Location, UInt32 NewKLSize)
1118 		{
1119 			IsConstructed = false;
1120 			ParentOffset = Location;
1121 			KLSize = NewKLSize;
1122 			Parent = Object;
1123 			ParentFile = NULL;
1124 		}
1125 
1126 		//! Access function for Parent
GetParent(void)1127 		MDObjectParent &GetParent(void) { return Parent; }
1128 
1129 		//! Access function for ParentFile
GetParentFile(void)1130 		MXFFilePtr &GetParentFile(void) { return ParentFile; };
1131 
1132 		//! Get the object's UL
GetUL(void)1133 		const ULPtr &GetUL(void) { return TheUL; }
1134 
1135 		//! Set the object's UL
SetUL(ULPtr & NewUL)1136 		void SetUL(ULPtr &NewUL) { TheUL = NewUL; }
1137 
1138 		//! Set the object's tag
SetTag(Tag NewTag)1139 		void SetTag(Tag NewTag) { TheTag = NewTag; }
1140 
1141 		//! Get the object's tag
GetTag(void)1142 		Tag GetTag(void) { return TheTag; }
1143 
1144 		//! Change the type of an MDObject
1145 		/*! \note This may result in very wrong data - exercise great care! */
ChangeType(const UL & NewType)1146 		bool ChangeType(const UL &NewType)
1147 		{
1148 			MDOTypePtr Ptr = MDOType::Find(NewType);
1149 
1150 			if(!Ptr) return false;
1151 
1152 			Type = Ptr;
1153 			ObjectName = Type->Name();
1154 			TheUL = Type->GetUL();
1155 			if(TheUL) TheTag = MDOType::GetStaticPrimer()->Lookup(TheUL);
1156 			else TheTag = 0;
1157 
1158 			return true;
1159 		}
1160 
1161 		//! Change the type of an MDObject
1162 		/*! \note This may result in very wrong data - exercise great care! */
ChangeType(ULPtr & NewType)1163 		bool ChangeType(ULPtr &NewType) { return ChangeType(*NewType); }
1164 
1165 		//! Change the type of an MDObject
1166 		/*! \note This may result in very wrong data - exercise great care! */
ChangeType(std::string NewType)1167 		bool ChangeType(std::string NewType)
1168 		{
1169 			MDOTypePtr Ptr = MDOType::Find(NewType);
1170 
1171 			if(!Ptr) return false;
1172 
1173 			Type = Ptr;
1174 			ObjectName = Type->Name();
1175 			TheUL = Type->GetUL();
1176 			if(TheUL) TheTag = MDOType::GetStaticPrimer()->Lookup(TheUL);
1177 			else TheTag = 0;
1178 
1179 			return true;
1180 		}
1181 
1182 		//! Make a copy of this object
1183 		MDObjectPtr MakeCopy(void);
1184 
1185 	protected:
1186 		//! Sets the modification state of this object
1187 		/*! \note This function should be used rather than setting "Modified" as a
1188 		 *        future revision may "bubble" this up from sub-items to sets and packs
1189 		 */
SetModified(bool State)1190 		void SetModified(bool State) { Modified = State; }
1191 
1192 	public:
1193 		//! Set the GenerationUID of an object iff it has been modified
1194 		/*! \return true if the GenerationUID has been set, otherwise false
1195 		 *  \note If the object does not have a GenerationUID property false is returned!
1196 		 */
1197 		bool SetGenerationUID(UUIDPtr UID);
1198 
1199 		//! Has this object (including any child objects) been modified?
1200 		bool IsModified(void);
1201 
1202 		//! Clear the modified flag on this object and any contained objects
1203 		void ClearModified(void);
1204 
1205 		//! Get the location within the ultimate parent
1206 		UInt64 GetLocation(void);
1207 
1208 		//! Get text that describes where this item came from
1209 		std::string GetSource(void);
1210 
1211 		//! Get text that describes exactly where this item came from
GetSourceLocation(void)1212 		std::string GetSourceLocation(void)
1213 		{
1214 			return std::string("0x") + Int64toHexString(GetLocation(),8) + std::string(" in ") + GetSource();
1215 		}
1216 
1217 		//! Get pointer to Outer object
GetOuter(void)1218 		ObjectInterface *GetOuter(void) { return Outer; };
1219 
1220 		//! Set pointer to Outer object
SetOuter(ObjectInterface * NewOuter)1221 		void SetOuter(ObjectInterface *NewOuter) { Outer = NewOuter; };
1222 
1223 	public:
1224 		//! Set a translator function to translate unknown ULs to object names
SetULTranslator(ULTranslator Trans)1225 		static void SetULTranslator(ULTranslator Trans) { UL2NameFunc = Trans; }
1226 
1227 		//! Set the "attempt to parse dark metadata" flag
SetParseDark(bool Value)1228 		static void SetParseDark(bool Value) { ParseDark = Value; }
1229 
1230 	protected:
1231 		// Some private helper functions
1232 		static UInt32 ReadKey(DictKeyFormat Format, size_t Size, const UInt8 *Buffer, DataChunk& Key);
1233 		static UInt32 ReadLength(DictLenFormat Format, size_t Size, const UInt8 *Buffer, Length& Length);
1234 		UInt32 WriteKey(DataChunkPtr &Buffer, DictKeyFormat Format, PrimerPtr UsePrimer = NULL);
1235 		static UInt32 WriteLength(DataChunkPtr &Buffer, Length Length, DictLenFormat Format, UInt32 Size = 0);
1236 	};
1237 }
1238 
1239 
1240 namespace mxflib
1241 {
1242 	//! Interface for any class containing an MDObject that needs to behave like an MDObject
1243 	/*! This class is required to prevent the need for polymorphism
1244 	 *	which doesn't really work with smart pointers
1245 	 */
1246 	class ObjectInterface
1247 	{
1248 	protected:
1249 		//! Protected constructor used to create from an existing MDObject
ObjectInterface(MDObjectPtr BaseObject)1250 		ObjectInterface(MDObjectPtr BaseObject) : Object(BaseObject) {}
1251 
1252 	public:
1253 		MDObjectPtr Object;					//!< The MDObject for this item
1254 
1255 	public:
ObjectInterface()1256 		ObjectInterface() {};				//!< Build a basic ObjectInterface
~ObjectInterface()1257 		virtual ~ObjectInterface() {};		//!< Virtual destructor to allow polymorphism
1258 
1259 		// ** MDObject Interface **
Name(void)1260 		std::string Name(void) const { return Object->Name(); };
FullName(void)1261 		std::string FullName(void) const { return Object->FullName(); };
1262 
1263 		//! Access function for child values of compound items
1264 		MDObjectPtr operator[](std::string ChildName) { return Object->operator[](ChildName); };
Child(std::string ChildName)1265 		MDObjectPtr Child(std::string ChildName) { return Object->operator[](ChildName); };
ChildList(std::string ChildName)1266 		MDObjectListPtr ChildList(std::string ChildName) { return Object->ChildList(ChildName); };
1267 
1268 		MDObjectPtr operator[](const UL &ChildType) { return Object->operator[](ChildType); };
Child(const UL & ChildType)1269 		MDObjectPtr Child(const UL &ChildType) { return Object->operator[](ChildType); };
ChildList(const UL & ChildType)1270 		MDObjectListPtr ChildList(const UL &ChildType) { return Object->ChildList(ChildType); };
1271 
1272 		MDObjectPtr operator[](ULPtr &ChildType) { return Object->operator[](*ChildType); };
Child(ULPtr & ChildType)1273 		MDObjectPtr Child(ULPtr &ChildType) { return Object->operator[](*ChildType); };
ChildList(ULPtr & ChildType)1274 		MDObjectListPtr ChildList(ULPtr &ChildType) { return Object->ChildList(*ChildType); };
1275 
1276 		MDObjectPtr operator[](MDOTypePtr ChildType) { return Object->operator[](ChildType); };
Child(MDOTypePtr ChildType)1277 		MDObjectPtr Child(MDOTypePtr ChildType) { return Object->operator[](ChildType); };
ChildList(MDOTypePtr ChildType)1278 		MDObjectListPtr ChildList(MDOTypePtr ChildType) { return Object->ChildList(ChildType); };
1279 
AddChild(void)1280 		MDObjectPtr AddChild(void) { return Object->AddChild(); }
1281 		MDObjectPtr AddChild(std::string ChildName, bool Replace = true) { return Object->AddChild(ChildName, Replace); };
1282 		MDObjectPtr AddChild(MDObjectPtr ChildObject, bool Replace = false) { return Object->AddChild(ChildObject, Replace); };
1283 		MDObjectPtr AddChild(const UL &ChildType, bool Replace = true) { return Object->AddChild(ChildType, Replace); };
1284 		MDObjectPtr AddChild(ULPtr &ChildType, bool Replace = true) { return Object->AddChild(*ChildType, Replace); };
1285 
RemoveChild(std::string ChildName)1286 		void RemoveChild(std::string ChildName) { Object->RemoveChild(ChildName); };
RemoveChild(MDOTypePtr ChildType)1287 		void RemoveChild(MDOTypePtr ChildType) { Object->RemoveChild(ChildType); };
RemoveChild(MDObjectPtr ChildObject)1288 		void RemoveChild(MDObjectPtr ChildObject) { Object->RemoveChild(ChildObject); };
1289 
SetInt(const char * ChildName,Int32 Val)1290 		void SetInt(const char *ChildName, Int32 Val) { Object->SetInt(ChildName, Val); };
SetInt64(const char * ChildName,Int64 Val)1291 		void SetInt64(const char *ChildName, Int64 Val) { Object->SetInt64(ChildName, Val); };
SetUInt(const char * ChildName,UInt32 Val)1292 		void SetUInt(const char *ChildName, UInt32 Val) { Object->SetUInt(ChildName, Val); };
SetUInt64(const char * ChildName,UInt64 Val)1293 		void SetUInt64(const char *ChildName, UInt64 Val) { Object->SetUInt64(ChildName, Val); };
SetUint(const char * ChildName,UInt32 Val)1294 		void SetUint(const char *ChildName, UInt32 Val) { Object->SetUInt(ChildName, Val); };
SetUint64(const char * ChildName,UInt64 Val)1295 		void SetUint64(const char *ChildName, UInt64 Val) { Object->SetUInt64(ChildName, Val); };
SetString(const char * ChildName,std::string Val)1296 		void SetString(const char *ChildName, std::string Val) { Object->SetString(ChildName, Val); };
SetDValue(const char * ChildName)1297 		bool SetDValue(const char *ChildName) { return Object->SetDValue(ChildName); };
SetValue(const char * ChildName,const DataChunk & Source)1298 		void SetValue(const char *ChildName, const DataChunk &Source) { Object->SetValue(ChildName, Source); }
SetValue(const char * ChildName,MDObjectPtr Source)1299 		void SetValue(const char *ChildName, MDObjectPtr Source) { Object->SetValue(ChildName, Source); }
1300 		Int32 GetInt(const char *ChildName, Int32 Default = 0) { return Object->GetInt(ChildName, Default); };
1301 		Int64 GetInt64(const char *ChildName, Int64 Default = 0) { return Object->GetInt64(ChildName, Default); };
1302 		UInt32 GetUInt(const char *ChildName, UInt32 Default = 0) { return Object->GetUInt(ChildName, Default); };
1303 		UInt64 GetUInt64(const char *ChildName, UInt64 Default = 0) { return Object->GetUInt64(ChildName, Default); };
1304 		UInt32 GetUint(const char *ChildName, UInt32 Default = 0) { return Object->GetUInt(ChildName, Default); };
1305 		UInt64 GetUint64(const char *ChildName, UInt64 Default = 0) { return Object->GetUInt64(ChildName, Default); };
1306 		std::string GetString(const char *ChildName, std::string Default = "") { return Object->GetString(ChildName, Default); };
IsDValue(const char * ChildName)1307 		bool IsDValue(const char *ChildName) { return Object->IsDValue(ChildName); };
1308 
SetInt(const UL & ChildType,Int32 Val)1309 		void SetInt(const UL &ChildType, Int32 Val) { Object->SetInt(ChildType, Val); };
SetInt(ULPtr & ChildType,Int32 Val)1310 		void SetInt(ULPtr &ChildType, Int32 Val) { Object->SetInt(*ChildType, Val); };
SetInt64(const UL & ChildType,Int64 Val)1311 		void SetInt64(const UL &ChildType, Int64 Val) { Object->SetInt64(ChildType, Val); };
SetInt64(ULPtr & ChildType,Int64 Val)1312 		void SetInt64(ULPtr &ChildType, Int64 Val) { Object->SetInt64(*ChildType, Val); };
SetUInt(const UL & ChildType,UInt32 Val)1313 		void SetUInt(const UL &ChildType, UInt32 Val) { Object->SetUInt(ChildType, Val); };
SetUInt(ULPtr & ChildType,UInt32 Val)1314 		void SetUInt(ULPtr &ChildType, UInt32 Val) { Object->SetUInt(*ChildType, Val); };
SetUInt64(const UL & ChildType,UInt64 Val)1315 		void SetUInt64(const UL &ChildType, UInt64 Val) { Object->SetUInt64(ChildType, Val); };
SetUInt64(ULPtr & ChildType,UInt64 Val)1316 		void SetUInt64(ULPtr &ChildType, UInt64 Val) { Object->SetUInt64(*ChildType, Val); };
SetString(const UL & ChildType,std::string Val)1317 		void SetString(const UL &ChildType, std::string Val) { Object->SetString(ChildType, Val); };
SetString(ULPtr & ChildType,std::string Val)1318 		void SetString(ULPtr &ChildType, std::string Val) { Object->SetString(*ChildType, Val); };
SetDValue(const UL & ChildType)1319 		bool SetDValue(const UL &ChildType) { return Object->SetDValue(ChildType); };
SetDValue(ULPtr & ChildType)1320 		bool SetDValue(ULPtr &ChildType) { return Object->SetDValue(*ChildType); };
SetValue(const UL & ChildType,const DataChunk & Source)1321 		void SetValue(const UL &ChildType, const DataChunk &Source) { Object->SetValue(ChildType, Source); }
SetValue(ULPtr & ChildType,const DataChunk & Source)1322 		void SetValue(ULPtr &ChildType, const DataChunk &Source) { Object->SetValue(*ChildType, Source); }
SetValue(const UL & ChildType,MDObjectPtr Source)1323 		void SetValue(const UL &ChildType, MDObjectPtr Source) { Object->SetValue(ChildType, Source); }
SetValue(ULPtr & ChildType,MDObjectPtr Source)1324 		void SetValue(ULPtr &ChildType, MDObjectPtr Source) { Object->SetValue(*ChildType, Source); }
1325 		Int32 GetInt(const UL &ChildType, Int32 Default = 0) { return Object->GetInt(ChildType, Default); };
1326 		Int32 GetInt(ULPtr &ChildType, Int32 Default = 0) { return Object->GetInt(*ChildType, Default); };
1327 		Int64 GetInt64(const UL &ChildType, Int64 Default = 0) { return Object->GetInt64(ChildType, Default); };
1328 		Int64 GetInt64(ULPtr &ChildType, Int64 Default = 0) { return Object->GetInt64(*ChildType, Default); };
1329 		UInt32 GetUInt(const UL &ChildType, UInt32 Default = 0) { return Object->GetUInt(ChildType, Default); };
1330 		UInt32 GetUInt(ULPtr &ChildType, UInt32 Default = 0) { return Object->GetUInt(*ChildType, Default); };
1331 		UInt64 GetUInt64(const UL &ChildType, UInt64 Default = 0) { return Object->GetUInt64(ChildType, Default); };
1332 		UInt64 GetUInt64(ULPtr &ChildType, UInt64 Default = 0) { return Object->GetUInt64(*ChildType, Default); };
1333 		std::string GetString(const UL &ChildType, std::string Default = "") { return Object->GetString(ChildType, Default); };
1334 		std::string GetString(ULPtr &ChildType, std::string Default = "") { return Object->GetString(*ChildType, Default); };
IsDValue(const UL & ChildType)1335 		bool IsDValue(const UL &ChildType) { return Object->IsDValue(ChildType); };
IsDValue(ULPtr & ChildType)1336 		bool IsDValue(ULPtr &ChildType) { return Object->IsDValue(*ChildType); };
1337 
SetInt(MDOTypePtr ChildType,Int32 Val)1338 		void SetInt(MDOTypePtr ChildType, Int32 Val) { Object->SetInt(ChildType, Val); };
SetInt64(MDOTypePtr ChildType,Int64 Val)1339 		void SetInt64(MDOTypePtr ChildType, Int64 Val) { Object->SetInt64(ChildType, Val); };
SetUInt(MDOTypePtr ChildType,UInt32 Val)1340 		void SetUInt(MDOTypePtr ChildType, UInt32 Val) { Object->SetUInt(ChildType, Val); };
SetUInt64(MDOTypePtr ChildType,UInt64 Val)1341 		void SetUInt64(MDOTypePtr ChildType, UInt64 Val) { Object->SetUInt64(ChildType, Val); };
SetUint(MDOTypePtr ChildType,UInt32 Val)1342 		void SetUint(MDOTypePtr ChildType, UInt32 Val) { Object->SetUInt(ChildType, Val); };
SetUint64(MDOTypePtr ChildType,UInt64 Val)1343 		void SetUint64(MDOTypePtr ChildType, UInt64 Val) { Object->SetUInt64(ChildType, Val); };
SetString(MDOTypePtr ChildType,std::string Val)1344 		void SetString(MDOTypePtr ChildType, std::string Val) { Object->SetString(ChildType, Val); };
SetDValue(MDOTypePtr ChildType)1345 		bool SetDValue(MDOTypePtr ChildType) { return Object->SetDValue(ChildType); };
SetValue(MDOTypePtr ChildType,const DataChunk & Source)1346 		void SetValue(MDOTypePtr ChildType, const DataChunk &Source) { Object->SetValue(ChildType, Source); }
SetValue(MDOTypePtr ChildType,MDObjectPtr Source)1347 		void SetValue(MDOTypePtr ChildType, MDObjectPtr Source) { Object->SetValue(ChildType, Source); }
1348 		Int32 GetInt(MDOTypePtr ChildType, Int32 Default = 0) { return Object->GetInt(ChildType, Default); };
1349 		Int64 GetInt64(MDOTypePtr ChildType, Int64 Default = 0) { return Object->GetInt64(ChildType, Default); };
1350 		UInt32 GetUInt(MDOTypePtr ChildType, UInt32 Default = 0) { return Object->GetUInt(ChildType, Default); };
1351 		UInt64 GetUInt64(MDOTypePtr ChildType, UInt64 Default = 0) { return Object->GetUInt64(ChildType, Default); };
1352 		UInt32 GetUint(MDOTypePtr ChildType, UInt32 Default = 0) { return Object->GetUInt(ChildType, Default); };
1353 		UInt64 GetUint64(MDOTypePtr ChildType, UInt64 Default = 0) { return Object->GetUInt64(ChildType, Default); };
1354 		std::string GetString(MDOTypePtr ChildType, std::string Default = "") { return Object->GetString(ChildType, Default); };
IsDValue(MDOTypePtr ChildType)1355 		bool IsDValue(MDOTypePtr ChildType) { return Object->IsDValue(ChildType); };
1356 
1357 		//! Get a reference to the data chunk (const to prevent setting!!)
GetData(void)1358 		const DataChunk& GetData(void) { ASSERT(Object); return Object->GetData(); };
1359 
1360 		//! Build a data chunk with all this item's data (including child data)
1361 		DataChunkPtr PutData(PrimerPtr UsePrimer = NULL) { if(Object) return Object->PutData(UsePrimer); else return new DataChunk(); };
1362 
1363 		//! Read the object's value from a data chunk
ReadValue(const DataChunk & Chunk)1364 		size_t ReadValue(const DataChunk &Chunk) { return Object->ReadValue(Chunk.Data, Chunk.Size); };
1365 
1366 		//! Read the object's value from a data chunk pointer
ReadValue(const DataChunkPtr & Chunk)1367 		size_t ReadValue(const DataChunkPtr &Chunk) { return Object->ReadValue(Chunk->Data, Chunk->Size); };
1368 
1369 		//! Read the object's value from a memory buffer
1370 		size_t ReadValue(const UInt8 *Buffer, size_t Size, PrimerPtr UsePrimer = NULL) { return Object->ReadValue(Buffer, Size, UsePrimer); };
1371 
1372 		//! Write this object to a new memory buffer
WriteObject(MDObjectPtr ParentObject,PrimerPtr UsePrimer)1373 		DataChunkPtr WriteObject(MDObjectPtr ParentObject, PrimerPtr UsePrimer) { return Object->WriteObject(ParentObject, UsePrimer); };
1374 
1375 		//! Write this object to a memory buffer
WriteObject(DataChunkPtr & Buffer,MDObjectPtr ParentObject,PrimerPtr UsePrimer)1376 		size_t WriteObject(DataChunkPtr &Buffer, MDObjectPtr ParentObject, PrimerPtr UsePrimer) { return Object->WriteObject(Buffer, ParentObject, UsePrimer); };
1377 
1378 		//! Write this top level object to a new memory buffer
1379 		/*! The object must be at the outer or top KLV level
1380 		 *	\return The number of bytes written
1381 		 */
1382 		DataChunkPtr WriteObject(PrimerPtr UsePrimer = NULL)
1383 		{
1384 			return Object->WriteObject(NULL, UsePrimer);
1385 		}
1386 
1387 		//! Write this top level object to a memory buffer
1388 		/*! The object must be at the outer or top KLV level. The object is appended to the buffer
1389 		 *	\return The number of bytes written
1390 		 */
1391 		size_t WriteObject(DataChunkPtr &Buffer, PrimerPtr UsePrimer = NULL)
1392 		{
1393 			return Object->WriteObject(Buffer, NULL, UsePrimer);
1394 		}
1395 
GetType(void)1396 		MDOTypePtr GetType(void) const { return Object->GetType(); };
GetLink(void)1397 		MDObjectPtr GetLink(void) const { return Object->GetLink(); };
SetLink(MDObjectPtr NewLink)1398 		void SetLink(MDObjectPtr NewLink) { Object->SetLink(NewLink); };
GetRefType(void)1399 		ClassRef GetRefType(void) const { return Object->GetRefType(); };
1400 
1401 		//! Determine if this object is derived from a specified type (directly or indirectly)
IsA(std::string BaseType)1402 		bool IsA(std::string BaseType) { return Object->IsA(BaseType); }
1403 
1404 		//! Determine if this object is derived from a specified type (directly or indirectly)
IsA(MDOTypePtr BaseType)1405 		bool IsA(MDOTypePtr BaseType) { return Object->IsA(BaseType); }
1406 
1407 		//! Determine if this object is derived from a specified type (directly or indirectly)
IsA(const UL & BaseType)1408 		bool IsA(const UL &BaseType) { return Object->IsA(BaseType); }
1409 
1410 		//! Determine if this object is derived from a specified type (directly or indirectly)
IsA(ULPtr & BaseType)1411 		bool IsA(ULPtr &BaseType) { return Object->IsA(*BaseType); }
1412 
1413 		//! Set the parent details when an object has been read from a file
SetParent(MXFFilePtr File,UInt64 Location,UInt32 NewKLSize)1414 		void SetParent(MXFFilePtr File, UInt64 Location, UInt32 NewKLSize) { Object->SetParent(File, Location, NewKLSize); };
1415 
1416 		//! Set the parent details when an object has been read from memory
SetParent(MDObjectPtr ParentObject,UInt64 Location,UInt32 NewKLSize)1417 		void SetParent(MDObjectPtr ParentObject, UInt64 Location, UInt32 NewKLSize) { Object->SetParent(ParentObject, Location, NewKLSize); };
1418 
IsModified(void)1419 		bool IsModified(void) { return Object->IsModified(); }
1420 
1421 		//! Clear the modified flag on this object and any contained objects
ClearModified(void)1422 		void ClearModified(void) { Object->ClearModified(); }
1423 
GetLocation(void)1424 		UInt64 GetLocation(void) { return Object->GetLocation(); }
GetSource(void)1425 		std::string GetSource(void) { return Object->GetSource(); }
GetSourceLocation(void)1426 		std::string GetSourceLocation(void) { return Object->GetSourceLocation(); }
1427 
1428 		//! Change the type of an MDObject
1429 		/*! \note This may result in very wrong data - exercise great care! */
ChangeType(std::string NewType)1430 		bool ChangeType(std::string NewType) { return Object->ChangeType(NewType); };
1431 
1432 		//! Change the type of an MDObject
1433 		/*! \note This may result in very wrong data - exercise great care! */
ChangeType(const UL & NewType)1434 		bool ChangeType(const UL &NewType) { return Object->ChangeType(NewType); }
1435 
1436 		//! Change the type of an MDObject
1437 		/*! \note This may result in very wrong data - exercise great care! */
ChangeType(ULPtr & NewType)1438 		bool ChangeType(ULPtr &NewType) { return Object->ChangeType(*NewType); }
1439 
1440 	};
1441 }
1442 
1443 
1444 // These simple inlines need to be defined after MDObject
1445 namespace mxflib
1446 {
1447 inline MDObjectPtr MDObjectPtr::operator[](const char *ChildName) { return GetPtr()->operator[](ChildName); }
1448 inline MDObjectPtr MDObjectPtr::operator[](MDOTypePtr &ChildType) { return GetPtr()->operator[](ChildType); }
1449 inline MDObjectPtr MDObjectPtr::operator[](const UL &ChildType) { return GetPtr()->operator[](ChildType); }
1450 inline MDObjectPtr MDObjectPtr::operator[](ULPtr &ChildType) { return GetPtr()->operator[](ChildType); }
1451 inline MDObjectPtr MDObjectParent::operator[](const char *ChildName) { return GetPtr()->operator[](ChildName); }
1452 inline MDObjectPtr MDObjectParent::operator[](MDOTypePtr &ChildType) { return GetPtr()->operator[](ChildType); }
1453 inline MDObjectPtr MDObjectParent::operator[](const UL &ChildType) { return GetPtr()->operator[](ChildType); }
1454 inline MDObjectPtr MDObjectParent::operator[](ULPtr &ChildType) { return GetPtr()->operator[](ChildType); }
1455 }
1456 
1457 #endif // MXFLIB__MDOBJECT_H
1458