1 /*! \file	deftypes.h
2  *	\brief	Definition of classes that load type and class dictionaries
3  *	\version $Id: deftypes.h,v 1.13 2007/04/01 11:54:24 matt-beard Exp $
4  *
5  */
6 /*
7  *	Copyright (c) 2005, Matt Beard
8  *
9  *	This software is provided 'as-is', without any express or implied warranty.
10  *	In no event will the authors be held liable for any damages arising from
11  *	the use of this software.
12  *
13  *	Permission is granted to anyone to use this software for any purpose,
14  *	including commercial applications, and to alter it and redistribute it
15  *	freely, subject to the following restrictions:
16  *
17  *	  1. The origin of this software must not be misrepresented; you must
18  *	     not claim that you wrote the original software. If you use this
19  *	     software in a product, an acknowledgment in the product
20  *	     documentation would be appreciated but is not required.
21  *
22  *	  2. Altered source versions must be plainly marked as such, and must
23  *	     not be misrepresented as being the original software.
24  *
25  *	  3. This notice may not be removed or altered from any source
26  *	     distribution.
27  */
28 #ifndef MXFLIB__DICTIONARY_H
29 #define MXFLIB__DICTIONARY_H
30 
31 // STL Includes
32 #include <string>
33 #include <list>
34 
35 
36 namespace mxflib
37 {
38 	// DRAGONS: Why are there two different (but similar) in memory versions of type records?
39 	//          The answer is that as some types depend on others the loading process requires stacking
40 	//          part-processed entries for later completion. It is not easy to stack the simple struct
41 	//          version, partly because of the char pointers to strings and partly because of the fact
42 	//          that the compound sub-items are linked by their position in the array rather than a pointer
43 	//          giving ownership - however these same features are required in order to allow data to be
44 	//          built at compile-time which is highly desirable. When a type definition table made from
45 	//          the "constant" struct version is loaded it is first copied to a list of classes for easy
46 	//          manipulation during further processing.
47 
48 	//! Enumeration identifying the type of an in-memory type definition entry to be processed by LoadTypes()
49 	enum TypeClass
50 	{
51 		TypeNULL = 0,						//!< Special token used to end a list of types
52 		TypeBasic,							//!< Basic type definition (the atomic definition of a type)
53 		TypeInterpretation,					//!< Interpretation - physically identical to another type, but with different symantics
54 		TypeMultiple,						//!< Multiple an array or batch of zero or more of another single type
55 		TypeCompound,						//!< Compound structure of two or more of another type, which may be different types, with a fixed layout
56 		TypeSub,							//!< An individual sub-item in a compound, or value in an enum
57 		TypeEnum,							//!< Enumeration type, with one or more named values
58 		TypeLabel,							//!< Define a label value
59 		TypeSymbolSpace						//!< Define the default symbol space for all types in this list
60 	};
61 
62 	//! Referencing kinds for Types
63 	enum TypeRef
64 	{
65 		TypeRefUndefined = -1,				//!< Not defined yet for this type (used to differentiate not defined and specifically defined as "none")
66 		TypeRefNone = 0,					//!< Not a reference
67 		TypeRefStrong,						//!< A strong reference
68 		TypeRefWeak,						//!< A weak reference
69 		TypeRefTarget,						//!< A target of a strong (or weak) reference
70 		TypeRefGlobal						//!< A global reference - may be to a definition in the file, or to a published definition (outside the scope of the file)
71 	};
72 
73 	//! Single entry for a type to be defined - can be stored as a compile-time built structure
74 	struct ConstTypeRecord
75 	{
76 		TypeClass Class;					//!< The class of type being defined by this entry
77 		const char *Type;					//!< The name of this type
78 		const char *Detail;					//!< The human readable description of this type
79 		const char *Base;					//!< The base type for an interpretation or multiple, or the type for a compound type sub-item
80 		const char *UL;						//!< The UL for this type (if known)
81 		const char *Value;					//!< Value if this is an enumerated value, or mask if this is a label
82 		int Size;							//!< The size in bytes of a basic type, or the number of entries in a multiple
83 		bool Endian;						//!< Used with basic types: "true" if this type gets endian swapped on reading/writing on a little-endian platform
84 		bool IsBatch;						//!< Used with multiple types: "true" is this type has an 8-byte Count-and-Size header
85 		TypeRef RefType;					//!< Reference type of this item (if a reference or target)
86 		const char *RefTarget;				//!< Type of the reference target (if this is a referencing type) or NULL
87 		const char *SymSpace;				//!< SymbolSpace for this type, or NULL if none specified (will inherit)
88 	};
89 
90 	// Forward declare TypeRecord to allow TypeRecordPtr to be defined early
91 	class TypeRecord;
92 
93 	//! A smart pointer to a TypeRecord
94 	typedef SmartPtr<TypeRecord> TypeRecordPtr;
95 
96 	//! List of smart pointers to TypeRecords
97 	typedef std::list<TypeRecordPtr> TypeRecordList;
98 
99 	//! List of TypeRecordLists
100 	typedef std::list<TypeRecordList> TypeRecordListList;
101 
102 	//! Single entry for a type to be defined - built at run-time and can be stacked if required to allow out-of-order definitions
103 	class TypeRecord : public RefCount<TypeRecord>
104 	{
105 	public:
106 		TypeClass Class;					//!< The class of type being defined by this entry
107 		std::string Type;					//!< The name of this type
108 		std::string Detail;					//!< The human readable description of this type
109 		std::string Base;					//!< The base type for an interpretation or multiple, or the type for a compound type sub-item
110 		ULPtr UL;							//!< The UL for this type (NULL or "" if not known)
111 		std::string Value;					//!< Value if this is an enumerated value, or mask if this is a label
112 		int Size;							//!< The size in bytes of a basic type, or the number of entries in a multiple
113 		bool Endian;						//!< Used with basic types: "true" if this type gets endian swapped on reading/writing on a little-endian platform
114 		bool IsBatch;						//!< Used with multiple types: "true" is this type has an 8-byte Count-and-Size header
115 		TypeRef RefType;					//!< Reference type of this item (if a reference or target)
116 		std::string RefTarget;				//!< Type of the reference target (if this is a referencing type)
117 		SymbolSpacePtr SymSpace;			//!< SymbolSpace for this type, or NULL if none specified (will inherit)
118 		TypeRecordList Children;			//!< Used with compound types: Sub-items within this compound
119 
120 	public:
121 		//! Build an empty TypeRecord
TypeRecord()122 		TypeRecord()
123 		{
124 			Class = TypeNULL;
125 			Size = 0;
126 			Endian = false;
127 			IsBatch = false;
128 			RefType = TypeRefUndefined;
129 		}
130 	};
131 
132 	//! Load types from the specified XML definitions
133 	/*! \return 0 if all OK
134 	 *  \return -1 on error
135 	 */
136 	int LoadTypes(char *TypesFile, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols);
137 
138 	//! Load types from the specified in-memory definitions
139 	/*! \note The last entry in the array must be a terminating entry with Class == TypeNULL
140 	 *  \return 0 if all OK
141 	 *  \return -1 on error
142 	 *  \note If any part of the dictionary loading fails the loading will continue unless FastFail is set to true
143 	 */
144 	int LoadTypes(const ConstTypeRecord *TypesData, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols);
145 
146 	//! Load types from the specified in-memory definitions
147 	/*! \return 0 if all OK
148 	 *  \return -1 on error
149 	 *  \note If any part of the dictionary loading fails the loading will continue unless FastFail is set to true
150 	 */
151 	int LoadTypes(TypeRecordList &TypesData, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols);
152 
153 	//! Find the traits for a given type - DEPRECATED
154 	/*! <b>DEPRECATED - Use MDTraits::Find()</B>
155 	 */
LookupTraits(const char * Name)156 	inline MDTraitsPtr LookupTraits(const char* Name) { return MDTraits::Find(std::string(Name)); }
157 
158 	//! Disable automatic loading of built-in traits
159 	/*! \note This needs to be called early as they may have already been loaded!
160 	 *  \ret false if the traits have already been loaded (or already disabled)
161 	 */
162 	bool DisableBuiltInTraits(void);
163 
164 
165 	/* Define macros for static type definitions */
166 
167 //! MXFLIB_TYPE_START - Use to start a type definition block
168 #define MXFLIB_TYPE_START(Name) const ConstTypeRecord Name[] = {
169 
170 //! MXFLIB_TYPE_START_SYM - Use to start a type definition block and define a default symbol space
171 #define MXFLIB_TYPE_START_SYM(Name, Sym) const ConstTypeRecord Name[] = { { TypeSymbolSpace, "", "", "", "", "", 0, false, false, TypeRefUndefined, NULL, Sym },
172 
173 //! MXFLIB_TYPE_BASIC - Use to define a "Basic" type
174 /*! \param Name The name of the type being defined
175  *  \param Detail A human readable description of the type
176  *  \param Size The number of bytes used to store this type (must be > 0)
177  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
178  *  \param Endian "true" if this type gets endian swapped on reading/writing on a little-endian platform
179  */
180 #define MXFLIB_TYPE_BASIC(Name, Detail, UL, Size, Endian) { TypeBasic, Name, Detail, "", UL, "", Size, Endian, false, TypeRefUndefined, NULL, NULL },
181 
182 //! MXFLIB_TYPE_BASIC_SYM - Use to define a "Basic" type and override the default symbol space
183 /*! \param Name The name of the type being defined
184  *  \param Detail A human readable description of the type
185  *  \param Size The number of bytes used to store this type (must be > 0)
186  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
187  *  \param Endian "true" if this type gets endian swapped on reading/writing on a little-endian platform
188  *  \param Sym The name of the symbol space for this type
189  */
190 #define MXFLIB_TYPE_BASIC_SYM(Name, Detail, UL, Size, Endian, Sym) { TypeBasic, Name, Detail, "", UL, "", Size, Endian, false, TypeRefUndefined, NULL, Sym },
191 
192 //! MXFLIB_TYPE_BASIC_REF - Use to define a "Basic" type that is a reference source or target
193 /*! \param Name The name of the type being defined
194  *  \param Detail A human readable description of the type
195  *  \param Size The number of bytes used to store this type (must be > 0)
196  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
197  *  \param Endian "true" if this type gets endian swapped on reading/writing on a little-endian platform
198  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
199  *  \param RefTarget The type of the reference target
200  */
201 #define MXFLIB_TYPE_BASIC_REF(Name, Detail, UL, Size, Endian, RefType, RefTarget) { TypeBasic, Name, Detail, "", UL, "", Size, Endian, false, RefType, RefTarget, NULL },
202 
203 //! MXFLIB_TYPE_BASIC_REF_SYM - Use to define a "Basic" type that is a reference source or target and override the default symbol space
204 /*! \param Name The name of the type being defined
205  *  \param Detail A human readable description of the type
206  *  \param Size The number of bytes used to store this type (must be > 0)
207  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
208  *  \param Endian "true" if this type gets endian swapped on reading/writing on a little-endian platform
209  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
210  *  \param RefTarget The type of the reference target
211  *  \param Sym The name of the symbol space for this type
212  */
213 #define MXFLIB_TYPE_BASIC_REF_SYM(Name, Detail, UL, Size, Endian, RefType, RefTarget, Sym) { TypeBasic, Name, Detail, "", UL, "", Size, Endian, false, RefType, RefTarget, Sym },
214 
215 //! MXFLIB_TYPE_INTERPRETATION - Use to define an "Interpretation" type
216 /*! \param Name The name of the type being defined
217  *  \param Detail A human readable description of the type
218  *  \param Base The type that this is an interpretation of
219  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
220  *  \param Size If non-zero this fixes the number of entries in the variable-length base array
221  */
222 #define MXFLIB_TYPE_INTERPRETATION(Name, Detail, Base, UL, Size) { TypeInterpretation, Name, Detail, Base, UL, "", Size, false, false, TypeRefUndefined, NULL, NULL },
223 
224 //! MXFLIB_TYPE_INTERPRETATION_SYM - Use to define an "Interpretation" type and override the default symbol space
225 /*! \param Name The name of the type being defined
226  *  \param Detail A human readable description of the type
227  *  \param Base The type that this is an interpretation of
228  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
229  *  \param Size If non-zero this fixes the number of entries in the variable-length base array
230  *  \param Sym The name of the symbol space for this type
231  */
232 #define MXFLIB_TYPE_INTERPRETATION_SYM(Name, Detail, Base, UL, Size, Sym) { TypeInterpretation, Name, Detail, Base, UL, "", Size, false, false, TypeRefUndefined, NULL, Sym },
233 
234 //! MXFLIB_TYPE_INTERPRETATION_REF - Use to define an "Interpretation" type that is a reference source or target
235 /*! \param Name The name of the type being defined
236  *  \param Detail A human readable description of the type
237  *  \param Base The type that this is an interpretation of
238  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
239  *  \param Size If non-zero this fixes the number of entries in the variable-length base array
240  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
241  *  \param RefTarget The type of the reference target
242  */
243 #define MXFLIB_TYPE_INTERPRETATION_REF(Name, Detail, Base, UL, Size, RefType, RefTarget) { TypeInterpretation, Name, Detail, Base, UL, "", Size, false, false, RefType, RefTarget, NULL },
244 
245 //! MXFLIB_TYPE_INTERPRETATION_REF_SYM - Use to define an "Interpretation" type that is a reference source or target and override the default symbol space
246 /*! \param Name The name of the type being defined
247  *  \param Detail A human readable description of the type
248  *  \param Base The type that this is an interpretation of
249  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
250  *  \param Size If non-zero this fixes the number of entries in the variable-length base array
251  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
252  *  \param RefTarget The type of the reference target
253  *  \param Sym The name of the symbol space for this type
254  */
255 #define MXFLIB_TYPE_INTERPRETATION_REF_SYM(Name, Detail, Base, UL, Size, RefType, RefTarget, Sym) { TypeInterpretation, Name, Detail, Base, UL, "", Size, false, false, RefType, RefTarget, Sym },
256 
257 //! MXFLIB_TYPE_MULTIPLE - Use to define a "Multiple" type
258 /*! \param Name The name of the type being defined
259  *  \param Detail A human readable description of the type
260  *  \param Base The type of which this is a multiple
261  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
262  *  \param IsBatch "true" is this type has an 8-byte Count-and-Size header
263  *  \param Size If non-zero this fixes the number of entries, if zero the size is variable
264  */
265 #define MXFLIB_TYPE_MULTIPLE(Name, Detail, Base, UL, IsBatch, Size) { TypeMultiple, Name, Detail, Base, UL, "", Size, false, IsBatch, TypeRefUndefined, NULL, NULL },
266 
267 //! MXFLIB_TYPE_MULTIPLE_SYM - Use to define a "Multiple" type and override the default symbol space
268 /*! \param Name The name of the type being defined
269  *  \param Detail A human readable description of the type
270  *  \param Base The type of which this is a multiple
271  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
272  *  \param IsBatch "true" is this type has an 8-byte Count-and-Size header
273  *  \param Size If non-zero this fixes the number of entries, if zero the size is variable
274  *  \param Sym The name of the symbol space for this type
275  */
276 #define MXFLIB_TYPE_MULTIPLE_SYM(Name, Detail, Base, UL, IsBatch, Size, Sym) { TypeMultiple, Name, Detail, Base, UL, "", Size, false, IsBatch, TypeRefUndefined, NULL, Sym },
277 
278 //! MXFLIB_TYPE_MULTIPLE_REF - Use to define a "Multiple" type that is a reference source or target
279 /*! \param Name The name of the type being defined
280  *  \param Detail A human readable description of the type
281  *  \param Base The type of which this is a multiple
282  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
283  *  \param IsBatch "true" is this type has an 8-byte Count-and-Size header
284  *  \param Size If non-zero this fixes the number of entries, if zero the size is variable
285  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
286  *  \param RefTarget The type of the reference target
287  */
288 #define MXFLIB_TYPE_MULTIPLE_REF(Name, Detail, Base, UL, IsBatch, Size, RefType, RefTarget) { TypeMultiple, Name, Detail, Base, UL, "", Size, false, IsBatch, RefType, RefTarget, NULL },
289 
290 //! MXFLIB_TYPE_MULTIPLE_REF_SYM - Use to define a "Multiple" type that is a reference source or target and override the default symbol space
291 /*! \param Name The name of the type being defined
292  *  \param Detail A human readable description of the type
293  *  \param Base The type of which this is a multiple
294  *  \param UL The UL, or endian-swapped UUID, for this type (or "" to force one to be generated)
295  *  \param IsBatch "true" is this type has an 8-byte Count-and-Size header
296  *  \param Size If non-zero this fixes the number of entries, if zero the size is variable
297  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
298  *  \param RefTarget The type of the reference target
299  *  \param Sym The name of the symbol space for this type
300  */
301 #define MXFLIB_TYPE_MULTIPLE_REF_SYM(Name, Detail, Base, UL, IsBatch, Size, RefType, RefTarget, Sym) { TypeMultiple, Name, Detail, Base, UL, "", Size, false, IsBatch, RefType, RefTarget, Sym },
302 
303 //! MXFLIB_TYPE_COMPOUND - Use to start the definition of a "Compound" type
304 /*! \param Name The name of the type being defined
305  *  \param Detail A human readable description of the type
306  */
307 #define MXFLIB_TYPE_COMPOUND(Name, Detail, UL) { TypeCompound, Name, Detail, "", UL, "", 0, false, false, TypeRefUndefined, NULL, NULL },
308 
309 //! MXFLIB_TYPE_COMPOUND_SYM - Use to start the definition of a "Compound" type and override the default symbol space
310 /*! \param Name The name of the type being defined
311  *  \param Detail A human readable description of the type
312  *  \param Sym The name of the symbol space for this type
313  */
314 #define MXFLIB_TYPE_COMPOUND_SYM(Name, Detail, UL, Sym) { TypeCompound, Name, Detail, "", UL, "", 0, false, false, TypeRefUndefined, NULL, Sym },
315 
316 //! MXFLIB_TYPE_COMPOUND_ITEM - Use to define an item within the current "Compound" type
317 /*! \param Name The name of the item being defined
318  *  \param Detail A human readable description of the item
319  *  \param Type The type of this item within the compound
320  *  \param UL The UL, or endian-swapped UUID, for this item (or "" to force one to be generated)
321  *  \param Size If non-zero this fixes the number of entries in a variable-length array
322  */
323 #define MXFLIB_TYPE_COMPOUND_ITEM(Name, Detail, Type, UL, Size) { TypeSub, Name, Detail, Type, UL, "", Size, false, false, TypeRefUndefined, NULL, NULL },
324 
325 //! MXFLIB_TYPE_COMPOUND_END - Use to end definition of a "Compound" type
326 #define MXFLIB_TYPE_COMPOUND_END
327 
328 //! MXFLIB_TYPE_ENUM - Use to start the definition of an "Enumeration" type
329 /*! \param Name The name of the type being defined
330  *  \param Detail A human readable description of the type
331  *  \param Type The type of the values in this enumeration
332  */
333 #define MXFLIB_TYPE_ENUM(Name, Detail, Type, UL) { TypeEnum, Name, Detail, Type, UL, "", 0, false, false, TypeRefUndefined, NULL, NULL },
334 
335 //! MXFLIB_TYPE_ENUM_SYM - Use to start the definition of a "Enumeration" type and override the default symbol space
336 /*! \param Name The name of the type being defined
337  *  \param Detail A human readable description of the type
338  *  \param Type The type of the values in this enumeration
339  *  \param Sym The name of the symbol space for this type
340  */
341 #define MXFLIB_TYPE_ENUM_SYM(Name, Detail, Type, UL, Sym) { TypeEnum, Name, Detail, Type, UL, "", 0, false, false, TypeRefUndefined, NULL, Sym },
342 
343 //! MXFLIB_TYPE_ENUM_VALUE - Use to define a value for the current "Enumeration" type
344 /*! \param Name The name of the value being defined
345  *  \param Detail A human readable description of the value
346  *  \param Value The value being defined
347  */
348 #define MXFLIB_TYPE_ENUM_VALUE(Name, Detail, Value) { TypeSub, Name, Detail, "", "", Value, 0, false, false, TypeRefUndefined, NULL, NULL },
349 
350 //! MXFLIB_LABEL - Use to define a label
351 /*! \param Name The name of the label being defined
352  *  \param Detail A human readable description of the label
353  *  \param UL The UL, or end-swapped UUID of thsi label
354  */
355 #define MXFLIB_LABEL(Name, Detail, UL) { TypeLabel, Name, Detail, "", UL, NULL, 0, false, false, TypeRefUndefined, NULL, NULL },
356 
357 //! MXFLIB_LABEL_SYM - Use to define a label and override the default symbol space
358 /*! \param Name The name of the label being defined
359  *  \param Detail A human readable description of the label
360  *  \param UL The UL, or end-swapped UUID of thsi label
361  *  \param Sym The name of the symbol space for this type
362  */
363 #define MXFLIB_LABEL_SYM(Name, Detail, UL, Sym) { TypeLabel, Name, Detail, "", UL, NULL, 0, false, false, TypeRefUndefined, NULL, Sym },
364 
365 //! MXFLIB_MASKED_LABEL - Use to define a masked label
366 /*! \param Name The name of the label being defined
367  *  \param Detail A human readable description of the label
368  *  \param UL The UL, or end-swapped UUID of thsi label
369  *  \param Mask The mask of bits that can change in this label
370  */
371 #define MXFLIB_MASKED_LABEL(Name, Detail, UL, Mask) { TypeLabel, Name, Detail, "", UL, Mask, 0, false, false, TypeRefUndefined, NULL, NULL },
372 
373 //! MXFLIB_MASKED_LABEL_SYM - Use to define a masked label and override the default symbol space
374 /*! \param Name The name of the label being defined
375  *  \param Detail A human readable description of the label
376  *  \param UL The UL, or end-swapped UUID of thsi label
377  *  \param Mask The mask of bits that can change in this label
378  *  \param Sym The name of the symbol space for this type
379  */
380 #define MXFLIB_MASKED_LABEL_SYM(Name, Detail, UL, Mask, Sym) { TypeLabel, Name, Detail, "", UL, Mask, 0, false, false, TypeRefUndefined, NULL, Sym },
381 
382 
383 //! MXFLIB_TYPE_ENUM_END - Use to end definition of a "Enumeration" type
384 #define MXFLIB_TYPE_ENUM_END
385 
386 //! MXFLIB_TYPE_END - Use to end a type definition block
387 #define MXFLIB_TYPE_END { TypeNULL, "", "", "", "", "", 0, false, false, TypeRefUndefined, NULL, NULL } };
388 
389 /* Example usage:
390 	MXFLIB_TYPE_START(TypeArray)
391 		MXFLIB_TYPE_BASIC("UInt8", "Unsigned 8 bit integer", "urn:x-ul:060E2B34.0104.0101.01010100.00000000", 1, false)
392 		MXFLIB_TYPE_BASIC("UInt16", "Unsigned 16 bit integer", "urn:x-ul:060E2B34.0104.0101.01010200.00000000", 2, true)
393 		MXFLIB_TYPE_BASIC("Int32", "32 bit integer", "urn:x-ul:060E2B34.0104.0101.01010700.00000000", 4, true)
394 
395 		MXFLIB_TYPE_INTERPRETATION("VersionType", "Version number (created from major*256 + minor)", "UInt16", "urn:x-ul:060E2B34.0104.0101.03010300.00000000", 0)
396 		MXFLIB_TYPE_INTERPRETATION("UTF16", "Unicode UTF-16 coded character", "UInt16", "urn:x-ul:060E2B34.0104.0101.01100100.00000000", 0)
397 		MXFLIB_TYPE_INTERPRETATION("Boolean", "Boolean", "UInt8", "urn:x-ul:060E2B34.0104.0101.01040100.00000000", 0)
398 
399 		MXFLIB_TYPE_MULTIPLE("UTF16String", "Unicode UTF-16 coded string", "UTF16", "urn:x-ul:060E2B34.0104.0101.01100200.00000000", false, 0)
400 		MXFLIB_TYPE_MULTIPLE("Int32Array", "Array of Int32 values", "Int32", "urn:x-ul:060E2B34.0104.0101.04010900.00000000", false, 0)
401 		MXFLIB_TYPE_MULTIPLE("Int32Batch", "Batch of Int32 values", "Int32", "urn:x-ul:060E2B34.0104.0101.04030200.00000000", true, 0)
402 		MXFLIB_TYPE_MULTIPLE("Int32Pair", "Pair of Int32 values", "Int32", "", false, 2)
403 
404 		MXFLIB_TYPE_COMPOUND("Rational", "Rational", "urn:x-ul:060E2B34.0104.0101.03010100.00000000")
405 			MXFLIB_TYPE_COMPOUND_ITEM("Numerator", "Numerator", "Int32", "urn:x-ul:060E2B34.0104.0101.03010101.00000000", 0)
406 			MXFLIB_TYPE_COMPOUND_ITEM("Denominator", "Denominator", "Int32", "urn:x-ul:060E2B34.0104.0101.03010102.00000000", 0)
407 		MXFLIB_TYPE_COMPOUND_END
408 	MXFLIB_TYPE_END
409 */
410 }
411 
412 
413 namespace mxflib
414 {
415 	//! Enumeration identifying the type of an in-memory type definition entry to be processed by LoadTypes()
416 	enum ClassType
417 	{
418 		ClassNULL = 0,						//!< Special token used to end a list of classes or the end of a set, pack or vector
419 		ClassPack,							//!< Pack definition
420 		ClassSet,							//!< Local set definition
421 		ClassVector,						//!< Vector (with 8-byte count and size header) definition
422 		ClassArray,							//!< Array definition
423 		ClassItem,							//!< Definition of an item in a set, pack, vector or array
424 		ClassRename,						//!< Rename of a set or pack without new children
425 		ClassSymbolSpace					//!< Define the default symbol space for all classes in this list
426 	};
427 
428 	//! Usage types for classes
429 	enum ClassUsage
430 	{
431 		ClassUsageNULL = 0,					//!< Not a usage - flag used to signify no usage supplied (or not required)
432 		ClassUsageOptional,					//!< Item is optional, if present the decoder may ignore it
433 		ClassUsageDecoderRequired,			//!< Item is optional, but if present the decoder must use this value
434 		ClassUsageEncoderRequired,			//!< Item must be encoded, but decoder may ignore the value
435 		ClassUsageRequired,					//!< Item must be encoded and the decoder must use this value
436 		ClassUsageBestEffort,				//!< As ClassUsageRequired, but an "Incomplete" set of metadata may signal unknown by using a distinguished value
437 		ClassUsageToxic,					//!< Item must not be encoded - kept for compatibility!
438 		ClassUsageDark						//!< Item is dark - no longer makes sense: kept for compatibility
439 	};
440 
441 	//! Referencing types for classes - an exact copy of the type ref kinds
442 	typedef TypeRef ClassRef;
443 
444 	//! ClassRef version of TypeRefUndefined
445 	const ClassRef ClassRefUndefined = TypeRefUndefined;
446 
447 	//! ClassRef version of TypeRefNone
448 	const ClassRef ClassRefNone = TypeRefNone;
449 
450 	//! ClassRef version of TypeRefStrong
451 	const ClassRef ClassRefStrong = TypeRefStrong;
452 
453 	//! ClassRef version of TypeRefWeak
454 	const ClassRef ClassRefWeak = TypeRefWeak;
455 
456 	//! ClassRef version of TypeRefGlobal
457 	const ClassRef ClassRefGlobal = TypeRefGlobal;
458 
459 	//! ClassRef version of TypeRefTarget
460 	const ClassRef ClassRefTarget = TypeRefTarget;
461 
462 
463 	//! Single entry for a class to be defined - can be stored as a compile-time built structure
464 	struct ConstClassRecord
465 	{
466 		ClassType Class;					//!< The type of class being defined by this entry
467 		unsigned int MinSize;				//!< The minimum size of an item, or the tag size for a set (0 = no lower limit)
468 		unsigned int MaxSize;				//!< The maximum size of an item, or the length size/format for a set (0 = no upper limit)
469 		const char *Name;					//!< The name of this class
470 		const char *Detail;					//!< The human readable description of this type
471 		ClassUsage Usage;					//!< The usage type for this class
472 		const char *Base;					//!< The type of an item, or base type if redefining
473 		UInt16 Tag;							//!< The 2-byte tag, or zero
474 		const char *UL;						//!< The UL for this class or item (if known)
475 		const char *Default;				//!< Default value as a string, or NULL if none
476 		const char *DValue;					//!< Distinguished value as a string, or NULL if none
477 		ClassRef RefType;					//!< Reference type of this item (if a reference or target)
478 		const char *RefTarget;				//!< Type of the reference target (if this is a referencing type)
479 		const char *SymSpace;				//!< SymbolSpace for this class, or NULL if none specified (will inherit)
480 		bool ExtendSubs;					//!< If this entry is extending a class, should sub-classes also be extended?
481 	};
482 
483 	// Forward declare ClassRecord to allow ClassRecordPtr to be defined early
484 	class ClassRecord;
485 
486 	//! A smart pointer to a ClassRecord
487 	typedef SmartPtr<ClassRecord> ClassRecordPtr;
488 
489 	//! List of smart pointers to ClassRecords
490 	typedef std::list<ClassRecordPtr> ClassRecordList;
491 
492 	//! List of ClassRecordLists
493 	typedef std::list<ClassRecordList> ClassRecordListList;
494 
495 	//! Single entry for a class to be defined - built at run-time and can be stacked if required to allow out-of-order definitions
496 	class ClassRecord : public RefCount<ClassRecord>
497 	{
498 	public:
499 		ClassType Class;					//!< The type of class being defined by this entry
500 		unsigned int MinSize;				//!< The minimum size of an item, or the tag size for a set (0 = no lower limit)
501 		unsigned int MaxSize;				//!< The maximum size of an item, or the length size/format for a set (0 = no upper limit)
502 		std::string Name;					//!< The name of this class
503 		std::string Detail;					//!< The human readable description of this type
504 		ClassUsage Usage;					//!< The usage type for this class
505 		std::string Base;					//!< The type of an item, or base type if redefining
506 		UInt16 Tag;							//!< The 2-byte tag, or zero
507 		ULPtr UL;							//!< The UL for this class or item (or NULL if not known)
508 		bool HasDefault;					//!< True if the item has a default value
509 		std::string Default;				//!< Default value as a string
510 		bool HasDValue;						//!< True if the item has a distinguished value
511 		std::string DValue;					//!< Distinguished value as a string
512 		ClassRecordList Children;			//!< Sub-items within this class (if it is a set or pack)
513 		ClassRef RefType;					//!< Reference type of this item (if a reference or target)
514 		std::string RefTarget;				//!< Type of the reference target (if this is a referencing type)
515 		SymbolSpacePtr SymSpace;			//!< SymbolSpace for this class, or NULL if none specified (will inherit)
516 		bool ExtendSubs;					//!< If this entry is extending a class, should sub-classes also be extended?
517 
518 	public:
519 		//! Build an empty ClassRecord
ClassRecord()520 		ClassRecord()
521 		{
522 			Class = ClassNULL;
523 			MinSize = 0;
524 			MaxSize = 0;
525 			Usage = ClassUsageNULL;
526 			Tag = 0;
527 			HasDefault = false;
528 			HasDValue = false;
529 			RefType = ClassRefUndefined;
530 			ExtendSubs = true;
531 		}
532 	};
533 
534 
535 	//! Load classes from the specified in-memory definitions
536 	/*! \return 0 if all OK
537 	 *  \return -1 on error
538 	 */
539 	int LoadClasses(ClassRecordList &ClassesData, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols);
540 
541 	//! Load classeses from the specified in-memory definitions
542 	/*! \note There must be enough terminating entries (with Class == TypeNULL) to end the list
543 	 *  \return 0 if all OK
544 	 *  \return -1 on error
545 	 */
546 	int LoadClasses(const ConstClassRecord *ClassData, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols);
547 
548 
549 	/* Define macros for static type definitions */
550 
551 //! MXFLIB_CLASS_START - Use to start a class definition block
552 #define MXFLIB_CLASS_START(Name) const ConstClassRecord Name[] = {
553 
554 //! MXFLIB_CLASS_START_SYM - Use to start a class definition block and define a default symbol space
555 #define MXFLIB_CLASS_START_SYM(Name, Sym) const ConstClassRecord Name[] = { { ClassSymbolSpace, 0, 0, "", "", ClassUsageNULL, "", 0, "", NULL, NULL, ClassRefUndefined, "", Sym, true },
556 
557 //! MXFLIB_CLASS_SET - Use to define a local set that has 2-byte tags and 2-byte lengths
558 /*! \param Name The name of the set being defined
559  *  \param Detail A human readable description of the set
560  *  \param Base The base class if this set is a derived class, else ""
561  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
562  */
563 #define MXFLIB_CLASS_SET(Name, Detail, Base, UL) { ClassSet, 2, 2, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", NULL, true },
564 
565 //! MXFLIB_CLASS_SET_SYM - Use to define a local set that has 2-byte tags and 2-byte lengths and override the default symbol space
566 /*! \param Name The name of the set being defined
567  *  \param Detail A human readable description of the set
568  *  \param Base The base class if this set is a derived class, else ""
569  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
570  *  \param Sym The name of the symbol space for this set
571  */
572 #define MXFLIB_CLASS_SET_SYM(Name, Detail, Base, UL, Sym) { ClassSet, 2, 2, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", Sym, true },
573 
574 //! MXFLIB_CLASS_SET_NOSUB - Use to extend a local set that has 2-byte tags and 2-byte lengths, without extending sub-classes
575 /*! \param Name The name of the set being extended
576  *  \param Detail A human readable description of the set
577  *  \param Base The base class if this set is a derived class, else ""
578  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
579  */
580 #define MXFLIB_CLASS_SET_NOSUB(Name, Detail, Base, UL) { ClassSet, 2, 2, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", NULL, false },
581 
582 //! MXFLIB_CLASS_SET_NOSUB_SYM - Use to extend a local set that has 2-byte tags and 2-byte lengths, without extending sub-classes, and override the default symbol space
583 /*! \param Name The name of the set being extended
584  *  \param Detail A human readable description of the set
585  *  \param Base The base class if this set is a derived class, else ""
586  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
587  *  \param Sym The name of the symbol space for this set
588  */
589 #define MXFLIB_CLASS_SET_NOSUB_SYM(Name, Detail, Base, UL, Sym) { ClassSet, 2, 2, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", Sym, false },
590 
591 //! MXFLIB_CLASS_SET_END - Use to end a set definition
592 #define MXFLIB_CLASS_SET_END { ClassNULL, 0, 0, "", "", ClassUsageNULL, "", 0, "", NULL, NULL, ClassRefUndefined, "", NULL, true },
593 
594 //! MXFLIB_CLASS_FIXEDPACK - Use to define a fixed length pack (defined length pack)
595 /*! \param Name The name of the pack being defined
596  *  \param Detail A human readable description of the pack
597  *  \param Base The base class if this pack is a derived class, else ""
598  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
599  */
600 #define MXFLIB_CLASS_FIXEDPACK(Name, Detail, Base, UL) { ClassPack, 0, 0, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", NULL, true },
601 
602 //! MXFLIB_CLASS_FIXEDPACK_SYM - Use to define a fixed length pack (defined length pack) and override the default symbol space
603 /*! \param Name The name of the pack being defined
604  *  \param Detail A human readable description of the pack
605  *  \param Base The base class if this pack is a derived class, else ""
606  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
607  *  \param Sym The name of the symbol space for this set
608  */
609 #define MXFLIB_CLASS_FIXEDPACK_SYM(Name, Detail, Base, UL, Sym) { ClassPack, 0, 0, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", Sym, true },
610 
611 //! MXFLIB_CLASS_FIXEDPACK - Use to extend a fixed length pack (defined length pack, without extending sub-classes
612 /*! \param Name The name of the pack being extended
613  *  \param Detail A human readable description of the pack
614  *  \param Base The base class if this pack is a derived class, else ""
615  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
616  */
617 #define MXFLIB_CLASS_FIXEDPACK_NOSUB(Name, Detail, Base, UL) { ClassPack, 0, 0, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", NULL, false },
618 
619 //! MXFLIB_CLASS_FIXEDPACK_SYM - Use to extend a fixed length pack (defined length pack), without extending sub-classes, and override the default symbol space
620 /*! \param Name The name of the pack being extended
621  *  \param Detail A human readable description of the pack
622  *  \param Base The base class if this pack is a derived class, else ""
623  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
624  *  \param Sym The name of the symbol space for this set
625  */
626 #define MXFLIB_CLASS_FIXEDPACK_NOSUB_SYM(Name, Detail, Base, UL, Sym) { ClassPack, 0, 0, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", Sym, false },
627 
628 //! MXFLIB_CLASS_FIXEDPACK_END - Use to end a pack definition
629 #define MXFLIB_CLASS_FIXEDPACK_END { ClassNULL, 0, 0, "", "", ClassUsageNULL, "", 0, "", NULL, NULL, ClassRefUndefined, "", NULL, true },
630 
631 //! MXFLIB_CLASS_ITEM - Use to define a single item in a set or pack
632 /*! \param Name The name of the item being defined
633  *  \param Detail A human readable description of the item
634  *  \param Usage The usage type of this item (ClassUsageRequired, ClassUsageOptional, etc.)
635  *  \param Type The type of this item
636  *  \param Tag The tag for this item as a string of hex bytes e.g. "03 2b" (if in a set, else "")
637  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
638  *	\param Default The default value for this item as a string (or NULL if none)
639  *	\param DValue The distinguished value for this item as a string (or NULL if none)
640  */
641 #define MXFLIB_CLASS_ITEM(Name, Detail, Usage, Type, MinSize, MaxSize, Tag, UL, Default, DValue) { ClassItem, MinSize, MaxSize, Name, Detail, Usage, Type, Tag, UL, Default, DValue, ClassRefUndefined, "", NULL, true },
642 
643 //! MXFLIB_CLASS_ITEM_REF - Use to define a single item in a set or pack that is a reference source or target
644 /*! \param Name The name of the item being defined
645  *  \param Detail A human readable description of the item
646  *  \param Usage The usage type of this item (ClassUsageRequired, ClassUsageOptional, etc.)
647  *  \param Type The type of this item
648  *  \param Tag The tag for this item as a string of hex bytes e.g. "03 2b" (if in a set, else "")
649  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
650  *	\param Default The default value for this item as a string (or NULL if none)
651  *	\param DValue The distinguished value for this item as a string (or NULL if none)
652  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
653  *  \param RefTarget The type of the reference target
654  */
655 #define MXFLIB_CLASS_ITEM_REF(Name, Detail, Usage, Type, MinSize, MaxSize, Tag, UL, RefType, RefTarget, Default, DValue) { ClassItem, MinSize, MaxSize, Name, Detail, Usage, Type, Tag, UL, Default, DValue, RefType, RefTarget, NULL, true },
656 
657 //! MXFLIB_CLASS_ITEM_SYM - Use to define a single item in a set or pack and override the default symbol space
658 /*! \param Name The name of the item being defined
659  *  \param Detail A human readable description of the item
660  *  \param Usage The usage type of this item (ClassUsageRequired, ClassUsageOptional, etc.)
661  *  \param Type The type of this item
662  *  \param Tag The tag for this item as a string of hex bytes e.g. "03 2b" (if in a set, else "")
663  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
664  *	\param Default The default value for this item as a string (or NULL if none)
665  *	\param DValue The distinguished value for this item as a string (or NULL if none)
666  *  \param Sym The name of the symbol space for this set
667  */
668 #define MXFLIB_CLASS_ITEM_SYM(Name, Detail, Usage, Type, MinSize, MaxSize, Tag, UL, Default, DValue, Sym) { ClassItem, MinSize, MaxSize, Name, Detail, Usage, Type, Tag, UL, Default, DValue, ClassRefUndefined, "", Sym, true },
669 
670 //! MXFLIB_CLASS_ITEM_REF_SYM - Use to define a single item in a set or pack that is a reference source or target and override the default symbol space
671 /*! \param Name The name of the item being defined
672  *  \param Detail A human readable description of the item
673  *  \param Usage The usage type of this item (ClassUsageRequired, ClassUsageOptional, etc.)
674  *  \param Type The type of this item
675  *  \param Tag The tag for this item as a string of hex bytes e.g. "03 2b" (if in a set, else "")
676  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
677  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
678  *  \param RefTarget The type of the reference target
679  *	\param Default The default value for this item as a string (or NULL if none)
680  *	\param DValue The distinguished value for this item as a string (or NULL if none)
681  *  \param Sym The name of the symbol space for this set
682  */
683 #define MXFLIB_CLASS_ITEM_REF_SYM(Name, Detail, Usage, Type, MinSize, MaxSize, Tag, UL, RefType, RefTarget, Default, DValue, Sym) { ClassItem, MinSize, MaxSize, Name, Detail, Usage, Type, Tag, UL, Default, DValue, RefType, RefTarget, Sym, true },
684 
685 //! MXFLIB_CLASS_VECTOR - Use to define a vector holding items
686 /*! \param Name The name of the vector being defined
687  *  \param Detail A human readable description of the vector
688  *  \param Usage The usage type of this vector (ClassUsageRequired, ClassUsageOptional, etc.)
689  *  \param Tag The tag for this vector as a string of hex bytes e.g. "03 2b" (if in a set, else "")
690  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
691  */
692 #define MXFLIB_CLASS_VECTOR(Name, Detail, Usage, Tag, UL) { ClassVector, 0, 0, Name, Detail, Usage, "", Tag, UL, NULL, NULL, ClassRefUndefined, "", NULL, true },
693 
694 //! MXFLIB_CLASS_VECTOR_REF - Use to define a vector holding items that are reference sources or targets
695 /*! \param Name The name of the vector being defined
696  *  \param Detail A human readable description of the vector
697  *  \param Usage The usage type of this vector (ClassUsageRequired, ClassUsageOptional, etc.)
698  *  \param Tag The tag for this vector as a string of hex bytes e.g. "03 2b" (if in a set, else "")
699  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
700  *	\param RefType The reference type (RefWeak, RefStrong or RefTarget)
701  *  \param RefTarget The type of the reference target
702  */
703 #define MXFLIB_CLASS_VECTOR_REF(Name, Detail, Usage, Tag, UL, RefType, RefTarget) { ClassVector, 0, 0, Name, Detail, Usage, "", Tag, UL, NULL, NULL, RefType, RefTarget, NULL, true },
704 
705 //! MXFLIB_CLASS_VECTOR_END - Use to end a vector definition
706 #define MXFLIB_CLASS_VECTOR_END { ClassNULL, 0, 0, "", "", ClassUsageNULL, "", 0, "", NULL, NULL, ClassRefUndefined, "", NULL, true },
707 
708 //! MXFLIB_CLASS_ARRAY - Use to define an array holding items
709 /*! \param Name The name of the array being defined
710  *  \param Detail A human readable description of the array
711  *  \param Usage The usage type of this array (ClassUsageRequired, ClassUsageOptional, etc.)
712  *  \param Tag The tag for this array as a string of hex bytes e.g. "03 2b" (if in a set, else "")
713  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
714  */
715 #define MXFLIB_CLASS_ARRAY(Name, Detail, Usage, Tag, UL) { ClassArray, 0, 0, Name, Detail, Usage, "", Tag, UL, NULL, NULL, ClassRefUndefined, "", NULL, true },
716 
717 //! MXFLIB_CLASS_ARRAY - Use to define an array holding items
718 /*! \param Name The name of the array being defined
719  *  \param Detail A human readable description of the array
720  *  \param Usage The usage type of this array (ClassUsageRequired, ClassUsageOptional, etc.)
721  *  \param Tag The tag for this array as a string of hex bytes e.g. "03 2b" (if in a set, else "")
722  *  \param UL The UL of this class as a hex string e.g. "06 0e 2b 34 etc." (if one exists, else "")
723  */
724 #define MXFLIB_CLASS_ARRAY_REF(Name, Detail, Usage, Tag, UL, RefType, RefTarget) { ClassArray, 0, 0, Name, Detail, Usage, "", Tag, UL, NULL, NULL, RefType, RefTarget, NULL, true },
725 
726 //! MXFLIB_CLASS_ARRAY_END - Use to end a array definition
727 #define MXFLIB_CLASS_ARRAY_END { ClassNULL, 0, 0, "", "", ClassUsageNULL, "", 0, "", NULL, NULL, ClassRefUndefined, "", NULL, true },
728 
729 //! MXFLIB_CLASS_RENAME - Use to rename a set or pack without defining new members
730 /*! \param Name The name of the class being defined
731  *  \param Detail A human readable description of the class
732  *  \param Base The base class of which this is a rename
733  *  \param UL The UL of this class (if one exists, else "")
734  */
735 #define MXFLIB_CLASS_RENAME(Name, Detail, Base, UL) { ClassRename, 0, 0, Name, Detail, ClassUsageNULL, Base, 0, UL, NULL, NULL, ClassRefUndefined, "", NULL, true },
736 
737 //! MXFLIB_CLASS_END - Use to end a class definition block
738 #define MXFLIB_CLASS_END { ClassNULL, 0, 0, "", "", ClassUsageNULL, "", 0, "", NULL, NULL, ClassRefUndefined, "", NULL, true } };
739 
740 
741 /* Example usage:
742 	MXFLIB_CLASS_RENAME("KLVFill", "KLV Filler packet", "RAW", "06 0E 2B 34 01 01 01 01 03 01 02 10 01 00 00 00")
743 	MXFLIB_CLASS_FIXEDPACK("PartitionMetadata", "Identifies a Partition Pack", "")
744 		MXFLIB_CLASS_ITEM("MajorVersion", "Major Version number of MXF byte-level format (non-backwards compatible version number)", ClassUsageRequired, "UInt16", 2, 2, "06 0e 2b 34 01 01 01 04  03 01 02 01 06 00 00 00", "", "0001", "")
745 		MXFLIB_CLASS_ITEM("MinorVersion", "Minor Version number of MXF byte-level format (backwards compatible version number)", ClassUsageRequired, "UInt16", 2, 2, "06 0e 2b 34 01 01 01 04  03 01 02 01 06 00 00 00", "", "0001", "")
746 ...
747 		MXFLIB_CLASS_ITEM_REF("PrimaryPackage", "The primary Package in this file", ClassUsageOptional, "UUID", 16, 16, "06 0e 2b 34 01 01 01 04  06 01 01 04 01 08 00 00", "3b 08", "", "", RefWeak, "GenericPackage")
748 ...
749 		MXFLIB_CLASS_VECTOR("EssenceContainers", "The unordered batch of Universal Labels of Essence Containers used in or referenced by this file", ClassUsageRequired, "06 0e 2b 34 01 01 01 05  01 02 02 10 02 01 00 00", "", "")
750 			MXFLIB_CLASS_ITEM("EssenceContainer", "Universal Labels of Essence Container", ClassUsageRequired, "Label", 16, 16, "", "", "", "")
751 		MXFLIB_CLASS_VECTOR_END
752 	MXFLIB_CLASS_END
753 
754 	MXFLIB_CLASS_RENAME("OpenHeader", "Open Header Partition Pack", "PartitionMetadata", "06 0e 2b 34 02 05 01 01  0d 01 02 01 01 02 01 00")
755 	MXFLIB_CLASS_RENAME("OpenCompleteHeader", "Open Complete Header Partition Pack", "PartitionMetadata", "06 0e 2b 34 02 05 01 01  0d 01 02 01 01 02 03 00")
756 
757  <PrimaryPackage detail="The primary Package in this file" use="optional" type="UUID" minLength="16" maxLength="16" key="3b 08" globalKey="06 0e 2b 34 01 01 01 04  06 01 01 04 01 08 00 00" ref="weak" target="GenericPackage"/>
758 */
759 }
760 
761 
762 namespace mxflib
763 {
764 	//! Enumeration identifying the type of an in-memory dictionary definition entry to be processed by LoadDictionary()
765 	enum DictionaryType
766 	{
767 		DictionaryNULL = 0,					//!< Special token used to end a list of dictionary entries
768 		DictionaryTypes,					//!< Types dictionary befinition
769 		DictionaryClasses					//!< Class dictionary definition
770 	};
771 
772 	//! Single entry for a dictionary to be defined - can be stored as a compile-time built structure
773 	struct ConstDictionaryRecord
774 	{
775 		DictionaryType Type;				//!< The type of dictionary being defined by this entry
776 		const void *Dict;					//!< Pointer to either a ConstTypeRecord array or a ConstClassRecord array holding the dictionary to load
777 	};
778 
779 	// Forward declare Dictionary to allow DictionaryPtr to be defined early
780 	class Dictionary;
781 
782 	//! A smart pointer to a Dictionary
783 	typedef SmartPtr<Dictionary> DictionaryPtr;
784 
785 	//! List of smart pointers to Dictionary objects
786 	typedef std::list<DictionaryPtr> DictionaryList;
787 
788 	//! Run-time dictionary definition - built from other run-time record definitions
789 	class Dictionary : public RefCount<Dictionary>
790 	{
791 	public:
792 		TypeRecordListList Types;			//!< All the types to define
793 		ClassRecordListList Classes;		//!< All the classes to define
794 	};
795 
796 
797 	//! Load dictionary from the specified in-memory definitions with a default symbol space
798 	/*! \return 0 if all OK
799 	 *  \return -1 on error
800 	 */
801 	int LoadDictionary(DictionaryPtr &DictionaryData, SymbolSpacePtr DefaultSymbolSpace, bool FastFail = false);
802 
803 	//! Load dictionary from the specified in-memory definitions
804 	/*! \return 0 if all OK
805 	 *  \return -1 on error
806 	 */
807 	inline int LoadDictionary(DictionaryPtr &DictionaryData, bool FastFail = false, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols)
808 	{
809 		return LoadDictionary(DictionaryData, DefaultSymbolSpace, FastFail );
810 	}
811 
812 	//! Load dictionary from the specified in-memory definitions with a default symbol space
813 	/*! \note There must be a terminating entry (with Type == DictionaryNULL) to end the list
814 	 *  \return 0 if all OK
815 	 *  \return -1 on error
816 	 */
817 	int LoadDictionary(const ConstDictionaryRecord *DictionaryData, SymbolSpacePtr DefaultSymbolSpace, bool FastFail = false);
818 
819 	//! Load dictionary from the specified in-memory definitions
820 	/*! \note There must be a terminating entry (with Type == DictionaryNULL) to end the list
821 	 *  \return 0 if all OK
822 	 *  \return -1 on error
823 	 */
824 	inline int LoadDictionary(const ConstDictionaryRecord *DictionaryData, bool FastFail = false, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols)
825 	{
826 		return LoadDictionary(DictionaryData, DefaultSymbolSpace, FastFail);
827 	}
828 
829 	//! Load dictionary from the specified XML definitions with a default symbol space
830 	/*! \return 0 if all OK
831 	 *  \return -1 on error
832 	 */
833 	int LoadDictionary(const char *DictFile, SymbolSpacePtr DefaultSymbolSpace, bool FastFail = false);
834 
835 	//! Load dictionary from the specified XML definitions with a default symbol space
836 	/*! \return 0 if all OK
837 	 *  \return -1 on error
838 	 */
839 	inline int LoadDictionary(std::string DictFile, SymbolSpacePtr DefaultSymbolSpace, bool FastFail = false)
840 	{
841 		return LoadDictionary(DictFile.c_str(), DefaultSymbolSpace, FastFail );
842 	}
843 
844 	//! Load dictionary from the specified XML definitions
845 	/*! \return 0 if all OK
846 	 *  \return -1 on error
847 	 */
848 	inline int LoadDictionary(const char *DictFile, bool FastFail = false, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols)
849 	{
850 		return LoadDictionary(DictFile, DefaultSymbolSpace, FastFail );
851 	}
852 
853 	//! Load dictionary from the specified XML definitions
854 	/*! \return 0 if all OK
855 	 *  \return -1 on error
856 	 */
857 	inline int LoadDictionary(std::string DictFile, bool FastFail = false, SymbolSpacePtr DefaultSymbolSpace = MXFLibSymbols)
858 	{
859 		return LoadDictionary(DictFile.c_str(), DefaultSymbolSpace, FastFail );
860 	}
861 
862 
863 //! MXFLIB_DICTIONARY_START - Use to start a type definition block
864 #define MXFLIB_DICTIONARY_START(Name)		const ConstDictionaryRecord Name[] = {
865 
866 //! MXFLIB_DICTIONARY_TYPES - Add a set of types to the current dictionary
867 #define MXFLIB_DICTIONARY_TYPES(Types)		{ DictionaryTypes, Types },
868 
869 //! MXFLIB_DICTIONARY_CLASSES - Add a set of classes to the current dictionary
870 #define MXFLIB_DICTIONARY_CLASSES(Classes)	{ DictionaryClasses, Classes },
871 
872 //! MXFLIB_DICTIONARY_END - Use to end a dictionary definition block
873 #define MXFLIB_DICTIONARY_END				{ DictionaryNULL, NULL } };
874 
875 /* Example usage:
876 	MXFLIB_DICTIONARY_START(Dict)
877 		MXFLIB_DICTIONARY_TYPES(MyTypes)
878 		MXFLIB_DICTIONARY_CLASSES(MyClasses)
879 	MXFLIB_DICTIONARY_END
880 */
881 }
882 
883 namespace mxflib
884 {
885 	class Label;
886 
887 	// A Smart pointer to a Label
888 	typedef SmartPtr<Label> LabelPtr;
889 
890 	//! A UL or end-swapped UUID label
891 	class Label : public RefCount<Label>
892 	{
893 	protected:
894 		UL Value;										//!< The value of this label
895 		UInt8 Mask[16];									//!< Mask of ignore bits, each set bit flags a bit to be ignored when comparing
896 		bool NonZeroMask;								//!< True if there is a non-zero mask
897 		std::string Name;								//!< The XML-Tag-valid name for this label
898 		std::string Detail; 							//!< The human-readable description for this label
899 
900 	protected:
901 		//! Type of the Label map (map of UL to LabelPtr)
902 		typedef std::map<UL, LabelPtr> LabelULMap;
903 
904 		//! Type of the Label multi-map (map of UL to LabelPtr)
905 		typedef std::multimap<UL, LabelPtr> LabelULMultiMap;
906 
907 		//! Map of all existing labels that don't use masking
908 		static LabelULMap LabelMap;
909 
910 		//! Map of all existing labels that use masking - this is a multimap to allow the same base with different masks
911 		static LabelULMultiMap LabelMultiMap;
912 
913 	protected:
914 		// Private constructor - to build a new label one of the Insert() functions must be called
Label(std::string LabelName,std::string Detail,const UInt8 * LabelUL,const UInt8 * LabelMask)915 		Label(std::string LabelName, std::string Detail, const UInt8 *LabelUL, const UInt8 *LabelMask)
916 			: Value(LabelUL), Detail(Detail)
917 		{
918 			Init(LabelName, LabelMask);
919 		}
920 
921 		// Private constructor - to build a new label one of the Insert() functions must be called
Label(std::string LabelName,std::string Detail,const UUID & LabelULasUUID,const UInt8 * LabelMask)922 		Label(std::string LabelName, std::string Detail, const UUID &LabelULasUUID, const UInt8 *LabelMask)
923 			: Value(LabelULasUUID), Detail(Detail)
924 		{
925 			Init(LabelName, LabelMask);
926 		}
927 
928 		// Constructor common part - called by constructors
Init(std::string LabelName,const UInt8 * LabelMask)929 		void Init(std::string LabelName, const UInt8 *LabelMask)
930 		{
931 			Name = LabelName;
932 
933 			if(LabelMask)
934 			{
935 				memcpy(Mask, LabelMask, 16);
936 				NonZeroMask = true;
937 			}
938 			else
939 			{
940 				memset(Mask, 0, 16);
941 				NonZeroMask = false;
942 			}
943 		}
944 
945 	public:
946 		//! Get the name of this label
GetName(void)947 		std::string GetName(void) { return Name; };
948 
949 		//! Get the detail for this label
GetDetail(void)950 		std::string GetDetail(void) { return Detail; };
951 
952 		//! Return true if this label uses a (non-zero) mask
HasMask(void)953 		bool HasMask(void) { return NonZeroMask; }
954 
955 	public:
956 		//! Construct and add a label from a byte array
957 		/*! \return true if succeeded, else false
958 		 */
959 		static bool Insert(std::string Name, std::string Detail, const UInt8 *LabelValue, const UInt8 *LabelMask = NULL);
960 
961 		//! Construct and add a label from a UL smart pointer
962 		/*! \return true if succeeded, else false
963 		 */
964 		static bool Insert(std::string Name, std::string Detail, const ULPtr &LabelValue, const UInt8 *LabelMask = NULL);
965 
966 		//! Construct and add a label from a UL reference
967 		/*! \return true if succeeded, else false
968 		 */
969 		static bool Insert(std::string Name, std::string Detail, const UL &LabelValue, const UInt8 *LabelMask = NULL);
970 
971 		//! Construct and add a label from a UUID smart pointer
972 		/*! \return true if succeeded, else false
973 		 */
974 		static bool Insert(std::string Name, std::string Detail, const UUIDPtr &LabelValue, const UInt8 *LabelMask = NULL);
975 
976 		//! Construct and add a label from a UUID reference
977 		/*! \return true if succeeded, else false
978 		 */
979 		static bool Insert(std::string Name, std::string Detail, const mxflib::UUID &LabelValue, const UInt8 *LabelMask = NULL);
980 
981 	public:
982 		//! Find a label with a given value, from a UL reference
983 		static LabelPtr Find(const UL &LabelValue);
984 
985 		//! Find a label with a given value, from a ULPtr
Find(const ULPtr & LabelValue)986 		static LabelPtr Find(const ULPtr &LabelValue)
987 		{
988 			return Find(*LabelValue);
989 		}
990 
991 		//! Find a label with a given value, from the label bytes
Find(const UInt8 * LabelValue)992 		static LabelPtr Find(const UInt8 *LabelValue)
993 		{
994 			/* Make a value UL and use that in the main search */
995 			UL ValueUL(LabelValue);
996 			return Find(ValueUL);
997 		}
998 	};
999 }
1000 
1001 #endif // MXFLIB__DICTIONARY_H
1002 
1003