This repository has been archived by the owner on Jun 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathxump_headers.icl
122 lines (105 loc) · 3.57 KB
/
xump_headers.icl
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
<?xml?>
<!--
Copyright (c) 1996-2009 iMatix Corporation
This file is licensed under the GPL as follows:
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
For information on alternative licensing for OEMs, please contact
iMatix Corporation.
-->
<class
name = "xump_headers"
comment = "Xump headers class"
script = "icl_gen"
license = "gpl"
opaque = "1"
>
<doc>
The xump_headers class implements a environ-style headers block.
</doc>
<inherit class = "icl_object">
<option name = "alloc" value = "cache" />
<option name = "links" value = "1" />
</inherit>
<import class = "xump" />
<context>
icl_longstr_t
*longstr; // Data for headers table
</context>
<method name = "new">
// Constructor is deliberately empty
</method>
<method name = "destroy">
icl_longstr_destroy (&self->longstr);
</method>
<method name = "set" template = "function">
<doc>
Sets a header value.
</doc>
<argument name = "name" type = "char *" />
<argument name = "value" type = "char *" />
//
// Name may not contain '=', that's a fail
assert (strchr (name, '=') == NULL);
if (self->longstr) {
// Look for existing value, squash if any
icl_shortstr_t
name_key;
char
*found;
icl_shortstr_fmt (name_key, "%s=", name);
found = (char *) icl_longstr_find (
self->longstr, 0, (byte *) name_key, strlen (name_key));
if (found) {
byte
*next = (byte *) strchr (found, 0) + 1;
self->longstr->cur_size -= (next - self->longstr->data);
memcpy (found, next, self->longstr->cur_size);
}
// String ends in double null, we'll quash the last one
if (self->longstr->cur_size)
self->longstr->cur_size--;
}
else
self->longstr = icl_longstr_new (NULL, 1024);
icl_longstr_cat (self->longstr, "%s=%s%c%c", name, value, 0, 0);
</method>
<method name = "get" return = "value">
<doc>
Returns value of specified header; if not found returns an empty string.
</doc>
<argument name = "self" type = "$(selftype) *" />
<argument name = "name" type = "char *" />
<declare name = "value" type = "char *" />
value = ""; // Default is empty string
if (self->longstr) {
icl_shortstr_t
name_key;
char
*found;
icl_shortstr_fmt (name_key, "%s=", name);
found = (char *) icl_longstr_find (
self->longstr, 0, (byte *) name_key, strlen (name_key));
if (found)
value = found + strlen (name_key);
}
</method>
<method name = "selftest">
xump_headers_t
*headers;
headers = xump_headers_new ();
xump_headers_set (headers, "a", "one");
xump_headers_set (headers, "b", "two");
xump_headers_set (headers, "c", "three");
xump_headers_set (headers, "a", "value");
assert (streq (xump_headers_get (headers, "a"), "value"));
assert (streq (xump_headers_get (headers, "z"), ""));
xump_headers_destroy (&headers);
</method>
</class>