1 using System;
2 using System.Collections;
3 using System.Lex;
4 using System.Parsing;
5 using System.Net.Http;
6 using HttpTokens;
7
8
9
10 public static class HttpChunkHeaderParser
11 {
12 public static void Parse(HttpLexer& lexer, ulong* chunkSize, ChunkExtensionAdder* adder)
13 {
14 #if (DEBUG)
15 if (lexer.Log() != null)
16 {
17 lexer.Log()->WriteBeginRule(u"parse");
18 lexer.Log()->IncIndent();
19 }
20 #endif
21 ++lexer;
22 System.Lex.Span span = lexer.GetSpan();
23 Match match = ChunkHeader(lexer, chunkSize, adder);
24 if (match.hit)
25 {
26 if (*lexer == System.Lex.END_TOKEN)
27 {
28 return;
29 }
30 else
31 {
32 lexer.ThrowExpectationFailure(lexer.GetSpan(), GetEndTokenInfo());
33 }
34 }
35 else
36 {
37 lexer.ThrowExpectationFailure(span, u"ChunkHeader");
38 }
39 return;
40 }
41 public static Match ChunkHeader(HttpLexer& lexer, ulong* chunkSize, ChunkExtensionAdder* adder)
42 {
43 #if (DEBUG)
44 Span debugSpan;
45 bool writeToLog = lexer.Log() != null;
46 if (writeToLog)
47 {
48 debugSpan = lexer.GetSpan();
49 System.Lex.WriteBeginRuleToLog(lexer, u"ChunkHeader");
50 }
51 #endif
52 string s;
53 Match match(false);
54 Match* parentMatch0 = &match;
55 {
56 Match match(false);
57 Match* parentMatch1 = &match;
58 {
59 long pos = lexer.GetPos();
60 Match match(false);
61 Match* parentMatch2 = &match;
62 {
63 Match match(false);
64 Match* parentMatch3 = &match;
65 {
66 Match match(false);
67 Match* parentMatch4 = &match;
68 {
69 Match match(false);
70 Match* parentMatch5 = &match;
71 {
72 long save = lexer.GetPos();
73 Match match(false);
74 Match* parentMatch6 = &match;
75 {
76 long pos = lexer.GetPos();
77 Match match(false);
78 if (*lexer == DIGIT)
79 {
80 ++lexer;
81 match.hit = true;
82 }
83 if (match.hit)
84 {
85 s.Append(lexer.GetChar(pos));
86 }
87 *parentMatch6 = match;
88 }
89 *parentMatch5 = match;
90 if (!match.hit)
91 {
92 Match match(false);
93 Match* parentMatch7 = &match;
94 lexer.SetPos(save);
95 {
96 Match match(false);
97 Match* parentMatch8 = &match;
98 {
99 long pos = lexer.GetPos();
100 Match match(false);
101 if (*lexer == HEX)
102 {
103 ++lexer;
104 match.hit = true;
105 }
106 if (match.hit)
107 {
108 s.Append(lexer.GetChar(pos));
109 }
110 *parentMatch8 = match;
111 }
112 *parentMatch7 = match;
113 }
114 *parentMatch5 = match;
115 }
116 }
117 *parentMatch4 = match;
118 }
119 *parentMatch3 = match;
120 }
121 if (match.hit)
122 {
123 Match match(true);
124 Match* parentMatch9 = &match;
125 while (true)
126 {
127 long save = lexer.GetPos();
128 {
129 Match match(false);
130 Match* parentMatch10 = &match;
131 {
132 Match match(false);
133 Match* parentMatch11 = &match;
134 {
135 long save = lexer.GetPos();
136 Match match(false);
137 Match* parentMatch12 = &match;
138 {
139 long pos = lexer.GetPos();
140 Match match(false);
141 if (*lexer == DIGIT)
142 {
143 ++lexer;
144 match.hit = true;
145 }
146 if (match.hit)
147 {
148 s.Append(lexer.GetChar(pos));
149 }
150 *parentMatch12 = match;
151 }
152 *parentMatch11 = match;
153 if (!match.hit)
154 {
155 Match match(false);
156 Match* parentMatch13 = &match;
157 lexer.SetPos(save);
158 {
159 Match match(false);
160 Match* parentMatch14 = &match;
161 {
162 long pos = lexer.GetPos();
163 Match match(false);
164 if (*lexer == HEX)
165 {
166 ++lexer;
167 match.hit = true;
168 }
169 if (match.hit)
170 {
171 s.Append(lexer.GetChar(pos));
172 }
173 *parentMatch14 = match;
174 }
175 *parentMatch13 = match;
176 }
177 *parentMatch11 = match;
178 }
179 }
180 *parentMatch10 = match;
181 }
182 if (match.hit)
183 {
184 *parentMatch9 = match;
185 }
186 else
187 {
188 lexer.SetPos(save);
189 break;
190 }
191 }
192 }
193 }
194 *parentMatch2 = match;
195 }
196 if (match.hit)
197 {
198 *chunkSize = ParseHexULong(s);
199 }
200 *parentMatch1 = match;
201 }
202 *parentMatch0 = match;
203 }
204 if (match.hit)
205 {
206 Match match(false);
207 Match* parentMatch15 = &match;
208 {
209 Match match(true);
210 long save = lexer.GetPos();
211 Match* parentMatch16 = &match;
212 {
213 Match match = HttpChunkHeaderParser.ChunkExtensions(lexer, adder);
214 if (match.hit)
215 {
216 *parentMatch16 = match;
217 }
218 else
219 {
220 lexer.SetPos(save);
221 }
222 }
223 *parentMatch15 = match;
224 }
225 *parentMatch0 = match;
226 }
227 #if (DEBUG)
228 if (writeToLog)
229 {
230 if (match.hit)
231 {
232 System.Lex.WriteSuccessToLog(lexer, debugSpan, u"ChunkHeader");
233 }
234 else
235 {
236 System.Lex.WriteFailureToLog(lexer, u"ChunkHeader");
237 }
238 }
239 #endif
240 if (!match.hit)
241 {
242 match.value = null;
243 }
244 return match;
245 }
246 public static Match ChunkExtensions(HttpLexer& lexer, ChunkExtensionAdder* adder)
247 {
248 #if (DEBUG)
249 Span debugSpan;
250 bool writeToLog = lexer.Log() != null;
251 if (writeToLog)
252 {
253 debugSpan = lexer.GetSpan();
254 System.Lex.WriteBeginRuleToLog(lexer, u"ChunkExtensions");
255 }
256 #endif
257 UniquePtr<Value<string>> cn;
258 UniquePtr<Value<string>> cv;
259 Match match(true);
260 Match* parentMatch0 = &match;
261 {
262 while (true)
263 {
264 long save = lexer.GetPos();
265 {
266 Match match(false);
267 Match* parentMatch1 = &match;
268 {
269 Match match(false);
270 Match* parentMatch2 = &match;
271 {
272 Match match(false);
273 if (*lexer == SEMICOLON)
274 {
275 ++lexer;
276 match.hit = true;
277 }
278 *parentMatch2 = match;
279 }
280 if (match.hit)
281 {
282 Match match(false);
283 Match* parentMatch3 = &match;
284 {
285 Match match(false);
286 Match* parentMatch4 = &match;
287 {
288 long pos = lexer.GetPos();
289 Match match(false);
290 Match* parentMatch5 = &match;
291 {
292 Match match(false);
293 Match* parentMatch6 = &match;
294 {
295 Match match = HttpChunkHeaderParser.ChunkExtName(lexer);
296 cn.Reset(cast<Value<string>*>(match.value));
297 *parentMatch6 = match;
298 }
299 if (match.hit)
300 {
301 Match match(false);
302 Match* parentMatch7 = &match;
303 {
304 Match match(true);
305 long save = lexer.GetPos();
306 Match* parentMatch8 = &match;
307 {
308 Match match(false);
309 Match* parentMatch9 = &match;
310 {
311 Match match(false);
312 Match* parentMatch10 = &match;
313 {
314 Match match(false);
315 if (*lexer == 61)
316 {
317 ++lexer;
318 match.hit = true;
319 }
320 *parentMatch10 = match;
321 }
322 if (match.hit)
323 {
324 Match match(false);
325 Match* parentMatch11 = &match;
326 {
327 Match match = HttpChunkHeaderParser.ChunkExtVal(lexer);
328 cv.Reset(cast<Value<string>*>(match.value));
329 *parentMatch11 = match;
330 }
331 *parentMatch10 = match;
332 }
333 *parentMatch9 = match;
334 }
335 if (match.hit)
336 {
337 *parentMatch8 = match;
338 }
339 else
340 {
341 lexer.SetPos(save);
342 }
343 }
344 *parentMatch7 = match;
345 }
346 *parentMatch6 = match;
347 }
348 *parentMatch5 = match;
349 }
350 if (match.hit)
351 {
352 adder->AddChunkExtension(cn->value, cv->value);
353 }
354 *parentMatch4 = match;
355 }
356 *parentMatch3 = match;
357 }
358 *parentMatch2 = match;
359 }
360 *parentMatch1 = match;
361 }
362 if (match.hit)
363 {
364 *parentMatch0 = match;
365 }
366 else
367 {
368 lexer.SetPos(save);
369 break;
370 }
371 }
372 }
373 }
374 #if (DEBUG)
375 if (writeToLog)
376 {
377 if (match.hit)
378 {
379 System.Lex.WriteSuccessToLog(lexer, debugSpan, u"ChunkExtensions");
380 }
381 else
382 {
383 System.Lex.WriteFailureToLog(lexer, u"ChunkExtensions");
384 }
385 }
386 #endif
387 if (!match.hit)
388 {
389 match.value = null;
390 }
391 return match;
392 }
393 public static Match ChunkExtName(HttpLexer& lexer)
394 {
395 #if (DEBUG)
396 Span debugSpan;
397 bool writeToLog = lexer.Log() != null;
398 if (writeToLog)
399 {
400 debugSpan = lexer.GetSpan();
401 System.Lex.WriteBeginRuleToLog(lexer, u"ChunkExtName");
402 }
403 #endif
404 UniquePtr<Value<string>> t;
405 Match match(false);
406 Match* parentMatch0 = &match;
407 {
408 long pos = lexer.GetPos();
409 Match match = Http.token(lexer);
410 t.Reset(cast<Value<string>*>(match.value));
411 if (match.hit)
412 {
413 {
414 #if (DEBUG)
415 if (writeToLog) System.Lex.WriteSuccessToLog(lexer, debugSpan, u"ChunkExtName");
416 #endif
417 return Match(true, new Value<string>(t->value));
418 }
419 }
420 *parentMatch0 = match;
421 }
422 #if (DEBUG)
423 if (writeToLog)
424 {
425 if (match.hit)
426 {
427 System.Lex.WriteSuccessToLog(lexer, debugSpan, u"ChunkExtName");
428 }
429 else
430 {
431 System.Lex.WriteFailureToLog(lexer, u"ChunkExtName");
432 }
433 }
434 #endif
435 if (!match.hit)
436 {
437 match.value = null;
438 }
439 return match;
440 }
441 public static Match ChunkExtVal(HttpLexer& lexer)
442 {
443 #if (DEBUG)
444 Span debugSpan;
445 bool writeToLog = lexer.Log() != null;
446 if (writeToLog)
447 {
448 debugSpan = lexer.GetSpan();
449 System.Lex.WriteBeginRuleToLog(lexer, u"ChunkExtVal");
450 }
451 #endif
452 UniquePtr<Value<string>> t;
453 UniquePtr<Value<string>> qs;
454 Match match(false);
455 Match* parentMatch0 = &match;
456 {
457 long save = lexer.GetPos();
458 Match match(false);
459 Match* parentMatch1 = &match;
460 {
461 long pos = lexer.GetPos();
462 Match match = Http.token(lexer);
463 t.Reset(cast<Value<string>*>(match.value));
464 if (match.hit)
465 {
466 {
467 #if (DEBUG)
468 if (writeToLog) System.Lex.WriteSuccessToLog(lexer, debugSpan, u"ChunkExtVal");
469 #endif
470 return Match(true, new Value<string>(t->value));
471 }
472 }
473 *parentMatch1 = match;
474 }
475 *parentMatch0 = match;
476 if (!match.hit)
477 {
478 Match match(false);
479 Match* parentMatch2 = &match;
480 lexer.SetPos(save);
481 {
482 Match match(false);
483 Match* parentMatch3 = &match;
484 {
485 long pos = lexer.GetPos();
486 Match match = Http.quoted_string(lexer);
487 qs.Reset(cast<Value<string>*>(match.value));
488 if (match.hit)
489 {
490 {
491 #if (DEBUG)
492 if (writeToLog) System.Lex.WriteSuccessToLog(lexer, debugSpan, u"ChunkExtVal");
493 #endif
494 return Match(true, new Value<string>(qs->value));
495 }
496 }
497 *parentMatch3 = match;
498 }
499 *parentMatch2 = match;
500 }
501 *parentMatch0 = match;
502 }
503 }
504 #if (DEBUG)
505 if (writeToLog)
506 {
507 if (match.hit)
508 {
509 System.Lex.WriteSuccessToLog(lexer, debugSpan, u"ChunkExtVal");
510 }
511 else
512 {
513 System.Lex.WriteFailureToLog(lexer, u"ChunkExtVal");
514 }
515 }
516 #endif
517 if (!match.hit)
518 {
519 match.value = null;
520 }
521 return match;
522 }
523 }