]>
Commit | Line | Data |
---|---|---|
4b292b55 | 1 | /* -*- mode: c; c-file-style: "openbsd" -*- */ |
1480ce74 AH |
2 | /* |
3 | * Copyright (c) 2010 Andreas Hofmeister <andi@collax.com> | |
4 | * | |
51434125 | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
1480ce74 AH |
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 | ||
d7460a6f ALG |
22 | #if defined(__clang__) |
23 | #pragma clang diagnostic push | |
24 | #pragma clang diagnostic ignored "-Wdocumentation" | |
25 | #endif | |
1480ce74 AH |
26 | #include <libxml/encoding.h> |
27 | #include <libxml/xmlwriter.h> | |
d7460a6f ALG |
28 | #if defined(__clang__) |
29 | #pragma clang diagnostic pop | |
30 | #endif | |
1480ce74 AH |
31 | |
32 | #include "writer.h" | |
4b292b55 | 33 | #include "../log.h" |
1480ce74 AH |
34 | |
35 | struct xml_writer_private { | |
9cff0cc8 | 36 | FILE *fh; |
1480ce74 AH |
37 | xmlTextWriterPtr xw; |
38 | xmlDocPtr doc; | |
39 | }; | |
40 | ||
9cff0cc8 VB |
41 | void xml_start(struct writer *w , const char *tag, const char *descr ) { |
42 | struct xml_writer_private *p = w->priv; | |
1480ce74 AH |
43 | |
44 | if (xmlTextWriterStartElement(p->xw, BAD_CAST tag) < 0) | |
9a775667 | 45 | log_warnx("lldpctl", "cannot start '%s' element", tag); |
38221459 | 46 | |
9cff0cc8 | 47 | if (descr && (strlen(descr) > 0)) { |
38221459 | 48 | if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST "label", "%s", descr) < 0) |
9a775667 | 49 | log_warnx("lldpctl", "cannot add attribute 'label' to element %s", tag); |
38221459 | 50 | } |
1480ce74 AH |
51 | } |
52 | ||
9cff0cc8 VB |
53 | void xml_attr(struct writer *w, const char *tag, const char *descr, const char *value ) { |
54 | struct xml_writer_private *p = w->priv; | |
1480ce74 | 55 | |
58288829 VB |
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)"); | |
1480ce74 AH |
58 | } |
59 | ||
9cff0cc8 VB |
60 | void xml_data(struct writer *w, const char *data) { |
61 | struct xml_writer_private *p = w->priv; | |
58288829 VB |
62 | if (xmlTextWriterWriteString(p->xw, BAD_CAST (data?data:"")) < 0 ) |
63 | log_warnx("lldpctl", "cannot add '%s' as data to element", data?data:"(none)"); | |
1480ce74 AH |
64 | } |
65 | ||
9cff0cc8 VB |
66 | void xml_end(struct writer *w) { |
67 | struct xml_writer_private *p = w->priv; | |
1480ce74 AH |
68 | |
69 | if (xmlTextWriterEndElement(p->xw) < 0 ) | |
9a775667 | 70 | log_warnx("lldpctl", "cannot end element"); |
1480ce74 AH |
71 | } |
72 | ||
73 | #define MY_ENCODING "UTF-8" | |
74 | ||
9cff0cc8 VB |
75 | void xml_finish(struct writer *w) { |
76 | struct xml_writer_private *p = w->priv; | |
1480ce74 AH |
77 | int failed = 0; |
78 | ||
79 | if (xmlTextWriterEndDocument(p->xw) < 0 ) { | |
9a775667 | 80 | log_warnx("lldpctl", "cannot finish document"); |
1480ce74 AH |
81 | failed = 1; |
82 | } | |
83 | ||
84 | xmlFreeTextWriter(p->xw); | |
58288829 | 85 | |
9cff0cc8 VB |
86 | if (!failed) |
87 | xmlDocDump(p->fh, p->doc); | |
1480ce74 AH |
88 | |
89 | xmlFreeDoc(p->doc); | |
90 | ||
9cff0cc8 VB |
91 | free(w->priv); |
92 | free(w); | |
1480ce74 AH |
93 | } |
94 | ||
9cff0cc8 | 95 | struct writer *xml_init(FILE *fh) { |
1480ce74 | 96 | |
9cff0cc8 VB |
97 | struct writer *result; |
98 | struct xml_writer_private *priv; | |
1480ce74 | 99 | |
9cff0cc8 VB |
100 | priv = malloc(sizeof(*priv)); |
101 | priv->fh = fh; | |
102 | if (!priv) { | |
a87db231 | 103 | fatalx("lldpctl", "out of memory"); |
1480ce74 AH |
104 | return NULL; |
105 | } | |
106 | ||
107 | priv->xw = xmlNewTextWriterDoc(&(priv->doc), 0); | |
9cff0cc8 | 108 | if (!priv->xw) { |
a87db231 | 109 | fatalx("lldpctl", "cannot create xml writer"); |
1480ce74 AH |
110 | return NULL; |
111 | } | |
112 | ||
113 | xmlTextWriterSetIndent(priv->xw, 4); | |
114 | ||
115 | if (xmlTextWriterStartDocument(priv->xw, NULL, MY_ENCODING, NULL) < 0 ) { | |
a87db231 | 116 | fatalx("lldpctl", "cannot start xml document"); |
1480ce74 AH |
117 | return NULL; |
118 | } | |
119 | ||
9cff0cc8 VB |
120 | result = malloc(sizeof(struct writer)); |
121 | if (!result) { | |
a87db231 | 122 | fatalx("lldpctl", "out of memory"); |
1480ce74 AH |
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 | } |