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
);