]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/client/xml_writer.c
client: ensure XML is written to the provided file handle
[thirdparty/lldpd.git] / src / client / xml_writer.c
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3 * Copyright (c) 2010 Andreas Hofmeister <andi@collax.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #if defined(__clang__)
23 #pragma clang diagnostic push
24 #pragma clang diagnostic ignored "-Wdocumentation"
25 #endif
26 #include <libxml/encoding.h>
27 #include <libxml/xmlwriter.h>
28 #if defined(__clang__)
29 #pragma clang diagnostic pop
30 #endif
31
32 #include "writer.h"
33 #include "../log.h"
34
35 struct xml_writer_private {
36 FILE *fh;
37 xmlTextWriterPtr xw;
38 xmlDocPtr doc;
39 };
40
41 void xml_start(struct writer *w , const char *tag, const char *descr ) {
42 struct xml_writer_private *p = w->priv;
43
44 if (xmlTextWriterStartElement(p->xw, BAD_CAST tag) < 0)
45 log_warnx("lldpctl", "cannot start '%s' element", tag);
46
47 if (descr && (strlen(descr) > 0)) {
48 if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST "label", "%s", descr) < 0)
49 log_warnx("lldpctl", "cannot add attribute 'label' to element %s", tag);
50 }
51 }
52
53 void xml_attr(struct writer *w, const char *tag, const char *descr, const char *value ) {
54 struct xml_writer_private *p = w->priv;
55
56 if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST tag, "%s", value?value:"") < 0)
57 log_warnx("lldpctl", "cannot add attribute %s with value %s", tag, value?value:"(none)");
58 }
59
60 void xml_data(struct writer *w, const char *data) {
61 struct xml_writer_private *p = w->priv;
62 if (xmlTextWriterWriteString(p->xw, BAD_CAST (data?data:"")) < 0 )
63 log_warnx("lldpctl", "cannot add '%s' as data to element", data?data:"(none)");
64 }
65
66 void xml_end(struct writer *w) {
67 struct xml_writer_private *p = w->priv;
68
69 if (xmlTextWriterEndElement(p->xw) < 0 )
70 log_warnx("lldpctl", "cannot end element");
71 }
72
73 #define MY_ENCODING "UTF-8"
74
75 void xml_finish(struct writer *w) {
76 struct xml_writer_private *p = w->priv;
77 int failed = 0;
78
79 if (xmlTextWriterEndDocument(p->xw) < 0 ) {
80 log_warnx("lldpctl", "cannot finish document");
81 failed = 1;
82 }
83
84 xmlFreeTextWriter(p->xw);
85
86 if (!failed)
87 xmlDocDump(p->fh, p->doc);
88
89 xmlFreeDoc(p->doc);
90
91 free(w->priv);
92 free(w);
93 }
94
95 struct writer *xml_init(FILE *fh) {
96
97 struct writer *result;
98 struct xml_writer_private *priv;
99
100 priv = malloc(sizeof(*priv));
101 priv->fh = fh;
102 if (!priv) {
103 fatalx("lldpctl", "out of memory");
104 return NULL;
105 }
106
107 priv->xw = xmlNewTextWriterDoc(&(priv->doc), 0);
108 if (!priv->xw) {
109 fatalx("lldpctl", "cannot create xml writer");
110 return NULL;
111 }
112
113 xmlTextWriterSetIndent(priv->xw, 4);
114
115 if (xmlTextWriterStartDocument(priv->xw, NULL, MY_ENCODING, NULL) < 0 ) {
116 fatalx("lldpctl", "cannot start xml document");
117 return NULL;
118 }
119
120 result = malloc(sizeof(struct writer));
121 if (!result) {
122 fatalx("lldpctl", "out of memory");
123 return NULL;
124 }
125
126 result->priv = priv;
127 result->start = xml_start;
128 result->attr = xml_attr;
129 result->data = xml_data;
130 result->end = xml_end;
131 result->finish= xml_finish;
132
133 return result;
134 }