]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
idnode prop: make it possible to properly sort/filter enum/list types
authorAdam Sutton <dev@adamsutton.me.uk>
Mon, 16 Sep 2013 20:41:21 +0000 (21:41 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Mon, 16 Sep 2013 20:41:21 +0000 (21:41 +0100)
This does require a certain level of extra input from prop_t users where
the type is enumerated. A new routine rend() must be implemented to provide
the rendered value (for lists that are not enum, this is done transparently).

src/idnode.c
src/prop.h

index 92ad4c1a78554044c770b17c3be0c916144b0a06..bbf068253b3a4ec3335143b21da0f59b1eae70ab 100644 (file)
@@ -126,7 +126,6 @@ idnode_init(void)
 {
   pthread_t tid;
 
-
   randfd = open("/dev/urandom", O_RDONLY);
   if(randfd == -1)
     exit(1);
@@ -301,6 +300,23 @@ idnode_find_prop
   return NULL;
 }
 
+/*
+ * Get display value
+ */
+static char *
+idnode_get_display
+  ( idnode_t *self, const property_t *p )
+{
+  if (p->rend)
+    return p->rend(self);
+  if (p->islist) {
+    htsmsg_t *l = (htsmsg_t*)p->get(self);
+    if (l)
+      return htsmsg_list_2_csv(l);
+  }
+  return NULL;
+}
+
 /*
  * Get field as string
  */
@@ -329,6 +345,7 @@ idnode_get_u32
   ( idnode_t *self, const char *key, uint32_t *u32 )
 {
   const property_t *p = idnode_find_prop(self, key);
+  if (p->islist) return 1;
   if (p) {
     const void *ptr;
     if (p->get)
@@ -361,6 +378,7 @@ idnode_get_bool
   ( idnode_t *self, const char *key, int *b )
 {
   const property_t *p = idnode_find_prop(self, key);
+  if (p->islist) return 1;
   if (p) {
     void *ptr = self;
     ptr += p->off;
@@ -446,17 +464,32 @@ idnode_cmp_sort
   idnode_t      *inb  = *(idnode_t**)b;
   idnode_sort_t *sort = s;
   const property_t *p = idnode_find_prop(ina, sort->key);
+  if (!p) return 0;
+
+  /* Get display string */
+  if (p->islist || p->list) {
+    int r;
+    char *stra = idnode_get_display(ina, p);
+    char *strb = idnode_get_display(inb, p);
+    if (sort->dir == IS_ASC)
+      r = strcmp(stra ?: "", strb ?: "");
+    else
+      r = strcmp(strb ?: "", stra ?: "");
+    free(stra);
+    free(strb);
+    return r;
+  }
+
   switch (p->type) {
     case PT_STR:
       {
         int r;
-        char *stra = strdup(idnode_get_str(ina, sort->key) ?: "");
+        const char *stra = idnode_get_str(ina, sort->key);
         const char *strb = idnode_get_str(inb, sort->key);
         if (sort->dir == IS_ASC)
           r = strcmp(stra ?: "", strb ?: "");
         else
           r = strcmp(strb ?: "", stra ?: "");
-        free(stra);
         return r;
       }
       break;
@@ -490,8 +523,10 @@ idnode_filter
   LIST_FOREACH(f, filter, link) {
     if (f->type == IF_STR) {
       const char *str;
-      if (!(str = idnode_get_str(in, f->key)))
-        return 1;
+      str = idnode_get_display(in, idnode_find_prop(in, f->key));
+      if (!str)
+        if (!(str = idnode_get_str(in, f->key)))
+          return 1;
       switch(f->comp) {
         case IC_IN:
           if (strstr(str, f->u.s) == NULL)
index 995cd92100957527f21ebf254917570e6db87ead..9567d8aa5e1bc41b99c035583326f900597c513e 100644 (file)
@@ -59,8 +59,9 @@ typedef struct property {
   const void *(*get)  (void *ptr);
   int         (*set)  (void *ptr, const void *v);
   htsmsg_t   *(*list) (void *ptr);
-  // Note: htsmsg_t can either be a string list or object list
-  //       where the object has "key" and "val" fields
+  char       *(*rend) (void *ptr); ///< Provide the rendered value for enum/list
+                                   ///< Lists should be CSV. This is used for
+                                   ///< sorting and searching in UI API
 
   /* Notification callback */
   void        (*notify)   (void *ptr);