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 }
|