1 // Sun, 18 Jun 2000 2 // Y.Takagi 3 4 #ifdef WIN32 5 #include <winsock.h> 6 #else 7 #include <net/socket.h> 8 #endif 9 10 #include <fstream> 11 #include <list> 12 #include <cstring> 13 14 #include "IppContent.h" 15 16 /*----------------------------------------------------------------------*/ 17 18 short readLength(istream &is) 19 { 20 short len = 0; 21 is.read((char *)&len, sizeof(short)); 22 len = ntohs(len); 23 return len; 24 } 25 26 void writeLength(ostream &os, short len) 27 { 28 len = htons(len); 29 os.write((char *)&len, sizeof(short)); 30 } 31 32 /*----------------------------------------------------------------------*/ 33 34 DATETIME::DATETIME() 35 { 36 memset(this, 0, sizeof(DATETIME)); 37 } 38 39 DATETIME::DATETIME(const DATETIME &dt) 40 { 41 memcpy(this, &dt.datetime, sizeof(DATETIME)); 42 } 43 44 DATETIME & DATETIME::operator = (const DATETIME &dt) 45 { 46 memcpy(this, &dt.datetime, sizeof(DATETIME)); 47 return *this; 48 } 49 50 istream& operator >> (istream &is, DATETIME &attr) 51 { 52 return is; 53 } 54 55 ostream& operator << (ostream &os, const DATETIME &attr) 56 { 57 return os; 58 } 59 60 61 /*----------------------------------------------------------------------*/ 62 63 IppAttribute::IppAttribute(IPP_TAG t) 64 : tag(t) 65 { 66 } 67 68 int IppAttribute::length() const 69 { 70 return 1; 71 } 72 73 istream &IppAttribute::input(istream &is) 74 { 75 return is; 76 } 77 78 ostream &IppAttribute::output(ostream &os) const 79 { 80 os << (unsigned char)tag; 81 return os; 82 } 83 84 ostream &IppAttribute::print(ostream &os) const 85 { 86 os << "Tag: " << hex << (int)tag << '\n'; 87 return os; 88 } 89 90 /*----------------------------------------------------------------------*/ 91 92 IppNamedAttribute::IppNamedAttribute(IPP_TAG t) 93 : IppAttribute(t) 94 { 95 } 96 97 IppNamedAttribute::IppNamedAttribute(IPP_TAG t, const char *s) 98 : IppAttribute(t), name(s ? s : "") 99 { 100 } 101 102 int IppNamedAttribute::length() const 103 { 104 return IppAttribute::length() + 2 + name.length(); 105 } 106 107 istream &IppNamedAttribute::input(istream &is) 108 { 109 short len = readLength(is); 110 111 if (0 < len) { 112 char *buffer = new char[len + 1]; 113 is.read(buffer, len); 114 buffer[len] = '\0'; 115 name = buffer; 116 delete [] buffer; 117 } 118 119 return is; 120 } 121 122 ostream &IppNamedAttribute::output(ostream &os) const 123 { 124 IppAttribute::output(os); 125 126 writeLength(os, name.length()); 127 os << name; 128 129 return os; 130 } 131 132 ostream &IppNamedAttribute::print(ostream &os) const 133 { 134 IppAttribute::print(os); 135 os << '\t' << "Name: " << name << '\n'; 136 return os; 137 } 138 139 /*----------------------------------------------------------------------*/ 140 141 IppNoValueAttribute::IppNoValueAttribute(IPP_TAG t) 142 : IppNamedAttribute(t) 143 { 144 } 145 146 IppNoValueAttribute::IppNoValueAttribute(IPP_TAG t, const char *n) 147 : IppNamedAttribute(t, n) 148 { 149 } 150 151 int IppNoValueAttribute::length() const 152 { 153 return IppAttribute::length() + 2; 154 } 155 156 istream &IppNoValueAttribute::input(istream &is) 157 { 158 IppNamedAttribute::input(is); 159 160 short len = readLength(is); 161 162 if (0 < len) { 163 is.seekg(len, ios::cur); 164 } 165 166 return is; 167 } 168 169 ostream &IppNoValueAttribute::output(ostream &os) const 170 { 171 IppAttribute::output(os); 172 173 writeLength(os, 0); 174 175 return os; 176 } 177 178 ostream &IppNoValueAttribute::print(ostream &os) const 179 { 180 return IppNamedAttribute::print(os); 181 } 182 183 /*----------------------------------------------------------------------*/ 184 185 IppIntegerAttribute::IppIntegerAttribute(IPP_TAG t) 186 : IppNamedAttribute(t), value(0) 187 { 188 } 189 190 IppIntegerAttribute::IppIntegerAttribute(IPP_TAG t, const char *n, int v) 191 : IppNamedAttribute(t, n), value(v) 192 { 193 } 194 195 int IppIntegerAttribute::length() const 196 { 197 return IppNamedAttribute::length() + 2 + 4; 198 } 199 200 istream &IppIntegerAttribute::input(istream &is) 201 { 202 IppNamedAttribute::input(is); 203 204 short len = readLength(is); 205 206 if (0 < len && len <= 4) { 207 is.read((char *)&value, sizeof(value)); 208 value = ntohl(value); 209 } else { 210 is.seekg(len, ios::cur); 211 } 212 213 return is; 214 } 215 216 ostream &IppIntegerAttribute::output(ostream &os) const 217 { 218 IppNamedAttribute::output(os); 219 220 writeLength(os, 4); 221 unsigned long val = htonl(value); 222 os.write((char *)&val, sizeof(val)); 223 return os; 224 } 225 226 ostream &IppIntegerAttribute::print(ostream &os) const 227 { 228 IppNamedAttribute::print(os); 229 os << '\t' << "Value: " << dec << value << '\n'; 230 return os; 231 } 232 233 /*----------------------------------------------------------------------*/ 234 235 IppBooleanAttribute::IppBooleanAttribute(IPP_TAG t) 236 : IppNamedAttribute(t), value(false) 237 { 238 } 239 240 IppBooleanAttribute::IppBooleanAttribute(IPP_TAG t, const char *n, bool f) 241 : IppNamedAttribute(t, n), value(f) 242 { 243 } 244 245 int IppBooleanAttribute::length() const 246 { 247 return IppNamedAttribute::length() + 2 + 1; 248 } 249 250 251 istream &IppBooleanAttribute::input(istream &is) 252 { 253 IppNamedAttribute::input(is); 254 255 short len = readLength(is); 256 257 if (0 < len && len <= 1) { 258 char c; 259 is.read((char *)&c, sizeof(c)); 260 value = c ? true : false; 261 } else { 262 is.seekg(len, ios::cur); 263 } 264 265 return is; 266 } 267 268 ostream &IppBooleanAttribute::output(ostream &os) const 269 { 270 IppNamedAttribute::output(os); 271 272 writeLength(os, 1); 273 char c = (char)value; 274 os.write((char *)&c, sizeof(c)); 275 276 return os; 277 } 278 279 ostream &IppBooleanAttribute::print(ostream &os) const 280 { 281 IppNamedAttribute::print(os); 282 os << '\t' << "Value: " << value << '\n'; 283 return os; 284 } 285 286 /*----------------------------------------------------------------------*/ 287 288 IppDatetimeAttribute::IppDatetimeAttribute(IPP_TAG t) 289 : IppNamedAttribute(t) 290 { 291 } 292 293 IppDatetimeAttribute::IppDatetimeAttribute(IPP_TAG t, const char *n, const DATETIME *dt) 294 : IppNamedAttribute(t, n), datetime(*dt) 295 { 296 } 297 298 int IppDatetimeAttribute::length() const 299 { 300 return IppNamedAttribute::length() + 2 + 11; 301 } 302 303 istream &IppDatetimeAttribute::input(istream &is) 304 { 305 IppNamedAttribute::input(is); 306 307 short len = readLength(is); 308 309 if (0 < len) { 310 if (len == 11) { 311 is >> datetime; 312 } else { 313 is.seekg(len, ios::cur); 314 } 315 } 316 317 return is; 318 } 319 320 ostream &IppDatetimeAttribute::output(ostream &os) const 321 { 322 IppNamedAttribute::output(os); 323 324 writeLength(os, 11); 325 os << datetime; 326 327 return os; 328 } 329 330 ostream &IppDatetimeAttribute::print(ostream &os) const 331 { 332 IppNamedAttribute::print(os); 333 os << '\t' << "Value(DateTime): " << datetime << '\n'; 334 return os; 335 } 336 337 /*----------------------------------------------------------------------*/ 338 339 IppStringAttribute::IppStringAttribute(IPP_TAG t) 340 : IppNamedAttribute(t) 341 { 342 } 343 344 IppStringAttribute::IppStringAttribute(IPP_TAG t, const char *n, const char *s) 345 : IppNamedAttribute(t, n), text(s ? s : "") 346 { 347 } 348 349 int IppStringAttribute::length() const 350 { 351 return IppNamedAttribute::length() + 2 + text.length(); 352 } 353 354 istream &IppStringAttribute::input(istream &is) 355 { 356 IppNamedAttribute::input(is); 357 358 short len = readLength(is); 359 360 if (0 < len) { 361 char *buffer = new char[len + 1]; 362 is.read(buffer, len); 363 buffer[len] = '\0'; 364 text = buffer; 365 delete [] buffer; 366 } 367 368 return is; 369 } 370 371 ostream &IppStringAttribute::output(ostream &os) const 372 { 373 IppNamedAttribute::output(os); 374 375 writeLength(os, text.length()); 376 os << text; 377 378 return os; 379 } 380 381 ostream &IppStringAttribute::print(ostream &os) const 382 { 383 IppNamedAttribute::print(os); 384 os << '\t' << "Value: " << text << '\n'; 385 return os; 386 } 387 388 /*----------------------------------------------------------------------*/ 389 390 IppDoubleStringAttribute::IppDoubleStringAttribute(IPP_TAG t) 391 : IppNamedAttribute(t) 392 { 393 } 394 395 IppDoubleStringAttribute::IppDoubleStringAttribute(IPP_TAG t, const char *n, const char *s1, const char *s2) 396 : IppNamedAttribute(t, n), text1(s1 ? s1 : ""), text2(s2 ? s2 : "") 397 { 398 } 399 400 int IppDoubleStringAttribute::length() const 401 { 402 return IppNamedAttribute::length() + 2 + text1.length() + 2 + text2.length(); 403 } 404 405 istream &IppDoubleStringAttribute::input(istream &is) 406 { 407 IppNamedAttribute::input(is); 408 409 short len = readLength(is); 410 411 if (0 < len) { 412 char *buffer = new char[len + 1]; 413 is.read(buffer, len); 414 buffer[len] = '\0'; 415 text1 = buffer; 416 delete [] buffer; 417 } 418 419 len = readLength(is); 420 421 if (0 < len) { 422 char *buffer = new char[len + 1]; 423 is.read(buffer, len); 424 buffer[len] = '\0'; 425 text2 = buffer; 426 delete [] buffer; 427 } 428 429 return is; 430 } 431 432 ostream &IppDoubleStringAttribute::output(ostream &os) const 433 { 434 IppNamedAttribute::output(os); 435 436 writeLength(os, text1.length()); 437 os << text1; 438 439 writeLength(os, text2.length()); 440 os << text2; 441 442 return os; 443 } 444 445 ostream &IppDoubleStringAttribute::print(ostream &os) const 446 { 447 IppNamedAttribute::print(os); 448 os << '\t' << "Value1: " << text1 << '\n'; 449 os << '\t' << "Value2: " << text2 << '\n'; 450 return os; 451 } 452 453 /*----------------------------------------------------------------------*/ 454 455 IppResolutionAttribute::IppResolutionAttribute(IPP_TAG t) 456 : IppNamedAttribute(t), xres(0), yres(0), resolution_units((IPP_RESOLUTION_UNITS)0) 457 { 458 } 459 460 IppResolutionAttribute::IppResolutionAttribute(IPP_TAG t, const char *n, int x, int y, IPP_RESOLUTION_UNITS u) 461 : IppNamedAttribute(t, n), xres(x), yres(y), resolution_units(u) 462 { 463 } 464 465 int IppResolutionAttribute::length() const 466 { 467 return IppNamedAttribute::length() + 2 + 4 + 2 + 4 + 2 + 1; 468 } 469 470 istream &IppResolutionAttribute::input(istream &is) 471 { 472 IppNamedAttribute::input(is); 473 474 short len = readLength(is); 475 476 if (0 < len && len <= 4) { 477 is.read((char *)&xres, sizeof(xres)); 478 xres = ntohl(xres); 479 } else { 480 is.seekg(len, ios::cur); 481 } 482 483 len = readLength(is); 484 485 if (0 < len && len <= 4) { 486 is.read((char *)&yres, sizeof(yres)); 487 yres = ntohl(yres); 488 } else { 489 is.seekg(len, ios::cur); 490 } 491 492 len = readLength(is); 493 494 if (len == 1) { 495 char c; 496 is.read((char *)&c, sizeof(c)); 497 resolution_units = (IPP_RESOLUTION_UNITS)c; 498 } else { 499 is.seekg(len, ios::cur); 500 } 501 502 return is; 503 } 504 505 ostream &IppResolutionAttribute::output(ostream &os) const 506 { 507 IppNamedAttribute::output(os); 508 509 writeLength(os, 4); 510 unsigned long val = htonl(xres); 511 os.write((char *)&val, sizeof(val)); 512 513 writeLength(os, 4); 514 val = htonl(yres); 515 os.write((char *)&val, sizeof(val)); 516 517 writeLength(os, 1); 518 unsigned char c = (unsigned char)resolution_units; 519 os.write((char *)&c, sizeof(c)); 520 521 return os; 522 } 523 524 ostream &IppResolutionAttribute::print(ostream &os) const 525 { 526 IppNamedAttribute::print(os); 527 os << '\t' << "Value(xres): " << dec << xres << '\n'; 528 os << '\t' << "Value(yres): " << dec << yres << '\n'; 529 os << '\t' << "Value(unit): " << dec << resolution_units << '\n'; 530 return os; 531 } 532 533 /*----------------------------------------------------------------------*/ 534 535 IppRangeOfIntegerAttribute::IppRangeOfIntegerAttribute(IPP_TAG t) 536 : IppNamedAttribute(t), lower(0), upper(0) 537 { 538 } 539 540 IppRangeOfIntegerAttribute::IppRangeOfIntegerAttribute(IPP_TAG t, const char *n, int l, int u) 541 : IppNamedAttribute(t, n), lower(l), upper(u) 542 { 543 } 544 545 int IppRangeOfIntegerAttribute::length() const 546 { 547 return IppNamedAttribute::length() + 2 + 4 + 2 + 4; 548 } 549 550 istream &IppRangeOfIntegerAttribute::input(istream &is) 551 { 552 IppNamedAttribute::input(is); 553 554 short len = readLength(is); 555 556 if (0 < len && len <= 4) { 557 is.read((char *)&lower, sizeof(lower)); 558 lower = ntohl(lower); 559 } else { 560 is.seekg(len, ios::cur); 561 } 562 563 len = readLength(is); 564 565 if (0 < len && len <= 4) { 566 is.read((char *)&upper, sizeof(upper)); 567 upper = ntohl(upper); 568 } else { 569 is.seekg(len, ios::cur); 570 } 571 572 return is; 573 } 574 575 ostream &IppRangeOfIntegerAttribute::output(ostream &os) const 576 { 577 IppNamedAttribute::output(os); 578 579 writeLength(os, 4); 580 unsigned long val = htonl(lower); 581 os.write((char *)&val, sizeof(val)); 582 583 writeLength(os, 4); 584 val = htonl(upper); 585 os.write((char *)&val, sizeof(val)); 586 587 return os; 588 } 589 590 ostream &IppRangeOfIntegerAttribute::print(ostream &os) const 591 { 592 IppNamedAttribute::print(os); 593 os << '\t' << "Value(lower): " << dec << lower << '\n'; 594 os << '\t' << "Value(upper): " << dec << upper << '\n'; 595 return os; 596 } 597 598 /*----------------------------------------------------------------------*/ 599 600 IppContent::IppContent() 601 { 602 version = 0x0100; 603 operation_id = IPP_GET_PRINTER_ATTRIBUTES; 604 request_id = 0x00000001; 605 606 is = NULL; 607 size = -1; 608 } 609 610 IppContent::~IppContent() 611 { 612 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) { 613 delete (*it); 614 } 615 } 616 617 unsigned short IppContent::getVersion() const 618 { 619 return version; 620 } 621 622 void IppContent::setVersion(unsigned short i) 623 { 624 version = i; 625 } 626 627 628 IPP_OPERATION_ID IppContent::getOperationId() const 629 { 630 return (IPP_OPERATION_ID)operation_id; 631 } 632 633 void IppContent::setOperationId(IPP_OPERATION_ID i) 634 { 635 operation_id = i; 636 } 637 638 IPP_STATUS_CODE IppContent::getStatusCode() const 639 { 640 return (IPP_STATUS_CODE)operation_id; 641 } 642 643 unsigned long IppContent::getRequestId() const 644 { 645 return request_id; 646 } 647 648 void IppContent::setRequestId(unsigned long i) 649 { 650 request_id = i; 651 } 652 653 istream &IppContent::input(istream &is) 654 { 655 if (!is.read((char *)&version, sizeof(version))) { 656 return is; 657 } 658 659 version = ntohs(version); 660 661 if (!is.read((char *)&operation_id, sizeof(operation_id))) { 662 return is; 663 } 664 665 operation_id = ntohs(operation_id); 666 667 if (!is.read((char *)&request_id, sizeof(request_id))) { 668 return is; 669 } 670 671 request_id = ntohl(request_id); 672 char tag; 673 674 while (1) { 675 676 if (!is.read((char *)&tag, sizeof(tag))) { 677 return is; 678 } 679 680 if (tag <= 0x0F) { // delimiter 681 682 // case IPP_OPERATION_ATTRIBUTES_TAG: 683 // case IPP_JOB_ATTRIBUTES_TAG: 684 // case IPP_END_OF_ATTRIBUTES_TAG: 685 // case IPP_PRINTER_ATTRIBUTES_TAG: 686 // case IPP_UNSUPPORTED_ATTRIBUTES_TAG: 687 688 attrs.push_back(new IppAttribute((IPP_TAG)tag)); 689 if (tag == IPP_END_OF_ATTRIBUTES_TAG) { 690 break; 691 } 692 693 } else if (tag <= 0x1F) { 694 695 IppNoValueAttribute *attr = new IppNoValueAttribute((IPP_TAG)tag); 696 is >> *attr; 697 attrs.push_back(attr); 698 699 } else if (tag <= 0x2F) { // integer values 700 701 switch (tag) { 702 case IPP_INTEGER: 703 case IPP_ENUM: 704 { 705 IppIntegerAttribute *attr = new IppIntegerAttribute((IPP_TAG)tag); 706 is >> *attr; 707 attrs.push_back(attr); 708 } 709 break; 710 case IPP_BOOLEAN: 711 { 712 IppBooleanAttribute *attr = new IppBooleanAttribute((IPP_TAG)tag); 713 is >> *attr; 714 attrs.push_back(attr); 715 } 716 break; 717 default: 718 { 719 short len = readLength(is); 720 is.seekg(len, ios::cur); 721 len = readLength(is); 722 is.seekg(len, ios::cur); 723 } 724 break; 725 } 726 727 } else if (tag <= 0x3F) { // octetString values 728 729 switch (tag) { 730 case IPP_STRING: 731 { 732 IppStringAttribute *attr = new IppStringAttribute((IPP_TAG)tag); 733 is >> *attr; 734 attrs.push_back(attr); 735 } 736 break; 737 case IPP_DATETIME: 738 { 739 IppDatetimeAttribute *attr = new IppDatetimeAttribute((IPP_TAG)tag); 740 is >> *attr; 741 attrs.push_back(attr); 742 } 743 break; 744 case IPP_RESOLUTION: 745 { 746 IppResolutionAttribute *attr = new IppResolutionAttribute((IPP_TAG)tag); 747 is >> *attr; 748 attrs.push_back(attr); 749 } 750 break; 751 case IPP_RANGE_OF_INTEGER: 752 { 753 IppRangeOfIntegerAttribute *attr = new IppRangeOfIntegerAttribute((IPP_TAG)tag); 754 is >> *attr; 755 attrs.push_back(attr); 756 } 757 break; 758 case IPP_TEXT_WITH_LANGUAGE: 759 case IPP_NAME_WITH_LANGUAGE: 760 { 761 IppDoubleStringAttribute *attr = new IppDoubleStringAttribute((IPP_TAG)tag); 762 is >> *attr; 763 attrs.push_back(attr); 764 } 765 break; 766 default: 767 { 768 short len = readLength(is); 769 is.seekg(len, ios::cur); 770 len = readLength(is); 771 is.seekg(len, ios::cur); 772 } 773 break; 774 } 775 776 } else if (tag <= 0x5F) { // character-string values 777 778 // case IPP_TEXT_WITHOUT_LANGUAGE: 779 // case IPP_NAME_WITHOUT_LANGUAGE: 780 // case IPP_KEYWORD: 781 // case IPP_URI: 782 // case IPP_URISCHEME: 783 // case IPP_CHARSET: 784 // case IPP_NATURAL_LANGUAGE: 785 // case IPP_MIME_MEDIA_TYPE: 786 787 IppStringAttribute *attr = new IppStringAttribute((IPP_TAG)tag); 788 is >> *attr; 789 attrs.push_back(attr); 790 } 791 } 792 return is; 793 } 794 795 ostream &IppContent::output(ostream &os) const 796 { 797 unsigned short ns_version = htons(version); // version-number 798 os.write((char *)&ns_version, sizeof(ns_version)); // version-number 799 800 unsigned short ns_operation_id = htons(operation_id); // operation-id 801 os.write((char *)&ns_operation_id, sizeof(ns_operation_id)); // operation-id 802 803 unsigned long ns_request_id = htonl(request_id); // request-id 804 os.write((char *)&ns_request_id, sizeof(ns_request_id)); // request-id 805 806 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) { 807 os << *(*it); 808 } 809 810 ifstream ifs; 811 istream *iss = is; 812 if (iss == NULL) { 813 if (!file_path.empty()) { 814 ifs.open(file_path.c_str(), ios::in | ios::binary); 815 iss = &ifs; 816 } 817 } 818 if (iss && iss->good()) { 819 if (iss->good()) { 820 char c; 821 while (iss->get(c)) { 822 os.put(c); 823 } 824 } 825 } 826 827 return os; 828 } 829 830 void IppContent::setDelimiter(IPP_TAG tag) 831 { 832 attrs.push_back(new IppAttribute(tag)); 833 } 834 835 void IppContent::setInteger(const char *name, int value) 836 { 837 attrs.push_back(new IppIntegerAttribute(IPP_INTEGER, name, value)); 838 } 839 840 void IppContent::setBoolean(const char *name, bool value) 841 { 842 attrs.push_back(new IppBooleanAttribute(IPP_BOOLEAN, name, value)); 843 } 844 845 void IppContent::setString(const char *name, const char *value) 846 { 847 attrs.push_back(new IppStringAttribute(IPP_STRING, name, value)); 848 } 849 850 void IppContent::setDateTime(const char *name, const DATETIME *dt) 851 { 852 attrs.push_back(new IppDatetimeAttribute(IPP_DATETIME, name, dt)); 853 } 854 855 void IppContent::setResolution(const char *name, int x, int y, IPP_RESOLUTION_UNITS u) 856 { 857 attrs.push_back(new IppResolutionAttribute(IPP_RESOLUTION, name, x, y, u)); 858 } 859 860 void IppContent::setRangeOfInteger(const char *name, int lower, int upper) 861 { 862 attrs.push_back(new IppRangeOfIntegerAttribute(IPP_RANGE_OF_INTEGER, name, lower, upper)); 863 } 864 865 void IppContent::setTextWithLanguage(const char *name, const char *s1, const char *s2) 866 { 867 attrs.push_back(new IppDoubleStringAttribute(IPP_TEXT_WITH_LANGUAGE, name, s1, s2)); 868 } 869 870 void IppContent::setNameWithLanguage(const char *name, const char *s1, const char *s2) 871 { 872 attrs.push_back(new IppDoubleStringAttribute(IPP_NAME_WITH_LANGUAGE, name, s1, s2)); 873 } 874 875 void IppContent::setTextWithoutLanguage(const char *name, const char *value) 876 { 877 attrs.push_back(new IppStringAttribute(IPP_TEXT_WITHOUT_LANGUAGE, name, value)); 878 } 879 880 void IppContent::setNameWithoutLanguage(const char *name, const char *value) 881 { 882 attrs.push_back(new IppStringAttribute(IPP_NAME_WITHOUT_LANGUAGE, name, value)); 883 } 884 885 void IppContent::setKeyword(const char *name, const char *value) 886 { 887 attrs.push_back(new IppStringAttribute(IPP_KEYWORD, name, value)); 888 } 889 890 void IppContent::setURI(const char *name, const char *value) 891 { 892 attrs.push_back(new IppStringAttribute(IPP_URI, name, value)); 893 } 894 895 void IppContent::setURIScheme(const char *name, const char *value) 896 { 897 attrs.push_back(new IppStringAttribute(IPP_URISCHEME, name, value)); 898 } 899 900 void IppContent::setCharset(const char *name, const char *value) 901 { 902 attrs.push_back(new IppStringAttribute(IPP_CHARSET, name, value)); 903 } 904 905 void IppContent::setNaturalLanguage(const char *name, const char *value) 906 { 907 attrs.push_back(new IppStringAttribute(IPP_NATURAL_LANGUAGE, name, value)); 908 } 909 910 void IppContent::setMimeMediaType(const char *name, const char *value) 911 { 912 attrs.push_back(new IppStringAttribute(IPP_MIME_MEDIA_TYPE, name, value)); 913 } 914 915 int IppContent::length() const 916 { 917 int length = 8; // sizeof(version-number + operation-id + request-id) 918 919 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) { 920 length += (*it)->length(); 921 } 922 923 ifstream ifs; 924 istream *iss = is; 925 if (iss == NULL) { 926 if (!file_path.empty()) { 927 ifs.open(file_path.c_str(), ios::in | ios::binary); 928 iss = &ifs; 929 } 930 } 931 if (iss && iss->good()) { 932 int fsize = size; 933 if (fsize < 0) { 934 streampos pos = iss->tellg(); 935 iss->seekg(0, ios::end); 936 fsize = iss->tellg(); 937 iss->seekg(pos, ios::beg); 938 } 939 if (fsize > 0) { 940 length += fsize; 941 } 942 } 943 944 return length; 945 } 946 947 void IppContent::setRawData(const char *file, int n) 948 { 949 file_path = file; 950 size = n; 951 } 952 953 void IppContent::setRawData(istream &ifs, int n) 954 { 955 is = &ifs; 956 size = n; 957 } 958 959 ostream &IppContent::print(ostream &os) const 960 { 961 os << "version: " << hex << version << '\n'; 962 os << "operation_id: " << hex << operation_id << '\n'; 963 os << "request_id: " << hex << request_id << '\n'; 964 965 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) { 966 (*it)->print(os); 967 } 968 969 return os; 970 } 971 972 bool IppContent::fail() const 973 { 974 return !good(); 975 } 976 977 bool IppContent::good() const 978 { 979 return (IPP_SUCCESSFUL_OK_S <= operation_id) && (operation_id <= IPP_SUCCESSFUL_OK_E); 980 } 981 982 bool IppContent::operator !() const 983 { 984 return fail(); 985 } 986 987 const char *IppContent::getStatusMessage() const 988 { 989 if (good()) { 990 switch (operation_id) { 991 case IPP_SUCCESSFUL_OK: 992 return "successful-ok"; 993 case IPP_SUCCESSFUL_OK_IGNORED_OR_SUBSTITUTED_ATTRIBUTES: 994 return "successful-ok-ignored-or-substituted-attributes"; 995 case IPP_SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES: 996 return "successful-ok-conflicting-attributes"; 997 default: 998 return "successful-ok-???"; 999 } 1000 } else if (IPP_CLIENT_ERROR_S <= operation_id && operation_id <= IPP_CLIENT_ERROR_E) { 1001 switch (operation_id) { 1002 case IPP_CLIENT_ERROR_BAD_REQUEST: 1003 return "client-error-bad-request"; 1004 case IPP_CLIENT_ERROR_FORBIDDEN: 1005 return "client-error-forbidden"; 1006 case IPP_CLIENT_ERROR_NOT_AUTHENTICATED: 1007 return "client-error-not-authenticated"; 1008 case IPP_CLIENT_ERROR_NOT_AUTHORIZED: 1009 return "client-error-not-authorized"; 1010 case IPP_CLIENT_ERROR_NOT_POSSIBLE: 1011 return "client-error-not-possible"; 1012 case IPP_CLIENT_ERROR_TIMEOUT: 1013 return "client-error-timeout"; 1014 case IPP_CLIENT_ERROR_NOT_FOUND: 1015 return "client-error-not-found"; 1016 case IPP_CLIENT_ERROR_GONE: 1017 return "client-error-gone"; 1018 case IPP_CLIENT_ERROR_REQUEST_ENTITY_TOO_LARGE: 1019 return "client-error-request-entity-too-large"; 1020 case IPP_CLIENT_ERROR_REQUEST_VALUE_TOO_LONG: 1021 return "client-error-request-value-too-long"; 1022 case IPP_CLIENT_ERROR_DOCUMENT_FORMAT_NOT_SUPPORTED: 1023 return "client-error-document-format-not-supported"; 1024 case IPP_CLIENT_ERROR_ATTRIBUTES_OR_VALUES_NOT_SUPPORTED: 1025 return "client-error-attributes-or-values-not-supported"; 1026 case IPP_CLIENT_ERROR_URI_SCHEME_NOT_SUPPORTED: 1027 return "client-error-uri-scheme-not-supported"; 1028 case IPP_CLIENT_ERROR_CHARSET_NOT_SUPPORTED: 1029 return "client-error-charset-not-supported"; 1030 case IPP_CLIENT_ERROR_CONFLICTING_ATTRIBUTES: 1031 return "client-error-conflicting-attributes"; 1032 default: 1033 return "client-error-???"; 1034 } 1035 } else if (IPP_SERVER_ERROR_S <= operation_id && operation_id <= IPP_SERVER_ERROR_E) { 1036 switch (operation_id) { 1037 case IPP_SERVER_ERROR_INTERNAL_ERROR: 1038 return "server-error-internal-error"; 1039 case IPP_SERVER_ERROR_OPERATION_NOT_SUPPORTED: 1040 return "server-error-operation-not-supported"; 1041 case IPP_SERVER_ERROR_SERVICE_UNAVAILABLE: 1042 return "server-error-service-unavailable"; 1043 case IPP_SERVER_ERROR_VERSION_NOT_SUPPORTED: 1044 return "server-error-version-not-supported"; 1045 case IPP_SERVER_ERROR_DEVICE_ERROR: 1046 return "server-error-device-error"; 1047 case IPP_SERVER_ERROR_TEMPORARY_ERROR: 1048 return "server-error-temporary-error"; 1049 case IPP_SERVER_ERROR_NOT_ACCEPTING_JOBS: 1050 return "server-error-not-accepting-jobs"; 1051 case IPP_SERVER_ERROR_BUSY: 1052 return "server-error-busy"; 1053 case IPP_SERVER_ERROR_JOB_CANCELED: 1054 return "server-error-job-canceled"; 1055 default: 1056 return "server-error-???"; 1057 } 1058 } else { 1059 return "unknown error."; 1060 } 1061 } 1062