summaryrefslogtreecommitdiff
path: root/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.h
blob: 5c1826818a538f7237780dde81d5dc441bf25c1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#ifndef __iXMLMetadata_h__
#define __iXMLMetadata_h__ 1

// =================================================================================================
// ADOBE SYSTEMS INCORPORATED
// Copyright 2014 Adobe Systems Incorporated
// All Rights Reserved
//
// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
// of the Adobe license agreement accompanying it.
// =================================================================================================

#include "public/include/XMP_Environment.h"	// ! XMP_Environment.h must be the first included header.
#include "public/include/XMP_Const.h"
#include "public/include/XMP_IO.hpp"

#include "XMPFiles/source/NativeMetadataSupport/IMetadata.h"

class ExpatAdapter;
class XML_Node;

namespace IFF_RIFF {

	/**
	*	iXML Metadata model.
	*	Implements the IMetadata interface
	*/
	class iXMLMetadata : public IMetadata
	{
	public:

		class TrackListInfo {
		public:
			TrackListInfo() : mChannelIndex( 0 ) {}

			TrackListInfo( XMP_Uns64 channelIndex, const std::string & name, const std::string & function )
				: mChannelIndex( channelIndex )
				, mName( name )
				, mFunction( function ) {}

			bool operator == ( const TrackListInfo & other ) const {
				return mChannelIndex == other.mChannelIndex &&
					mName.compare( other.mName ) == 0 &&
					mFunction.compare( other.mFunction ) == 0;
			}

			bool operator != ( const TrackListInfo & other ) const {
				return !( this->operator==( other ) );
			}

			XMP_Uns64			mChannelIndex;
			std::string			mName;
			std::string			mFunction;
		};

		enum
		{
			kTape,								// std::string
			kTake,								// std::string
			kScene,								// std::string
			kNote,								// std::string
			kProject,							// std::string
			kNoGood,							// bool( true/false )
			kFileSampleRate,					// XMP_Uns64
			kAudioBitDepth,						// XMP_Uns64
			kCircled,							// bool( true/false )
			kBWFDescription,					// std::string
			kBWFOriginator,						// std::string
			kBWFOriginatorReference,			// std::string
			kBWFOriginationDate,				// std::string
			kBWFOriginationTime,				// std::string
			kBWFTimeReferenceLow,				// XMP_Uns32
			kBWFTimeReferenceHigh,				// XMP_Uns32
			kBWFVersion,						// XMP_Uns16
			kBWFUMID,							// std::string[64]
			kBWFHistory,						// std::string
			kTimeCodeFlag,						// std::string[DF/NDF]
			kTimeCodeRate,						// std::string
			kTimeStampSampleRate,				// XMP_Uns64
			kTimeStampSampleSinceMidnightLow,	// XMP_Uns32
			kTimeStampSampleSinceMidnightHigh,	// XMP_Uns32
			kTrackList,							// std::vector< TrackListInfo >
			kLastEntry
		};

	public:
		/**
		*ctor/dtor
		*/
		iXMLMetadata();
		~iXMLMetadata();

		/**
		* Parses the given memory block and creates a data model representation
		* The implementation expects that the memory block is the data area of
		* the iXML chunk.
		* Throws exceptions if parsing is not possible
		*
		* @param input		The byte buffer to parse
		* @param size		Size of the given byte buffer
		*/
		void		parse( const XMP_Uns8* chunkData, XMP_Uns64 size );

		/**
		* See IMetadata::parse( const LFA_FileRef input )
		*/
		void		parse( XMP_IO* input ) { IMetadata::parse( input ); }

		/**
		* Serializes the data model to a memory block. 
		* The memory block will be the data area of a iXML chunk.
		* Throws exceptions if serializing is not possible
		*
		* @param buffer	Buffer that gets filled with serialized data
		* @param size		Size of passed in buffer
		*
		* @return			Size of serialized data (might be smaller than buffer size)
		*/
		XMP_Uns64		serialize( XMP_Uns8** buffer );

		void SetErrorCallback( GenericErrorCallback * errorCallback );

		void SetExtraSpaceSize( size_t size ) { mExtraSpaceSize = size; }

		size_t GetExtraSpaceSize() const { return mExtraSpaceSize; }

	protected:
		/**
		* @see IMetadata::isEmptyValue
		*/
		virtual	bool isEmptyValue( XMP_Uns32 id, ValueObject& valueObj );

		/**
		 * @see iMetadata::valueValid
		 */
		virtual bool valueValid( XMP_Uns32 id, ValueObject * valueObj );

		/**
		 * @see IMetadata::valueModify
		 */
		virtual void valueModify( XMP_Uns32 id, ValueObject * value );

		void ParseAndSetProperties();
		void UpdateProperties();

		std::string ParseStringValue( XML_Node * parentNode, XMP_Uns32 id );
		std::string ParseStringValue( XML_Node * parentNode, const char * tagName, bool recoverableError = true );
		XMP_Uns64 ParseUns64Value( XML_Node * parentNode, const char * tagName );

		void ParseAndSetTrackListInfo( XML_Node * parentNode );
		void ParseAndSetStringProperty( XML_Node * parentNode, XMP_Uns32 id );
		void ParseAndSetIntegerProperty( XML_Node * parentNode, XMP_Uns32 id );
		void ParseAndSetBoolProperty( XML_Node * parentNode, XMP_Uns32 id );

		void UpdateStringProperty( XML_Node * parentNode, XMP_Uns32 id );
		void UpdateIntegerProperty( XML_Node * parentNode, XMP_Uns32 id );
		void UpdateBoolProperty( XML_Node * parentNode, XMP_Uns32 id );
		void UpdateTrackListInfo( XML_Node * parentNode );

		void UpdateXMLNode( XML_Node * parentNode, const char * localName, const std::string &  value );
		void RemoveXMLNode( XML_Node * parentNode, const char * localName );

		void NotifyClient( XMP_ErrorSeverity severity, XMP_Error & error );

		bool validateStringSize( ValueObject * value, size_t minSize = 1, size_t maxSize = std::string::npos );
		bool validateInt( ValueObject * value, XMP_Uns64 minValue = 0, XMP_Uns64 maxValue = Max_XMP_Uns64 );
		bool validateBool( ValueObject * value );
		void shortenString( ValueObject * value, size_t lengthOfString );
		bool validateDate( ValueObject * value );
		bool validateTime( ValueObject * value );
		bool validateUMID( ValueObject * value );
		bool validateTimeCodeFlag( ValueObject * value );
		bool validateRational( ValueObject * value );
		bool validateTrackListInfo( ValueObject * value );
	private:
		// Operators hidden on purpose
		iXMLMetadata( const iXMLMetadata& ) {};
		iXMLMetadata& operator=( const iXMLMetadata& ) { return *this; };

		ExpatAdapter *			mExpatAdapter;
		XML_Node *				mRootNode;
		GenericErrorCallback *	mErrorCallback;
		size_t					mExtraSpaceSize;
	};

}

#endif  // __iXMLMetadata_h__