ksgi

Форк
0
/
kcgixml.c 
287 строк · 6.0 Кб
1
/*	$Id$ */
2
/*
3
 * Copyright (c) 2015, 2017, 2020 Kristaps Dzonsons <kristaps@bsd.lv>
4
 *
5
 * Permission to use, copy, modify, and 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
#include "config.h"
18

19
#include <assert.h>
20
#include <inttypes.h>
21
#include <stdarg.h>
22
#include <stdint.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26

27
#include "kcgi.h"
28
#include "kcgixml.h"
29

30
enum kcgi_err
31
kxml_open(struct kxmlreq *r, struct kreq *req,
32
	const char *const *elems, size_t elemsz)
33
{
34

35
	memset(r, 0, sizeof(struct kxmlreq));
36
	if (NULL == (r->arg = kcgi_writer_get(req, 0)))
37
		return(KCGI_ENOMEM);
38
	r->elems = elems;
39
	r->elemsz = elemsz;
40
	return(KCGI_OK);
41
}
42

43
enum kcgi_err
44
kxml_prologue(struct kxmlreq *r)
45
{
46

47
	return kcgi_writer_puts(r->arg, 
48
		"<?xml version=\"1.0\" "
49
		"encoding=\"utf-8\" ?>");
50
}
51

52
enum kcgi_err
53
kxml_close(struct kxmlreq *r)
54
{
55
	enum kcgi_err	 er;
56

57
	er = kxml_popall(r);
58
	kcgi_writer_free(r->arg);
59
	r->arg = NULL;
60
	return er;
61
}
62

63
enum kcgi_err
64
kxml_push(struct kxmlreq *r, size_t elem)
65
{
66
	enum kcgi_err	 er;
67

68
	if (r->stackpos >= KXML_STACK_MAX) {
69
		kutil_warnx(NULL, NULL, 
70
			"maximum xml stack size exceeded");
71
		return KCGI_ENOMEM;
72
	} else if (elem >= r->elemsz)
73
		return KCGI_WRITER;
74

75
	if ((er = kcgi_writer_putc(r->arg, '<')) != KCGI_OK)
76
		return er;
77
	if ((er = kcgi_writer_puts(r->arg, r->elems[elem])) != KCGI_OK)
78
		return er;
79
	if ((er = kcgi_writer_putc(r->arg, '>')) != KCGI_OK)
80
		return er;
81

82
	r->stack[r->stackpos++] = elem;
83
	return KCGI_OK;
84
}
85

86
enum kcgi_err
87
kxml_pushnull(struct kxmlreq *r, size_t elem)
88
{
89
	enum kcgi_err	 er;
90

91
	if (r->stackpos >= KXML_STACK_MAX) {
92
		kutil_warnx(NULL, NULL, 
93
			"maximum xml stack size exceeded");
94
		return KCGI_ENOMEM;
95
	} else if (elem >= r->elemsz)
96
		return KCGI_WRITER;
97

98
	if ((er = kcgi_writer_putc(r->arg, '<')) != KCGI_OK)
99
		return er;
100
	if ((er = kcgi_writer_puts(r->arg, r->elems[elem])) != KCGI_OK)
101
		return er;
102

103
	return kcgi_writer_puts(r->arg, " />");
104
}
105

106
enum kcgi_err
107
kxml_putc(struct kxmlreq *r, char c)
108
{
109
	enum kcgi_err	 er;
110

111
	switch (c) {
112
	case ('<'):
113
		er = kcgi_writer_puts(r->arg, "&lt;");
114
		break;
115
	case ('>'):
116
		er = kcgi_writer_puts(r->arg, "&gt;");
117
		break;
118
	case ('"'):
119
		er = kcgi_writer_puts(r->arg, "&quot;");
120
		break;
121
	case ('&'):
122
		er = kcgi_writer_puts(r->arg, "&amp;");
123
		break;
124
	default:
125
		er = kcgi_writer_putc(r->arg, c);
126
		break;
127
	}
128

129
	return(er);
130
}
131

132
enum kcgi_err
133
kxml_write(const char *p, size_t sz, void *arg)
134
{
135
	struct kxmlreq 	*r = arg;
136
	size_t	 	 i;
137
	enum kcgi_err	 er;
138

139
	if (p == NULL || sz == 0)
140
		return KCGI_OK;
141

142
	for (i = 0; i < sz; i++)
143
		if ((er = kxml_putc(r, p[i])) != KCGI_OK)
144
			return er;
145

146
	return KCGI_OK;
147
}
148

149
enum kcgi_err
150
kxml_puts(struct kxmlreq *r, const char *p)
151
{
152

153
	if (p == NULL)
154
		return KCGI_OK;
155
	return kxml_write(p, strlen(p), r);
156
}
157

158
enum kcgi_err
159
kxml_pushattrs(struct kxmlreq *r, size_t elem, ...)
160
{
161
	va_list	 	 ap;
162
	const char	*key, *val;
163
	enum kcgi_err	 er = KCGI_OK;
164

165
	if (r->stackpos >= KXML_STACK_MAX) {
166
		kutil_warnx(NULL, NULL, 
167
			"maximum xml stack size exceeded");
168
		return KCGI_ENOMEM;
169
	} else if (elem >= r->elemsz)
170
		return KCGI_WRITER;
171

172
	if ((er = kcgi_writer_putc(r->arg, '<')) != KCGI_OK)
173
		return er;
174
	if ((er = kcgi_writer_puts(r->arg, r->elems[elem])) != KCGI_OK)
175
		return er;
176
	va_start(ap, elem);
177
	for (;;) {
178
		if ((key = va_arg(ap, char *)) == NULL)
179
			break;
180
		val = va_arg(ap, char *);
181
		if ((er = kcgi_writer_putc(r->arg, ' ')) != KCGI_OK)
182
			goto out;
183
		if ((er = kcgi_writer_puts(r->arg, key)) != KCGI_OK)
184
			goto out;
185
		if ((er = kcgi_writer_puts(r->arg, "=\"")) != KCGI_OK)
186
			goto out;
187
		if ((er = kxml_puts(r, val)) != KCGI_OK)
188
			goto out;
189
		if ((er = kcgi_writer_putc(r->arg, '"')) != KCGI_OK)
190
			goto out;
191
	}
192
	va_end(ap);
193
	r->stack[r->stackpos++] = elem;
194
	return kcgi_writer_putc(r->arg, '>');
195
out:
196
	va_end(ap);
197
	return er;
198
}
199

200
enum kcgi_err
201
kxml_pushnullattrs(struct kxmlreq *r, size_t elem, ...)
202
{
203
	va_list	 	 ap;
204
	const char	*key, *val;
205
	enum kcgi_err	 er;
206

207
	if (r->stackpos >= KXML_STACK_MAX) {
208
		kutil_warnx(NULL, NULL, 
209
			"maximum xml stack size exceeded");
210
		return KCGI_ENOMEM;
211
	} else if (elem >= r->elemsz)
212
		return KCGI_WRITER;
213

214
	if ((er = kcgi_writer_putc(r->arg, '<')) != KCGI_OK)
215
		return er;
216
	if ((er = kcgi_writer_puts(r->arg, r->elems[elem])) != KCGI_OK)
217
		return er;
218
	va_start(ap, elem);
219
	for (;;) {
220
		if ((key = va_arg(ap, char *)) == NULL)
221
			break;
222
		val = va_arg(ap, char *);
223
		if ((er = kcgi_writer_putc(r->arg, ' ')) != KCGI_OK)
224
			goto out;
225
		if ((er = kcgi_writer_puts(r->arg, key)) != KCGI_OK)
226
			goto out;
227
		if ((er = kcgi_writer_puts(r->arg, "=\"")) != KCGI_OK)
228
			goto out;
229
		if ((er = kxml_puts(r, val)) != KCGI_OK)
230
			goto out;
231
		if ((er = kcgi_writer_putc(r->arg, '"')) != KCGI_OK)
232
			goto out;
233
	}
234
	va_end(ap);
235
	return kcgi_writer_puts(r->arg, " />");
236
out:
237
	va_end(ap);
238
	return er;
239
}
240

241
static int
242
kxml_pop_inner(struct kxmlreq *r, enum kcgi_err *er)
243
{
244

245
	if (r->stackpos == 0)
246
		return 0;
247

248
	*er = kcgi_writer_puts(r->arg, "</");
249
	if (*er != KCGI_OK)
250
		return (-1);
251

252
	*er = kcgi_writer_puts(r->arg,
253
		r->elems[r->stack[--r->stackpos]]);
254
	if (*er != KCGI_OK)
255
		return (-1);
256

257
	*er = kcgi_writer_putc(r->arg, '>');
258
	if (*er != KCGI_OK)
259
		return (-1);
260

261
	return 1;
262
}
263

264
enum kcgi_err
265
kxml_popall(struct kxmlreq *r)
266
{
267
	enum kcgi_err	 er = KCGI_OK;
268

269
	while (kxml_pop_inner(r, &er) > 0)
270
		/* Spin. */ ;
271

272
	return er;
273
}
274

275
enum kcgi_err
276
kxml_pop(struct kxmlreq *r)
277
{
278
	enum kcgi_err	 er;
279
	int		 c;
280

281
	if ((c = kxml_pop_inner(r, &er)) < 0)
282
		return er;
283
	else if (c == 0)
284
		return KCGI_WRITER;
285

286
	return KCGI_OK;
287
}
288

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.