1// Sun, 18 Jun 2000 2// Y.Takagi 3 4#if defined(__HAIKU__) || defined(HAIKU_TARGET_PLATFORM_BONE) 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 19short readLength(istream &is) 20{ 21 short len = 0; 22 is.read((char *)&len, sizeof(short)); 23 len = ntohs(len); 24 return len; 25} 26 27void writeLength(ostream &os, short len) 28{ 29 len = htons(len); 30 os.write((char *)&len, sizeof(short)); 31} 32 33/*----------------------------------------------------------------------*/ 34 35DATETIME::DATETIME() 36{ 37 memset(this, 0, sizeof(DATETIME)); 38} 39 40DATETIME::DATETIME(const DATETIME &dt) 41{ 42 memcpy(this, &dt.datetime, sizeof(DATETIME)); 43} 44 45DATETIME & DATETIME::operator = (const DATETIME &dt) 46{ 47 memcpy(this, &dt.datetime, sizeof(DATETIME)); 48 return *this; 49} 50 51istream& operator >> (istream &is, DATETIME &attr) 52{ 53 return is; 54} 55 56ostream& operator << (ostream &os, const DATETIME &attr) 57{ 58 return os; 59} 60 61 62/*----------------------------------------------------------------------*/ 63 64IppAttribute::IppAttribute(IPP_TAG t) 65 : tag(t) 66{ 67} 68 69int IppAttribute::length() const 70{ 71 return 1; 72} 73 74istream &IppAttribute::input(istream &is) 75{ 76 return is; 77} 78 79ostream &IppAttribute::output(ostream &os) const 80{ 81 os << (unsigned char)tag; 82 return os; 83} 84 85ostream &IppAttribute::print(ostream &os) const 86{ 87 os << "Tag: " << hex << (int)tag << '\n'; 88 return os; 89} 90 91/*----------------------------------------------------------------------*/ 92 93IppNamedAttribute::IppNamedAttribute(IPP_TAG t) 94 : IppAttribute(t) 95{ 96} 97 98IppNamedAttribute::IppNamedAttribute(IPP_TAG t, const char *s) 99 : IppAttribute(t), name(s ? s : "") 100{ 101} 102 103int IppNamedAttribute::length() const 104{ 105 return IppAttribute::length() + 2 + name.length(); 106} 107 108istream &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 123ostream &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 133ostream &IppNamedAttribute::print(ostream &os) const 134{ 135 IppAttribute::print(os); 136 os << '\t' << "Name: " << name << '\n'; 137 return os; 138} 139 140/*----------------------------------------------------------------------*/ 141 142IppNoValueAttribute::IppNoValueAttribute(IPP_TAG t) 143 : IppNamedAttribute(t) 144{ 145} 146 147IppNoValueAttribute::IppNoValueAttribute(IPP_TAG t, const char *n) 148 : IppNamedAttribute(t, n) 149{ 150} 151 152int IppNoValueAttribute::length() const 153{ 154 return IppAttribute::length() + 2; 155} 156 157istream &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 170ostream &IppNoValueAttribute::output(ostream &os) const 171{ 172 IppAttribute::output(os); 173 174 writeLength(os, 0); 175 176 return os; 177} 178 179ostream &IppNoValueAttribute::print(ostream &os) const 180{ 181 return IppNamedAttribute::print(os); 182} 183 184/*----------------------------------------------------------------------*/ 185 186IppIntegerAttribute::IppIntegerAttribute(IPP_TAG t) 187 : IppNamedAttribute(t), value(0) 188{ 189} 190 191IppIntegerAttribute::IppIntegerAttribute(IPP_TAG t, const char *n, int v) 192 : IppNamedAttribute(t, n), value(v) 193{ 194} 195 196int IppIntegerAttribute::length() const 197{ 198 return IppNamedAttribute::length() + 2 + 4; 199} 200 201istream &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 217ostream &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 227ostream &IppIntegerAttribute::print(ostream &os) const 228{ 229 IppNamedAttribute::print(os); 230 os << '\t' << "Value: " << dec << value << '\n'; 231 return os; 232} 233 234/*----------------------------------------------------------------------*/ 235 236IppBooleanAttribute::IppBooleanAttribute(IPP_TAG t) 237 : IppNamedAttribute(t), value(false) 238{ 239} 240 241IppBooleanAttribute::IppBooleanAttribute(IPP_TAG t, const char *n, bool f) 242 : IppNamedAttribute(t, n), value(f) 243{ 244} 245 246int IppBooleanAttribute::length() const 247{ 248 return IppNamedAttribute::length() + 2 + 1; 249} 250 251 252istream &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 269ostream &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 280ostream &IppBooleanAttribute::print(ostream &os) const 281{ 282 IppNamedAttribute::print(os); 283 os << '\t' << "Value: " << value << '\n'; 284 return os; 285} 286 287/*----------------------------------------------------------------------*/ 288 289IppDatetimeAttribute::IppDatetimeAttribute(IPP_TAG t) 290 : IppNamedAttribute(t) 291{ 292} 293 294IppDatetimeAttribute::IppDatetimeAttribute(IPP_TAG t, const char *n, const DATETIME *dt) 295 : IppNamedAttribute(t, n), datetime(*dt) 296{ 297} 298 299int IppDatetimeAttribute::length() const 300{ 301 return IppNamedAttribute::length() + 2 + 11; 302} 303 304istream &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 321ostream &IppDatetimeAttribute::output(ostream &os) const 322{ 323 IppNamedAttribute::output(os); 324 325 writeLength(os, 11); 326 os << datetime; 327 328 return os; 329} 330 331ostream &IppDatetimeAttribute::print(ostream &os) const 332{ 333 IppNamedAttribute::print(os); 334 os << '\t' << "Value(DateTime): " << datetime << '\n'; 335 return os; 336} 337 338/*----------------------------------------------------------------------*/ 339 340IppStringAttribute::IppStringAttribute(IPP_TAG t) 341 : IppNamedAttribute(t) 342{ 343} 344 345IppStringAttribute::IppStringAttribute(IPP_TAG t, const char *n, const char *s) 346: IppNamedAttribute(t, n), text(s ? s : "") 347{ 348} 349 350int IppStringAttribute::length() const 351{ 352 return IppNamedAttribute::length() + 2 + text.length(); 353} 354 355istream &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 372ostream &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 382ostream &IppStringAttribute::print(ostream &os) const 383{ 384 IppNamedAttribute::print(os); 385 os << '\t' << "Value: " << text << '\n'; 386 return os; 387} 388 389/*----------------------------------------------------------------------*/ 390 391IppDoubleStringAttribute::IppDoubleStringAttribute(IPP_TAG t) 392 : IppNamedAttribute(t) 393{ 394} 395 396IppDoubleStringAttribute::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 401int IppDoubleStringAttribute::length() const 402{ 403 return IppNamedAttribute::length() + 2 + text1.length() + 2 + text2.length(); 404} 405 406istream &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 433ostream &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 446ostream &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 456IppResolutionAttribute::IppResolutionAttribute(IPP_TAG t) 457 : IppNamedAttribute(t), xres(0), yres(0), resolution_units((IPP_RESOLUTION_UNITS)0) 458{ 459} 460 461IppResolutionAttribute::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 466int IppResolutionAttribute::length() const 467{ 468 return IppNamedAttribute::length() + 2 + 4 + 2 + 4 + 2 + 1; 469} 470 471istream &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 506ostream &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 525ostream &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 536IppRangeOfIntegerAttribute::IppRangeOfIntegerAttribute(IPP_TAG t) 537 : IppNamedAttribute(t), lower(0), upper(0) 538{ 539} 540 541IppRangeOfIntegerAttribute::IppRangeOfIntegerAttribute(IPP_TAG t, const char *n, int l, int u) 542 : IppNamedAttribute(t, n), lower(l), upper(u) 543{ 544} 545 546int IppRangeOfIntegerAttribute::length() const 547{ 548 return IppNamedAttribute::length() + 2 + 4 + 2 + 4; 549} 550 551istream &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 576ostream &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 591ostream &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 601IppContent::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 611IppContent::~IppContent() 612{ 613 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) { 614 delete (*it); 615 } 616} 617 618unsigned short IppContent::getVersion() const 619{ 620 return version; 621} 622 623void IppContent::setVersion(unsigned short i) 624{ 625 version = i; 626} 627 628 629IPP_OPERATION_ID IppContent::getOperationId() const 630{ 631 return (IPP_OPERATION_ID)operation_id; 632} 633 634void IppContent::setOperationId(IPP_OPERATION_ID i) 635{ 636 operation_id = i; 637} 638 639IPP_STATUS_CODE IppContent::getStatusCode() const 640{ 641 return (IPP_STATUS_CODE)operation_id; 642} 643 644unsigned long IppContent::getRequestId() const 645{ 646 return request_id; 647} 648 649void IppContent::setRequestId(unsigned long i) 650{ 651 request_id = i; 652} 653 654istream &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 796ostream &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 831void IppContent::setDelimiter(IPP_TAG tag) 832{ 833 attrs.push_back(new IppAttribute(tag)); 834} 835 836void IppContent::setInteger(const char *name, int value) 837{ 838 attrs.push_back(new IppIntegerAttribute(IPP_INTEGER, name, value)); 839} 840 841void IppContent::setBoolean(const char *name, bool value) 842{ 843 attrs.push_back(new IppBooleanAttribute(IPP_BOOLEAN, name, value)); 844} 845 846void IppContent::setString(const char *name, const char *value) 847{ 848 attrs.push_back(new IppStringAttribute(IPP_STRING, name, value)); 849} 850 851void IppContent::setDateTime(const char *name, const DATETIME *dt) 852{ 853 attrs.push_back(new IppDatetimeAttribute(IPP_DATETIME, name, dt)); 854} 855 856void 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 861void 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 866void 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 871void 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 876void IppContent::setTextWithoutLanguage(const char *name, const char *value) 877{ 878 attrs.push_back(new IppStringAttribute(IPP_TEXT_WITHOUT_LANGUAGE, name, value)); 879} 880 881void IppContent::setNameWithoutLanguage(const char *name, const char *value) 882{ 883 attrs.push_back(new IppStringAttribute(IPP_NAME_WITHOUT_LANGUAGE, name, value)); 884} 885 886void IppContent::setKeyword(const char *name, const char *value) 887{ 888 attrs.push_back(new IppStringAttribute(IPP_KEYWORD, name, value)); 889} 890 891void IppContent::setURI(const char *name, const char *value) 892{ 893 attrs.push_back(new IppStringAttribute(IPP_URI, name, value)); 894} 895 896void IppContent::setURIScheme(const char *name, const char *value) 897{ 898 attrs.push_back(new IppStringAttribute(IPP_URISCHEME, name, value)); 899} 900 901void IppContent::setCharset(const char *name, const char *value) 902{ 903 attrs.push_back(new IppStringAttribute(IPP_CHARSET, name, value)); 904} 905 906void IppContent::setNaturalLanguage(const char *name, const char *value) 907{ 908 attrs.push_back(new IppStringAttribute(IPP_NATURAL_LANGUAGE, name, value)); 909} 910 911void IppContent::setMimeMediaType(const char *name, const char *value) 912{ 913 attrs.push_back(new IppStringAttribute(IPP_MIME_MEDIA_TYPE, name, value)); 914} 915 916int 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 948void IppContent::setRawData(const char *file, int n) 949{ 950 file_path = file; 951 size = n; 952} 953 954void IppContent::setRawData(istream &ifs, int n) 955{ 956 is = &ifs; 957 size = n; 958} 959 960ostream &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 973bool IppContent::fail() const 974{ 975 return !good(); 976} 977 978bool IppContent::good() const 979{ 980 return /*operation_id >= IPP_SUCCESSFUL_OK_S &&*/ operation_id <= IPP_SUCCESSFUL_OK_E; 981} 982 983bool IppContent::operator !() const 984{ 985 return fail(); 986} 987 988const 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