[vlc-devel] [PATCH 4/5] variables: add VLC_VAR_LIST

Thomas Guillem thomas at gllm.fr
Thu Nov 3 10:16:50 CET 2016


It's now possible to store a list of int/float/bool/coords/string inside a
variable.
---
 include/vlc_variables.h | 68 +++++++++++++++++++++++++++++++++++++++-
 src/libvlccore.sym      |  1 +
 src/misc/variables.c    | 83 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 150 insertions(+), 2 deletions(-)

diff --git a/include/vlc_variables.h b/include/vlc_variables.h
index e68e723..b1c7b9e 100644
--- a/include/vlc_variables.h
+++ b/include/vlc_variables.h
@@ -52,6 +52,7 @@
 #define VLC_VAR_FLOAT     0x0050
 #define VLC_VAR_ADDRESS   0x0070
 #define VLC_VAR_COORDS    0x00A0
+#define VLC_VAR_LIST      0x00B0
 /**@}*/
 
 /** \defgroup var_flags Additive flags
@@ -222,6 +223,12 @@ VLC_API int var_Inherit( vlc_object_t *, const char *, int, vlc_value_t * );
  */
 VLC_API void var_FreeChoiceLists( vlc_value_t *, vlc_value_t * );
 
+/**
+ * Free a vlc_list_list_t returned by var_GetChecked( ..., VLC_VAR_LIST ), by
+ * var_GetList(), by var_CreateGetList() or by var_InheritList()
+ */
+VLC_API void var_FreeList( vlc_list_t * );
+
 /*****************************************************************************
  * Variable callbacks
  *****************************************************************************/
@@ -370,12 +377,26 @@ int var_SetAddress( vlc_object_t *p_obj, const char *psz_name, void *ptr )
     return var_SetChecked( p_obj, psz_name, VLC_VAR_ADDRESS, val );
 }
 
+/**
+ * Set the value of a list variable
+ *
+ * \param p_obj The object that holds the variable
+ * \param psz_name The name of the variable
+ * \param p_list The new list value of this variable (will be duplicated)
+ */
+static inline
+int var_SetList( vlc_object_t *p_obj, const char *psz_name, const vlc_list_t *p_list )
+{
+    vlc_value_t val = { .p_list = (vlc_list_t *) p_list };
+    return var_SetChecked( p_obj, psz_name, VLC_VAR_LIST, val );
+}
+
 #define var_SetInteger(a,b,c)   var_SetInteger( VLC_OBJECT(a),b,c)
 #define var_SetBool(a,b,c)      var_SetBool( VLC_OBJECT(a),b,c)
 #define var_SetFloat(a,b,c)     var_SetFloat( VLC_OBJECT(a),b,c)
 #define var_SetString(a,b,c)    var_SetString( VLC_OBJECT(a),b,c)
 #define var_SetAddress(o, n, p) var_SetAddress(VLC_OBJECT(o), n, p)
