3 * \brief Property class definition
5 * Copyright (C) 2003-2008 Ushodaya Enterprises Limited
6 * \author Charles Yates <charles.yates@pandora.be>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "mlt_property.h"
30 /** Bit pattern used internally to indicated representations available.
35 mlt_prop_none = 0, //!< not set
36 mlt_prop_int = 1, //!< set as an integer
37 mlt_prop_string = 2, //!< set as string or already converted to string
38 mlt_prop_position = 4,//!< set as a position
39 mlt_prop_double = 8, //!< set as a floating point
40 mlt_prop_data = 16, //!< set as opaque binary
41 mlt_prop_int64 = 32 //!< set as a 64-bit integer
45 /** \brief Property class
47 * A property is like a variant or dynamic type. They are used for many things
48 * in MLT, but in particular they are the parameter mechanism for the plugins.
53 /// Stores a bit pattern of types available for this property
54 mlt_property_type types;
56 /// Atomic type handling
58 mlt_position prop_position;
65 /// Generic type handling
68 mlt_destructor destructor;
69 mlt_serialiser serialiser;
72 /** Construct a property and initialize it
73 * \public \memberof mlt_property_s
76 mlt_property mlt_property_init( )
78 mlt_property this = malloc( sizeof( struct mlt_property_s ) );
83 this->prop_position = 0;
84 this->prop_double = 0;
86 this->prop_string = NULL;
89 this->destructor = NULL;
90 this->serialiser = NULL;
95 /** Clear (0/null) a property.
97 * Frees up any associated resources in the process.
98 * \private \memberof mlt_property_s
99 * \param this a property
102 static inline void mlt_property_clear( mlt_property this )
104 // Special case data handling
105 if ( this->types & mlt_prop_data && this->destructor != NULL )
106 this->destructor( this->data );
108 // Special case string handling
109 if ( this->types & mlt_prop_string )
110 free( this->prop_string );
115 this->prop_position = 0;
116 this->prop_double = 0;
117 this->prop_int64 = 0;
118 this->prop_string = NULL;
121 this->destructor = NULL;
122 this->serialiser = NULL;
125 /** Set the property to an integer value.
127 * \public \memberof mlt_property_s
128 * \param this a property
129 * \param value an integer
133 int mlt_property_set_int( mlt_property this, int value )
135 mlt_property_clear( this );
136 this->types = mlt_prop_int;
137 this->prop_int = value;
141 /** Set the property to a floating point value.
143 * \public \memberof mlt_property_s
144 * \param this a property
145 * \param value a double precision floating point value
149 int mlt_property_set_double( mlt_property this, double value )
151 mlt_property_clear( this );
152 this->types = mlt_prop_double;
153 this->prop_double = value;
157 /** Set the property to a position value.
159 * Position is a relative time value in frame units.
160 * \public \memberof mlt_property_s
161 * \param this a property
162 * \param value a position value
166 int mlt_property_set_position( mlt_property this, mlt_position value )
168 mlt_property_clear( this );
169 this->types = mlt_prop_position;
170 this->prop_position = value;
174 /** Set the property to a string value.
176 * This makes a copy of the string you supply so you do not need to track
177 * a new reference to it.
178 * \public \memberof mlt_property_s
179 * \param this a property
180 * \param value the string to copy to the property
181 * \return true if it failed
184 int mlt_property_set_string( mlt_property this, const char *value )
186 if ( value != this->prop_string )
188 mlt_property_clear( this );
189 this->types = mlt_prop_string;
191 this->prop_string = strdup( value );
195 this->types = mlt_prop_string;
197 return this->prop_string == NULL;
200 /** Set the property to a 64-bit integer value.
202 * \public \memberof mlt_property_s
203 * \param this a property
204 * \param value a 64-bit integer
208 int mlt_property_set_int64( mlt_property this, int64_t value )
210 mlt_property_clear( this );
211 this->types = mlt_prop_int64;
212 this->prop_int64 = value;
216 /** Set a property to an opaque binary value.
218 * This does not make a copy of the data. You can use a Properties object
219 * with its reference tracking and the destructor function to control
220 * the lifetime of the data. Otherwise, pass NULL for the destructor
221 * function and control the lifetime yourself.
222 * \public \memberof mlt_property_s
223 * \param this a property
224 * \param value an opaque pointer
225 * \param length the number of bytes pointed to by value (optional)
226 * \param destructor a function to use to destroy this binary data (optional, assuming you manage the resource)
227 * \param serialiser a function to use to convert this binary data to a string (optional)
231 int mlt_property_set_data( mlt_property this, void *value, int length, mlt_destructor destructor, mlt_serialiser serialiser )
233 if ( this->data == value )
234 this->destructor = NULL;
235 mlt_property_clear( this );
236 this->types = mlt_prop_data;
238 this->length = length;
239 this->destructor = destructor;
240 this->serialiser = serialiser;
244 /** Convert a base 10 or base 16 string to an integer.
246 * The string must begin with '0x' to be interpreted as hexadecimal.
247 * Otherwise, it is interpreted as base 10.
248 * \private \memberof mlt_property_s
249 * \param value a string to convert
250 * \return the resultant integer
252 static inline int mlt_property_atoi( const char *value )
256 else if ( value[0] == '0' && value[1] == 'x' )
257 return strtol( value + 2, NULL, 16 );
259 return strtol( value, NULL, 10 );
262 /** Get the property as an integer.
264 * \public \memberof mlt_property_s
265 * \param this a property
266 * \return an integer value
269 int mlt_property_get_int( mlt_property this )
271 if ( this->types & mlt_prop_int )
272 return this->prop_int;
273 else if ( this->types & mlt_prop_double )
274 return ( int )this->prop_double;
275 else if ( this->types & mlt_prop_position )
276 return ( int )this->prop_position;
277 else if ( this->types & mlt_prop_int64 )
278 return ( int )this->prop_int64;
279 else if ( this->types & mlt_prop_string )
280 return mlt_property_atoi( this->prop_string );
284 /** Get the property as a floating point.
286 * \public \memberof mlt_property_s
287 * \param this a property
288 * \return a floating point value
291 double mlt_property_get_double( mlt_property this )
293 if ( this->types & mlt_prop_double )
294 return this->prop_double;
295 else if ( this->types & mlt_prop_int )
296 return ( double )this->prop_int;
297 else if ( this->types & mlt_prop_position )
298 return ( double )this->prop_position;
299 else if ( this->types & mlt_prop_int64 )
300 return ( double )this->prop_int64;
301 else if ( this->types & mlt_prop_string )
302 return atof( this->prop_string );
306 /** Get the property as a position.
308 * A position is an offset time in terms of frame units.
309 * \public \memberof mlt_property_s
310 * \param this a property
311 * \return the position in frames
314 mlt_position mlt_property_get_position( mlt_property this )
316 if ( this->types & mlt_prop_position )
317 return this->prop_position;
318 else if ( this->types & mlt_prop_int )
319 return ( mlt_position )this->prop_int;
320 else if ( this->types & mlt_prop_double )
321 return ( mlt_position )this->prop_double;
322 else if ( this->types & mlt_prop_int64 )
323 return ( mlt_position )this->prop_int64;
324 else if ( this->types & mlt_prop_string )
325 return ( mlt_position )atol( this->prop_string );
329 /** Convert a string to a 64-bit integer.
331 * If the string begins with '0x' it is interpreted as a hexadecimal value.
332 * \private \memberof mlt_property_s
333 * \param value a string
334 * \return a 64-bit integer
337 static inline int64_t mlt_property_atoll( const char *value )
341 else if ( value[0] == '0' && value[1] == 'x' )
342 return strtoll( value + 2, NULL, 16 );
344 return strtoll( value, NULL, 10 );
347 /** Get the property as a signed integer.
349 * \public \memberof mlt_property_s
350 * \param this a property
351 * \return a 64-bit integer
354 int64_t mlt_property_get_int64( mlt_property this )
356 if ( this->types & mlt_prop_int64 )
357 return this->prop_int64;
358 else if ( this->types & mlt_prop_int )
359 return ( int64_t )this->prop_int;
360 else if ( this->types & mlt_prop_double )
361 return ( int64_t )this->prop_double;
362 else if ( this->types & mlt_prop_position )
363 return ( int64_t )this->prop_position;
364 else if ( this->types & mlt_prop_string )
365 return mlt_property_atoll( this->prop_string );
369 /** Get the property as a string.
371 * The caller is not responsible for deallocating the returned string!
372 * The string is deallocated when the Property is closed.
373 * This tries its hardest to convert the property to string including using
374 * a serialization function for binary data, if supplied.
375 * \public \memberof mlt_property_s
376 * \param this a property
377 * \return a string representation of the property or NULL if failed
380 char *mlt_property_get_string( mlt_property this )
382 // Construct a string if need be
383 if ( ! ( this->types & mlt_prop_string ) )
385 if ( this->types & mlt_prop_int )
387 this->types |= mlt_prop_string;
388 this->prop_string = malloc( 32 );
389 sprintf( this->prop_string, "%d", this->prop_int );
391 else if ( this->types & mlt_prop_double )
393 this->types |= mlt_prop_string;
394 this->prop_string = malloc( 32 );
395 sprintf( this->prop_string, "%f", this->prop_double );
397 else if ( this->types & mlt_prop_position )
399 this->types |= mlt_prop_string;
400 this->prop_string = malloc( 32 );
401 sprintf( this->prop_string, "%d", (int)this->prop_position ); /* I don't know if this is wanted. -Zach */
403 else if ( this->types & mlt_prop_int64 )
405 this->types |= mlt_prop_string;
406 this->prop_string = malloc( 32 );
407 sprintf( this->prop_string, "%lld", this->prop_int64 );
409 else if ( this->types & mlt_prop_data && this->serialiser != NULL )
411 this->types |= mlt_prop_string;
412 this->prop_string = this->serialiser( this->data, this->length );
416 // Return the string (may be NULL)
417 return this->prop_string;
420 /** Get the binary data from a property.
422 * This only works if you previously put binary data into the property.
423 * This does not return a copy of the data; it returns a pointer to it.
424 * If you supplied a destructor function when setting the binary data,
425 * the destructor is used when the Property is closed to free the memory.
426 * Therefore, only free the returned pointer if you did not supply a
427 * destructor function.
428 * \public \memberof mlt_property_s
429 * \param this a property
430 * \param[out] length the size of the binary object in bytes
431 * \return an opaque data pointer or NULL if not available
434 void *mlt_property_get_data( mlt_property this, int *length )
436 // Assign length if not NULL
437 if ( length != NULL )
438 *length = this->length;
440 // Return the data (note: there is no conversion here)
444 /** Destroy a property and free all related resources.
446 * \public \memberof mlt_property_s
447 * \param this a property
450 void mlt_property_close( mlt_property this )
452 mlt_property_clear( this );
458 * A Property holding binary data only copies the data if a serialiser
459 * function was supplied when you set the Property.
460 * \public \memberof mlt_property_s
461 * \author Zach <zachary.drew@gmail.com>
462 * \param this a property
463 * \param that another property
465 void mlt_property_pass( mlt_property this, mlt_property that )
467 mlt_property_clear( this );
469 this->types = that->types;
471 if ( this->types & mlt_prop_int64 )
472 this->prop_int64 = that->prop_int64;
473 else if ( this->types & mlt_prop_int )
474 this->prop_int = that->prop_int;
475 else if ( this->types & mlt_prop_double )
476 this->prop_double = that->prop_double;
477 else if ( this->types & mlt_prop_position )
478 this->prop_position = that->prop_position;
479 else if ( this->types & mlt_prop_string )
481 if ( that->prop_string != NULL )
482 this->prop_string = strdup( that->prop_string );
484 else if ( this->types & mlt_prop_data && this->serialiser != NULL )
486 this->types = mlt_prop_string;
487 this->prop_string = this->serialiser( this->data, this->length );