1/* 2 * copyright (c) 2009 Michael Niedermayer 3 * 4 * This file is part of Libav. 5 * 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. 10 * 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. 15 * 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 19 */ 20 21#include "avstring.h" 22#include "dict.h" 23#include "internal.h" 24#include "mem.h" 25 26AVDictionaryEntry * 27av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags) 28{ 29 unsigned int i, j; 30 31 if(!m) 32 return NULL; 33 34 if(prev) i= prev - m->elems + 1; 35 else i= 0; 36 37 for(; i<m->count; i++){ 38 const char *s= m->elems[i].key; 39 if(flags & AV_DICT_MATCH_CASE) for(j=0; s[j] == key[j] && key[j]; j++); 40 else for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++); 41 if(key[j]) 42 continue; 43 if(s[j] && !(flags & AV_DICT_IGNORE_SUFFIX)) 44 continue; 45 return &m->elems[i]; 46 } 47 return NULL; 48} 49 50int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags) 51{ 52 AVDictionary *m = *pm; 53 AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); 54 char *oldval = NULL; 55 56 if(!m) 57 m = *pm = av_mallocz(sizeof(*m)); 58 59 if(tag) { 60 if (flags & AV_DICT_DONT_OVERWRITE) 61 return 0; 62 if (flags & AV_DICT_APPEND) 63 oldval = tag->value; 64 else 65 av_free(tag->value); 66 av_free(tag->key); 67 *tag = m->elems[--m->count]; 68 } else { 69 AVDictionaryEntry *tmp = av_realloc(m->elems, (m->count+1) * sizeof(*m->elems)); 70 if(tmp) { 71 m->elems = tmp; 72 } else 73 return AVERROR(ENOMEM); 74 } 75 if (value) { 76 if (flags & AV_DICT_DONT_STRDUP_KEY) { 77 m->elems[m->count].key = key; 78 } else 79 m->elems[m->count].key = av_strdup(key ); 80 if (flags & AV_DICT_DONT_STRDUP_VAL) { 81 m->elems[m->count].value = value; 82 } else if (oldval && flags & AV_DICT_APPEND) { 83 int len = strlen(oldval) + strlen(value) + 1; 84 if (!(oldval = av_realloc(oldval, len))) 85 return AVERROR(ENOMEM); 86 av_strlcat(oldval, value, len); 87 m->elems[m->count].value = oldval; 88 } else 89 m->elems[m->count].value = av_strdup(value); 90 m->count++; 91 } 92 if (!m->count) { 93 av_free(m->elems); 94 av_freep(pm); 95 } 96 97 return 0; 98} 99 100void av_dict_free(AVDictionary **pm) 101{ 102 AVDictionary *m = *pm; 103 104 if (m) { 105 while(m->count--) { 106 av_free(m->elems[m->count].key); 107 av_free(m->elems[m->count].value); 108 } 109 av_free(m->elems); 110 } 111 av_freep(pm); 112} 113 114void av_dict_copy(AVDictionary **dst, AVDictionary *src, int flags) 115{ 116 AVDictionaryEntry *t = NULL; 117 118 while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX))) 119 av_dict_set(dst, t->key, t->value, flags); 120} 121