2 * copyright (c) 2009 Michael Niedermayer
4 * This file is part of Libav.
6 * Libav 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 * Libav 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 Libav; 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(const 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
);
77 m
= *pm
= av_mallocz(sizeof(*m
));
79 return AVERROR(ENOMEM
);
82 if (flags
& AV_DICT_DONT_OVERWRITE
) {
83 if (flags
& AV_DICT_DONT_STRDUP_KEY
) av_free(key
);
84 if (flags
& AV_DICT_DONT_STRDUP_VAL
) av_free(value
);
87 if (flags
& AV_DICT_APPEND
)
92 *tag
= m
->elems
[--m
->count
];
94 int ret
= av_reallocp_array(&m
->elems
,
95 m
->count
+ 1, sizeof(*m
->elems
));
104 if (flags
& AV_DICT_DONT_STRDUP_KEY
)
105 m
->elems
[m
->count
].key
= key
;
107 m
->elems
[m
->count
].key
= av_strdup(key
);
108 if (flags
& AV_DICT_DONT_STRDUP_VAL
) {
109 m
->elems
[m
->count
].value
= value
;
110 } else if (oldval
&& flags
& AV_DICT_APPEND
) {
111 int len
= strlen(oldval
) + strlen(value
) + 1;
112 if (!(oldval
= av_realloc(oldval
, len
)))
113 return AVERROR(ENOMEM
);
114 av_strlcat(oldval
, value
, len
);
115 m
->elems
[m
->count
].value
= oldval
;
117 m
->elems
[m
->count
].value
= av_strdup(value
);
128 static int parse_key_value_pair(AVDictionary
**pm
, const char **buf
,
129 const char *key_val_sep
, const char *pairs_sep
,
132 char *key
= av_get_token(buf
, key_val_sep
);
136 if (key
&& *key
&& strspn(*buf
, key_val_sep
)) {
138 val
= av_get_token(buf
, pairs_sep
);
141 if (key
&& *key
&& val
&& *val
)
142 ret
= av_dict_set(pm
, key
, val
, flags
);
144 ret
= AVERROR(EINVAL
);
152 int av_dict_parse_string(AVDictionary
**pm
, const char *str
,
153 const char *key_val_sep
, const char *pairs_sep
,
161 /* ignore STRDUP flags */
162 flags
&= ~(AV_DICT_DONT_STRDUP_KEY
| AV_DICT_DONT_STRDUP_VAL
);
165 if ((ret
= parse_key_value_pair(pm
, &str
, key_val_sep
, pairs_sep
, flags
)) < 0)
175 void av_dict_free(AVDictionary
**pm
)
177 AVDictionary
*m
= *pm
;
181 av_free(m
->elems
[m
->count
].key
);
182 av_free(m
->elems
[m
->count
].value
);
189 int av_dict_copy(AVDictionary
**dst
, const AVDictionary
*src
, int flags
)
191 AVDictionaryEntry
*t
= NULL
;
193 while ((t
= av_dict_get(src
, "", t
, AV_DICT_IGNORE_SUFFIX
))) {
194 int ret
= av_dict_set(dst
, t
->key
, t
->value
, flags
);