FFmpeg
Loading...
Searching...
No Matches
dict.c
Go to the documentation of this file.
1/*
2 * copyright (c) 2009 Michael Niedermayer
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <inttypes.h>
22#include <stdio.h>
23#include <string.h>
24
25#include "avassert.h"
26#include "avstring.h"
27#include "dict.h"
28#include "error.h"
29#include "mem.h"
30#include "bprint.h"
31
36
38{
39 return m ? m->count : 0;
40}
41
43 const AVDictionaryEntry *prev)
44{
45 int i = 0;
46
47 if (!m)
48 return NULL;
49
50 if (prev)
51 i = prev - m->elems + 1;
52
53 av_assert2(i >= 0);
54 if (i >= m->count)
55 return NULL;
56
57 return &m->elems[i];
58}
59
61 const AVDictionaryEntry *prev, int flags)
62{
63 const AVDictionaryEntry *entry = prev;
64 unsigned int j;
65
66 if (!key)
67 return NULL;
68
69 while ((entry = av_dict_iterate(m, entry))) {
70 const char *s = entry->key;
72 for (j = 0; s[j] == key[j] && key[j]; j++)
73 ;
74 else
75 for (j = 0; av_toupper(s[j]) == av_toupper(key[j]) && key[j]; j++)
76 ;
77 if (key[j])
78 continue;
79 if (s[j] && !(flags & AV_DICT_IGNORE_SUFFIX))
80 continue;
81 return (AVDictionaryEntry *)entry;
82 }
83 return NULL;
84}
85
86int av_dict_set(AVDictionary **pm, const char *key, const char *value,
87 int flags)
88{
89 AVDictionary *m = *pm;
91 char *copy_key = NULL, *copy_value = NULL;
92 int err;
93
95 copy_value = (void *)value;
96 else if (value)
97 copy_value = av_strdup(value);
98 if (!key) {
99 err = AVERROR(EINVAL);
100 goto err_out;
101 }
103 copy_key = (void *)key;
104 else
105 copy_key = av_strdup(key);
106 if (!copy_key || (value && !copy_value))
107 goto enomem;
108
109 if (!(flags & AV_DICT_MULTIKEY)) {
110 tag = av_dict_get(m, key, NULL, flags);
111 } else if (flags & AV_DICT_DEDUP) {
112 while ((tag = av_dict_get(m, key, tag, flags))) {
113 if ((!value && !tag->value) ||
114 (value && tag->value && !strcmp(value, tag->value))) {
115 av_free(copy_key);
116 av_free(copy_value);
117 return 0;
118 }
119 }
120 }
121 if (!m)
122 m = *pm = av_mallocz(sizeof(*m));
123 if (!m)
124 goto enomem;
125
126 if (tag) {
128 av_free(copy_key);
129 av_free(copy_value);
130 return 0;
131 }
132 if (copy_value && flags & AV_DICT_APPEND) {
133 size_t oldlen = strlen(tag->value);
134 size_t new_part_len = strlen(copy_value);
135 size_t len = oldlen + new_part_len + 1;
136 char *newval = av_realloc(tag->value, len);
137 if (!newval)
138 goto enomem;
139 memcpy(newval + oldlen, copy_value, new_part_len + 1);
140 av_freep(&copy_value);
141 copy_value = newval;
142 } else
143 av_free(tag->value);
144 av_free(tag->key);
145 *tag = m->elems[--m->count];
146 } else if (copy_value) {
148 m->count + 1, sizeof(*m->elems));
149 if (!tmp)
150 goto enomem;
151 m->elems = tmp;
152 }
153 if (copy_value) {
154 m->elems[m->count].key = copy_key;
155 m->elems[m->count].value = copy_value;
156 m->count++;
157 } else {
158 err = 0;
159 goto end;
160 }
161
162 return 0;
163
164enomem:
165 err = AVERROR(ENOMEM);
166err_out:
167 av_free(copy_value);
168end:
169 if (m && !m->count) {
170 av_freep(&m->elems);
171 av_freep(pm);
172 }
173 av_free(copy_key);
174 return err;
175}
176
178 int flags)
179{
180 char valuestr[22];
181 snprintf(valuestr, sizeof(valuestr), "%"PRId64, value);
183 return av_dict_set(pm, key, valuestr, flags);
184}
185
186static int parse_key_value_pair(AVDictionary **pm, const char **buf,
187 const char *key_val_sep, const char *pairs_sep,
188 int flags)
189{
190 char *key = av_get_token(buf, key_val_sep);
191 char *val = NULL;
192 int ret;
193
194 if (key && *key && strspn(*buf, key_val_sep)) {
195 (*buf)++;
196 val = av_get_token(buf, pairs_sep);
197 }
198
199 if (key && *key && val && *val)
200 ret = av_dict_set(pm, key, val, flags);
201 else
202 ret = AVERROR(EINVAL);
203
204 av_freep(&key);
205 av_freep(&val);
206
207 return ret;
208}
209
210int av_dict_parse_string(AVDictionary **pm, const char *str,
211 const char *key_val_sep, const char *pairs_sep,
212 int flags)
213{
214 int ret;
215
216 if (!str)
217 return 0;
218
219 /* ignore STRDUP flags */
221
222 while (*str) {
223 if ((ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0)
224 return ret;
225
226 if (*str)
227 str++;
228 }
229
230 return 0;
231}
232
234{
235 AVDictionary *m = *pm;
236
237 if (m) {
238 while (m->count--) {
239 av_freep(&m->elems[m->count].key);
240 av_freep(&m->elems[m->count].value);
241 }
242 av_freep(&m->elems);
243 }
244 av_freep(pm);
245}
246
248{
249 const AVDictionaryEntry *t = NULL;
250
251 while ((t = av_dict_iterate(src, t))) {
252 int ret = av_dict_set(dst, t->key, t->value, flags);
253 if (ret < 0)
254 return ret;
255 }
256
257 return 0;
258}
259
261 const char key_val_sep, const char pairs_sep)
262{
263 const AVDictionaryEntry *t = NULL;
264 AVBPrint bprint;
265 int cnt = 0;
266 char special_chars[] = {pairs_sep, key_val_sep, '\0'};
267
268 if (!buffer || pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
269 pairs_sep == '\\' || key_val_sep == '\\')
270 return AVERROR(EINVAL);
271
272 if (!av_dict_count(m)) {
273 *buffer = av_strdup("");
274 return *buffer ? 0 : AVERROR(ENOMEM);
275 }
276
278 while ((t = av_dict_iterate(m, t))) {
279 if (cnt++)
280 av_bprint_append_data(&bprint, &pairs_sep, 1);
281 av_bprint_escape(&bprint, t->key, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
282 av_bprint_append_data(&bprint, &key_val_sep, 1);
283 av_bprint_escape(&bprint, t->value, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
284 }
285 return av_bprint_finalize(&bprint, buffer);
286}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static double val(void *priv, double ch)
Definition aeval.c:77
#define entry
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition avassert.h:68
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static int parse_key_value_pair(AVDictionary **pm, const char **buf, const char *key_val_sep, const char *pairs_sep, int flags)
Definition dict.c:186
Public dictionary API.
error code definitions
double value
Definition eval.c:102
const char * key
void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, enum AVEscapeMode mode, int flags)
Escape the content in src and append it to dstbuf.
Definition bprint.c:263
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition bprint.c:148
#define AV_DICT_MULTIKEY
Allow to store several equal keys in the dictionary.
Definition dict.h:84
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition dict.h:75
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_get_string(const AVDictionary *m, char **buffer, const char key_val_sep, const char pairs_sep)
Get dictionary entries as a string.
Definition dict.c:260
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition dict.h:82
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition dict.h:81
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition dict.c:210
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition dict.h:77
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition dict.c:37
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition dict.h:74
#define AV_DICT_DEDUP
If inserting a value that already exists for a key, do nothing.
Definition dict.h:85
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition dict.c:177
#define AVERROR(e)
Definition error.h:45
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
Definition avstring.c:143
static av_const int av_toupper(int c)
Locale-independent conversion of ASCII characters to uppercase.
Definition avstring.h:227
@ AV_ESCAPE_MODE_BACKSLASH
Use backslash escaping.
Definition avstring.h:316
Memory handling functions.
uint32_t tag
Definition movenc.c:2073
#define av_strdup(s)
Definition ops_static.c:55
#define av_realloc(p, s)
Definition ops_static.c:54
#define snprintf
Definition snprintf.h:34
char * key
Definition dict.h:91
char * value
Definition dict.h:92
AVDictionaryEntry * elems
Definition dict.c:34
int count
Definition dict.c:33
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
static char buffer[20]
Definition seek.c:32
int len