1try:
2    from collections.abc import MutableMapping
3except ImportError:
4    from collections import MutableMapping
5
6from av.error cimport err_check
7
8
9cdef class _Dictionary(object):
10
11    def __cinit__(self, *args, **kwargs):
12        for arg in args:
13            self.update(arg)
14        if kwargs:
15            self.update(kwargs)
16
17    def __dealloc__(self):
18        if self.ptr != NULL:
19            lib.av_dict_free(&self.ptr)
20
21    def __getitem__(self, str key):
22        cdef lib.AVDictionaryEntry *element = lib.av_dict_get(self.ptr, key, NULL, 0)
23        if element != NULL:
24            return element.value
25        else:
26            raise KeyError(key)
27
28    def __setitem__(self, str key, str value):
29        err_check(lib.av_dict_set(&self.ptr, key, value, 0))
30
31    def __delitem__(self, str key):
32        err_check(lib.av_dict_set(&self.ptr, key, NULL, 0))
33
34    def __len__(self):
35        return err_check(lib.av_dict_count(self.ptr))
36
37    def __iter__(self):
38        cdef lib.AVDictionaryEntry *element = NULL
39        while True:
40            element = lib.av_dict_get(self.ptr, "", element, lib.AV_DICT_IGNORE_SUFFIX)
41            if element == NULL:
42                break
43            yield element.key
44
45    def __repr__(self):
46        return 'av.Dictionary(%r)' % dict(self)
47
48    cpdef _Dictionary copy(self):
49        cdef _Dictionary other = Dictionary()
50        lib.av_dict_copy(&other.ptr, self.ptr, 0)
51        return other
52
53
54class Dictionary(_Dictionary, MutableMapping):
55    pass
56
57
58cdef _Dictionary wrap_dictionary(lib.AVDictionary *input_):
59    cdef _Dictionary output = Dictionary()
60    output.ptr = input_
61    return output
62