1 /*! \file	mdtype.h
2  *	\brief	Definition of classes that define metadata type info
3  *
4  *			Class MDDict holds the overall dictionary definitions and
5  *          manages loading them from a dictionary file and adding new
6  *			metadata types.
7  *<br><br>
8  *			Class MDType holds info about a specific metadata type
9  *<br><br>
10  *			These classes are currently wrappers around KLVLib structures
11  *
12  *	\version $Id: mdtype.h,v 1.13 2007/03/31 16:01:39 matt-beard Exp $
13  *
14  */
15 /*
16  *	Copyright (c) 2003, Matt Beard
17  *
18  *	This software is provided 'as-is', without any express or implied warranty.
19  *	In no event will the authors be held liable for any damages arising from
20  *	the use of this software.
21  *
22  *	Permission is granted to anyone to use this software for any purpose,
23  *	including commercial applications, and to alter it and redistribute it
24  *	freely, subject to the following restrictions:
25  *
26  *	  1. The origin of this software must not be misrepresented; you must
27  *	     not claim that you wrote the original software. If you use this
28  *	     software in a product, an acknowledgment in the product
29  *	     documentation would be appreciated but is not required.
30  *
31  *	  2. Altered source versions must be plainly marked as such, and must
32  *	     not be misrepresented as being the original software.
33  *
34  *	  3. This notice may not be removed or altered from any source
35  *	     distribution.
36  */
37 #ifndef MXFLIB__MDTYPE_H
38 #define MXFLIB__MDTYPE_H
39 
40 // STL Includes
41 #include <string>
42 #include <list>
43 #include <map>
44 
45 namespace mxflib
46 {
47 	typedef std::list<std::string> StringList;
48 }
49 
50 namespace mxflib
51 {
52 	enum MDContainerType				//!< Container types
53 	{
54 		NONE,							//!< Not a container - a simple metadata item
55 		SET,							//!< A SMPTE-336M Set
56 		PACK,							//!< A SMPTE-336M Pack
57 		BATCH,							//!< A Batch (ordered or unordered)
58 		ARRAY							//!< An array
59 	};
60 	enum MDTypeClass					//!< Class of this type
61 	{
62 		BASIC,							//!< A basic, indivisible, type
63 		INTERPRETATION,					//!< An interpretation of another class
64 		TYPEARRAY,						//!< An array of another class
65 		COMPOUND,						//!< A compound type
66 		ENUM							//!< An enumerated value
67 	};
68 	enum MDArrayClass					//!< Sub-classes of arrays
69 	{
70 		ARRAYARRAY,						//!< Just a normal array
71 		ARRAYBATCH						//!< A batch with count and size
72 	};
73 }
74 
75 
76 namespace mxflib
77 {
78 	//! Number/String duality object for index item in objects
79 	/*! Number facet is used for arrays, String facet for compounds
80 	 */
81 	class MapIndex
82 	{
83 	public:
84 		bool IsNum;
85 		UInt32 Number;
86 		std::string String;
87 
88 	public:
89 //		MapIndex() { ASSERT(0); };
MapIndex(UInt32 Num)90 		MapIndex(UInt32 Num) { IsNum = true; Number = Num; String = Int2String(Num); };
MapIndex(std::string Str)91 		MapIndex(std::string Str) { IsNum = false; String = Str; };
MapIndex(const MapIndex & Map)92 		MapIndex(const MapIndex& Map)
93 		{ IsNum = Map.IsNum;
94 			if(IsNum) Number = Map.Number;
95 			String = Map.String;
96 		};
97 
98 		bool operator<(const MapIndex& Other) const
99 		{
100 			if((IsNum==true) && (Other.IsNum==true)) return (Number < Other.Number);
101 			if((IsNum==false) && (Other.IsNum==false)) return (String < Other.String);
102 
103 			// Numbers come before strings
104 			return Other.IsNum;
105 		}
106 
107 		//! Allocator which does not change underlying type
108 		MapIndex& operator=(UInt32 Num)
109 		{
110 			if(IsNum) { Number = Num; String = Int2String(Num); }
111 			return *this;
112 		};
113 
114 		//! Allocator which does not change underlying type
115 		MapIndex& operator=(std::string Str)
116 		{
117 			if(IsNum)
118 			{
119 				Number = atoi(Str.c_str());
120 				String = Int2String(Number);		// Reformat the string
121 			}
122 			else
123 			{
124 				String = Str;
125 			}
126 			return *this;
127 		};
128 
129 		//! Allocator which does not change underlying type
130 		MapIndex& operator=(const MapIndex& Map)
131 		{
132 			if(IsNum)
133 			{
134 				Number = atoi(Map.String.c_str());	// Will be zero in !Map.IsNum
135 				String = Int2String(Number);		// Reformat the string
136 			}
137 			else
138 			{
139 				String = Map.String;
140 			}
141 			return *this;
142 		};
143 
144 		//! Cast to a char string
c_str()145 		const char *c_str() const
146 		{
147 			return (const char *)String.c_str();
148 		}
149 
150 		//! Equality check
151 		bool operator==(const MapIndex& Other) const
152 		{
153 			if(Other.IsNum != IsNum) return false;
154 			if(IsNum) return (Number == Other.Number);
155 			return (String == Other.String);
156 		}
157 	};
158 }
159 
160 
161 namespace mxflib
162 {
163 	// Forward declare so the class can include pointers to itself
164 	class MDType;
165 
166 	//! A smart pointer to an MDType object
167 	typedef SmartPtr<MDType> MDTypePtr;
168 
169 	//! A parent pointer to an MDType object
170 	typedef ParentPtr<MDType> MDTypeParent;
171 
172 	//! A list of smart pointers to MDType objects
173 	typedef std::list<MDTypePtr> MDTypeList;
174 
175 	//! A list of smart pointers to MDType objects with names
176 //	typedef std::pair<MDTypePtr, std::string> MDNamedType;
177 //	typedef std::list<MDNamedType> MDNamedTypeList;
178 
179 	typedef std::map<std::string, MDTypePtr> MDTypeMap;
180 }
181 
182 
183 namespace mxflib
184 {
185 	//! Holds the definition of a metadata type
186 	class MDType : public RefCount<MDType> , public MDTypeMap
187 	{
188 	protected:
189 		std::string TypeName;			//!< Name of this MDType
190 		MDTypeClass Class;				//!< Class of this MDType
191 		MDArrayClass ArrayClass;		//!< Sub-class of array
192 		MDTraitsPtr Traits;				//!< Traits for this MDType
193 		ULPtr TypeUL;					//!< The UL for this type
194 		bool Endian;					//!< Flag set to 'true' if this basic type should ever be byte-swapped
195 		TypeRef RefType;				//!< Reference type of this type (if a reference source or target), if TypeRefUndefined then inherit
196 		std::string RefTarget;			//!< Reference target of this type (if a reference source), if "" then inherit
197 
198 	public:
199 		//! Name and value pair for enums
200 		typedef std::pair<std::string, MDValuePtr> NamedValue;
201 
202 		//! List of name and value pairs for enums
203 		typedef std::list<NamedValue> NamedValueList;
204 
205 	protected:
206 		NamedValueList EnumValues;		//!< List of enumerated values, if this is an enum, each with its value name
207 
208 	public:
209 		MDTypeParent Base;					//!< Base class if this is a derived class, else NULL
210 //		MDTypeList Children;			//!< Types contained in this if it is a compound
211 ////		StringList ChildrenNames;		//!< Corresponding child names if it is a compound
212 		StringList ChildOrder;			//!< Child names in order for compound types
213 		int Size;						//!< The size of the item in multiples of base class items, or 0 if it is variable
214 
215 		//! Access function for ContainerType
216 //		const MDContainerType &GetContainerType(void) { return (const MDContainerType &)ContainerType; };
217 
218 	protected:
219 		//!	Construct a basic MDType
220 		/*! This constructor is protected so the ONLY way to create
221 		 *	new MDTypes from outside this class is via AddBasic() etc.
222 		*/
MDType(std::string TypeName,MDTypeClass TypeClass,ULPtr & UL,MDTraitsPtr TypeTraits)223 		MDType(std::string TypeName, MDTypeClass TypeClass, ULPtr &UL, MDTraitsPtr TypeTraits)
224 			: TypeName(TypeName), Class(TypeClass), ArrayClass(ARRAYARRAY), Traits(TypeTraits), TypeUL(UL), Endian(false),
225 			  RefType(TypeRefUndefined)
226 		{ };
227 
228 		//! Prevent auto construction by NOT having an implementation to this constructor
229 		MDType();
230 
231 		//! Prevent copy construction by NOT having an implementation to this copy constructor
232 		MDType(const MDType &rhs);
233 
234 		//! Add a sub to a compound type
235 		void AddSub(std::string SubName, MDTypePtr SubType);
236 
237 	public:
238 		//! Report the effective type of this type
239 		MDTypePtr EffectiveType(void);
240 
241 		//! Report the effective class of this type
242 		MDTypeClass EffectiveClass(void) const;
243 
244 		//! Report the effective base type of this type
245 		MDTypePtr EffectiveBase(void) const;
246 
247 		//! Report the effective reference type of this type
248 		TypeRef EffectiveRefType(void) const;
249 
250 		//! Report the effective reference target of this type
251 		std::string EffectiveRefTarget(void) const;
252 
253 		//! Report the effective size of this type
254 		/*! \return The size in bytes of a single instance of this type, or 0 if variable size
255 		 */
256 		UInt32 EffectiveSize(void) const;
257 
258 		//! Does this value's trait take control of all sub-data and build values in the our own DataChunk?
259 		/*! Normally any contained sub-types (such as array items or compound members) hold their own data */
HandlesSubdata(void)260 		bool HandlesSubdata(void) const
261 		{
262 			if(Traits) return Traits->HandlesSubdata();
263 			return false;
264 		}
265 
266 		//! Endian access function (set)
SetEndian(bool Val)267 		void SetEndian(bool Val) { Endian = Val; };
268 
269 		//! Endian access function (get)
GetEndian(void)270 		bool GetEndian(void) const { return Endian; };
271 
272 		//! ArrayClass access function (set)
SetArrayClass(MDArrayClass Val)273 		void SetArrayClass(MDArrayClass Val) { ArrayClass = Val; };
274 
275 		//! ArrayClass access function (get)
GetArrayClass(void)276 		MDArrayClass GetArrayClass(void) { return ArrayClass; };
277 
278 		//! Get the name of this type
Name(void)279 		const std::string &Name(void) const { return TypeName; }
280 
281 		//! Read-only access to the type UL
GetTypeUL(void)282 		const ULPtr &GetTypeUL(void) const { return TypeUL; }
283 
284 		//! (not Read-only) access to the enumerated value list
GetEnumValues(void)285 		NamedValueList &GetEnumValues(void) { return EnumValues; }
286 
287 		//! Set the reference type
SetRefType(TypeRef Val)288 		void SetRefType(TypeRef Val) { RefType = Val; }
289 
290 		//! Get the reference type
GetRefType(void)291 		TypeRef GetRefType(void) const { return RefType; }
292 
293 		//! Set the reference target
SetRefTarget(std::string Val)294 		void SetRefTarget(std::string Val) { RefTarget = Val; }
295 
296 		//! Get the reference target
GetRefTarget(void)297 		std::string GetRefTarget(void) const { return RefTarget; }
298 
299 
300 	//** Static Dictionary Handling data and functions **
301 	//***************************************************
302 	protected:
303 		static MDTypeList Types;		//!< All types managed by this object
304 
305 		//! Map for UL lookups
306 		static std::map<UL, MDTypePtr> ULLookup;
307 
308 		//! Map for UL lookups - ignoring the version number (all entries use version = 1)
309 		static std::map<UL, MDTypePtr> ULLookupVer1;
310 
311 		//! Map for reverse lookups based on type name
312 		static MDTypeMap NameLookup;
313 
314 	public:
315 		//! Add a new basic type
316 		static MDTypePtr AddBasic(std::string TypeName, ULPtr &UL, int TypeSize);
317 
318 		//! Add a new interpretation type
319 		static MDTypePtr AddInterpretation(std::string TypeName, MDTypePtr BaseType, ULPtr &UL, int Size = 0);
320 
321 		//! Add a new array type
322 		static MDTypePtr AddArray(std::string TypeName, MDTypePtr BaseType, ULPtr &UL, int ArraySize = 0);
323 
324 		//! Add a new compound type
325 		static MDTypePtr AddCompound(std::string TypeName, ULPtr &UL);
326 
327 		//! Add a new enumerated value type
328 		static MDTypePtr AddEnum(std::string TypeName, MDTypePtr BaseType, ULPtr &UL);
329 
330 		//! Add a new value to an enumerated value type
331 		bool AddEnumValue(std::string Name, MDValuePtr &Value);
332 
333 		//! Add a new value to an enumerated value type
334 		bool AddEnumValue(std::string Name, std::string Value);
335 
336 		//! Add a new UL value to an enumerated value type
337 		bool AddEnumValue(std::string Name, ULPtr &Value);
338 
339 		//! Find a type in the default symbol space, optionally searching all others
340 		static MDTypePtr Find(std::string TypeName, bool SearchAll = false) { return Find(TypeName, MXFLibSymbols, SearchAll); }
341 
342 		//! Find a type in a specified symbol space, optionally searching all others
343 		static MDTypePtr Find(std::string TypeName, SymbolSpacePtr &SymSpace, bool SearchAll = false);
344 
345 		//! Find a type by UL
346 		static MDTypePtr Find(const UL &BaseUL);
347 
348 		//! Find a type by ULPtr
Find(ULPtr & BaseUL)349 		static MDTypePtr Find(ULPtr &BaseUL) { return Find(*BaseUL); }
350 
351 
352 	/* Traits handling */
353 	/*******************/
354 
355 	public:
356 		//! Set the traits for this type
SetTraits(MDTraitsPtr Tr)357 		void SetTraits(MDTraitsPtr Tr)
358 		{
359 			Traits = Tr;
360 		};
361 
362 		//! Access the traits for this type
GetTraits(void)363 		MDTraitsPtr GetTraits(void) const { return Traits; };
364 
365 	protected:
366 		//! Type to map type names to their handling traits
367 		typedef std::map<std::string, MDTraitsPtr> TraitsMapType;
368 
369 		//! Map of type names to thair handling traits
370 		static TraitsMapType TraitsMap;
371 
372 		//! Type to map type ULs to their handling traits
373 		typedef std::map<UL, MDTraitsPtr> TraitsULMapType;
374 
375 		//! Map of type ULs to thair handling traits
376 		static TraitsULMapType TraitsULMap;
377 
378 	protected:
379 		//! Add a given type to the lookups
380 		static void AddType(MDTypePtr &Type, ULPtr &TypeUL);
381 
382 	public:
383 		//! Add a mapping to be applied to all types of a given type name
384 		/*! \note This will act retrospectively
385 		 */
386 		static bool AddTraitsMapping(std::string TypeName, std::string TraitsName);
387 
388 		//! Update an existing mapping and apply to any existing type of the given name
UpdateTraitsMapping(std::string TypeName,std::string TraitsName)389 		static bool UpdateTraitsMapping(std::string TypeName, std::string TraitsName)
390 		{
391 			// DRAGONS: For the moment this does exactly the same ass AddTraitsMapping - it may differ in future versions
392 			return AddTraitsMapping(TypeName, TraitsName);
393 		}
394 
395 		//! Add a mapping to be applied to all types of a given type UL
396 		/*! \note This will act retrospectively
397 		 */
398 		static bool AddTraitsMapping(const UL &TypeUL, std::string TraitsName);
399 
400 		//! Update an existing mapping and apply to any existing type of the given UL
UpdateTraitsMapping(const UL & TypeUL,std::string TraitsName)401 		static bool UpdateTraitsMapping(const UL &TypeUL, std::string TraitsName)
402 		{
403 			// DRAGONS: For the moment this does exactly the same ass AddTraitsMapping - it may differ in future versions
404 			return AddTraitsMapping(TypeUL, TraitsName);
405 		}
406 
407 		//! Lookup the traits for a specified type name
408 		/*! If no traits have been defined for the specified type the traits with the name given in DefaultTraitsName is used (if specified)
409 		 */
410 		static MDTraitsPtr LookupTraitsMapping(std::string TypeName, std::string DefaultTraitsName = "");
411 
412 		//! Lookup the traits for a specified type UL
413 		/*! If no traits have been defined for the specified type the traits with the UL given in DefaultTraitsName is used
414 		*/
415 		static MDTraitsPtr LookupTraitsMapping(const UL &TypeUL, const UL &DefaultTraitsUL);
416 
417 		//! Lookup the traits for a specified type name
418 		/*! If no traits have been defined for the specified type the traits with the UL given in DefaultTraitsName is used
419 		 */
420 		static MDTraitsPtr LookupTraitsMapping(std::string TypeName, const UL &DefaultTraitsUL);
421 
422 		//! Lookup the traits for a specified type UL
423 		/*! If no traits have been defined for the specified type the traits with the name given in DefaultTraitsName is used (if specified)
424 		*/
425 		static MDTraitsPtr LookupTraitsMapping(const UL &TypeUL, std::string DefaultTraitsName = "");
426 
427 		/* Allow MDValue class to view internals of this class */
428 		friend class MDValue;
429 	};
430 }
431 
432 namespace mxflib
433 {
434 	//! Add a mapping to apply a given set of traits to a certain type
435 	/*! \ret The name of the traits
436 	 */
AddTraitsMapping(std::string TypeName,MDTraitsPtr Tr)437 	/*template<class C>*/ inline std::string AddTraitsMapping(std::string TypeName, MDTraitsPtr Tr)
438 	{
439 //		MDTraitsPtr Tr = new C;
440 		MDTraitsPtr TrLookup = MDTraits::Find(Tr->Name());
441 
442 		if(!TrLookup) MDTraits::Add(Tr->Name(), Tr);
443 
444 		if(MDType::AddTraitsMapping(TypeName, Tr->Name()))
445 			return Tr->Name();
446 		else
447 			return "";
448 	}
449 
450 
451 	//! Update an existing mapping and apply to any existing type of the given name
452 	/*! \ret The name of the traits
453 	 */
UpdateTraitsMapping(std::string TypeName,MDTraitsPtr Tr)454 	/*template<class C>*/ inline std::string UpdateTraitsMapping(std::string TypeName, MDTraitsPtr Tr)
455 	{
456 //		MDTraitsPtr Tr = new C;
457 		MDTraitsPtr TrLookup = MDTraits::Find(Tr->Name());
458 
459 		if(!TrLookup) MDTraits::Add(Tr->Name(), Tr);
460 
461 		if(MDType::UpdateTraitsMapping(TypeName, Tr->Name()))
462 			return Tr->Name();
463 		else
464 			return "";
465 	}
466 
467 
468 	//! Add a mapping to apply a given set of traits to a certain type
469 	/*! \ret The name of the traits
470 	 */
AddTraitsMapping(const UL & Type,MDTraitsPtr Tr)471 	/*template<class C>*/ inline std::string AddTraitsMapping(const UL &Type, MDTraitsPtr Tr)
472 	{
473 //		MDTraitsPtr Tr = new C;
474 		MDTraitsPtr TrLookup = MDTraits::Find(Tr->Name());
475 
476 		if(!TrLookup) MDTraits::Add(Tr->Name(), Tr);
477 
478 		if(MDType::AddTraitsMapping(Type, Tr->Name()))
479 			return Tr->Name();
480 		else
481 			return "";
482 	}
483 
484 
485 	//! Update an existing mapping and apply to any existing type of the given name
486 	/*! \ret The name of the traits
487 	 */
UpdateTraitsMapping(const UL & Type,MDTraitsPtr Tr)488 	/*template<class C>*/ inline std::string UpdateTraitsMapping(const UL &Type, MDTraitsPtr Tr)
489 	{
490 //		MDTraitsPtr Tr = new C;
491 		MDTraitsPtr TrLookup = MDTraits::Find(Tr->Name());
492 
493 		if(!TrLookup) MDTraits::Add(Tr->Name(), Tr);
494 
495 		if(MDType::UpdateTraitsMapping(Type, Tr->Name()))
496 			return Tr->Name();
497 		else
498 			return "";
499 	}
500 }
501 
502 
503 namespace mxflib
504 {
505 	//! A map of smart pointers to MDValue objects indexed by MapIndex
506 	typedef std::map<MapIndex, MDValuePtr> MDValueMap;
507 }
508 
509 
510 namespace mxflib
511 {
512 	//! Metadata Object class
513 	class MDValue : public RefCount<MDValue>, public MDValueMap
514 	{
515 	private:
516 		MDTypePtr Type;
517 		DataChunk Data;
518 //		int Size;
519 //		UInt8 *Data;				// DRAGONS: This should be a DataChunk
520 
521 	public:
522 //		MDValueList Children;
523 
524 	public:
525 		MDValue(const std::string &BaseType);
526 		MDValue(MDTypePtr BaseType);
527 		void Init(void);
~MDValue()528 		~MDValue() {};
529 
530 		void AddChild(MDValuePtr Child, int Index = -1);
531 		void Resize(UInt32 Index);
532 
533 		MDValuePtr operator[](int Index);
Child(int Index)534 		MDValuePtr Child(int Index) { return operator[](Index); };
535 
536 		//! Access function for child values of compound items
537 		MDValuePtr operator[](const std::string ChildName);
Child(const std::string ChildName)538 		MDValuePtr Child(const std::string ChildName) { return operator[](ChildName); };
539 
540 		//! Access function for child values of compound items
541 		MDValuePtr operator[](const UL &Child);
Child(const UL & Child)542 		MDValuePtr Child(const UL &Child) { return operator[](Child); };
543 
544 		//! Value comparison
545 		bool operator==(MDValuePtr &RHS) { return operator==(*RHS); }
546 
547 		//! Value comparison
548 		bool operator==(MDValue &RHS)
549 		{
550 			if(Type->EffectiveType() != RHS.Type->EffectiveType()) return false;
551 			if(Data.Size != RHS.Data.Size) return false;
552 			return (memcmp(Data.Data, RHS.Data.Data, Data.Size) == 0);
553 		}
554 
555 		//! Value copy
556 		MDValue &operator=(MDValue &RHS)
557 		{
558 			// Do a bit-copy it the types are the same
559 			if(Type->EffectiveType() == RHS.Type->EffectiveType())
560 			{
561 				Data.Set(RHS.Data);
562 			}
563 			// ... otherwise copy by string value!
564 			else
565 			{
566 				SetString(RHS.GetString());
567 			}
568 
569 			return *this;
570 		}
571 
572 //		std::string ChildName(int Child);
573 
SetInt(Int32 Val)574 		void SetInt(Int32 Val) { Type->Traits->SetInt(this, Val); };
SetInt64(Int64 Val)575 		void SetInt64(Int64 Val) { Type->Traits->SetInt64(this, Val); };
SetUInt(UInt32 Val)576 		void SetUInt(UInt32 Val) { Type->Traits->SetUInt(this, Val); };
SetUInt64(UInt64 Val)577 		void SetUInt64(UInt64 Val) { Type->Traits->SetUInt64(this, Val); };
SetUint(UInt32 Val)578 		void SetUint(UInt32 Val) { Type->Traits->SetUInt(this, Val); };
SetUint64(UInt64 Val)579 		void SetUint64(UInt64 Val) { Type->Traits->SetUInt64(this, Val); };
SetString(std::string Val)580 		void SetString(std::string Val)	{ Type->Traits->SetString(this, Val); };
GetInt(void)581 		Int32 GetInt(void) { return Type->Traits->GetInt(this); };
GetInt64(void)582 		Int64 GetInt64(void) { return Type->Traits->GetInt64(this); };
GetUInt(void)583 		UInt32 GetUInt(void) { return Type->Traits->GetUInt(this); };
GetUInt64(void)584 		UInt64 GetUInt64(void) { return Type->Traits->GetUInt64(this); };
GetUint(void)585 		UInt32 GetUint(void) { return Type->Traits->GetUInt(this); };
GetUint64(void)586 		UInt64 GetUint64(void) { return Type->Traits->GetUInt64(this); };
GetString(void)587 		std::string GetString(void)	{ return Type->Traits->GetString(this); };
588 
589 		// Child value access
590 		// DRAGONS: May need to add code to check inside "optimised" compounds
591 		Int32 GetInt(const char *ChildName, Int32 Default = 0) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) return Ptr->GetInt(); else return Default; };
592 		Int64 GetInt64(const char *ChildName, Int64 Default = 0) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) return Ptr->GetInt64(); else return Default; };
593 		UInt32 GetUInt(const char *ChildName, UInt32 Default = 0) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) return Ptr->GetUInt(); else return Default; };
594 		UInt64 GetUInt64(const char *ChildName, UInt64 Default = 0) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) return Ptr->GetUInt64(); else return Default; };
595 		UInt32 GetUint(const char *ChildName, UInt32 Default = 0) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) return Ptr->GetUInt(); else return Default; };
596 		UInt64 GetUint64(const char *ChildName, UInt64 Default = 0) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) return Ptr->GetUInt64(); else return Default; };
597 		std::string GetString(const char *ChildName, std::string Default = "") { MDValuePtr Ptr = operator[](ChildName); if (Ptr) return Ptr->GetString(); else return Default; };
SetInt(const char * ChildName,Int32 Val)598 		void SetInt(const char *ChildName, Int32 Val) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->SetInt(Val); };
SetInt64(const char * ChildName,Int64 Val)599 		void SetInt64(const char *ChildName, Int64 Val) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->SetInt64(Val); };
SetUInt(const char * ChildName,UInt32 Val)600 		void SetUInt(const char *ChildName, UInt32 Val) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->SetUInt(Val); };
SetUInt64(const char * ChildName,UInt64 Val)601 		void SetUInt64(const char *ChildName, UInt64 Val) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->SetUInt64(Val); };
SetUint(const char * ChildName,UInt32 Val)602 		void SetUint(const char *ChildName, UInt32 Val) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->SetUInt(Val); };
SetUint64(const char * ChildName,UInt64 Val)603 		void SetUint64(const char *ChildName, UInt64 Val) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->SetUInt64(Val); };
SetString(const char * ChildName,std::string Val)604 		void SetString(const char *ChildName, std::string Val) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->SetString(Val); };
605 
606 		// Child value access
607 		// DRAGONS: May need to add code to check inside "optimised" compounds
608 		Int32 GetInt(const UL &Child, Int32 Default = 0) { MDValuePtr Ptr = operator[](Child); if (Ptr) return Ptr->GetInt(); else return Default; };
609 		Int64 GetInt64(const UL &Child, Int64 Default = 0) { MDValuePtr Ptr = operator[](Child); if (Ptr) return Ptr->GetInt64(); else return Default; };
610 		UInt32 GetUInt(const UL &Child, UInt32 Default = 0) { MDValuePtr Ptr = operator[](Child); if (Ptr) return Ptr->GetUInt(); else return Default; };
611 		UInt64 GetUInt64(const UL &Child, UInt64 Default = 0) { MDValuePtr Ptr = operator[](Child); if (Ptr) return Ptr->GetUInt64(); else return Default; };
612 		UInt32 GetUint(const UL &Child, UInt32 Default = 0) { MDValuePtr Ptr = operator[](Child); if (Ptr) return Ptr->GetUInt(); else return Default; };
613 		UInt64 GetUint64(const UL &Child, UInt64 Default = 0) { MDValuePtr Ptr = operator[](Child); if (Ptr) return Ptr->GetUInt64(); else return Default; };
614 		std::string GetString(const UL &Child, std::string Default = "") { MDValuePtr Ptr = operator[](Child); if (Ptr) return Ptr->GetString(); else return Default; };
SetInt(const UL & Child,Int32 Val)615 		void SetInt(const UL &Child, Int32 Val) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->SetInt(Val); };
SetInt64(const UL & Child,Int64 Val)616 		void SetInt64(const UL &Child, Int64 Val) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->SetInt64(Val); };
SetUInt(const UL & Child,UInt32 Val)617 		void SetUInt(const UL &Child, UInt32 Val) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->SetUInt(Val); };
SetUInt64(const UL & Child,UInt64 Val)618 		void SetUInt64(const UL &Child, UInt64 Val) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->SetUInt64(Val); };
SetUint(const UL & Child,UInt32 Val)619 		void SetUint(const UL &Child, UInt32 Val) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->SetUInt(Val); };
SetUint64(const UL & Child,UInt64 Val)620 		void SetUint64(const UL &Child, UInt64 Val) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->SetUInt64(Val); };
SetString(const UL & Child,std::string Val)621 		void SetString(const UL &Child, std::string Val) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->SetString(Val); };
622 
ReadValue(const char * ChildName,const DataChunk & Source)623 		void ReadValue(const char *ChildName, const DataChunk &Source) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->ReadValue(Source); };
ReadValue(const char * ChildName,DataChunkPtr & Source)624 		void ReadValue(const char *ChildName, DataChunkPtr &Source) { MDValuePtr Ptr = operator[](ChildName); if (Ptr) Ptr->ReadValue(Source); };
625 
ReadValue(const UL & Child,const DataChunk & Source)626 		void ReadValue(const UL &Child, const DataChunk &Source) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->ReadValue(Source); };
ReadValue(const UL & Child,DataChunkPtr & Source)627 		void ReadValue(const UL &Child, DataChunkPtr &Source) { MDValuePtr Ptr = operator[](Child); if (Ptr) Ptr->ReadValue(Source); };
628 
629 		// DRAGONS: These should probably be private and give access via MDTraits
630 		// to prevent users tinkering!
631 		size_t MakeSize(size_t NewSize);
632 
ReadValue(const DataChunk & Chunk)633 		size_t ReadValue(const DataChunk &Chunk) { return ReadValue(Chunk.Data, Chunk.Size); };
ReadValue(DataChunkPtr & Chunk)634 		size_t ReadValue(DataChunkPtr &Chunk) { return ReadValue(Chunk->Data, Chunk->Size); };
635 		size_t ReadValue(const UInt8 *Buffer, size_t Size, int Count=0);
636 
637 		//! Get a reference to the data chunk (const to prevent setting!!)
GetData(void)638 		const DataChunk& GetData(void) { return (const DataChunk&) Data; };
639 
640 		//! Build a data chunk with all this items data (including child data)
641 		DataChunkPtr PutData(void);
642 
643 		//! Set data into the datachunk
644 		// DRAGONS: This is dangerous!!
SetData(size_t MemSize,const UInt8 * Buffer)645 		void SetData(size_t MemSize, const UInt8 *Buffer)
646 		{
647 			Data.Resize(MemSize);
648 			Data.Set(MemSize, Buffer);
649 		};
650 
651 		// Report the name of this item (the name of its type)
Name(void)652 		const std::string &Name(void) const { ASSERT(Type); return Type->TypeName; };
653 
654 		// Type access function
GetType(void)655 		MDTypePtr GetType(void) { return Type; };
EffectiveType(void)656 		MDTypePtr EffectiveType(void) { return Type->EffectiveType(); };
EffectiveBase(void)657 		MDTypePtr EffectiveBase(void) { return Type->EffectiveBase(); };
658 	};
659 }
660 
661 
662 // These simple inlines need to be defined after MDValue
663 namespace mxflib
664 {
665 	inline MDValuePtr MDValuePtr::operator[](int Index)
666 	{
667 		// TODO: We need to find a solution to this!
668 		ASSERT(!(operator->()->GetType()->HandlesSubdata()));
669 		return operator->()->operator[](Index);
670 	};
671 	inline MDValuePtr MDValuePtr::operator[](const std::string ChildName)
672 	{
673 		// TODO: We need to find a solution to this!
674 		ASSERT(!(operator->()->GetType()->HandlesSubdata()));
675 		return operator->()->operator[](ChildName);
676 	};
677 }
678 
679 
680 #endif // MXFLIB__MDTYPE_H
681 
682