Skip to content

Commit bef11bb

Browse files
committed
improved parser
1 parent 99a2307 commit bef11bb

File tree

2 files changed

+175
-119
lines changed

2 files changed

+175
-119
lines changed

JSCDebugger/http_state.c

Lines changed: 141 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class ParserDelegate
2727

2828
extern "C" {
2929

30-
int parseHeaders(char *buffer, int length, ParserDelegate *delegate);
30+
int parseHeaders(int file, ParserDelegate *delegate);
3131

3232

3333
#line 74 "http_state.rl"
@@ -40,6 +40,47 @@ static const char _http_simple_actions[] = {
4040
3, 1, 4, 1, 5, 1, 6
4141
};
4242

43+
static const char _http_simple_key_offsets[] = {
44+
0, 0, 1, 8, 10, 13, 17, 18,
45+
21
46+
};
47+
48+
static const char _http_simple_trans_keys[] = {
49+
10, 32, 45, 58, 65, 90, 97, 122,
50+
32, 58, 32, 33, 126, 13, 32, 33,
51+
126, 10, 13, 32, 126, 13, 45, 65,
52+
90, 97, 122, 0
53+
};
54+
55+
static const char _http_simple_single_lengths[] = {
56+
0, 1, 3, 2, 1, 2, 1, 1,
57+
2
58+
};
59+
60+
static const char _http_simple_range_lengths[] = {
61+
0, 0, 2, 0, 1, 1, 0, 1,
62+
2
63+
};
64+
65+
static const char _http_simple_index_offsets[] = {
66+
0, 0, 2, 8, 11, 14, 18, 20,
67+
23
68+
};
69+
70+
static const char _http_simple_trans_targs[] = {
71+
8, 0, 3, 2, 4, 2, 2, 0,
72+
3, 4, 0, 5, 7, 0, 6, 5,
73+
7, 0, 8, 0, 6, 7, 0, 1,
74+
2, 2, 2, 0, 0
75+
};
76+
77+
static const char _http_simple_trans_actions[] = {
78+
13, 0, 1, 0, 1, 0, 0, 0,
79+
0, 0, 0, 5, 5, 0, 3, 5,
80+
5, 0, 11, 0, 3, 0, 0, 0,
81+
5, 5, 5, 0, 0
82+
};
83+
4384
static const char _http_simple_to_state_actions[] = {
4485
0, 0, 0, 0, 0, 0, 0, 0,
4586
7
@@ -59,7 +100,7 @@ static const int http_simple_en_main = 8;
59100

60101
#line 77 "http_state.rl"
61102

62-
int parseHeaders(char *buffer, int length, ParserDelegate *delegate)
103+
int parseHeaders(int file, ParserDelegate *delegate)
63104
{
64105
// machine state
65106
int cs, act, done = 0;
@@ -69,7 +110,7 @@ int parseHeaders(char *buffer, int length, ParserDelegate *delegate)
69110
char *myTs;
70111

71112

72-
#line 73 "http_state.c"
113+
#line 114 "http_state.c"
73114
{
74115
cs = http_simple_start;
75116
ts = 0;
@@ -79,14 +120,26 @@ int parseHeaders(char *buffer, int length, ParserDelegate *delegate)
79120

80121
#line 88 "http_state.rl"
81122

123+
#define READ_CHUNK_SIZE 2
124+
int bufferSize = READ_CHUNK_SIZE;
125+
char *buffer = (char *)calloc(bufferSize + 1, 1);
126+
char *p = buffer;
82127
while (!done) {
83-
char *p = buffer, *pe = (buffer + length);
128+
ssize_t readBytes = read(file, p, READ_CHUNK_SIZE);
129+
if (readBytes <= 0) {
130+
printf("EOF!?\n");
131+
return -1;
132+
}
133+
char *pe = (p + readBytes);
84134

85135

86-
#line 87 "http_state.c"
136+
#line 137 "http_state.c"
87137
{
138+
int _klen;
139+
unsigned int _trans;
88140
const char *_acts;
89141
unsigned int _nacts;
142+
const char *_keys;
90143

91144
if ( p == pe )
92145
goto _test_eof;
@@ -101,97 +154,70 @@ int parseHeaders(char *buffer, int length, ParserDelegate *delegate)
101154
#line 1 "NONE"
102155
{ts = p;}
103156
break;
104-
#line 105 "http_state.c"
157+
#line 158 "http_state.c"
105158
}
106159
}
107160

108-
switch ( cs ) {
109-
case 8:
110-
switch( (*p) ) {
111-
case 13: goto tr12;
112-
case 45: goto tr13;
113-
}
114-
if ( (*p) > 90 ) {
115-
if ( 97 <= (*p) && (*p) <= 122 )
116-
goto tr13;
117-
} else if ( (*p) >= 65 )
118-
goto tr13;
119-
goto tr1;
120-
case 0:
121-
goto _out;
122-
case 1:
123-
if ( (*p) == 10 )
124-
goto tr0;
125-
goto tr1;
126-
case 2:
127-
switch( (*p) ) {
128-
case 32: goto tr2;
129-
case 45: goto tr3;
130-
case 58: goto tr4;
131-
}
132-
if ( (*p) > 90 ) {
133-
if ( 97 <= (*p) && (*p) <= 122 )
134-
goto tr3;
135-
} else if ( (*p) >= 65 )
136-
goto tr3;
137-
goto tr1;
138-
case 3:
139-
switch( (*p) ) {
140-
case 32: goto tr5;
141-
case 58: goto tr6;
142-
}
143-
goto tr1;
144-
case 4:
145-
if ( (*p) == 32 )
146-
goto tr7;
147-
if ( 33 <= (*p) && (*p) <= 126 )
148-
goto tr8;
149-
goto tr1;
150-
case 5:
151-
switch( (*p) ) {
152-
case 13: goto tr9;
153-
case 32: goto tr7;
161+
_keys = _http_simple_trans_keys + _http_simple_key_offsets[cs];
162+
_trans = _http_simple_index_offsets[cs];
163+
164+
_klen = _http_simple_single_lengths[cs];
165+
if ( _klen > 0 ) {
166+
const char *_lower = _keys;
167+
const char *_mid;
168+
const char *_upper = _keys + _klen - 1;
169+
while (1) {
170+
if ( _upper < _lower )
171+
break;
172+
173+
_mid = _lower + ((_upper-_lower) >> 1);
174+
if ( (*p) < *_mid )
175+
_upper = _mid - 1;
176+
else if ( (*p) > *_mid )
177+
_lower = _mid + 1;
178+
else {
179+
_trans += (unsigned int)(_mid - _keys);
180+
goto _match;
181+
}
182+
}
183+
_keys += _klen;
184+
_trans += _klen;
154185
}
155-
if ( 33 <= (*p) && (*p) <= 126 )
156-
goto tr8;
157-
goto tr1;
158-
case 6:
159-
if ( (*p) == 10 )
160-
goto tr10;
161-
goto tr1;
162-
case 7:
163-
if ( (*p) == 13 )
164-
goto tr9;
165-
if ( 32 <= (*p) && (*p) <= 126 )
166-
goto tr11;
167-
goto tr1;
186+
187+
_klen = _http_simple_range_lengths[cs];
188+
if ( _klen > 0 ) {
189+
const char *_lower = _keys;
190+
const char *_mid;
191+
const char *_upper = _keys + (_klen<<1) - 2;
192+
while (1) {
193+
if ( _upper < _lower )
194+
break;
195+
196+
_mid = _lower + (((_upper-_lower) >> 1) & ~1);
197+
if ( (*p) < _mid[0] )
198+
_upper = _mid - 2;
199+
else if ( (*p) > _mid[1] )
200+
_lower = _mid + 2;
201+
else {
202+
_trans += (unsigned int)((_mid - _keys)>>1);
203+
goto _match;
204+
}
205+
}
206+
_trans += _klen;
168207
}
169208

170-
tr1: cs = 0; goto _again;
171-
tr12: cs = 1; goto _again;
172-
tr3: cs = 2; goto _again;
173-
tr13: cs = 2; goto f2;
174-
tr5: cs = 3; goto _again;
175-
tr2: cs = 3; goto f1;
176-
tr6: cs = 4; goto _again;
177-
tr4: cs = 4; goto f1;
178-
tr7: cs = 5; goto f2;
179-
tr9: cs = 6; goto f3;
180-
tr11: cs = 7; goto _again;
181-
tr8: cs = 7; goto f2;
182-
tr0: cs = 8; goto f0;
183-
tr10: cs = 8; goto f4;
184-
185-
f1: _acts = _http_simple_actions + 1; goto execFuncs;
186-
f3: _acts = _http_simple_actions + 3; goto execFuncs;
187-
f2: _acts = _http_simple_actions + 5; goto execFuncs;
188-
f4: _acts = _http_simple_actions + 11; goto execFuncs;
189-
f0: _acts = _http_simple_actions + 13; goto execFuncs;
190-
191-
execFuncs:
192-
_nacts = *_acts++;
193-
while ( _nacts-- > 0 ) {
194-
switch ( *_acts++ ) {
209+
_match:
210+
cs = _http_simple_trans_targs[_trans];
211+
212+
if ( _http_simple_trans_actions[_trans] == 0 )
213+
goto _again;
214+
215+
_acts = _http_simple_actions + _http_simple_trans_actions[_trans];
216+
_nacts = (unsigned int) *_acts++;
217+
while ( _nacts-- > 0 )
218+
{
219+
switch ( *_acts++ )
220+
{
195221
case 0:
196222
#line 33 "http_state.rl"
197223
{
@@ -232,10 +258,9 @@ case 7:
232258
{p++; goto _out; }
233259
}}
234260
break;
235-
#line 236 "http_state.c"
261+
#line 262 "http_state.c"
236262
}
237263
}
238-
goto _again;
239264

240265
_again:
241266
_acts = _http_simple_actions + _http_simple_to_state_actions[cs];
@@ -246,7 +271,7 @@ case 7:
246271
#line 1 "NONE"
247272
{ts = 0;}
248273
break;
249-
#line 250 "http_state.c"
274+
#line 275 "http_state.c"
250275
}
251276
}
252277

@@ -258,21 +283,29 @@ case 7:
258283
_out: {}
259284
}
260285

261-
#line 93 "http_state.rl"
286+
#line 102 "http_state.rl"
262287

263288
if (cs == http_simple_error) {
264-
printf("error state\n");
265-
return -1;
289+
printf("error parsing\n");
266290
}
267-
if (!done && p == pe) {
268-
// EOF
269-
printf("EOF??");
270-
return -1;
291+
if (!done) {
292+
bufferSize *= 2;
293+
char *newBuffer = (char *)realloc(buffer, bufferSize + 1);
294+
if (!newBuffer) {
295+
free(buffer);
296+
printf("OUT OF MEMORY\n");
297+
return 0;
298+
}
299+
if (newBuffer != buffer) {
300+
myTs = newBuffer + (myTs - buffer);
301+
p = newBuffer + (p - buffer);
302+
buffer = newBuffer;
303+
}
271304
}
272-
273305
}
306+
free(buffer);
274307
// return how many bytes we actually parsed
275-
return (te - buffer);
308+
return (p - buffer);
276309
}
277310

278311
#ifdef DEBUG_HTTP
@@ -292,11 +325,14 @@ class SomeDelegate : public ParserDelegate
292325

293326
int main(int argc, char **argv) {
294327
if (argc > 0) {
295-
char *buff = (char *)malloc(2048);
328+
char *buff = (char *)calloc(2048, 1);
296329
SomeDelegate *delegate = new SomeDelegate();
297330
int f = open(argv[1], O_RDONLY);
298-
int readBytes = read(f, buff, 2048);
299-
parseHeaders(buff, readBytes, delegate);
331+
int parsedBytes = parseHeaders(f, delegate);
332+
if (parsedBytes > 0) {
333+
read(f, buff, 2048);
334+
printf("body:\n%s", buff);
335+
}
300336
close(f);
301337
free(buff);
302338
delete delegate;

0 commit comments

Comments
 (0)