#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
+#include <locale.h>
/** \brief private implementation of the property list */
mlt_properties mirror;
int ref_count;
pthread_mutex_t mutex;
+ locale_t locale;
}
property_list;
return self;
}
+/** Set the numeric locale used for string/double conversions.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param locale the locale name
+ * \return true if error
+ */
+
+int mlt_properties_set_lcnumeric( mlt_properties self, const char *locale )
+{
+ int error = 0;
+
+ if ( self && locale )
+ {
+ property_list *list = self->local;
+
+ if ( list->locale )
+ freelocale( list->locale );
+ list->locale = newlocale( LC_NUMERIC, locale, NULL );
+ error = list->locale == NULL;
+ }
+ else
+ error = 1;
+
+ return error;
+}
+
static int load_properties( mlt_properties self, const char *filename )
{
// Open the file
char *mlt_properties_get( mlt_properties self, const char *name )
{
mlt_property value = mlt_properties_find( self, name );
- return value == NULL ? NULL : mlt_property_get_string( value );
+ property_list *list = self->local;
+ return value == NULL ? NULL : mlt_property_get_string_l( value, list->locale );
}
/** Get a property name by index.
{
property_list *list = self->local;
if ( index >= 0 && index < list->count )
- return mlt_property_get_string( list->value[ index ] );
+ return mlt_property_get_string_l( list->value[ index ], list->locale );
return NULL;
}
double mlt_properties_get_double( mlt_properties self, const char *name )
{
mlt_property value = mlt_properties_find( self, name );
- return value == NULL ? 0 : mlt_property_get_double( value );
+ property_list *list = self->local;
+ return value == NULL ? 0 : mlt_property_get_double_l( value, list->locale );
}
/** Set a property to a floating point value.
static int mlt_compare( const void *self, const void *that )
{
- return strcmp( mlt_property_get_string( *( const mlt_property * )self ), mlt_property_get_string( *( const mlt_property * )that ) );
+ return strcmp( mlt_property_get_string( *( const mlt_property * )self ), mlt_property_get_string( *( const mlt_property * )that ) );
}
/** Get the contents of a directory.
free( list->name[ index ] );
}
+ // Cleanup locale
+ if ( list->locale )
+ freelocale( list->locale );
+
// Clear up the list
pthread_mutex_destroy( &list->mutex );
free( list->name );
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+// For strtod_l
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#include "mlt_property.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <locale.h>
/** Bit pattern used internally to indicated representations available.
return 0;
}
+/** Get the property (with locale) as a floating point.
+ *
+ * \public \memberof mlt_property_s
+ * \param self a property
+ * \param locale the locale to use for this conversion
+ * \return a floating point value
+ */
+
+double mlt_property_get_double_l( mlt_property self, locale_t locale )
+{
+ if ( self->types & mlt_prop_double )
+ return self->prop_double;
+ else if ( self->types & mlt_prop_int )
+ return ( double )self->prop_int;
+ else if ( self->types & mlt_prop_position )
+ return ( double )self->prop_position;
+ else if ( self->types & mlt_prop_int64 )
+ return ( double )self->prop_int64;
+ else if ( locale && ( self->types & mlt_prop_string ) && self->prop_string )
+ return strtod_l( self->prop_string, NULL, locale );
+ else if ( ( self->types & mlt_prop_string ) && self->prop_string )
+ return strtod( self->prop_string, NULL );
+ return 0;
+}
+
/** Get the property as a position.
*
* A position is an offset time in terms of frame units.
return self->prop_string;
}
+/** Get the property as a string (with locale).
+ *
+ * The caller is not responsible for deallocating the returned string!
+ * The string is deallocated when the Property is closed.
+ * This tries its hardest to convert the property to string including using
+ * a serialization function for binary data, if supplied.
+ * \public \memberof mlt_property_s
+ * \param self a property
+ * \param locale the locale to use for this conversion
+ * \return a string representation of the property or NULL if failed
+ */
+
+char *mlt_property_get_string_l( mlt_property self, locale_t locale )
+{
+ // Optimization for no locale
+ if ( !locale )
+ return mlt_property_get_string( self );
+
+ // Construct a string if need be
+ if ( ! ( self->types & mlt_prop_string ) )
+ {
+ // TODO: when glibc gets sprintf_l, start using it! For now, hack on setlocale.
+ // Save the current locale
+#ifdef querylocale
+ const char *localename = querylocale( LC_NUMERIC, locale );
+#else
+ const char *localename = locale->__names[ LC_NUMERIC ];
+#endif
+ const char *orig_localename = setlocale( LC_NUMERIC, NULL );
+
+ // Set the new locale
+ setlocale( LC_NUMERIC, localename );
+
+ if ( self->types & mlt_prop_int )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ sprintf( self->prop_string, "%d", self->prop_int );
+ }
+ else if ( self->types & mlt_prop_double )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ sprintf( self->prop_string, "%f", self->prop_double );
+ }
+ else if ( self->types & mlt_prop_position )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ sprintf( self->prop_string, "%d", (int)self->prop_position );
+ }
+ else if ( self->types & mlt_prop_int64 )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = malloc( 32 );
+ sprintf( self->prop_string, "%"PRId64, self->prop_int64 );
+ }
+ else if ( self->types & mlt_prop_data && self->serialiser != NULL )
+ {
+ self->types |= mlt_prop_string;
+ self->prop_string = self->serialiser( self->data, self->length );
+ }
+ // Restore the current locale
+ setlocale( LC_NUMERIC, orig_localename );
+ }
+
+ // Return the string (may be NULL)
+ return self->prop_string;
+}
+
/** Get the binary data from a property.
*
* This only works if you previously put binary data into the property.
#define _MLT_PROPERTY_H_
#include "mlt_types.h"
+#include <xlocale.h>
extern mlt_property mlt_property_init( );
extern int mlt_property_set_int( mlt_property self, int value );
extern int mlt_property_set_data( mlt_property self, void *value, int length, mlt_destructor destructor, mlt_serialiser serialiser );
extern int mlt_property_get_int( mlt_property self );
extern double mlt_property_get_double( mlt_property self );
+extern double mlt_property_get_double_l( mlt_property self, locale_t );
extern mlt_position mlt_property_get_position( mlt_property self );
extern int64_t mlt_property_get_int64( mlt_property self );
extern char *mlt_property_get_string( mlt_property self );
+extern char *mlt_property_get_string_l( mlt_property self, locale_t );
extern void *mlt_property_get_data( mlt_property self, int *length );
extern void mlt_property_close( mlt_property self );