1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "types.h"
lw_unit lw_unit_v = {};
struct lw_context {
char *page, *page_front, *page_back;
};
lw_context lw_init(int page_len) {
lw_context ctx = malloc(sizeof(struct lw_context));
ctx->page_front = ctx->page = malloc(page_len);
ctx->page_back = ctx->page_front + page_len;
return ctx;
}
void lw_free(lw_context ctx) {
free(ctx->page);
}
int lw_really_send(int sock, const void *buf, ssize_t len) {
while (len > 0) {
ssize_t n = send(sock, buf, len, 0);
if (n < 0)
return n;
buf += n;
len -= n;
}
return 0;
}
int lw_send(lw_context ctx, int sock) {
return lw_really_send(sock, ctx->page, ctx->page_front - ctx->page);
}
static void lw_check(lw_context ctx, size_t extra) {
size_t desired = ctx->page_back - ctx->page_front + extra, next;
char *new_page;
for (next = ctx->page_back - ctx->page_front; next < desired; next *= 2);
new_page = realloc(ctx->page, next);
ctx->page_front = new_page + (ctx->page_front - ctx->page);
ctx->page_back = new_page + (ctx->page_back - ctx->page);
ctx->page = new_page;
}
static void lw_writec_unsafe(lw_context ctx, char c) {
*(ctx->page_front)++ = c;
}
void lw_writec(lw_context ctx, char c) {
lw_check(ctx, 1);
lw_writec_unsafe(ctx, c);
}
static void lw_write_unsafe(lw_context ctx, const char* s) {
int len = strlen(s);
memcpy(ctx->page_front, s, len);
ctx->page_front += len;
}
void lw_write(lw_context ctx, const char* s) {
lw_check(ctx, strlen(s));
lw_write_unsafe(ctx, s);
}
char *lw_Basis_attrifyInt(lw_Basis_int n) {
return "0";
}
char *lw_Basis_attrifyFloat(lw_Basis_float n) {
return "0.0";
}
char *lw_Basis_attrifyString(lw_Basis_string s) {
return "";
}
#define INTS_MAX 50
#define FLOATS_MAX 100
static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
int len;
sprintf(ctx->page_front, "%d%n", n, &len);
ctx->page_front += len;
}
void lw_Basis_attrifyInt_w(lw_context ctx, lw_Basis_int n) {
lw_check(ctx, INTS_MAX);
lw_Basis_attrifyInt_w_unsafe(ctx, n);
}
void lw_Basis_attrifyFloat_w(lw_context ctx, lw_Basis_float n) {
int len;
lw_check(ctx, FLOATS_MAX);
sprintf(ctx->page_front, "%g%n", n, &len);
ctx->page_front += len;
}
void lw_Basis_attrifyString_w(lw_context ctx, lw_Basis_string s) {
lw_check(ctx, strlen(s) * 6);
for (; *s; s++) {
char c = *s;
if (c == '"')
lw_write_unsafe(ctx, """);
else if (isprint(c))
lw_writec_unsafe(ctx, c);
else {
lw_write_unsafe(ctx, "&#");
lw_Basis_attrifyInt_w_unsafe(ctx, c);
lw_writec_unsafe(ctx, ';');
}
}
}
|