LGPL
[vlc.git] / src / input / info.h
1 /*****************************************************************************
2  * info.h
3  *****************************************************************************
4  * Copyright (C) 2010 Laurent Aimar
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program 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
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #ifndef LIBVLC_INPUT_INFO_H
25 #define LIBVLC_INPUT_INFO_H 1
26
27 #include "vlc_input_item.h"
28
29 static inline info_t *info_New(const char *name, const char *value )
30 {
31     info_t *info = malloc(sizeof(*info));
32     if (!info)
33         return NULL;
34
35     info->psz_name = strdup(name);
36     info->psz_value = value ? strdup(value) : NULL;
37     return info;
38 }
39
40 static inline void info_Delete(info_t *i)
41 {
42     free(i->psz_name);
43     free(i->psz_value);
44     free(i);
45 }
46
47 static inline info_category_t *info_category_New(const char *name)
48 {
49     info_category_t *cat = malloc(sizeof(*cat));
50     if (!cat)
51         return NULL;
52     cat->psz_name = strdup(name);
53     cat->i_infos  = 0;
54     cat->pp_infos = NULL;
55
56     return cat;
57 }
58
59 static inline info_t *info_category_FindInfo(const info_category_t *cat,
60                                              int *index, const char *name)
61 {
62     for (int i = 0; i < cat->i_infos; i++) {
63         if (!strcmp(cat->pp_infos[i]->psz_name, name)) {
64             if (index)
65                 *index = i;
66             return cat->pp_infos[i];
67         }
68     }
69     return NULL;
70 }
71
72 static inline void info_category_ReplaceInfo(info_category_t *cat,
73                                              info_t *info)
74 {
75     int index;
76     info_t *old = info_category_FindInfo(cat, &index, info->psz_name);
77     if (old) {
78         info_Delete(cat->pp_infos[index]);
79         cat->pp_infos[index] = info;
80     } else {
81         INSERT_ELEM(cat->pp_infos, cat->i_infos, cat->i_infos, info);
82     }
83 }
84
85 static inline info_t *info_category_VaAddInfo(info_category_t *cat,
86                                               const char *name,
87                                               const char *format, va_list args)
88 {
89     info_t *info = info_category_FindInfo(cat, NULL, name);
90     if (!info) {
91         info = info_New(name, NULL);
92         if (!info)
93             return NULL;
94         INSERT_ELEM(cat->pp_infos, cat->i_infos, cat->i_infos, info);
95     } else
96         free(info->psz_value);
97     if (vasprintf(&info->psz_value, format, args) == -1)
98         info->psz_value = NULL;
99     return info;
100 }
101
102 static inline info_t *info_category_AddInfo(info_category_t *cat,
103                                             const char *name,
104                                             const char *format, ...)
105 {
106     va_list args;
107
108     va_start(args, format);
109     info_t *info = info_category_VaAddInfo(cat, name, format, args);
110     va_end(args);
111
112     return info;
113 }
114
115 static inline int info_category_DeleteInfo(info_category_t *cat, const char *name)
116 {
117     int index;
118     if (info_category_FindInfo(cat, &index, name)) {
119         info_Delete(cat->pp_infos[index]);
120         REMOVE_ELEM(cat->pp_infos, cat->i_infos, index);
121         return VLC_SUCCESS;
122     }
123     return VLC_EGENERIC;
124 }
125
126 static inline void info_category_Delete(info_category_t *cat)
127 {
128     for (int i = 0; i < cat->i_infos; i++)
129         info_Delete(cat->pp_infos[i]);
130     free(cat->pp_infos);
131     free(cat->psz_name);
132     free(cat);
133 }
134
135 #endif