Bincimap 2.0.16
Easy Imapping
Loading...
Searching...
No Matches
recursivedescent.cc
Go to the documentation of this file.
1
7#include "imapparser.h"
8#include "recursivedescent.h"
9#include "iodevice.h"
10#include "iofactory.h"
11#include "convert.h"
12#include "session.h"
13
14#include <stdio.h>
15#include <ctype.h>
16#include <stack>
17#include <iostream>
18#include <iomanip>
19
20using namespace ::std;
21using namespace Binc;
22
25
26
27//----------------------------------------------------------------------
29{
30 Session &session = Session::getInstance();
31
32 string tmp;
33
34 bool match = true;
35 for (string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
36
37 char c;
38 if (!bincClient.readChar(&c)) {
39 session.setLastError(bincClient.getLastErrorString());
40
41 if (bincClient.getLastError() == IODevice::Timeout) return Operator::TIMEOUT;
42 return Operator::ERROR;
43 }
44
45 tmp += c;
46
47 if (toupper(*i) != toupper(c)) {
48 match = false;
49 break;
50 }
51 }
52
53 if (!match) {
54 bincClient.unreadStr(tmp);
55 return Operator::REJECT;
56 } else
57 return Operator::ACCEPT;
58}
59
60//----------------------------------------------------------------------
62{
63 Session &session = Session::getInstance();
64
66 return Operator::REJECT;
67
68 unsigned int digit1, digit2;
70 digit1 = 0;
72 if ((res = expectDigit(digit2)) != Operator::ACCEPT) {
73 session.setLastError("expected digit (day) after \" and a SPACE.");
74 return res;
75 }
76 } else {
78 if ((res = expectDigit(digit1)) != Operator::ACCEPT) {
79 session.setLastError("expected first digit of day");
80 return res;
81 }
82 if ((res = expectDigit(digit2)) != Operator::ACCEPT) {
83 session.setLastError("expected second digit of day");
84 return res;
85 }
86 }
87
88 int day = digit1 * 10 + digit2;
89
90 BincStream daystr;
91
92 if (day < 10)
93 daystr << '0';
94 daystr << day;
95
96 s_in += daystr.str();
97
99 if ((res = expectThisString("-")) != Operator::ACCEPT) {
100 session.setLastError("expected -");
101 return res;
102 }
103
104 s_in += "-";
105
106 /* month */
107 if ((res = expectThisString("Jan")) == Operator::ACCEPT) s_in += "Jan";
108 else if ((res = expectThisString("Feb")) == Operator::ACCEPT) s_in += "Feb";
109 else if ((res = expectThisString("Mar")) == Operator::ACCEPT) s_in += "Mar";
110 else if ((res = expectThisString("Apr")) == Operator::ACCEPT) s_in += "Apr";
111 else if ((res = expectThisString("May")) == Operator::ACCEPT) s_in += "May";
112 else if ((res = expectThisString("Jun")) == Operator::ACCEPT) s_in += "Jun";
113 else if ((res = expectThisString("Jul")) == Operator::ACCEPT) s_in += "Jul";
114 else if ((res = expectThisString("Aug")) == Operator::ACCEPT) s_in += "Aug";
115 else if ((res = expectThisString("Sep")) == Operator::ACCEPT) s_in += "Sep";
116 else if ((res = expectThisString("Oct")) == Operator::ACCEPT) s_in += "Oct";
117 else if ((res = expectThisString("Nov")) == Operator::ACCEPT) s_in += "Nov";
118 else if ((res = expectThisString("Dec")) == Operator::ACCEPT) s_in += "Dec";
119 else {
120 session.setLastError("expected month");
121 return res;
122 }
123
124 if ((res = expectThisString("-")) != Operator::ACCEPT) {
125 session.setLastError("expected -");
126 return res;
127 }
128
129 s_in += "-";
130
131 /* year */
132 unsigned int year, c;
133 if ((res = expectDigit(year)) != Operator::ACCEPT) {
134 session.setLastError("expected digit (first digit of year)");
135 return res;
136 }
137
138 if ((res = expectDigit(c)) != Operator::ACCEPT) {
139 session.setLastError("expected digit (second digit of year)");
140 return res;
141 }
142
143 year = (year * 10) + c;
144
145 if ((res = expectDigit(c)) != Operator::ACCEPT) {
146 session.setLastError("expected digit (third digit of year)");
147 return res;
148 }
149
150 year = (year * 10) + c;
151
152 if ((res = expectDigit(c)) != Operator::ACCEPT) {
153 session.setLastError("expected digit (last digit of year)");
154 return res;
155 }
156
157 year = (year * 10) + c;
158
159 BincStream yearstr;
160
161 yearstr << year;
162
163 s_in += yearstr.str();
164
165 if ((res = expectSPACE()) != Operator::ACCEPT) {
166 session.setLastError("expected SPACE");
167 return res;
168 }
169
170 s_in += " ";
171
172 if ((res = expectTime(s_in)) != Operator::ACCEPT) {
173 session.setLastError("expected time");
174 return res;
175 }
176
177 if ((res = expectSPACE()) != Operator::ACCEPT) {
178 session.setLastError("expected SPACE");
179 return res;
180 }
181
182 s_in += " ";
183
184 if ((res = expectZone(s_in)) != Operator::ACCEPT) {
185 session.setLastError("expected zone");
186 return res;
187 }
188
189 if ((res = expectThisString("\"")) != Operator::ACCEPT) {
190 session.setLastError("expected \"");
191 return res;
192 }
193
194 return Operator::ACCEPT;
195}
196
197//----------------------------------------------------------------------
199{
200 Session &session = Session::getInstance();
201
202 unsigned int c, t;
204 if ((res = expectDigit(t)) != Operator::ACCEPT)
205 return res;
206
207 if ((res = expectDigit(c)) != Operator::ACCEPT) {
208 session.setLastError("expected digit");
209 return res;
210 }
211
212 t = (t * 10) + c;
213
214 BincStream tstr;
215
216 tstr << t;
217
218 s_in += tstr.str();
219
220 if ((res = expectThisString(":")) != Operator::ACCEPT) {
221 session.setLastError("expected colon");
222 return res;
223 }
224
225 s_in += ":";
226
227 if ((res = expectDigit(t)) != Operator::ACCEPT) {
228 session.setLastError("expected digit");
229 return res;
230 }
231
232 if ((res = expectDigit(c)) != Operator::ACCEPT) {
233 session.setLastError("expected digit");
234 return res;
235 }
236
237 t = (t * 10) + c;
238
239 tstr.clear();
240
241 tstr << t;
242
243 s_in += tstr.str();
244
245 if ((res = expectThisString(":")) != Operator::ACCEPT) {
246 session.setLastError("expected colon");
247 return res;
248 }
249
250 s_in += ":";
251
252 if ((res = expectDigit(t)) != Operator::ACCEPT) {
253 session.setLastError("expected digit");
254 return res;
255 }
256
257 if ((res = expectDigit(c)) != Operator::ACCEPT) {
258 session.setLastError("expected digit");
259 return res;
260 }
261
262 t = (t * 10) + c;
263
264 tstr.clear();
265
266 tstr << t;
267
268 s_in += tstr.str();
269
270 return Operator::ACCEPT;
271}
272
273//----------------------------------------------------------------------
275{
276 Session &session = Session::getInstance();
277
279 if ((res = expectThisString("-")) == Operator::ACCEPT)
280 s_in += "-";
281 else if ((res = expectThisString("+")) == Operator::ACCEPT)
282 s_in += "+";
283 else
284 return res;
285
286 unsigned int c, t;
287 if ((res = expectDigit(t)) != Operator::ACCEPT) {
288 session.setLastError("expected digit");
289 return res;
290 }
291
292 if ((res = expectDigit(c)) != Operator::ACCEPT) {
293 session.setLastError("expected digit");
294 return res;
295 }
296
297 t = (t * 10) + c;
298
299 if ((res = expectDigit(c)) != Operator::ACCEPT) {
300 session.setLastError("expected digit");
301 return res;
302 }
303
304 t = (t * 10) + c;
305
306 if ((res = expectDigit(c)) != Operator::ACCEPT) {
307 session.setLastError("expected digit");
308 return res;
309 }
310
311 t = (t * 10) + c;
312
313 BincStream tstr;
314
315 tstr << t;
316
317 s_in += tstr.str();
318
319 return Operator::ACCEPT;
320}
321
322//----------------------------------------------------------------------
324{
326 if ((res = expectThisString("%")) == Operator::ACCEPT) {
327 c_in = '%';
328 return Operator::ACCEPT;
329 } else if ((res = expectThisString("*")) == Operator::ACCEPT) {
330 c_in = '*';
331 return Operator::ACCEPT;
332 } else
333 return res;
334}
335
336//----------------------------------------------------------------------
338{
340 if ((res = expectString(s_in)) == Operator::ACCEPT)
341 return Operator::ACCEPT;
342
343 int c;
344 if ((res = expectAtomChar(c)) == Operator::ACCEPT
346 || (res = expectThisString("]")) == Operator::ACCEPT) {
347 do {
348 s_in += (char) c;
349 if ((res = expectAtomChar(c)) != Operator::ACCEPT
351 && (res = expectThisString("]")) != Operator::ACCEPT)
352 return Operator::ACCEPT;
353 } while (1);
354 }
355
356 bincClient.unreadStr(s_in);
357
358 return res;
359}
360
361//----------------------------------------------------------------------
362Operator::ParseResult Binc::expectFlag(vector<string> &v_in)
363{
364 Session &session = Session::getInstance();
365
367 string flag;
368 if ((res = expectThisString("\\Answered")) == Operator::ACCEPT)
369 v_in.push_back("\\Answered");
370 else if ((res = expectThisString("\\Flagged")) == Operator::ACCEPT)
371 v_in.push_back("\\Flagged");
372 else if ((res = expectThisString("\\Deleted")) == Operator::ACCEPT)
373 v_in.push_back("\\Deleted");
374 else if ((res = expectThisString("\\Seen")) == Operator::ACCEPT)
375 v_in.push_back("\\Seen");
376 else if ((res = expectThisString("\\Draft")) == Operator::ACCEPT)
377 v_in.push_back("\\Draft");
378 else if ((res = expectThisString("\\Answered")) == Operator::ACCEPT)
379 v_in.push_back("\\Answered");
380 else {
381 if ((res = expectThisString("\\")) == Operator::ACCEPT) {
382 if ((res = expectAtom(flag)) == Operator::ACCEPT)
383 v_in.push_back("\\" + flag);
384 else {
385 session.setLastError("expected atom");
386 return res;
387 }
388
389 } else if (expectAtom(flag) == Operator::ACCEPT) {
390 v_in.push_back(flag);
391 } else
392 return res;
393 }
394
395 return Operator::ACCEPT;
396}
397
398//----------------------------------------------------------------------
400{
401 Session &session = Session::getInstance();
402
404 bool quoted = false;
405 if ((res = expectThisString("\"")) == Operator::ACCEPT)
406 quoted = true;
407
408 /* day */
409 unsigned int day, c;
410 if ((res = expectDigit(c)) == Operator::ACCEPT) {
411 day = c;
412 if ((res = expectDigit(c)) == Operator::ACCEPT)
413 day = (day * 10) + c;
414
415 BincStream daystr;
416
417 daystr << day;
418
419 s_in += daystr.str();
420 } else {
421 session.setLastError("expected digit");
422 return res;
423 }
424
425 /* - */
426 if ((res = expectThisString("-")) != Operator::ACCEPT) {
427 session.setLastError("expected -");
428 return res;
429 }
430
431 s_in += '-';
432
433 /* month */
434 if ((res = expectThisString("Jan")) == Operator::ACCEPT) s_in += "Jan";
435 else if ((res = expectThisString("Feb")) == Operator::ACCEPT) s_in += "Feb";
436 else if ((res = expectThisString("Mar")) == Operator::ACCEPT) s_in += "Mar";
437 else if ((res = expectThisString("Apr")) == Operator::ACCEPT) s_in += "Apr";
438 else if ((res = expectThisString("May")) == Operator::ACCEPT) s_in += "May";
439 else if ((res = expectThisString("Jun")) == Operator::ACCEPT) s_in += "Jun";
440 else if ((res = expectThisString("Jul")) == Operator::ACCEPT) s_in += "Jul";
441 else if ((res = expectThisString("Aug")) == Operator::ACCEPT) s_in += "Aug";
442 else if ((res = expectThisString("Sep")) == Operator::ACCEPT) s_in += "Sep";
443 else if ((res = expectThisString("Oct")) == Operator::ACCEPT) s_in += "Oct";
444 else if ((res = expectThisString("Nov")) == Operator::ACCEPT) s_in += "Nov";
445 else if ((res = expectThisString("Dec")) == Operator::ACCEPT) s_in += "Dec";
446 else {
447 session.setLastError("expected month");
448 return res;
449 }
450
451 /* - */
452 if ((res = expectThisString("-")) != Operator::ACCEPT) {
453 session.setLastError("expected -");
454 return res;
455 }
456
457 s_in += '-';
458
459 /* year */
460 unsigned int year;
461 if ((res = expectDigit(year)) != Operator::ACCEPT) {
462 session.setLastError("expected digit");
463 return res;
464 }
465
466 if ((res = expectDigit(c)) != Operator::ACCEPT) {
467 session.setLastError("expected digit");
468 return res;
469 }
470
471 year = (year * 10) + c;
472
473 if ((res = expectDigit(c)) != Operator::ACCEPT) {
474 session.setLastError("expected digit");
475 return res;
476 }
477
478 year = (year * 10) + c;
479
480 if ((res = expectDigit(c)) != Operator::ACCEPT) {
481 session.setLastError("expected digit");
482 return res;
483 }
484
485 year = (year * 10) + c;
486
487 BincStream yearstr;
488
489 yearstr << year;
490
491 s_in += yearstr.str();
492
493 if (quoted)
494 if ((res = expectThisString("\"")) != Operator::ACCEPT) {
495 session.setLastError("expected \"");
496 return res;
497 }
498
499 return Operator::ACCEPT;
500}
501
502//----------------------------------------------------------------------
504{
506 if ((res = expectCR()) == Operator::ACCEPT
507 && (res = expectLF()) == Operator::ACCEPT)
508 return Operator::ACCEPT;
509 else
510 return res;
511}
512
513//----------------------------------------------------------------------
515{
516 Session &session = Session::getInstance();
517
518 char c;
519 if (!bincClient.readChar(&c)) {
520 session.setLastError(bincClient.getLastErrorString());
521
522 if (bincClient.getLastError() == IODevice::Timeout)
523 return Operator::TIMEOUT;
524 return Operator::ERROR;
525 }
526
527 if (c == 0x0d)
528 return Operator::ACCEPT;
529 else {
530 bincClient.unreadChar(c);
531 return Operator::REJECT;
532 }
533}
534
535//----------------------------------------------------------------------
537{
538 Session &session = Session::getInstance();
539
540 char c;
541 if (!bincClient.readChar(&c)) {
542 session.setLastError(bincClient.getLastErrorString());
543
544 if (bincClient.getLastError() == IODevice::Timeout)
545 return Operator::TIMEOUT;
546 return Operator::ERROR;
547 }
548
549 if (c == 0x0a)
550 return Operator::ACCEPT;
551 else {
552 bincClient.unreadChar(c);
553 return Operator::REJECT;
554 }
555}
556
557//----------------------------------------------------------------------
559{
560 Session &session = Session::getInstance();
561
562 char c;
563 if (!bincClient.readChar(&c)) {
564 session.setLastError(bincClient.getLastErrorString());
565
566 if (bincClient.getLastError() == IODevice::Timeout)
567 return Operator::TIMEOUT;
568 return Operator::ERROR;
569 }
570
571 switch (c) {
572 case 041: case 043: case 044: case 046: case 047: case 054:
573 case 055: case 056: case 057: case 060: case 061: case 062:
574 case 063: case 064: case 065: case 066: case 067: case 070:
575 case 071: case 072: case 073: case 074: case 075: case 076:
576 case 077: case 0100: case 0101: case 0102: case 0103: case 0104:
577 case 0105: case 0106: case 0107: case 0110: case 0111: case 0112:
578 case 0113: case 0114: case 0115: case 0116: case 0117: case 0120:
579 case 0121: case 0122: case 0123: case 0124: case 0125: case 0126:
580 case 0127: case 0130: case 0131: case 0132: case 0133: case 0135:
581 case 0136: case 0137: case 0140: case 0141: case 0142: case 0143:
582 case 0144: case 0145: case 0146: case 0147: case 0150: case 0151:
583 case 0152: case 0153: case 0154: case 0155: case 0156: case 0157:
584 case 0160: case 0161: case 0162: case 0163: case 0164: case 0165:
585 case 0166: case 0167: case 0170: case 0171: case 0172: case 0174:
586 case 0175: case 0176:
587 c_in = c;
588 return Operator::ACCEPT;
589 default:
590 break;
591 }
592
593 bincClient.unreadChar(c);
594
595 return Operator::REJECT;
596}
597
598//----------------------------------------------------------------------
600{
601 string tag;
602 int tagchar;
603
604 int eres = expectTagChar(tagchar);
605 if (eres == Operator::REJECT)
606 return Operator::REJECT;
607 else if (eres == Operator::ERROR)
608 return Operator::ERROR;
609 else if (eres == Operator::TIMEOUT)
610 return Operator::TIMEOUT;
611 else {
612 tag += tagchar;
613
614 bool done = false;
615
616 while (!done) {
617 switch (expectTagChar(tagchar)) {
618 case Operator::ACCEPT:
619 tag += tagchar;
620 break;
621 case Operator::REJECT:
622 done = true;
623 break;
624 case Operator::ERROR:
625 return Operator::ERROR;
627 return Operator::TIMEOUT;
628 }
629 }
630 }
631
632 s_in = tag;
633
634 return Operator::ACCEPT;
635}
636
637//----------------------------------------------------------------------
639{
640 Session &session = Session::getInstance();
641
642 char c;
643 if (!bincClient.readChar(&c)) {
644 session.setLastError(bincClient.getLastErrorString());
645
646 if (bincClient.getLastError() == IODevice::Timeout)
647 return Operator::TIMEOUT;
648 return Operator::ERROR;
649 }
650
651 if (c == ' ')
652 return Operator::ACCEPT;
653 else {
654 bincClient.unreadChar(c);
655 return Operator::REJECT;
656 }
657}
658
659//----------------------------------------------------------------------
661{
662 return expectAstring(s_in);
663}
664
665//----------------------------------------------------------------------
666// FIXME: This rule is wrong.
668{
670 if ((res = expectAtom(s_in)) == Operator::ACCEPT)
671 return Operator::ACCEPT;
672
673 if ((res = expectString(s_in)) == Operator::ACCEPT)
674 return Operator::ACCEPT;
675
676 return res;
677}
678
679//----------------------------------------------------------------------
681{
682 Session &session = Session::getInstance();
683
684 char c;
685 if (!bincClient.readChar(&c)) {
686 session.setLastError(bincClient.getLastErrorString());
687
688 if (bincClient.getLastError() == IODevice::Timeout)
689 return Operator::TIMEOUT;
690 return Operator::ERROR;
691 }
692
693 switch (c) {
694 case 041: case 043: case 044: case 046: case 047: case 053:
695 case 054: case 055: case 056: case 057: case 060: case 061:
696 case 062: case 063: case 064: case 065: case 066: case 067:
697 case 070: case 071: case 072: case 073: case 074: case 075:
698 case 076: case 077: case 0100: case 0101: case 0102: case 0103:
699 case 0104: case 0105: case 0106: case 0107: case 0110: case 0111:
700 case 0112: case 0113: case 0114: case 0115: case 0116: case 0117:
701 case 0120: case 0121: case 0122: case 0123: case 0124: case 0125:
702 case 0126: case 0127: case 0130: case 0131: case 0132: case 0133:
703 case 0135: case 0136: case 0137: case 0140: case 0141: case 0142:
704 case 0143: case 0144: case 0145: case 0146: case 0147: case 0150:
705 case 0151: case 0152: case 0153: case 0154: case 0155: case 0156:
706 case 0157: case 0160: case 0161: case 0162: case 0163: case 0164:
707 case 0165: case 0166: case 0167: case 0170: case 0171: case 0172:
708 case 0174: case 0175: case 0176:
709 c_in = c;
710 return Operator::ACCEPT;
711 default:
712 break;
713 }
714
715 bincClient.unreadChar(c);
716 return Operator::REJECT;
717}
718
719//----------------------------------------------------------------------
721{
722 string atom;
723 int atomchar;
724
726 while ((res = expectAtomChar(atomchar)) == Operator::ACCEPT)
727 atom += atomchar;
728
729 if (atom == "") {
730 bincClient.unreadStr(atom);
731 return res;
732 } else
733 s_in = atom;
734
735 return Operator::ACCEPT;
736}
737
738//----------------------------------------------------------------------
740{
742 if ((res = expectQuoted(s_in)) == Operator::ACCEPT)
743 return Operator::ACCEPT;
744
745 if ((res = expectLiteral(s_in)) == Operator::ACCEPT)
746 return Operator::ACCEPT;
747
748 return res;
749}
750
751//----------------------------------------------------------------------
753{
754 string quoted;
755 int quotedchar;
757
758 if ((res = expectThisString("\"")) != Operator::ACCEPT)
759 return res;
760
761 while ((res = expectQuotedChar(quotedchar)) == Operator::ACCEPT)
762 quoted += quotedchar;
763
764 if ((res = expectThisString("\"")) != Operator::ACCEPT) {
765 bincClient.unreadStr("\"" + quoted);
766 return res;
767 }
768
769 s_in = quoted;
770 return Operator::ACCEPT;
771}
772
773//----------------------------------------------------------------------
775{
776 Session &session = Session::getInstance();
777
778 char c;
779 if (!bincClient.readChar(&c)) {
780 session.setLastError(bincClient.getLastErrorString());
781
782 if (bincClient.getLastError() == IODevice::Timeout)
783 return Operator::TIMEOUT;
784 return Operator::ERROR;
785 }
786
787 switch (c) {
788 case 01: case 02: case 03: case 04: case 05: case 06: case 07:
789 case 010: case 011: case 013: case 014: case 016: case 017:
790 case 020: case 021: case 022: case 023: case 024: case 025: case 026: case 027:
791 case 030: case 031: case 032: case 033: case 034: case 035: case 036: case 037:
792 case 040: case 041: case 043: case 044: case 045: case 046: case 047:
793 case 050: case 051: case 052: case 053: case 054: case 055: case 056: case 057:
794 case 060: case 061: case 062: case 063: case 064: case 065: case 066: case 067:
795 case 070: case 071: case 072: case 073: case 074: case 075: case 076: case 077:
796 case 0100: case 0101: case 0102: case 0103: case 0104: case 0105: case 0106: case 0107:
797 case 0110: case 0111: case 0112: case 0113: case 0114: case 0115: case 0116: case 0117:
798 case 0120: case 0121: case 0122: case 0123: case 0124: case 0125: case 0126: case 0127:
799 case 0130: case 0131: case 0132: case 0133: case 0135: case 0136: case 0137:
800 case 0140: case 0141: case 0142: case 0143: case 0144: case 0145: case 0146: case 0147:
801 case 0150: case 0151: case 0152: case 0153: case 0154: case 0155: case 0156: case 0157:
802 case 0160: case 0161: case 0162: case 0163: case 0164: case 0165: case 0166: case 0167:
803 case 0170: case 0171: case 0172: case 0173: case 0174: case 0175: case 0176: case 0177:
804 c_in = c;
805 return Operator::ACCEPT;
806 case '\\': {
807 char d;
808 if (!bincClient.readChar(&d)) {
809 session.setLastError(bincClient.getLastErrorString());
810
811 if (bincClient.getLastError() == IODevice::Timeout) return Operator::TIMEOUT;
812 return Operator::ERROR;
813 }
814
815 if (d == '\"' || d == '\\') {
816 c_in = d;
817 return Operator::ACCEPT;
818 } else {
819 bincClient.unreadChar(d);
820 bincClient.unreadChar(c);
821 return Operator::REJECT;
822 }
823 }
824 default:
825 break;
826 }
827
828 bincClient.unreadChar(c);
829 return Operator::REJECT;
830}
831
832//----------------------------------------------------------------------
834{
835 Session &session = Session::getInstance();
836
837 string literal;
839
840 if ((res = expectThisString("{")) != Operator::ACCEPT) return res;
841
842 unsigned int nchar;
843
844 if ((res = expectNumber(nchar)) != Operator::ACCEPT) {
845 session.setLastError("expected number");
846 return res;
847 }
848
849 // rfc2088 describes the non-synchronizing literal, or LITERAL+, as
850 // sent by the client with an extra '+' appended after the octet
851 // count.
852 bool literalPlus = false;
853 if ((res = expectThisString("+")) == Operator::ACCEPT)
854 literalPlus = true;
855
856 if ((res = expectThisString("}")) != Operator::ACCEPT) {
857 session.setLastError("expected }");
858 return res;
859 }
860
861 if ((res = expectCRLF()) != Operator::ACCEPT) {
862 session.setLastError("expected CRLF");
863 return Operator::ERROR;
864 }
865
866 // Only send the reply if the client did not send a LITERAL+
867 // request.
868 if (!literalPlus) {
869 bincClient << "+ ok, send " << nchar << " bytes of data." << endl;
870 bincClient.flush();
871 }
872
873 for (unsigned int i = 0; i < nchar; ++i) {
874 char c;
875 if (!bincClient.readChar(&c)) {
876 session.setLastError(bincClient.getLastErrorString());
877 if (bincClient.getLastError() == IODevice::Timeout) return Operator::TIMEOUT;
878 return Operator::ERROR;
879 }
880
881 literal += c;
882 }
883
884 s_in = literal;
885
886 return Operator::ACCEPT;
887}
888
889//----------------------------------------------------------------------
891{
892 i_in = 0;
893 unsigned int n;
895
896 while ((res = expectDigit(n)) == Operator::ACCEPT) {
897 if (i_in == 0)
898 i_in = n;
899 else
900 i_in = (i_in * 10) + n;
901 }
902
903 if (res == Operator::TIMEOUT)
904 return res;
905
906 return Operator::ACCEPT;
907}
908
909//----------------------------------------------------------------------
911{
912 Session &session = Session::getInstance();
913
914 char c;
915 if (!bincClient.readChar(&c)) {
916 session.setLastError(bincClient.getLastErrorString());
917
918 if (bincClient.getLastError() == IODevice::Timeout)
919 return Operator::TIMEOUT;
920 return Operator::ERROR;
921 }
922
923 if (c == '0') {
924 i_in = 0;
925 return Operator::ACCEPT;
926 } else
927 bincClient.unreadChar(c);
928
929 if (expectDigitNZ(i_in) != Operator::ACCEPT)
930 return Operator::REJECT;
931
932 return Operator::ACCEPT;
933}
934
935//----------------------------------------------------------------------
937{
938 Session &session = Session::getInstance();
939
940 char c;
941 if (!bincClient.readChar(&c)) {
942 session.setLastError(bincClient.getLastErrorString());
943
944 if (bincClient.getLastError() == IODevice::Timeout)
945 return Operator::TIMEOUT;
946 return Operator::ERROR;
947 }
948
949 switch (c) {
950 case '1': i_in = 1; break;
951 case '2': i_in = 2; break;
952 case '3': i_in = 3; break;
953 case '4': i_in = 4; break;
954 case '5': i_in = 5; break;
955 case '6': i_in = 6; break;
956 case '7': i_in = 7; break;
957 case '8': i_in = 8; break;
958 case '9': i_in = 9; break;
959 case -1:
960 session.setLastError(bincClient.getLastErrorString());
961 return Operator::ERROR;
962 case -2:
963 return Operator::TIMEOUT;
964 default:
965 bincClient.unreadChar(c);
966 return Operator::REJECT;
967 }
968
969 return Operator::ACCEPT;
970}
971
972//----------------------------------------------------------------------
974{
975 Session &session = Session::getInstance();
976 unsigned int seqnum = (unsigned int) -1;
977
979
980 /* if a set does not start with a sequencenum, then it's not a
981 * set. :-) seqnum == -1 means '*'. */
982 if ((res = expectSequenceNum(seqnum)) != Operator::ACCEPT)
983 return res;
984
985 /* the first number is always a part of the set */
986 s_in.addNumber(seqnum);
987
988 /* if _after_ a set there is a ':', then there will always be a
989 * sequencenum after the colon. if not, it's a syntax error. a
990 * colon delimits two numbers in a range. */
991 if ((res = expectThisString(":")) == Operator::ACCEPT) {
992 unsigned int seqnum2 = (unsigned int) -1;
993 if ((res = expectSequenceNum(seqnum2)) != Operator::ACCEPT) {
994 session.setLastError("expected sequencenum");
995 return res;
996 }
997
998 s_in.addRange(seqnum, seqnum2);
999 }
1000
1001 /* if _after_ a set there is a ',', then there will always be
1002 * a set after the comma. if not, it's a syntax error. */
1003 if ((res = expectThisString(",")) == Operator::ACCEPT)
1004 if ((res = expectSet(s_in)) != Operator::ACCEPT) {
1005 session.setLastError("expected set");
1006 return res;
1007 }
1008
1009 return Operator::ACCEPT;
1010}
1011
1012//----------------------------------------------------------------------
1014{
1015 Session &session = Session::getInstance();
1016
1017 char c;
1018 if (!bincClient.readChar(&c)) {
1019 session.setLastError(bincClient.getLastErrorString());
1020
1021 if (bincClient.getLastError() == IODevice::Timeout)
1022 return Operator::TIMEOUT;
1023 return Operator::ERROR;
1024 }
1025
1026 if (c == '*') {
1027 i_in = (unsigned int) -1;
1028 return Operator::ACCEPT;
1029 } else
1030 bincClient.unreadChar(c);
1031
1032 if (expectNZNumber(i_in) != Operator::ACCEPT)
1033 return Operator::REJECT;
1034 else
1035 return Operator::ACCEPT;
1036}
1037
1038//----------------------------------------------------------------------
1040{
1041 unsigned int c;
1043
1044 if ((res = expectDigitNZ(c)) != Operator::ACCEPT)
1045 return res;
1046
1047 i_in = c;
1048 while ((res = expectDigit(c)) == Operator::ACCEPT)
1049 i_in = (i_in * 10) + c;
1050
1051 if (res == Operator::TIMEOUT)
1052 return res;
1053
1054 return Operator::ACCEPT;
1055}
const std::string & str(void) const
Definition: convert.cc:58
void clear(void)
Definition: convert.cc:64
void addRange(unsigned int a_in, unsigned int b_in)
Definition: imapparser.cc:287
void addNumber(unsigned int a_in)
Definition: imapparser.cc:294
void setLastError(const std::string &error) const
Definition: session.cc:185
static Session & getInstance(void)
Definition: session.cc:33
Declaration of miscellaneous convertion functions.
Declaration of the common items for parsing IMAP input.
Declaration of the IODevice class.
Declaration of the IOFactory class.
#define bincClient
Definition: iofactory.h:31
Definition: bincimapd.cc:9
Operator::ParseResult expectNumber(unsigned int &i_in)
Operator::ParseResult expectFlag(std::vector< std::string > &v_in)
Operator::ParseResult expectLF(void)
Operator::ParseResult expectTagChar(int &c_in)
Operator::ParseResult expectAtomChar(int &i_in)
Operator::ParseResult expectAstring(std::string &s_in)
Operator::ParseResult expectZone(std::string &s_in)
Operator::ParseResult expectString(std::string &s_in)
Operator::ParseResult expectSPACE(void)
Operator::ParseResult expectLiteral(std::string &s_in)
Operator::ParseResult expectTime(std::string &s_in)
Operator::ParseResult expectDigit(unsigned int &i_in)
Operator::ParseResult expectTag(std::string &s_in)
Operator::ParseResult expectThisString(const std::string &s_in)
Operator::ParseResult expectAtom(std::string &s_in)
Operator::ParseResult expectQuotedChar(int &c_in)
Operator::ParseResult expectListWildcards(int &c_in)
Operator::ParseResult expectCR(void)
Operator::ParseResult expectSequenceNum(unsigned int &i_in)
Operator::ParseResult expectDateTime(std::string &s_in)
Operator::ParseResult expectDigitNZ(unsigned int &i_in)
Operator::ParseResult expectQuoted(std::string &s_in)
Operator::ParseResult expectListMailbox(std::string &s_in)
Operator::ParseResult expectDate(std::string &s_in)
Operator::ParseResult expectNZNumber(unsigned int &i_in)
Operator::ParseResult expectSet(SequenceSet &s_in)
Operator::ParseResult expectCRLF(void)
std::stack< int > inputBuffer
Operator::ParseResult expectMailbox(std::string &s_in)
Declaration of a recursive descent IMAP command parser.