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