-
+#define var_SetList(o, n, p) var_SetList(VLC_OBJECT(o), n, p)
 
 /**
  * Get an integer value
@@ -480,6 +501,23 @@ static inline void *var_GetAddress( vlc_object_t *p_obj, const char *psz_name )
 }
 
 /**
+ * Get a list value
+ *
+ * \param p_obj The object that holds the variable
+ * \param psz_name The name of the variable
+ * \return a list that should be freed with var_FreeList()
+ */
+VLC_USED
+static inline vlc_list_t *var_GetList( vlc_object_t *p_obj, const char *psz_name )
+{
+    vlc_value_t val;
+    if( var_GetChecked( p_obj, psz_name, VLC_VAR_LIST, &val ) )
+        return NULL;
+    else
+        return val.p_list;
+}
+
+/**
  * Increment an integer variable
  * \param p_obj the object that holds the variable
  * \param psz_name the name of the variable
@@ -606,12 +644,28 @@ static inline void *var_CreateGetAddress( vlc_object_t *p_obj,
     return var_GetAddress( p_obj, psz_name );
 }
 
+/**
+ * Create a list variable with inherit and get its value.
+ *
+ * \param p_obj The object that holds the variable
+ * \param psz_name The name of the variable
+ * \return a list that should be freed with var_FreeList()
+ */
+VLC_USED
+static inline vlc_list_t *var_CreateGetList( vlc_object_t *p_obj,
+                                             const char *psz_name )
+{
+    var_Create( p_obj, psz_name, VLC_VAR_ADDRESS | VLC_VAR_DOINHERIT );
+    return var_GetList( p_obj, psz_name );
+}
+
 #define var_CreateGetInteger(a,b)   var_CreateGetInteger( VLC_OBJECT(a),b)
 #define var_CreateGetBool(a,b)   var_CreateGetBool( VLC_OBJECT(a),b)
 #define var_CreateGetFloat(a,b)   var_CreateGetFloat( VLC_OBJECT(a),b)
 #define var_CreateGetString(a,b)   var_CreateGetString( VLC_OBJECT(a),b)
 #define var_CreateGetNonEmptyString(a,b)   var_CreateGetNonEmptyString( VLC_OBJECT(a),b)
 #define var_CreateGetAddress(a,b)  var_CreateGetAddress( VLC_OBJECT(a),b)
+#define var_CreateGetList(a,b)  var_CreateGetList( VLC_OBJECT(a),b)
 
 /**
  * Create a integer command variable with inherit and get its value.
@@ -766,6 +820,17 @@ static inline void *var_InheritAddress( vlc_object_t *obj, const char *name )
 }
 #define var_InheritAddress(o, n) var_InheritAddress(VLC_OBJECT(o), n)
 
+VLC_USED
+static inline void *var_InheritList( vlc_object_t *obj, const char *name )
+{
+    vlc_value_t val;
+
+    if( var_Inherit( obj, name, VLC_VAR_LIST, &val ) )
+        val.p_list = NULL;
+    return val.p_list;
+}
+#define var_InheritList(o, n) var_InheritList(VLC_OBJECT(o), n)
+
 /**
  * It inherits a string as an unsigned rational number (it also accepts basic
  * float number).
@@ -782,6 +847,7 @@ VLC_API int var_InheritURational( vlc_object_t *, unsigned *num, unsigned *den,
 #define var_GetString(a,b)   var_GetString( VLC_OBJECT(a),b)
 #define var_GetNonEmptyString(a,b)   var_GetNonEmptyString( VLC_OBJECT(a),b)
 #define var_GetAddress(a,b)  var_GetAddress( VLC_OBJECT(a),b)
+#define var_GetList(a,b)  var_GetList( VLC_OBJECT(a),b)
 
 /**
  * Parses a set of colon-separated or semicolon-separated
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 2784bd6..e8afae4 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -499,6 +499,7 @@ var_DelCallback
 var_DelChoiceCallback
 var_Destroy
 var_FreeChoiceLists
+var_FreeList
 var_Get
 var_GetAndSet
 var_GetChecked
diff --git a/src/misc/variables.c b/src/misc/variables.c
index 9d5e3ba..b25c543 100644
--- a/src/misc/variables.c
+++ b/src/misc/variables.c
@@ -127,9 +127,56 @@ static void DupString( vlc_value_t *p_val )
 {
     p_val->psz_string = strdup( p_val->psz_string ? p_val->psz_string :  "" );
 }
+static void DupList( vlc_value_t *p_val )
+{
+    if( p_val->p_list->i_count == 0 )
+        return;
+    vlc_list_t *p_list = malloc( sizeof( vlc_list_t )
+                                 + p_val->p_list->i_count
+                                 * sizeof( vlc_value_t ) );
+
+    if( p_list == NULL )
+    {
+        p_val->p_list = NULL;
+        return;
+    }
+
+    p_list->i_type = p_val->p_list->i_type;
+    p_list->i_count = p_val->p_list->i_count;
+    p_list->p_values = (void *) ( (uint8_t *) p_list + sizeof( vlc_list_t ) );
+
+    memcpy( p_list->p_values, p_val->p_list->p_values, p_list->i_count
+            * sizeof(vlc_value_t) );
+    switch( p_list->i_type & VLC_VAR_TYPE )
+    {
+        case VLC_VAR_VOID:
+        case VLC_VAR_BOOL:
+        case VLC_VAR_INTEGER:
+        case VLC_VAR_FLOAT:
+        case VLC_VAR_ADDRESS:
+        case VLC_VAR_COORDS:
+            break;
+        case VLC_VAR_STRING:
+            for( int i = 0; i < p_list->i_count; ++i )
+                DupString( &p_list->p_values[i] );
+            break;
+        case VLC_VAR_LIST:
+            for( int i = 0; i < p_list->i_count; ++i )
+                DupList( &p_list->p_values[i] );
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+    p_val->p_list = p_list;
+}
 
 static void FreeDummy( vlc_value_t *p_val ) { (void)p_val; /* unused */ }
 static void FreeString( vlc_value_t *p_val ) { free( p_val->psz_string ); }
