On 18.11.2014 20:47, Michael Niedermayer wrote:
how will that work without any way to identify the version or format?
also a serialization stream thats self containd seems much nicer to
handle as theres no need to keep track of the exact version (if we
end up having more than 1) the used seperators, ...
also consider 2 libs or apps to interface with each other using this
serialization format, if one requires a change to the format how can
the other know without a version in it, it would need to know it by
external means. it can surely be done but it doesnt feel like
something desirable
I can do one of followings:
- I can move this function to ffserver_config.c, where it is needed as
presented here (to create simple pairs separated with comas)
- Rename function to av_dict_get_string or something so it wont get
confused with your idea of serialize function. I still think both version
has own usecases
iam fine with either of these
OK, renamed. I swapped separators order to be the same as parse_string's
ones. added tests for corner cases where potential escape chars are
separators.
>From f23203f83687ae5a354847919046fb107b145700 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 | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
libavutil/dict.h | 17 ++++++++++
3 files changed, 112 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..e071ec9 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,96 @@ 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_get_string(const AVDictionary *m, char **buffer,
+ const char key_val_sep, const char pairs_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");
+}
+
+static void test_separators(const AVDictionary *m, const char pair, const char val)
+{
+ AVDictionary *dict = NULL;
+ char pairs[] = {pair , '\0'};
+ char vals[] = {val, '\0'};
+
+ char *buffer = NULL;
+ av_dict_copy(&dict, m, 0);
+ print_dict(dict);
+ av_dict_get_string(dict, &buffer, val, pair);
+ printf("%s\n", buffer);
+ av_dict_free(&dict);
+ av_dict_parse_string(&dict, buffer, vals, pairs, 0);
+ av_freep(&buffer);
+ print_dict(dict);
+ av_dict_free(&dict);
+}
+
+int main(void)
+{
+ AVDictionary *dict = NULL;
+ char *buffer = NULL;
+
+ printf("Testing av_dict_get_string() and av_dict_parse_string()");
+ av_dict_get_string(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);
+ test_separators(dict, ',', '=');
+ av_dict_free(&dict);
+ av_dict_set(&dict, "aaa", "aaa", 0);
+ av_dict_set(&dict, "bbb", "bbb", 0);
+ av_dict_set(&dict, "ccc", "ccc", 0);
+ test_separators(dict, '"', '=');
+ test_separators(dict, '\'', '=');
+ test_separators(dict, '\\', '=');
+ test_separators(dict, ',', '"');
+ test_separators(dict, ',', '\'');
+ test_separators(dict, ',', '\\');
+ test_separators(dict, '\\', '"');
+ test_separators(dict, '\\', '\'');
+ test_separators(dict, '\'', '"');
+ test_separators(dict, '\'', '\\');
+ test_separators(dict, '"', '\'');
+ test_separators(dict, '"', '\\');
+ av_dict_free(&dict);
+
+ return 0;
+}
+#endif
diff --git a/libavutil/dict.h b/libavutil/dict.h
index 9b3381b..4cad00e 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -172,6 +172,23 @@ void av_dict_copy(AVDictionary **dst, FF_CONST_AVUTIL53 AVDictionary *src, int f
void av_dict_free(AVDictionary **m);
/**
+ * Get dictionary entries as a string.
+ *
+ * Create a string containing dictionary's entries.
+ * Such string may be passed back to av_dict_parse_string().
+ * @note String is escaped with backslashes ('\').
+ *
+ * @param[in] m dictionary
+ * @param[out] buffer Pointer to buffer that will be allocated with string containg 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_get_string(const AVDictionary *m, char **buffer,
+ const char key_val_sep, const char pairs_sep);
+
+/**
* @}
*/
--
1.9.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel