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