-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathh3prio.c
110 lines (97 loc) · 2.62 KB
/
h3prio.c
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
/* Parse HTTP/3 Priority Parameters
*
* See
* https://tools.ietf.org/html/draft-ietf-httpbis-priority-01
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ls-sfparser.h"
struct prio {
enum {
URG_SET = 1 << 0, /* True if `urgency' is set */
INC_SET = 1 << 1, /* True if `incremental' is set */
URG_NAME = 1 << 2, /* True if previous element dictionary name "u" */
INC_NAME = 1 << 3, /* True if previous element dictionary name "i" */
} flags;
unsigned urgency;
bool incremental;
};
static int
callback (void *user_data, enum ls_sf_dt type, char *str, size_t len, int off)
{
struct prio *const prio = user_data;
if (type == LS_SF_DT_NAME)
{
if (1 == len)
switch (str[0])
{
case 'u': prio->flags |= URG_NAME; return 0;
case 'i': prio->flags |= INC_NAME; return 0;
}
}
else if (prio->flags & URG_NAME)
{
if (type == LS_SF_DT_INTEGER)
{
prio->urgency = atoi(str);
if (prio->urgency <= 7)
prio->flags |= URG_SET;
else
{
printf("invalid value of urgency: %.*s\n", (int) len, str);
return -1;
}
}
else
{
printf("invalid type of urgency: %s\n", ls_sf_dt2str[type]);
return -1;
}
}
else if (prio->flags & INC_NAME)
{
if (type == LS_SF_DT_BOOLEAN)
{
prio->flags |= INC_SET;
prio->incremental = str[0] - '0';
}
else
{
printf("invalid type of incremental: %s\n", ls_sf_dt2str[type]);
return -1;
}
}
prio->flags &= ~(INC_NAME|URG_NAME);
return 0;
}
int
main (int argc, char **argv)
{
struct prio prio;
int ret;
if (argc != 2)
{
printf("Usage: %s 'HTTP/3 priority parameters'\n", argv[0]);
return 1;
}
memset(&prio, 0, sizeof(prio));
ret = ls_sf_parse(LS_SF_TLT_DICTIONARY, argv[1], strlen(argv[1]), callback,
&prio, NULL, 0);
if (ret == 0)
{
printf("parsing successful\n");
if (prio.flags & URG_SET)
printf("urgency: %u\n", prio.urgency);
else
printf("urgency: <not set>\n");
if (prio.flags & INC_SET)
printf("incremental: %i\n", (int) prio.incremental);
else
printf("incremental: <not set>\n");
}
else
printf("parsing failed\n");
return ret ? -1 : 0;
}