--- /dev/null
+/*
+ * Copyright (c) 2010 Andreas Hofmeister <andi@collax.com>
+ * 2010 Vincent Bernat <bernat@luffy.cx>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "writer.h"
+#include "lldpd.h"
+
+struct kv_writer_private {
+ FILE * fh;
+ char * prefix;
+};
+
+void
+kv_start(struct writer *w , const char *tag, const char *descr)
+{
+ struct kv_writer_private *p = w->priv;
+ char *newprefix;
+ int s;
+
+ s = strlen(p->prefix) + 1 + strlen(tag);
+ if ((newprefix = malloc(s+1)) == NULL)
+ fatal(NULL);
+ if (strlen(p->prefix) > 0)
+ snprintf(newprefix, s+1, "%s.%s", p->prefix, tag);
+ else
+ snprintf(newprefix, s+1, "%s", tag);
+ free(p->prefix);
+ p->prefix = newprefix;
+}
+
+void
+kv_data(struct writer *w, const char *data)
+{
+ struct kv_writer_private *p = w->priv;
+ fprintf(p->fh, "%s=%s\n", p->prefix, data);
+}
+
+void
+kv_end(struct writer *w)
+{
+ struct kv_writer_private *p = w->priv;
+ char *dot;
+
+ if ((dot = strrchr(p->prefix, '.')) == NULL)
+ p->prefix[0] = '\0';
+ else
+ *dot = '\0';
+}
+
+void
+kv_attr(struct writer *w, const char *tag, const char *descr, const char *value)
+{
+ if (!strcmp(tag, "name") || !strcmp(tag, "type")) {
+ /* Special case for name, replace the last prefix */
+ kv_end(w);
+ kv_start(w, value, NULL);
+ } else {
+ kv_start(w, tag, NULL);
+ kv_data(w, value);
+ kv_end(w);
+ }
+}
+
+void
+kv_finish(struct writer *w)
+{
+ struct kv_writer_private *p = w->priv;
+
+ free(p->prefix);
+ free(w->priv);
+ w->priv = NULL;
+
+ free(w);
+}
+
+struct writer *
+kv_init(FILE *fh)
+{
+
+ struct writer *result;
+ struct kv_writer_private *priv;
+
+ if ((priv = malloc(sizeof(*priv))) == NULL)
+ fatal(NULL);
+
+ priv->fh = fh;
+ priv->prefix = strdup("");
+
+ if ((result = malloc(sizeof(struct writer))) == NULL)
+ fatal(NULL);
+
+ result->priv = priv;
+ result->start = kv_start;
+ result->attr = kv_attr;
+ result->data = kv_data;
+ result->end = kv_end;
+ result->finish= kv_finish;
+
+ return result;
+}