2 * copyright (c) 2009 Michael Niedermayer
4 * This file is part of FFmpeg.
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.
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.
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
30 AVDictionaryEntry
*elems
;
33 int av_dict_count(const AVDictionary
*m
)
35 return m
? m
->count
: 0;
38 AVDictionaryEntry
*av_dict_get(FF_CONST_AVUTIL53 AVDictionary
*m
, const char *key
,
39 const AVDictionaryEntry
*prev
, int flags
)
47 i
= prev
- m
->elems
+ 1;
51 for (; i
< m
->count
; i
++) {
52 const char *s
= m
->elems
[i
].key
;
53 if (flags
& AV_DICT_MATCH_CASE
)
54 for (j
= 0; s
[j
] == key
[j
] && key
[j
]; j
++)
57 for (j
= 0; av_toupper(s
[j
]) == av_toupper(key
[j
]) && key
[j
]; j
++)
61 if (s
[j
] && !(flags
& AV_DICT_IGNORE_SUFFIX
))
68 int av_dict_set(AVDictionary
**pm
, const char *key
, const char *value
,
71 AVDictionary
*m
= *pm
;
72 AVDictionaryEntry
*tag
= av_dict_get(m
, key
, NULL
, flags
);
76 m
= *pm
= av_mallocz(sizeof(*m
));
79 if (flags
& AV_DICT_DONT_OVERWRITE
) {
80 if (flags
& AV_DICT_DONT_STRDUP_KEY
) av_free((void*)key
);
81 if (flags
& AV_DICT_DONT_STRDUP_VAL
) av_free((void*)value
);
84 if (flags
& AV_DICT_APPEND
)
89 *tag
= m
->elems
[--m
->count
];
91 AVDictionaryEntry
*tmp
= av_realloc(m
->elems
,
92 (m
->count
+ 1) * sizeof(*m
->elems
));
98 if (flags
& AV_DICT_DONT_STRDUP_KEY
)
99 m
->elems
[m
->count
].key
= (char*)(intptr_t)key
;
101 m
->elems
[m
->count
].key
= av_strdup(key
);
102 if (flags
& AV_DICT_DONT_STRDUP_VAL
) {
103 m
->elems
[m
->count
].value
= (char*)(intptr_t)value
;
104 } else if (oldval
&& flags
& AV_DICT_APPEND
) {
105 int len
= strlen(oldval
) + strlen(value
) + 1;
106 char *newval
= av_mallocz(len
);
109 av_strlcat(newval
, oldval
, len
);
111 av_strlcat(newval
, value
, len
);
112 m
->elems
[m
->count
].value
= newval
;
114 m
->elems
[m
->count
].value
= av_strdup(value
);
129 if (flags
& AV_DICT_DONT_STRDUP_KEY
) av_free((void*)key
);
130 if (flags
& AV_DICT_DONT_STRDUP_VAL
) av_free((void*)value
);
131 return AVERROR(ENOMEM
);
134 int av_dict_set_int(AVDictionary
**pm
, const char *key
, int64_t value
,
138 snprintf(valuestr
, sizeof(valuestr
), "%"PRId64
, value
);
139 return av_dict_set(pm
, key
, valuestr
, flags
);
142 static int parse_key_value_pair(AVDictionary
**pm
, const char **buf
,
143 const char *key_val_sep
, const char *pairs_sep
,
146 char *key
= av_get_token(buf
, key_val_sep
);
150 if (key
&& *key
&& strspn(*buf
, key_val_sep
)) {
152 val
= av_get_token(buf
, pairs_sep
);
155 if (key
&& *key
&& val
&& *val
)
156 ret
= av_dict_set(pm
, key
, val
, flags
);
158 ret
= AVERROR(EINVAL
);
166 int av_dict_parse_string(AVDictionary
**pm
, const char *str
,
167 const char *key_val_sep
, const char *pairs_sep
,
175 /* ignore STRDUP flags */
176 flags
&= ~(AV_DICT_DONT_STRDUP_KEY
| AV_DICT_DONT_STRDUP_VAL
);
179 if ((ret
= parse_key_value_pair(pm
, &str
, key_val_sep
, pairs_sep
, flags
)) < 0)
189 void av_dict_free(AVDictionary
**pm
)
191 AVDictionary
*m
= *pm
;
195 av_free(m
->elems
[m
->count
].key
);
196 av_free(m
->elems
[m
->count
].value
);
203 void av_dict_copy(AVDictionary
**dst
, FF_CONST_AVUTIL53 AVDictionary
*src
, int flags
)
205 AVDictionaryEntry
*t
= NULL
;
207 while ((t
= av_dict_get(src
, "", t
, AV_DICT_IGNORE_SUFFIX
)))
208 av_dict_set(dst
, t
->key
, t
->value
, flags
);