adamc@117
|
1 #include <stdlib.h>
|
adamc@102
|
2 #include <stdio.h>
|
adamc@117
|
3 #include <string.h>
|
adamc@106
|
4 #include <ctype.h>
|
adamc@102
|
5
|
adamc@102
|
6 #include "types.h"
|
adamc@102
|
7
|
adamc@102
|
8 lw_unit lw_unit_v = {};
|
adamc@102
|
9
|
adamc@117
|
10 struct lw_context {
|
adamc@117
|
11 char *page, *page_front, *page_back;
|
adamc@117
|
12 };
|
adamc@117
|
13
|
adamc@117
|
14 lw_context lw_init(int page_len) {
|
adamc@117
|
15 lw_context ctx = malloc(sizeof(struct lw_context));
|
adamc@117
|
16 ctx->page_front = ctx->page = malloc(page_len);
|
adamc@117
|
17 ctx->page_back = ctx->page_front + page_len;
|
adamc@117
|
18 return ctx;
|
adamc@106
|
19 }
|
adamc@106
|
20
|
adamc@117
|
21 void lw_free(lw_context ctx) {
|
adamc@117
|
22 free(ctx->page);
|
adamc@117
|
23 }
|
adamc@117
|
24
|
adamc@117
|
25 int lw_really_send(int sock, const void *buf, ssize_t len) {
|
adamc@117
|
26 while (len > 0) {
|
adamc@117
|
27 ssize_t n = send(sock, buf, len, 0);
|
adamc@117
|
28
|
adamc@117
|
29 if (n < 0)
|
adamc@117
|
30 return n;
|
adamc@117
|
31
|
adamc@117
|
32 buf += n;
|
adamc@117
|
33 len -= n;
|
adamc@117
|
34 }
|
adamc@117
|
35
|
adamc@117
|
36 return 0;
|
adamc@117
|
37 }
|
adamc@117
|
38
|
adamc@117
|
39 int lw_send(lw_context ctx, int sock) {
|
adamc@117
|
40 return lw_really_send(sock, ctx->page, ctx->page_front - ctx->page);
|
adamc@117
|
41 }
|
adamc@117
|
42
|
adamc@117
|
43 static void lw_check(lw_context ctx, size_t extra) {
|
adamc@117
|
44 size_t desired = ctx->page_back - ctx->page_front + extra, next;
|
adamc@117
|
45 char *new_page;
|
adamc@117
|
46
|
adamc@117
|
47 for (next = ctx->page_back - ctx->page_front; next < desired; next *= 2);
|
adamc@117
|
48
|
adamc@117
|
49 new_page = realloc(ctx->page, next);
|
adamc@117
|
50 ctx->page_front = new_page + (ctx->page_front - ctx->page);
|
adamc@117
|
51 ctx->page_back = new_page + (ctx->page_back - ctx->page);
|
adamc@117
|
52 ctx->page = new_page;
|
adamc@117
|
53 }
|
adamc@117
|
54
|
adamc@117
|
55 static void lw_writec_unsafe(lw_context ctx, char c) {
|
adamc@117
|
56 *(ctx->page_front)++ = c;
|
adamc@117
|
57 }
|
adamc@117
|
58
|
adamc@117
|
59 void lw_writec(lw_context ctx, char c) {
|
adamc@117
|
60 lw_check(ctx, 1);
|
adamc@117
|
61 lw_writec_unsafe(ctx, c);
|
adamc@117
|
62 }
|
adamc@117
|
63
|
adamc@117
|
64 static void lw_write_unsafe(lw_context ctx, const char* s) {
|
adamc@117
|
65 int len = strlen(s);
|
adamc@117
|
66 memcpy(ctx->page_front, s, len);
|
adamc@117
|
67 ctx->page_front += len;
|
adamc@117
|
68 }
|
adamc@117
|
69
|
adamc@117
|
70 void lw_write(lw_context ctx, const char* s) {
|
adamc@117
|
71 lw_check(ctx, strlen(s));
|
adamc@117
|
72 lw_write_unsafe(ctx, s);
|
adamc@102
|
73 }
|
adamc@106
|
74
|
adamc@135
|
75
|
adamc@106
|
76 char *lw_Basis_attrifyInt(lw_Basis_int n) {
|
adamc@106
|
77 return "0";
|
adamc@106
|
78 }
|
adamc@106
|
79
|
adamc@106
|
80 char *lw_Basis_attrifyFloat(lw_Basis_float n) {
|
adamc@106
|
81 return "0.0";
|
adamc@106
|
82 }
|
adamc@106
|
83
|
adamc@106
|
84 char *lw_Basis_attrifyString(lw_Basis_string s) {
|
adamc@106
|
85 return "";
|
adamc@106
|
86 }
|
adamc@106
|
87
|
adamc@117
|
88 #define INTS_MAX 50
|
adamc@117
|
89 #define FLOATS_MAX 100
|
adamc@117
|
90
|
adamc@117
|
91 static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
|
adamc@117
|
92 int len;
|
adamc@117
|
93
|
adamc@117
|
94 sprintf(ctx->page_front, "%d%n", n, &len);
|
adamc@117
|
95 ctx->page_front += len;
|
adamc@106
|
96 }
|
adamc@106
|
97
|
adamc@117
|
98 void lw_Basis_attrifyInt_w(lw_context ctx, lw_Basis_int n) {
|
adamc@117
|
99 lw_check(ctx, INTS_MAX);
|
adamc@117
|
100 lw_Basis_attrifyInt_w_unsafe(ctx, n);
|
adamc@106
|
101 }
|
adamc@106
|
102
|
adamc@117
|
103 void lw_Basis_attrifyFloat_w(lw_context ctx, lw_Basis_float n) {
|
adamc@117
|
104 int len;
|
adamc@117
|
105
|
adamc@117
|
106 lw_check(ctx, FLOATS_MAX);
|
adamc@117
|
107 sprintf(ctx->page_front, "%g%n", n, &len);
|
adamc@117
|
108 ctx->page_front += len;
|
adamc@117
|
109 }
|
adamc@117
|
110
|
adamc@117
|
111 void lw_Basis_attrifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@117
|
112 lw_check(ctx, strlen(s) * 6);
|
adamc@117
|
113
|
adamc@106
|
114 for (; *s; s++) {
|
adamc@106
|
115 char c = *s;
|
adamc@106
|
116
|
adamc@106
|
117 if (c == '"')
|
adamc@117
|
118 lw_write_unsafe(ctx, """);
|
adamc@106
|
119 else if (isprint(c))
|
adamc@117
|
120 lw_writec_unsafe(ctx, c);
|
adamc@106
|
121 else {
|
adamc@117
|
122 lw_write_unsafe(ctx, "&#");
|
adamc@117
|
123 lw_Basis_attrifyInt_w_unsafe(ctx, c);
|
adamc@117
|
124 lw_writec_unsafe(ctx, ';');
|
adamc@106
|
125 }
|
adamc@106
|
126 }
|
adamc@106
|
127 }
|
adamc@120
|
128
|
adamc@120
|
129
|
adamc@120
|
130 char *lw_Basis_urlifyInt(lw_Basis_int n) {
|
adamc@120
|
131 return "0";
|
adamc@120
|
132 }
|
adamc@120
|
133
|
adamc@120
|
134 char *lw_Basis_urlifyFloat(lw_Basis_float n) {
|
adamc@120
|
135 return "0.0";
|
adamc@120
|
136 }
|
adamc@120
|
137
|
adamc@120
|
138 char *lw_Basis_urlifyString(lw_Basis_string s) {
|
adamc@120
|
139 return "";
|
adamc@120
|
140 }
|
adamc@120
|
141
|
adamc@120
|
142 static void lw_Basis_urlifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
|
adamc@120
|
143 int len;
|
adamc@120
|
144
|
adamc@120
|
145 sprintf(ctx->page_front, "%d%n", n, &len);
|
adamc@120
|
146 ctx->page_front += len;
|
adamc@120
|
147 }
|
adamc@120
|
148
|
adamc@120
|
149 void lw_Basis_urlifyInt_w(lw_context ctx, lw_Basis_int n) {
|
adamc@120
|
150 lw_check(ctx, INTS_MAX);
|
adamc@120
|
151 lw_Basis_urlifyInt_w_unsafe(ctx, n);
|
adamc@120
|
152 }
|
adamc@120
|
153
|
adamc@120
|
154 void lw_Basis_urlifyFloat_w(lw_context ctx, lw_Basis_float n) {
|
adamc@120
|
155 int len;
|
adamc@120
|
156
|
adamc@120
|
157 lw_check(ctx, FLOATS_MAX);
|
adamc@120
|
158 sprintf(ctx->page_front, "%g%n", n, &len);
|
adamc@120
|
159 ctx->page_front += len;
|
adamc@120
|
160 }
|
adamc@120
|
161
|
adamc@120
|
162 void lw_Basis_urlifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@120
|
163 lw_check(ctx, strlen(s) * 3);
|
adamc@120
|
164
|
adamc@120
|
165 for (; *s; s++) {
|
adamc@120
|
166 char c = *s;
|
adamc@120
|
167
|
adamc@120
|
168 if (c == ' ')
|
adamc@120
|
169 lw_writec_unsafe(ctx, '+');
|
adamc@120
|
170 else if (isalnum(c))
|
adamc@120
|
171 lw_writec_unsafe(ctx, c);
|
adamc@120
|
172 else {
|
adamc@120
|
173 sprintf(ctx->page_front, "%%%02X", c);
|
adamc@120
|
174 ctx->page_front += 3;
|
adamc@120
|
175 }
|
adamc@120
|
176 }
|
adamc@120
|
177 }
|
adamc@120
|
178
|
adamc@120
|
179
|
adamc@120
|
180 lw_Basis_int lw_unurlifyInt(char **s) {
|
adamc@120
|
181 char *new_s = strchr(*s, '/');
|
adamc@120
|
182 int r;
|
adamc@120
|
183
|
adamc@120
|
184 if (new_s)
|
adamc@120
|
185 *new_s++ = 0;
|
adamc@120
|
186 else
|
adamc@120
|
187 new_s = strchr(*s, 0);
|
adamc@120
|
188
|
adamc@120
|
189 r = atoi(*s);
|
adamc@120
|
190 *s = new_s;
|
adamc@120
|
191 return r;
|
adamc@120
|
192 }
|
adamc@120
|
193
|
adamc@120
|
194 lw_Basis_float lw_unurlifyFloat(char **s) {
|
adamc@120
|
195 char *new_s = strchr(*s, '/');
|
adamc@120
|
196 int r;
|
adamc@120
|
197
|
adamc@120
|
198 if (new_s)
|
adamc@120
|
199 *new_s++ = 0;
|
adamc@120
|
200 else
|
adamc@120
|
201 new_s = strchr(*s, 0);
|
adamc@120
|
202
|
adamc@120
|
203 r = atof(*s);
|
adamc@120
|
204 *s = new_s;
|
adamc@120
|
205 return r;
|
adamc@120
|
206 }
|
adamc@120
|
207
|
adamc@120
|
208 lw_Basis_string lw_unurlifyString(char **s) {
|
adamc@120
|
209 return "";
|
adamc@120
|
210 }
|
adamc@135
|
211
|
adamc@135
|
212
|
adamc@135
|
213 char *lw_Basis_htmlifyString(lw_Basis_string s) {
|
adamc@135
|
214 return "";
|
adamc@135
|
215 }
|
adamc@135
|
216
|
adamc@135
|
217 void lw_Basis_htmlifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@135
|
218 lw_check(ctx, strlen(s) * 5);
|
adamc@135
|
219
|
adamc@135
|
220 for (; *s; s++) {
|
adamc@135
|
221 char c = *s;
|
adamc@135
|
222
|
adamc@135
|
223 switch (c) {
|
adamc@135
|
224 case '<':
|
adamc@135
|
225 lw_write_unsafe(ctx, "<");
|
adamc@135
|
226 break;
|
adamc@135
|
227 case '&':
|
adamc@135
|
228 lw_write_unsafe(ctx, "&");
|
adamc@135
|
229 break;
|
adamc@135
|
230 default:
|
adamc@135
|
231 if (isprint(c))
|
adamc@135
|
232 lw_writec_unsafe(ctx, c);
|
adamc@135
|
233 else {
|
adamc@135
|
234 lw_write_unsafe(ctx, "&#");
|
adamc@135
|
235 lw_Basis_attrifyInt_w_unsafe(ctx, c);
|
adamc@135
|
236 lw_writec_unsafe(ctx, ';');
|
adamc@135
|
237 }
|
adamc@135
|
238 }
|
adamc@135
|
239 }
|
adamc@135
|
240 }
|