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