-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdoc.c
More file actions
86 lines (63 loc) · 1.64 KB
/
doc.c
File metadata and controls
86 lines (63 loc) · 1.64 KB
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
#include <assert.h>
#include <stdlib.h>
#include <uv.h>
#include "code.h"
#include "doc.h"
struct doc
{
int refcnt;
uv_buf_t html5[4];
struct doc *prev;
struct doc *next;
char internal[30];
int gen;
};
#define HEADERS \
"HTTP/1.1 200 OK\r\n" \
"Connection: close\r\n" \
"Content-Type: text/html\r\n" \
"Content-Length: "
enum code doc_add(struct doc **previous, char const *html5, size_t len, int gen)
{
if (*previous != NULL && (*previous)->gen > gen)
return CODE_OLD;
struct doc *latest = malloc(sizeof (*latest));
if (NULL == latest)
return CODE_ENOMEM;
*latest = (struct doc)
{
.refcnt = 0,
.html5 = {
[0] = {.base = HEADERS , .len = sizeof (HEADERS) - 1},
[2] = {.base = "\r\n\r\n" , .len = 4 },
[3] = {.base = (char *)html5, .len = len },
},
.prev = *previous,
.next = NULL,
};
int ndigit = snprintf(latest->internal, sizeof (latest->internal), "%zu", len);
latest->html5[1].base = latest->internal;
latest->html5[1].len = ndigit;
*previous = latest;
return CODE_OKAY;
}
uv_buf_t * doc_get(struct doc *latest)
{
latest->refcnt++;
return latest->html5;
}
void doc_free(struct doc *it)
{
it->refcnt--;
assert(it->refcnt >= 0);
if (it->next != NULL) for (struct doc *curr = it; curr != NULL && !curr->refcnt; )
{
struct doc *prev = curr->prev;
curr->next->prev = curr->prev;
curr->prev->next = curr->next;
free(curr->html5);
free(curr);
curr = prev;
}
}
// We should unit test.