+/**
+ * Serializes the given configuration.
+ *
+ * @param cfg configuration to serialize
+ * @param size will be set to the size of the serialized memory block
+ * @return the memory block where the serialized configuration is
+ * present. This memory should be freed by the caller
+ */
+char *
+GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ size_t *size)
+{
+ struct ConfigSection *sec;
+ struct ConfigEntry *ent;
+ char *mem;
+ char *cbuf;
+ char *val;
+ char *pos;
+ int len;
+ size_t m_size;
+ size_t c_size;
+
+
+ /* Pass1 : calculate the buffer size required */
+ m_size = 0;
+ for (sec = cfg->sections; NULL != sec; sec = sec->next)
+ {
+ /* For each section we need to add 3 charaters: {'[',']','\n'} */
+ m_size += strlen (sec->name) + 3;
+ for (ent = sec->entries; NULL != ent; ent = ent->next)
+ {
+ if (NULL != ent->val)
+ {
+ /* if val has any '\n' then they occupy +1 character as '\n'->'\\','n' */
+ pos = ent->val;
+ while (NULL != (pos = strstr (pos, "\n")))
+ {
+ m_size++;
+ pos++;
+ }
+ /* For each key = value pair we need to add 4 characters (2
+ spaces and 1 equal-to character and 1 new line) */
+ m_size += strlen (ent->key) + strlen (ent->val) + 4;
+ }
+ }
+ /* A new line after section end */
+ m_size++;
+ }
+
+ /* Pass2: Allocate memory and write the configuration to it */
+ mem = GNUNET_malloc (m_size);
+ sec = cfg->sections;
+ c_size = 0;
+ *size = c_size;
+ while (NULL != sec)
+ {
+ len = GNUNET_asprintf (&cbuf, "[%s]\n", sec->name);
+ GNUNET_assert (0 < len);
+ memcpy (mem + c_size, cbuf, len);
+ c_size += len;
+ GNUNET_free (cbuf);
+ for (ent = sec->entries; NULL != ent; ent = ent->next)
+ {
+ if (NULL != ent->val)
+ {
+ val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
+ strcpy (val, ent->val);
+ while (NULL != (pos = strstr (val, "\n")))
+ {
+ memmove (&pos[2], &pos[1], strlen (&pos[1]));
+ pos[0] = '\\';
+ pos[1] = 'n';
+ }
+ len = GNUNET_asprintf (&cbuf, "%s = %s\n", ent->key, val);
+ GNUNET_free (val);
+ memcpy (mem + c_size, cbuf, len);
+ c_size += len;
+ GNUNET_free (cbuf);
+ }
+ }
+ memcpy (mem + c_size, "\n", 1);
+ c_size ++;
+ sec = sec->next;
+ }
+ GNUNET_assert (c_size == m_size);
+ *size = c_size;
+ return mem;
+}
+
+