3 * \brief Property class definition
6 * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
7 * \author Charles Yates <charles.yates@pandora.be>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "mlt_property.h"
31 /** Bit pattern used internally to indicated representations available.
36 mlt_prop_none
= 0, //!< not set
37 mlt_prop_int
= 1, //!< set as an integer
38 mlt_prop_string
= 2, //!< set as string or already converted to string
39 mlt_prop_position
= 4,//!< set as a position
40 mlt_prop_double
= 8, //!< set as a floating point
41 mlt_prop_data
= 16, //!< set as opaque binary
42 mlt_prop_int64
= 32 //!< set as a 64-bit integer
46 /** \brief Property class
48 * A property is like a variant or dynamic type. They are used for many things
49 * in MLT, but in particular they are the parameter mechanism for the plugins.
54 /// Stores a bit pattern of types available for this property
55 mlt_property_type types
;
57 /// Atomic type handling
59 mlt_position prop_position
;
66 /// Generic type handling
69 mlt_destructor destructor
;
70 mlt_serialiser serialiser
;
73 /** Construct a property and initialize it
74 * \public \memberof mlt_property_s
77 mlt_property
mlt_property_init( )
79 mlt_property
this = malloc( sizeof( struct mlt_property_s
) );
84 this->prop_position
= 0;
85 this->prop_double
= 0;
87 this->prop_string
= NULL
;
90 this->destructor
= NULL
;
91 this->serialiser
= NULL
;
96 /** Clear (0/null) a property.
98 * Frees up any associated resources in the process.
99 * \private \memberof mlt_property_s
100 * \param this a property
103 static inline void mlt_property_clear( mlt_property
this )
105 // Special case data handling
106 if ( this->types
& mlt_prop_data
&& this->destructor
!= NULL
)
107 this->destructor( this->data
);
109 // Special case string handling
110 if ( this->types
& mlt_prop_string
)
111 free( this->prop_string
);
116 this->prop_position
= 0;
117 this->prop_double
= 0;
118 this->prop_int64
= 0;
119 this->prop_string
= NULL
;
122 this->destructor
= NULL
;
123 this->serialiser
= NULL
;
126 /** Set the property to an integer value.
128 * \public \memberof mlt_property_s
129 * \param this a property
130 * \param value an integer
134 int mlt_property_set_int( mlt_property
this, int value
)
136 mlt_property_clear( this );
137 this->types
= mlt_prop_int
;
138 this->prop_int
= value
;
142 /** Set the property to a floating point value.
144 * \public \memberof mlt_property_s
145 * \param this a property
146 * \param value a double precision floating point value
150 int mlt_property_set_double( mlt_property
this, double value
)
152 mlt_property_clear( this );
153 this->types
= mlt_prop_double
;
154 this->prop_double
= value
;
158 /** Set the property to a position value.
160 * Position is a relative time value in frame units.
161 * \public \memberof mlt_property_s
162 * \param this a property
163 * \param value a position value
167 int mlt_property_set_position( mlt_property
this, mlt_position value
)
169 mlt_property_clear( this );
170 this->types
= mlt_prop_position
;
171 this->prop_position
= value
;
175 /** Set the property to a string value.
177 * This makes a copy of the string you supply so you do not need to track
178 * a new reference to it.
179 * \public \memberof mlt_property_s
180 * \param this a property
181 * \param value the string to copy to the property
182 * \return true if it failed
185 int mlt_property_set_string( mlt_property
this, const char *value
)
187 if ( value
!= this->prop_string
)
189 mlt_property_clear( this );
190 this->types
= mlt_prop_string
;
192 this->prop_string
= strdup( value
);
196 this->types
= mlt_prop_string
;
198 return this->prop_string
== NULL
;
201 /** Set the property to a 64-bit integer value.
203 * \public \memberof mlt_property_s
204 * \param this a property
205 * \param value a 64-bit integer
209 int mlt_property_set_int64( mlt_property
this, int64_t value
)
211 mlt_property_clear( this );
212 this->types
= mlt_prop_int64
;
213 this->prop_int64
= value
;
217 /** Set a property to an opaque binary value.
219 * This does not make a copy of the data. You can use a Properties object
220 * with its reference tracking and the destructor function to control
221 * the lifetime of the data. Otherwise, pass NULL for the destructor
222 * function and control the lifetime yourself.
223 * \public \memberof mlt_property_s
224 * \param this a property
225 * \param value an opaque pointer
226 * \param length the number of bytes pointed to by value (optional)
227 * \param destructor a function to use to destroy this binary data (optional, assuming you manage the resource)
228 * \param serialiser a function to use to convert this binary data to a string (optional)
232 int mlt_property_set_data( mlt_property
this, void *value
, int length
, mlt_destructor destructor
, mlt_serialiser serialiser
)
234 if ( this->data
== value
)
235 this->destructor
= NULL
;
236 mlt_property_clear( this );
237 this->types
= mlt_prop_data
;
239 this->length
= length
;
240 this->destructor
= destructor
;
241 this->serialiser
= serialiser
;
245 /** Convert a base 10 or base 16 string to an integer.
247 * The string must begin with '0x' to be interpreted as hexadecimal.
248 * Otherwise, it is interpreted as base 10.
249 * \private \memberof mlt_property_s
250 * \param value a string to convert
251 * \return the resultant integer
253 static inline int mlt_property_atoi( const char *value
)
257 else if ( value
[0] == '0' && value
[1] == 'x' )
258 return strtol( value
+ 2, NULL
, 16 );
260 return strtol( value
, NULL
, 10 );
263 /** Get the property as an integer.
265 * \public \memberof mlt_property_s
266 * \param this a property
267 * \return an integer value
270 int mlt_property_get_int( mlt_property
this )
272 if ( this->types
& mlt_prop_int
)
273 return this->prop_int
;
274 else if ( this->types
& mlt_prop_double
)
275 return ( int )this->prop_double
;
276 else if ( this->types
& mlt_prop_position
)
277 return ( int )this->prop_position
;
278 else if ( this->types
& mlt_prop_int64
)
279 return ( int )this->prop_int64
;
280 else if ( this->types
& mlt_prop_string
)
281 return mlt_property_atoi( this->prop_string
);
285 /** Get the property as a floating point.
287 * \public \memberof mlt_property_s
288 * \param this a property
289 * \return a floating point value
292 double mlt_property_get_double( mlt_property
this )
294 if ( this->types
& mlt_prop_double
)
295 return this->prop_double
;
296 else if ( this->types
& mlt_prop_int
)
297 return ( double )this->prop_int
;
298 else if ( this->types
& mlt_prop_position
)
299 return ( double )this->prop_position
;
300 else if ( this->types
& mlt_prop_int64
)
301 return ( double )this->prop_int64
;
302 else if ( this->types
& mlt_prop_string
)
303 return atof( this->prop_string
);
307 /** Get the property as a position.
309 * A position is an offset time in terms of frame units.
310 * \public \memberof mlt_property_s
311 * \param this a property
312 * \return the position in frames
315 mlt_position
mlt_property_get_position( mlt_property
this )
317 if ( this->types
& mlt_prop_position
)
318 return this->prop_position
;
319 else if ( this->types
& mlt_prop_int
)
320 return ( mlt_position
)this->prop_int
;
321 else if ( this->types
& mlt_prop_double
)
322 return ( mlt_position
)this->prop_double
;
323 else if ( this->types
& mlt_prop_int64
)
324 return ( mlt_position
)this->prop_int64
;
325 else if ( this->types
& mlt_prop_string
)
326 return ( mlt_position
)atol( this->prop_string
);
330 /** Convert a string to a 64-bit integer.
332 * If the string begins with '0x' it is interpreted as a hexadecimal value.
333 * \private \memberof mlt_property_s
334 * \param value a string
335 * \return a 64-bit integer
338 static inline int64_t mlt_property_atoll( const char *value
)
342 else if ( value
[0] == '0' && value
[1] == 'x' )
343 return strtoll( value
+ 2, NULL
, 16 );
345 return strtoll( value
, NULL
, 10 );
348 /** Get the property as a signed integer.
350 * \public \memberof mlt_property_s
351 * \param this a property
352 * \return a 64-bit integer
355 int64_t mlt_property_get_int64( mlt_property
this )
357 if ( this->types
& mlt_prop_int64
)
358 return this->prop_int64
;
359 else if ( this->types
& mlt_prop_int
)
360 return ( int64_t )this->prop_int
;
361 else if ( this->types
& mlt_prop_double
)
362 return ( int64_t )this->prop_double
;
363 else if ( this->types
& mlt_prop_position
)
364 return ( int64_t )this->prop_position
;
365 else if ( this->types
& mlt_prop_string
)
366 return mlt_property_atoll( this->prop_string
);
370 /** Get the property as a string.
372 * The caller is not responsible for deallocating the returned string!
373 * The string is deallocated when the Property is closed.
374 * This tries its hardest to convert the property to string including using
375 * a serialization function for binary data, if supplied.
376 * \public \memberof mlt_property_s
377 * \param this a property
378 * \return a string representation of the property or NULL if failed
381 char *mlt_property_get_string( mlt_property
this )
383 // Construct a string if need be
384 if ( ! ( this->types
& mlt_prop_string
) )
386 if ( this->types
& mlt_prop_int
)
388 this->types
|= mlt_prop_string
;
389 this->prop_string
= malloc( 32 );
390 sprintf( this->prop_string
, "%d", this->prop_int
);
392 else if ( this->types
& mlt_prop_double
)
394 this->types
|= mlt_prop_string
;
395 this->prop_string
= malloc( 32 );
396 sprintf( this->prop_string
, "%f", this->prop_double
);
398 else if ( this->types
& mlt_prop_position
)
400 this->types
|= mlt_prop_string
;
401 this->prop_string
= malloc( 32 );
402 sprintf( this->prop_string
, "%d", (int)this->prop_position
); /* I don't know if this is wanted. -Zach */
404 else if ( this->types
& mlt_prop_int64
)
406 this->types
|= mlt_prop_string
;
407 this->prop_string
= malloc( 32 );
408 sprintf( this->prop_string
, "%lld", this->prop_int64
);
410 else if ( this->types
& mlt_prop_data
&& this->serialiser
!= NULL
)
412 this->types
|= mlt_prop_string
;
413 this->prop_string
= this->serialiser( this->data
, this->length
);
417 // Return the string (may be NULL)
418 return this->prop_string
;
421 /** Get the binary data from a property.
423 * This only works if you previously put binary data into the property.
424 * This does not return a copy of the data; it returns a pointer to it.
425 * If you supplied a destructor function when setting the binary data,
426 * the destructor is used when the Property is closed to free the memory.
427 * Therefore, only free the returned pointer if you did not supply a
428 * destructor function.
429 * \public \memberof mlt_property_s
430 * \param this a property
431 * \param[out] length the size of the binary object in bytes (optional)
432 * \return an opaque data pointer or NULL if not available
435 void *mlt_property_get_data( mlt_property
this, int *length
)
437 // Assign length if not NULL
438 if ( length
!= NULL
)
439 *length
= this->length
;
441 // Return the data (note: there is no conversion here)
445 /** Destroy a property and free all related resources.
447 * \public \memberof mlt_property_s
448 * \param this a property
451 void mlt_property_close( mlt_property
this )
453 mlt_property_clear( this );
459 * A Property holding binary data only copies the data if a serialiser
460 * function was supplied when you set the Property.
461 * \public \memberof mlt_property_s
462 * \author Zach <zachary.drew@gmail.com>
463 * \param this a property
464 * \param that another property
466 void mlt_property_pass( mlt_property
this, mlt_property that
)
468 mlt_property_clear( this );
470 this->types
= that
->types
;
472 if ( this->types
& mlt_prop_int64
)
473 this->prop_int64
= that
->prop_int64
;
474 else if ( this->types
& mlt_prop_int
)
475 this->prop_int
= that
->prop_int
;
476 else if ( this->types
& mlt_prop_double
)
477 this->prop_double
= that
->prop_double
;
478 else if ( this->types
& mlt_prop_position
)
479 this->prop_position
= that
->prop_position
;
480 else if ( this->types
& mlt_prop_string
)
482 if ( that
->prop_string
!= NULL
)
483 this->prop_string
= strdup( that
->prop_string
);
485 else if ( this->types
& mlt_prop_data
&& this->serialiser
!= NULL
)
487 this->types
= mlt_prop_string
;
488 this->prop_string
= this->serialiser( this->data
, this->length
);