Mercurial > urweb
changeset 136:133fa2d51bb4
Dynamic arena allocation
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 17 Jul 2008 14:18:57 -0400 |
parents | b1cfe49ce692 |
children | 4ffdbf429e8d |
files | include/lacweb.h src/c/driver.c src/c/lacweb.c src/cjr_print.sml tests/cdataL.lac |
diffstat | 5 files changed, 142 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/include/lacweb.h Thu Jul 17 13:33:56 2008 -0400 +++ b/include/lacweb.h Thu Jul 17 14:18:57 2008 -0400 @@ -6,19 +6,20 @@ extern lw_unit lw_unit_v; -lw_context lw_init(int page_len); +lw_context lw_init(size_t page_len, size_t heap_len); void lw_free(lw_context); +void *lw_malloc(lw_context, size_t); int lw_send(lw_context, int sock); void lw_write(lw_context, const char*); -char *lw_Basis_htmlifyString(lw_Basis_string); +char *lw_Basis_htmlifyString(lw_context, lw_Basis_string); void lw_Basis_htmlifyString_w(lw_context, lw_Basis_string); -char *lw_Basis_attrifyInt(lw_Basis_int); -char *lw_Basis_attrifyFloat(lw_Basis_float); -char *lw_Basis_attrifyString(lw_Basis_string); +char *lw_Basis_attrifyInt(lw_context, lw_Basis_int); +char *lw_Basis_attrifyFloat(lw_context, lw_Basis_float); +char *lw_Basis_attrifyString(lw_context, lw_Basis_string); void lw_Basis_attrifyInt_w(lw_context, lw_Basis_int); void lw_Basis_attrifyFloat_w(lw_context, lw_Basis_float); @@ -35,4 +36,4 @@ lw_Basis_int lw_unurlifyInt(char **); lw_Basis_float lw_unurlifyFloat(char **); -lw_Basis_string lw_unurlifyString(char **); +lw_Basis_string lw_unurlifyString(lw_context, char **);
--- a/src/c/driver.c Thu Jul 17 13:33:56 2008 -0400 +++ b/src/c/driver.c Thu Jul 17 14:18:57 2008 -0400 @@ -72,7 +72,7 @@ printf("Serving URI %s....\n", path); - ctx = lw_init(1024); + ctx = lw_init(1024, 1024); lw_write (ctx, "HTTP/1.1 200 OK\r\n"); lw_write(ctx, "Content-type: text/html\r\n\r\n"); lw_write(ctx, "<html>"); @@ -81,6 +81,7 @@ lw_send(ctx, sock); + lw_free(ctx); printf("Done with client.\n\n"); close(sock); return;
--- a/src/c/lacweb.c Thu Jul 17 13:33:56 2008 -0400 +++ b/src/c/lacweb.c Thu Jul 17 14:18:57 2008 -0400 @@ -2,6 +2,7 @@ #include <stdio.h> #include <string.h> #include <ctype.h> +#include <assert.h> #include "types.h" @@ -9,17 +10,54 @@ struct lw_context { char *page, *page_front, *page_back; + char *heap, *heap_front, *heap_back; }; -lw_context lw_init(int page_len) { +lw_context lw_init(size_t page_len, size_t heap_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; + + ctx->heap_front = ctx->heap = malloc(heap_len); + ctx->heap_back = ctx->heap_front + heap_len; + return ctx; } void lw_free(lw_context ctx) { free(ctx->page); + free(ctx->heap); + free(ctx); +} + +static void lw_check_heap(lw_context ctx, size_t extra) { + if (ctx->heap_back - ctx->heap_front < extra) { + size_t desired = ctx->heap_back - ctx->heap_front + extra, next; + char *new_heap; + + for (next = ctx->heap_back - ctx->heap_front; next < desired; next *= 2); + + new_heap = realloc(ctx->heap, next); + + if (new_heap != ctx->heap) { + ctx->heap = new_heap; + puts("Couldn't get contiguous chunk"); + exit(1); + } + + ctx->heap_back = new_heap + next; + } +} + +void *lw_malloc(lw_context ctx, size_t len) { + void *result; + + lw_check_heap(ctx, len); + + result = ctx->heap_front; + ctx->heap_front += len; + return result; } int lw_really_send(int sock, const void *buf, ssize_t len) { @@ -73,21 +111,59 @@ } -char *lw_Basis_attrifyInt(lw_Basis_int n) { - return "0"; +#define INTS_MAX 50 +#define FLOATS_MAX 100 + +char *lw_Basis_attrifyInt(lw_context ctx, lw_Basis_int n) { + char *result; + int len; + lw_check_heap(ctx, INTS_MAX); + result = ctx->heap_front; + sprintf(result, "%d%n", n, &len); + ctx->heap_front += len; + return result; } -char *lw_Basis_attrifyFloat(lw_Basis_float n) { - return "0.0"; +char *lw_Basis_attrifyFloat(lw_context ctx, lw_Basis_float n) { + char *result; + int len; + lw_check_heap(ctx, INTS_MAX); + result = ctx->heap_front; + sprintf(result, "%g%n", n, &len); + ctx->heap_front += len; + return result; } -char *lw_Basis_attrifyString(lw_Basis_string s) { - return ""; +char *lw_Basis_attrifyString(lw_context ctx, lw_Basis_string s) { + int len = strlen(s); + char *result, *p; + lw_check_heap(ctx, len * 6); + + result = p = ctx->heap_front; + + for (; *s; s++) { + char c = *s; + + if (c == '"') { + strcpy(p, """); + p += 6; + } else if (c == '&') { + strcpy(p, "&"); + p += 5; + } + else if (isprint(c)) + *p++ = c; + else { + int len2; + sprintf(p, "&#%d;%n", c, &len2); + p += len2; + } + } + + ctx->heap_front = p; + return result; } -#define INTS_MAX 50 -#define FLOATS_MAX 100 - static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) { int len; @@ -116,6 +192,8 @@ if (c == '"') lw_write_unsafe(ctx, """); + else if (c == '&') + lw_write_unsafe(ctx, "&"); else if (isprint(c)) lw_writec_unsafe(ctx, c); else { @@ -205,12 +283,45 @@ return r; } -lw_Basis_string lw_unurlifyString(char **s) { - return ""; +lw_Basis_string lw_unurlifyString(lw_context ctx, char **s) { + char *new_s = strchr(*s, '/'); + char *r, *s1, *s2; + int len, n; + + if (new_s) + *new_s++ = 0; + else + new_s = strchr(*s, 0); + + len = strlen(*s); + lw_check_heap(ctx, len + 1); + + r = ctx->heap_front; + for (s1 = r, s2 = *s; *s2; ++s1, ++s2) { + char c = *s2; + + switch (c) { + case '+': + *s1 = ' '; + break; + case '%': + assert(s2 + 2 < new_s); + sscanf(s2+1, "%02X", &n); + *s1 = n; + s2 += 2; + break; + default: + *s1 = c; + } + } + *s1++ = 0; + ctx->heap_front = s1; + *s = new_s; + return r; } -char *lw_Basis_htmlifyString(lw_Basis_string s) { +char *lw_Basis_htmlifyString(lw_context ctx, lw_Basis_string s) { return ""; }
--- a/src/cjr_print.sml Thu Jul 17 13:33:56 2008 -0400 +++ b/src/cjr_print.sml Thu Jul 17 14:18:57 2008 -0400 @@ -212,7 +212,7 @@ case t of TFfi ("Basis", "int") => string "lw_unurlifyInt(&request)" | TFfi ("Basis", "float") => string "lw_unurlifyFloat(&request)" - | TFfi ("Basis", "string") => string "lw_unurlifyString(&request)" + | TFfi ("Basis", "string") => string "lw_unurlifyString(ctx, &request)" | TRecord 0 => string "lw_unit_v"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/cdataL.lac Thu Jul 17 14:18:57 2008 -0400 @@ -0,0 +1,8 @@ +val subpage = fn s => <html><body> + <h1>{cdata s}</h1> +</body></html> + +val main = fn () => <html><body> + <li> <a link={subpage "<Hi."}>Door #1</a></li> + <li> <a link={subpage "Bye."}>Door #2</a></li> +</body></html>