avcpp  2.0
Wrapper for the FFmpeg that simplify usage from C++ projects.
dictionary.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <tuple>
4 #include <memory>
5 #include <iterator>
6 #include <vector>
7 #include <type_traits>
8 #include <cassert>
9 
10 extern "C" {
11 #include <libavutil/dict.h>
12 }
13 
14 #include "averror.h"
15 
16 #include "ffmpeg.h"
17 
18 namespace av {
19 
30 class Dictionary : public FFWrapperPtr<AVDictionary>
31 {
32 public:
36  enum Flags
37  {
39  FlagMatchCase = AV_DICT_MATCH_CASE,
41  FlagIgnoreSuffix = AV_DICT_IGNORE_SUFFIX,
44  FlagDontStrdupKey = AV_DICT_DONT_STRDUP_KEY,
48  FlagDontStrdupVal = AV_DICT_DONT_STRDUP_VAL,
50  FlagDontOverwrite = AV_DICT_DONT_OVERWRITE,
52  FlagAppend = AV_DICT_APPEND,
53  };
54 
61  {
62  void operator()(char *ptr)
63  {
64  av_freep(&ptr);
65  }
66  };
67 
68  // Back compatible
70  using RawStringDeleter = AvStringDeleter;
72 
76  struct AvStringPtr : public std::unique_ptr<char, AvStringDeleter>
77  {
78  using base_class = std::unique_ptr<char, AvStringDeleter>;
79  using base_class::unique_ptr;
80 
85  char* c_str() const noexcept
86  {
87  return get();
88  }
89 
102  size_t length() const noexcept
103  {
104  return strlen(c_str());
105  }
106 
115  char& operator[](size_t index) const noexcept
116  {
117  return c_str()[index];
118  }
119  };
120  // Our contract
121  static_assert (sizeof(AvStringPtr) == sizeof(char*), "Size must be same. Check and try again");
123  using RawStringPtr = AvStringPtr;
125 
126  // Fwd
127  template<bool constIterator>
129 
133  class Entry
134  {
135  public:
136 
137  template<bool>
138  friend class DictionaryIterator;
139  friend class Dictionary;
140 
145  const char* key() const noexcept;
150  const char* value() const noexcept;
157  void set(const char *value, int flags = 0) noexcept;
159  void set(const std::string& value, int flags = 0) noexcept;
161 
168  Entry& operator=(const char *value) noexcept;
170  Entry& operator=(const std::string &value) noexcept;
172 
177  operator bool() const;
182  bool isNull() const;
183 
184  friend bool operator==(const Entry& lhs, const Entry& rhs);
185  friend bool operator!=(const Entry& lhs, const Entry& rhs);
186 
187  private:
188  AVDictionaryEntry *m_entry = nullptr;
189  };
190 
191 
195  template<bool constIterator = false>
196  class DictionaryIterator
197  {
198  public:
199  // Iterator interface
200  using iterator_category = std::forward_iterator_tag;
201  using value_type = typename std::conditional<constIterator, const Entry, Entry>::type;
202  using difference_type = ptrdiff_t;
203  using pointer = value_type*;
205 
206  private:
207  using DictType = typename std::conditional<constIterator, const Dictionary, Dictionary>::type;
208  using EntryType = typename std::conditional<constIterator, const Entry, Entry>::type;
209 
210  DictType &m_dict;
211  Entry m_entry;
212 
213  public:
214  DictionaryIterator(DictType &dict, const Entry& entry) noexcept
215  : m_dict(dict),
216  m_entry(entry)
217  {
218  }
219 
220  DictionaryIterator(DictType &dict) noexcept
221  : m_dict(dict)
222  {
223  operator++();
224  }
225 
227  {
228  m_entry.m_entry = av_dict_get(m_dict.raw(), "", m_entry.m_entry, FlagIgnoreSuffix);
229  return *this;
230  }
231 
233  {
234  DictionaryIterator tmp(*this);
235  operator++();
236  return tmp;
237  }
238 
239  friend bool operator==(const DictionaryIterator& lhs, const DictionaryIterator& rhs) noexcept
240  {
241  return lhs.m_entry == rhs.m_entry;
242  }
243 
244  friend bool operator!=(const DictionaryIterator& lhs, const DictionaryIterator& rhs) noexcept
245  {
246  return lhs.m_entry != rhs.m_entry;
247  }
248 
249  EntryType& operator*() noexcept
250  {
251  return m_entry;
252  }
253 
254  EntryType* operator->() noexcept
255  {
256  return &m_entry;
257  }
258 
259  };
260 
269 
274  Dictionary();
275 
283  explicit Dictionary(AVDictionary *dict, bool takeOwning = true);
284 
289  ~Dictionary();
290 
296  Dictionary(const Dictionary& other);
297 
305  Dictionary& operator=(const Dictionary &rhs);
306 
312  Dictionary(Dictionary&& other);
313 
322 
338  Dictionary(std::initializer_list<std::pair<const char*, const char*>> list, int flags = 0);
339 
357  Dictionary& operator=(std::initializer_list<std::pair<const char*, const char*>> list);
358 
362  Iterator begin();
364  Iterator end();
365  ConstIterator begin() const;
366  ConstIterator end() const;
367  ConstIterator cbegin() const;
368  ConstIterator cend() const;
370 
375  bool isOwning() const noexcept;
376 
384  void assign(AVDictionary *dict, bool takeOwning = true) noexcept;
385 
393  const char* operator[](size_t index) const;
395  Entry operator[](size_t index);
397 
405  const char* operator[](const char* key) const;
407  Entry operator[](const char* key) noexcept;
409 
416  size_t count() const noexcept;
418  size_t size() const noexcept;
420 
429  const char *get(const char* key, int flags = 0) const noexcept;
431  const char *get(const std::string& key, int flags = 0) const noexcept;
433 
434 
446  template<typename Key, typename Value = Key>
447  auto set(const Key& key, const Value& value, OptionalErrorCode ec = throws(), int flags = 0) ->
448  typename std::enable_if
449  <
450  (std::is_same<Key, std::string>::value || std::is_same<typename std::remove_cv<typename std::decay<Key>::type>::type, char*>::value) &&
451  (std::is_same<Value, std::string>::value || std::is_same<typename std::remove_cv<typename std::decay<Value>::type>::type, char*>::value || std::is_integral<Value>::value)
452  ,void
453  >::type
454  {
455  clear_if(ec);
456  int sts;
457  if ((sts = set_priv(key, value, flags)) < 0) {
458  throws_if(ec, sts, ffmpeg_category());
459  }
460  }
461 
480  template<typename Str, typename Sep1, typename Sep2>
481  void parseString(const Str& str, const Sep1& keyValSep, const Sep2& pairsSep, int flags = 0, OptionalErrorCode ec = throws())
482  {
483  parseString_priv(ec,
484  _to_const_char_ptr(str),
485  _to_const_char_ptr(keyValSep),
486  _to_const_char_ptr(pairsSep),
487  flags);
488  }
489 
506  std::string toString(const char keyValSep, const char pairsSep, OptionalErrorCode ec = throws()) const;
507 
524  AvStringPtr toRawStringPtr(const char keyValSep, const char pairsSep, OptionalErrorCode ec = throws()) const;
525 
535  void copyFrom(const Dictionary& other, int flags = 0) noexcept;
536 
541  void swap(Dictionary& other) noexcept;
542 
547  AVDictionary* release();
548 
549 
550  AVDictionary **rawPtr() noexcept;
551 
552 private:
553  // Discard access to the reset() method
554  using FFWrapperPtr<AVDictionary>::reset;
555 
556  int set_priv(const char* key, const char *value, int flags = 0) noexcept;
557  int set_priv(const std::string& key, const std::string& value, int flags = 0) noexcept;
558  int set_priv(const char* key, int64_t value, int flags = 0) noexcept;
559  int set_priv(const std::string& key, int64_t value, int flags = 0) noexcept;
560 
561  const char* _to_const_char_ptr(const char *str)
562  {
563  return str;
564  }
565 
566  const char* _to_const_char_ptr(const std::string &str)
567  {
568  return str.c_str();
569  }
570 
571  int parseString_priv(const char* str, const char* keyvalSep, const char* pairsSep, int flags);
572  void parseString_priv(OptionalErrorCode ec, const char* str, const char* keyvalSep, const char* pairsSep, int flags);
573 
574 
575 private:
576  bool m_owning = true;
577 };
578 
579 
589 {
590 public:
591 
592  DictionaryArray() = default;
593  DictionaryArray(std::initializer_list<Dictionary> dicts);
594  DictionaryArray(AVDictionary **dicts, size_t count, bool takeOwning = true);
595 
596  DictionaryArray(const DictionaryArray& rhs);
598 
599  DictionaryArray(DictionaryArray&&) = default;
601 
602  void assign(AVDictionary **dicts, size_t count, bool takeOwning = true);
603  void reserve(size_t size);
604  void resize(size_t size);
605 
606  size_t size() const;
607 
608  void pushBack(const Dictionary &dict);
609  void pushBack(Dictionary &&dict);
610 
611  const Dictionary& operator[](size_t index) const;
612  Dictionary& operator[](size_t index);
613  const Dictionary& at(size_t index) const;
614  Dictionary& at(size_t index);
615 
616  const AVDictionary* const* raws() const;
617  AVDictionary** raws();
618 
619  AVDictionary** release();
620  void swap(DictionaryArray &rhs);
621 private:
622  std::vector<AVDictionary*> m_raws;
623  std::vector<Dictionary> m_dicts;
624 };
625 
626 } // namespace av
627 
av::Dictionary::Entry::set
void set(const char *value, int flags=0) noexcept
Definition: dictionary.cpp:338
av::Dictionary::DictionaryIterator::operator*
EntryType & operator*() noexcept
Definition: dictionary.h:249
av::Dictionary::AvStringPtr::base_class
std::unique_ptr< char, AvStringDeleter > base_class
Definition: dictionary.h:78
av::ffmpeg_category
FfmpegCategory & ffmpeg_category()
Definition: averror.h:121
av::Dictionary::AvStringDeleter
Deleter for raw string.
Definition: dictionary.h:60
av::DictionaryArray
Array of Dictinaries wrapper.
Definition: dictionary.h:588
av::Dictionary
Implements interface to access to the AVDictionary entity.
Definition: dictionary.h:30
av::Dictionary::Entry::Dictionary
friend class Dictionary
Definition: dictionary.h:139
av::Dictionary::DictionaryIterator::difference_type
ptrdiff_t difference_type
Definition: dictionary.h:202
averror.h
ffmpeg.h
av::Dictionary::FlagDontStrdupVal
@ FlagDontStrdupVal
Do not duplicate string value.
Definition: dictionary.h:48
av::Dictionary::DictionaryIterator::pointer
value_type * pointer
Definition: dictionary.h:203
FFWrapperPtr
Definition: ffmpeg.h:68
av::Dictionary::assign
void assign(AVDictionary *dict, bool takeOwning=true) noexcept
assign - assign new resouces Old dictionary destroyes (if owning).
Definition: dictionary.cpp:109
av::Dictionary::cend
ConstIterator cend() const
Definition: dictionary.cpp:99
av::Dictionary::DictionaryIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: dictionary.h:200
av::Dictionary::Entry::operator=
Entry & operator=(const char *value) noexcept
Definition: dictionary.cpp:371
av::Dictionary::isOwning
bool isOwning() const noexcept
isOwning - checks resources owning status
Definition: dictionary.cpp:104
av::Dictionary::swap
void swap(Dictionary &other) noexcept
swap - swaps resouces between objects
Definition: dictionary.cpp:308
av::clear_if
void clear_if(OptionalErrorCode ec)
clear_if - clear error code if it is not av::throws()
Definition: averror.h:211
av::OptionalErrorCode
Definition: averror.h:63
av::Dictionary::toString
std::string toString(const char keyValSep, const char pairsSep, OptionalErrorCode ec=throws()) const
toString - converts dictionary to the string representation (serialize)
Definition: dictionary.cpp:206
av::Dictionary::size
size_t size() const noexcept
Definition: dictionary.cpp:186
av::Dictionary::DictionaryIterator::operator==
friend bool operator==(const DictionaryIterator &lhs, const DictionaryIterator &rhs) noexcept
Definition: dictionary.h:239
av::Dictionary::count
size_t count() const noexcept
Definition: dictionary.cpp:181
av::Dictionary::Entry::key
const char * key() const noexcept
key - item key accessor
Definition: dictionary.cpp:328
av::Dictionary::copyFrom
void copyFrom(const Dictionary &other, int flags=0) noexcept
copyFrom - copy data from other dictionary.
Definition: dictionary.cpp:303
av::Dictionary::operator[]
const char * operator[](size_t index) const
Definition: dictionary.cpp:121
av::Dictionary::toRawStringPtr
AvStringPtr toRawStringPtr(const char keyValSep, const char pairsSep, OptionalErrorCode ec=throws()) const
toRawStringPtr - converts dictionary to the raw string (char*) and protect it with smart pointer (std...
Definition: dictionary.cpp:227
av::Dictionary::Entry::isNull
bool isNull() const
isNull - checks that entry invalid (null)
Definition: dictionary.cpp:360
av::throws_if
void throws_if(OptionalErrorCode ec, int errcode, const Category &cat)
Throws exception if ec is av::throws() or fill error code.
Definition: averror.h:188
av::Dictionary::DictionaryIterator::operator->
EntryType * operator->() noexcept
Definition: dictionary.h:254
av::Dictionary::AvStringDeleter::operator()
void operator()(char *ptr)
Definition: dictionary.h:62
av::Dictionary::begin
Iterator begin()
Definition: dictionary.cpp:74
av::Dictionary::DictionaryIterator::operator!=
friend bool operator!=(const DictionaryIterator &lhs, const DictionaryIterator &rhs) noexcept
Definition: dictionary.h:244
av::Dictionary::end
Iterator end()
Definition: dictionary.cpp:79
av::Dictionary::parseString
void parseString(const Str &str, const Sep1 &keyValSep, const Sep2 &pairsSep, int flags=0, OptionalErrorCode ec=throws())
parseString - process string with options and fill dictionary String examples:
Definition: dictionary.h:481
av::Dictionary::DictionaryIterator::value_type
typename std::conditional< constIterator, const Entry, Entry >::type value_type
Definition: dictionary.h:201
av::Dictionary::FlagIgnoreSuffix
@ FlagIgnoreSuffix
Special case: Iterate via dictionary.
Definition: dictionary.h:41
av::Dictionary::cbegin
ConstIterator cbegin() const
Definition: dictionary.cpp:94
av::Dictionary::Flags
Flags
AVDictionary flags mapping.
Definition: dictionary.h:36
av::Dictionary::DictionaryIterator::operator++
DictionaryIterator operator++(int) noexcept
Definition: dictionary.h:232
av::Dictionary::operator=
Dictionary & operator=(const Dictionary &rhs)
Copy assign operator Make deep copy of dictionary.
Definition: dictionary.cpp:35
av
Definition: audioresampler.cpp:8
std
Definition: averror.h:228
av::Dictionary::DictionaryIterator::operator++
DictionaryIterator & operator++() noexcept
Definition: dictionary.h:226
av::Dictionary::FlagDontOverwrite
@ FlagDontOverwrite
Keep existing value if key already exists.
Definition: dictionary.h:50
av::Dictionary::~Dictionary
~Dictionary()
Dtor If Dictionary takes ownershipping on AVDictionary, it free allocated resources.
Definition: dictionary.cpp:21
av::Dictionary::DictionaryIterator::DictionaryIterator
DictionaryIterator(DictType &dict, const Entry &entry) noexcept
Definition: dictionary.h:214
av::Dictionary::FlagAppend
@ FlagAppend
Append value to the existing one (string concat)
Definition: dictionary.h:52
av::Dictionary::AvStringPtr::c_str
char * c_str() const noexcept
Access to the holded string with std::string interface.
Definition: dictionary.h:85
av::Dictionary::FlagMatchCase
@ FlagMatchCase
Do not ignore case.
Definition: dictionary.h:39
av::Dictionary::Entry::value
const char * value() const noexcept
value - item value accessor
Definition: dictionary.cpp:333
FFWrapperPtr< AVDictionary >::reset
void reset(AVDictionary *raw=nullptr)
Definition: ffmpeg.h:76
av::throws
OptionalErrorCode throws()
Helper to construct null OptionalErrorCode object.
Definition: averror.h:179
av::Dictionary::get
const char * get(const char *key, int flags=0) const noexcept
Definition: dictionary.cpp:191
av::Dictionary::DictionaryIterator::reference
value_type & reference
Definition: dictionary.h:204
av::Dictionary::DictionaryIterator
Base dictionary iterator implementation.
Definition: dictionary.h:128
av::Dictionary::rawPtr
AVDictionary ** rawPtr() noexcept
Definition: dictionary.cpp:323
av::Dictionary::FlagDontStrdupKey
@ FlagDontStrdupKey
Do not duplicate string key.
Definition: dictionary.h:44
av::Dictionary::AvStringPtr::operator[]
char & operator[](size_t index) const noexcept
Array-like char access.
Definition: dictionary.h:115
av::Dictionary::release
AVDictionary * release()
release - drops ownershipping
Definition: dictionary.cpp:315
av::Dictionary::DictionaryIterator::DictionaryIterator
DictionaryIterator(DictType &dict) noexcept
Definition: dictionary.h:220
av::Dictionary::AvStringPtr
RAII holder for strings allocated by FFmpeg internals.
Definition: dictionary.h:76
av::Dictionary::Entry
Dictionary key and value holder and accessor.
Definition: dictionary.h:133
av::Dictionary::AvStringPtr::length
size_t length() const noexcept
RAW string length in bytes.
Definition: dictionary.h:102