On 17.11.2014 14:01, Michael Niedermayer wrote:
On Mon, Nov 17, 2014 at 02:46:54AM +0100, Lukasz Marek wrote:
TODO: bump minor, update doc/APIchanges

Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
  libavutil/dict.c | 27 +++++++++++++++++++++++++++
  libavutil/dict.h | 16 ++++++++++++++++
  2 files changed, 43 insertions(+)

diff --git a/libavutil/dict.c b/libavutil/dict.c
index 475e906..a41d61e 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -24,6 +24,7 @@
  #include "dict.h"
  #include "internal.h"
  #include "mem.h"
+#include "bprint.h"

  struct AVDictionary {
      int count;

@@ -207,3 +208,29 @@ void av_dict_copy(AVDictionary **dst, FF_CONST_AVUTIL53 
AVDictionary *src, int f
      while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX)))
          av_dict_set(dst, t->key, t->value, flags);
  }
+
+int av_dict_serialize(const AVDictionary *m, char **buffer,
+                      const char pairs_sep, const char key_val_sep)
+{
+    AVDictionaryEntry *t = NULL;
+    AVBPrint bprint;
+    int cnt = 0;
+
+    if (!m || !buffer)
+        return AVERROR(EINVAL);

It should be also possible to serialize an empty dictionary

the serialization string should also contain a serialization format
identifer/version otherwise future maintaince could become hard
this identifer should specify the used separator chars

Escaping OK, added. But what is the point of this? It will just require additional function to remove these and pass it to av_dict_parse_string.
Of course user will not have to remember separators.

>From 13a3a26622fddf714a46580fccbe9e63563e2445 Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Sun, 16 Nov 2014 01:45:07 +0100
Subject: [PATCH] lavu/dict: add av_dict_serialize

TODO: bump minor, update doc/APIchanges

Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
 libavutil/Makefile |  1 +
 libavutil/dict.c   | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 libavutil/dict.h   | 16 +++++++++++++
 3 files changed, 84 insertions(+)

diff --git a/libavutil/Makefile b/libavutil/Makefile
index 6f90301..c1aa8aa 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -157,6 +157,7 @@ TESTPROGS = adler32                                                     \
             cpu                                                         \
             crc                                                         \
             des                                                         \
+            dict                                                        \
             error                                                       \
             eval                                                        \
             file                                                        \
diff --git a/libavutil/dict.c b/libavutil/dict.c
index 475e906..7e3bb25 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -24,6 +24,7 @@
 #include "dict.h"
 #include "internal.h"
 #include "mem.h"
+#include "bprint.h"
 
 struct AVDictionary {
     int count;
@@ -207,3 +208,69 @@ void av_dict_copy(AVDictionary **dst, FF_CONST_AVUTIL53 AVDictionary *src, int f
     while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX)))
         av_dict_set(dst, t->key, t->value, flags);
 }
+
+int av_dict_serialize(const AVDictionary *m, char **buffer,
+                      const char pairs_sep, const char key_val_sep)
+{
+    AVDictionaryEntry *t = NULL;
+    AVBPrint bprint;
+    int cnt = 0;
+    char special_chars[] = {pairs_sep, key_val_sep, '\0'};
+
+    if (!buffer || pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep)
+        return AVERROR(EINVAL);
+
+    if (!av_dict_count(m)) {
+        *buffer = av_strdup("");
+        return *buffer ? 0 : AVERROR(ENOMEM);
+    }
+
+    av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
+
+    while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) {
+        if (cnt++)
+            av_bprint_append_data(&bprint, &pairs_sep, 1);
+        av_bprint_escape(&bprint, t->key, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+        av_bprint_append_data(&bprint, &key_val_sep, 1);
+        av_bprint_escape(&bprint, t->value, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+    }
+
+    return av_bprint_finalize(&bprint, buffer);
+}
+
+#ifdef TEST
+static void print_dict(const AVDictionary *m)
+{
+    AVDictionaryEntry *t = NULL;
+    while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
+        printf("%s %s   ", t->key, t->value);
+    printf("\n");
+}
+
+int main(void)
+{
+    AVDictionary *dict = NULL;
+    char *buffer = NULL;
+
+    av_dict_serialize(dict, &buffer, ',', '=');
+    printf("%s\n", buffer);
+    av_freep(&buffer);
+
+    av_dict_set(&dict, "aaa", "aaa", 0);
+    av_dict_set(&dict, "b,b", "bbb", 0);
+    av_dict_set(&dict, "c=c", "ccc", 0);
+    av_dict_set(&dict, "ddd", "d,d", 0);
+    av_dict_set(&dict, "eee", "e=e", 0);
+    av_dict_set(&dict, "f,f", "f=f", 0);
+    av_dict_set(&dict, "g=g", "g,g", 0);
+    print_dict(dict);
+    av_dict_serialize(dict, &buffer, ',', '=');
+    printf("%s\n", buffer);
+    av_dict_free(&dict);
+    av_dict_parse_string(&dict, buffer, "=", ",", 0);
+    av_freep(&buffer);
+    print_dict(dict);
+
+    return 0;
+}
+#endif
diff --git a/libavutil/dict.h b/libavutil/dict.h
index 9b3381b..6088837 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -172,6 +172,22 @@ void av_dict_copy(AVDictionary **dst, FF_CONST_AVUTIL53 AVDictionary *src, int f
 void av_dict_free(AVDictionary **m);
 
 /**
+ * Serialize a dictionary.
+ *
+ * Create a string containing dictionary's serialized entries.
+ * Such string may be passed back to av_dict_parse_string().
+ *
+ * @param[in]  m             dictionary to serialize
+ * @param[out] buffer        Pointer to buffer that will be allocated with string containg serialized entries.
+ *                           Buffer must be freed by the caller when is no longer needed.
+ * @param[in]  key_val_sep   character used to separate key from value
+ * @param[in]  pairs_sep     character used to separate two pairs from each other
+ * @return                   >= 0 on success, negative on error
+ */
+int av_dict_serialize(const AVDictionary *m, char **buffer,
+                      const char pairs_sep, const char key_val_sep);
+
+/**
  * @}
  */
 
-- 
1.9.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to