summaryrefslogtreecommitdiff
path: root/XMPFiles/source/NativeMetadataSupport/ValueObject.h
blob: 7406bccaa8cdd518ef72ad9237b476951e6c76f8 (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
// =================================================================================================
// Copyright Adobe
// Copyright 2010 Adobe
// 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. If you have received this file from a source other 
// than Adobe, then your use, modification, or distribution of it requires the prior written permission
// of Adobe.
// =================================================================================================

#ifndef _ValueObject_h_
#define _ValueObject_h_

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

/**
 * The class ValueObject acts as a base class for the two generic classes
 * TValueObject and TValueArray.
 * The overall purpose of these classes is to store a single value (or array)
 * of any data types and a modification state. The modification state is
 * always set if the existing value has changed. It is not set if a new value
 * is set that is equal to the existing value.
 * If a ValueObject based instance is created or a new value is passed to an 
 * instance the actual value gets copied.
 *
 * So there're some requirements of possible data types:
 *   - data type needs to provide a relational operator
 *   - data type needs to provide an assign operator
 */

/**
 * The class ValueObject is the base class for the following generic classes.
 * It provids common functionality for handle the modification state.
 * This class can't be used directly!
 */
class ValueObject
{
public:
	virtual ~ValueObject()        {}

	inline bool		hasChanged() const				{ return mDirty;  }
	inline void		resetChanged()					{ mDirty = false; }

protected:
	ValueObject() : mDirty(false) {}

protected:
	bool	mDirty;
};

/**
 * The generic class TValueObject is supposed to store values of any data types.
 * It is based on the class ValueObject and support modification state functionality.
 * See above for the requirements of possible data types.
 */
template <class T> class TValueObject : public ValueObject
{
public:
	TValueObject( const T& value ) : mValue(value) {}
	~TValueObject() {}

	inline const T&	getValue() const				{ return mValue; }
	inline void		setValue( const T& value )		{ mDirty = !( mValue == value ); mValue = value; }

private:
	T		mValue;
};

/**
 * The generic class TArrayObject is supposed to store arrays of any data types.
 * It is based on the class ValueObject and supports modification state functionality.
 * See above for the requirements of possible data types.
 */
template <class T> class TArrayObject : public ValueObject
{
public:
	TArrayObject( const T* buffer, XMP_Uns32 bufferSize );
	~TArrayObject();

   inline const T* const getArray( XMP_Uns32& outSize ) const		{ outSize = mSize; return mArray; }
   void setArray( const T* buffer, XMP_Uns32 numElements);

private:
	T*			mArray;
	XMP_Uns32	mSize;
};

template<class T> inline TArrayObject<T>::TArrayObject( const T* buffer, XMP_Uns32 bufferSize ) 
: mArray(NULL), mSize(0)
{
	this->setArray( buffer, bufferSize );
	mDirty = false;
}

template<class T> inline TArrayObject<T>::~TArrayObject()
{
	if( mArray != NULL )
	{
		delete[] mArray;
	}
}

template<class T> inline void TArrayObject<T>::setArray( const T* buffer, XMP_Uns32 numElements )
{
	if( buffer != NULL && numElements > 0 )
	{
		bool doSet = true;

		if( mArray != NULL &&  mSize == numElements )
		{
			doSet = false;
			for( size_t i = 0; i < mSize; i++ ) {
				if ( mArray[i] != buffer[i] ) {
					doSet = true;
					break;
				}
			}
		}

		if( doSet )
		{
			if( mArray != NULL )
			{
				delete[] mArray;
			}

			mArray = new T[numElements];
			mSize  = numElements;

			for ( size_t i = 0; i < mSize; i++ ) {
				mArray[i] = buffer[i];
			}

			mDirty = true;
		}
	}
	else
	{
		mDirty = ( mArray != NULL );

		if( mArray != NULL )
		{
			delete[] mArray;
		}

		mArray = NULL;
		mSize  = 0;
	}
}

#endif