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@106
|
75 char *lw_Basis_attrifyInt(lw_Basis_int n) {
|
adamc@106
|
76 return "0";
|
adamc@106
|
77 }
|
adamc@106
|
78
|
adamc@106
|
79 char *lw_Basis_attrifyFloat(lw_Basis_float n) {
|
adamc@106
|
80 return "0.0";
|
adamc@106
|
81 }
|
adamc@106
|
82
|
adamc@106
|
83 char *lw_Basis_attrifyString(lw_Basis_string s) {
|
adamc@106
|
84 return "";
|
adamc@106
|
85 }
|
adamc@106
|
86
|
adamc@117
|
87 #define INTS_MAX 50
|
adamc@117
|
88 #define FLOATS_MAX 100
|
adamc@117
|
89
|
adamc@117
|
90 static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
|
adamc@117
|
91 int len;
|
adamc@117
|
92
|
adamc@117
|
93 sprintf(ctx->page_front, "%d%n", n, &len);
|
adamc@117
|
94 ctx->page_front += len;
|
adamc@106
|
95 }
|
adamc@106
|
96
|
adamc@117
|
97 void lw_Basis_attrifyInt_w(lw_context ctx, lw_Basis_int n) {
|
adamc@117
|
98 lw_check(ctx, INTS_MAX);
|
adamc@117
|
99 lw_Basis_attrifyInt_w_unsafe(ctx, n);
|
adamc@106
|
100 }
|
adamc@106
|
101
|
adamc@117
|
102 void lw_Basis_attrifyFloat_w(lw_context ctx, lw_Basis_float n) {
|
adamc@117
|
103 int len;
|
adamc@117
|
104
|
adamc@117
|
105 lw_check(ctx, FLOATS_MAX);
|
adamc@117
|
106 sprintf(ctx->page_front, "%g%n", n, &len);
|
adamc@117
|
107 ctx->page_front += len;
|
adamc@117
|
108 }
|
adamc@117
|
109
|
adamc@117
|
110 void lw_Basis_attrifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@117
|
111 lw_check(ctx, strlen(s) * 6);
|
adamc@117
|
112
|
adamc@106
|
113 for (; *s; s++) {
|
adamc@106
|
114 char c = *s;
|
adamc@106
|
115
|
adamc@106
|
116 if (c == '"')
|
adamc@117
|
117 lw_write_unsafe(ctx, """);
|
adamc@106
|
118 else if (isprint(c))
|
adamc@117
|
119 lw_writec_unsafe(ctx, c);
|
adamc@106
|
120 else {
|
adamc@117
|
121 lw_write_unsafe(ctx, "&#");
|
adamc@117
|
122 lw_Basis_attrifyInt_w_unsafe(ctx, c);
|
adamc@117
|
123 lw_writec_unsafe(ctx, ';');
|
adamc@106
|
124 }
|
adamc@106
|
125 }
|
adamc@106
|
126 }
|
adamc@120
|
127
|
adamc@120
|
128
|
adamc@120
|
129 char *lw_Basis_urlifyInt(lw_Basis_int n) {
|
adamc@120
|
130 return "0";
|
adamc@120
|
131 }
|
adamc@120
|
132
|
adamc@120
|
133 char *lw_Basis_urlifyFloat(lw_Basis_float n) {
|
adamc@120
|
134 return "0.0";
|
adamc@120
|
135 }
|
adamc@120
|
136
|
adamc@120
|
137 char *lw_Basis_urlifyString(lw_Basis_string s) {
|
adamc@120
|
138 return "";
|
adamc@120
|
139 }
|
adamc@120
|
140
|
adamc@120
|
141 static void lw_Basis_urlifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
|
adamc@120
|
142 int len;
|
adamc@120
|
143
|
adamc@120
|
144 sprintf(ctx->page_front, "%d%n", n, &len);
|
adamc@120
|
145 ctx->page_front += len;
|
adamc@120
|
146 }
|
adamc@120
|
147
|
adamc@120
|
148 void lw_Basis_urlifyInt_w(lw_context ctx, lw_Basis_int n) {
|
adamc@120
|
149 lw_check(ctx, INTS_MAX);
|
adamc@120
|
150 lw_Basis_urlifyInt_w_unsafe(ctx, n);
|
adamc@120
|
151 }
|
adamc@120
|
152
|
adamc@120
|
153 void lw_Basis_urlifyFloat_w(lw_context ctx, lw_Basis_float n) {
|
adamc@120
|
154 int len;
|
adamc@120
|
155
|
adamc@120
|
156 lw_check(ctx, FLOATS_MAX);
|
adamc@120
|
157 sprintf(ctx->page_front, "%g%n", n, &len);
|
adamc@120
|
158 ctx->page_front += len;
|
adamc@120
|
159 }
|
adamc@120
|
160
|
adamc@120
|
161 void lw_Basis_urlifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@120
|
162 lw_check(ctx, strlen(s) * 3);
|
adamc@120
|
163
|
adamc@120
|
164 for (; *s; s++) {
|
adamc@120
|
165 char c = *s;
|
adamc@120
|
166
|
adamc@120
|
167 if (c == ' ')
|
adamc@120
|
168 lw_writec_unsafe(ctx, '+');
|
adamc@120
|
169 else if (isalnum(c))
|
adamc@120
|
170 lw_writec_unsafe(ctx, c);
|
adamc@120
|
171 else {
|
adamc@120
|
172 sprintf(ctx->page_front, "%%%02X", c);
|
adamc@120
|
173 ctx->page_front += 3;
|
adamc@120
|
174 }
|
adamc@120
|
175 }
|
adamc@120
|
176 }
|
adamc@120
|
177
|
adamc@120
|
178
|
adamc@120
|
179 lw_Basis_int lw_unurlifyInt(char **s) {
|
adamc@120
|
180 char *new_s = strchr(*s, '/');
|
adamc@120
|
181 int r;
|
adamc@120
|
182
|
adamc@120
|
183 if (new_s)
|
adamc@120
|
184 *new_s++ = 0;
|
adamc@120
|
185 else
|
adamc@120
|
186 new_s = strchr(*s, 0);
|
adamc@120
|
187
|
adamc@120
|
188 r = atoi(*s);
|
adamc@120
|
189 *s = new_s;
|
adamc@120
|
190 return r;
|
adamc@120
|
191 }
|
adamc@120
|
192
|
adamc@120
|
193 lw_Basis_float lw_unurlifyFloat(char **s) {
|
adamc@120
|
194 char *new_s = strchr(*s, '/');
|
adamc@120
|
195 int r;
|
adamc@120
|
196
|
adamc@120
|
197 if (new_s)
|
adamc@120
|
198 *new_s++ = 0;
|
adamc@120
|
199 else
|
adamc@120
|
200 new_s = strchr(*s, 0);
|
adamc@120
|
201
|
adamc@120
|
202 r = atof(*s);
|
adamc@120
|
203 *s = new_s;
|
adamc@120
|
204 return r;
|
adamc@120
|
205 }
|
adamc@120
|
206
|
adamc@120
|
207 lw_Basis_string lw_unurlifyString(char **s) {
|
adamc@120
|
208 return "";
|
adamc@120
|
209 }
|