+static void FreeList( vlc_value_t *p_val )
+{
+    if( p_val->p_list != NULL )
+        var_FreeList( p_val->p_list );
+}
 
 static const struct variable_ops_t
 void_ops   = { NULL,       DupDummy,  FreeDummy,  },
@@ -138,7 +185,8 @@ bool_ops   = { CmpBool,    DupDummy,  FreeDummy,  },
 float_ops  = { CmpFloat,   DupDummy,  FreeDummy,  },
 int_ops    = { CmpInt,     DupDummy,  FreeDummy,  },
 string_ops = { CmpString,  DupString, FreeString, },
-coords_ops = { NULL,       DupDummy,  FreeDummy,  };
+coords_ops = { NULL,       DupDummy,  FreeDummy,  },
+list_ops =   { NULL,       DupList,   FreeList,   };
 
 static int varcmp( const void *a, const void *b )
 {
@@ -341,6 +389,9 @@ int var_Create( vlc_object_t *p_this, const char *psz_name, int i_type )
         case VLC_VAR_VOID:
             p_var->ops = &void_ops;
             break;
+        case VLC_VAR_LIST:
+            p_var->ops = &list_ops;
+            break;
         default:
             vlc_assert_unreachable ();
     }
@@ -1069,6 +1120,7 @@ int var_Inherit( vlc_object_t *p_this, const char *psz_name, int i_type,
         default:
             vlc_assert_unreachable();
         case VLC_VAR_ADDRESS:
+        case VLC_VAR_LIST:
             return VLC_ENOOBJ;
     }
     return VLC_SUCCESS;
@@ -1166,6 +1218,35 @@ void var_FreeChoiceLists( vlc_value_t *p_val, vlc_value_t *p_val2 )
     }
 }
 
+/**
+ * Free a vlc_list_list_t returned by var_GetChecked( ..., VLC_VAR_LIST ), by
+ * var_GetList(), by var_CreateGetList() or by var_InheritList()
+ */
+void var_FreeList( vlc_list_t *p_list )
+{
+    switch( p_list->i_type & VLC_VAR_TYPE )
+    {
+        case VLC_VAR_VOID:
+        case VLC_VAR_BOOL:
+        case VLC_VAR_INTEGER:
+        case VLC_VAR_FLOAT:
+        case VLC_VAR_ADDRESS:
+        case VLC_VAR_COORDS:
+            break;
+        case VLC_VAR_STRING:
+            for( int i = 0; i < p_list->i_count; ++i )
+                FreeString( &p_list->p_values[i] );
+            break;
+        case VLC_VAR_LIST:
+            for( int i = 0; i < p_list->i_count; ++i )
+                FreeList( &p_list->p_values[i] );
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+    free( p_list );
+}
+
 static void DumpVariable(const void *data, const VISIT which, const int depth)
 {
     if (which != postorder && which != leaf)
-- 
2.9.3



More information about the vlc-devel mailing list