vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / print / transports / ipp / IppContent.cpp
blob8f368b357328c9df0b1c1943de040733422b8b46
1 // Sun, 18 Jun 2000
2 // Y.Takagi
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
11 #include <fstream>
12 #include <list>
13 #include <cstring>
15 #include "IppContent.h"
17 /*----------------------------------------------------------------------*/
19 short readLength(istream &is)
21 short len = 0;
22 is.read((char *)&len, sizeof(short));
23 len = ntohs(len);
24 return len;
27 void writeLength(ostream &os, short len)
29 len = htons(len);
30 os.write((char *)&len, sizeof(short));
33 /*----------------------------------------------------------------------*/
35 DATETIME::DATETIME()
37 memset(this, 0, sizeof(DATETIME));
40 DATETIME::DATETIME(const DATETIME &dt)
42 memcpy(this, &dt.datetime, sizeof(DATETIME));
45 DATETIME & DATETIME::operator = (const DATETIME &dt)
47 memcpy(this, &dt.datetime, sizeof(DATETIME));
48 return *this;
51 istream& operator >> (istream &is, DATETIME &attr)
53 return is;
56 ostream& operator << (ostream &os, const DATETIME &attr)
58 return os;
62 /*----------------------------------------------------------------------*/
64 IppAttribute::IppAttribute(IPP_TAG t)
65 : tag(t)
69 int IppAttribute::length() const
71 return 1;
74 istream &IppAttribute::input(istream &is)
76 return is;
79 ostream &IppAttribute::output(ostream &os) const
81 os << (unsigned char)tag;
82 return os;
85 ostream &IppAttribute::print(ostream &os) const
87 os << "Tag: " << hex << (int)tag << '\n';
88 return os;
91 /*----------------------------------------------------------------------*/
93 IppNamedAttribute::IppNamedAttribute(IPP_TAG t)
94 : IppAttribute(t)
98 IppNamedAttribute::IppNamedAttribute(IPP_TAG t, const char *s)
99 : IppAttribute(t), name(s ? s : "")
103 int IppNamedAttribute::length() const
105 return IppAttribute::length() + 2 + name.length();
108 istream &IppNamedAttribute::input(istream &is)
110 short len = readLength(is);
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;
120 return is;
123 ostream &IppNamedAttribute::output(ostream &os) const
125 IppAttribute::output(os);
127 writeLength(os, name.length());
128 os << name;
130 return os;
133 ostream &IppNamedAttribute::print(ostream &os) const
135 IppAttribute::print(os);
136 os << '\t' << "Name: " << name << '\n';
137 return os;
140 /*----------------------------------------------------------------------*/
142 IppNoValueAttribute::IppNoValueAttribute(IPP_TAG t)
143 : IppNamedAttribute(t)
147 IppNoValueAttribute::IppNoValueAttribute(IPP_TAG t, const char *n)
148 : IppNamedAttribute(t, n)
152 int IppNoValueAttribute::length() const
154 return IppAttribute::length() + 2;
157 istream &IppNoValueAttribute::input(istream &is)
159 IppNamedAttribute::input(is);
161 short len = readLength(is);
163 if (0 < len) {
164 is.seekg(len, ios::cur);
167 return is;
170 ostream &IppNoValueAttribute::output(ostream &os) const
172 IppAttribute::output(os);
174 writeLength(os, 0);
176 return os;
179 ostream &IppNoValueAttribute::print(ostream &os) const
181 return IppNamedAttribute::print(os);
184 /*----------------------------------------------------------------------*/
186 IppIntegerAttribute::IppIntegerAttribute(IPP_TAG t)
187 : IppNamedAttribute(t), value(0)
191 IppIntegerAttribute::IppIntegerAttribute(IPP_TAG t, const char *n, int v)
192 : IppNamedAttribute(t, n), value(v)
196 int IppIntegerAttribute::length() const
198 return IppNamedAttribute::length() + 2 + 4;
201 istream &IppIntegerAttribute::input(istream &is)
203 IppNamedAttribute::input(is);
205 short len = readLength(is);
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);
214 return is;
217 ostream &IppIntegerAttribute::output(ostream &os) const
219 IppNamedAttribute::output(os);
221 writeLength(os, 4);
222 unsigned long val = htonl(value);
223 os.write((char *)&val, sizeof(val));
224 return os;
227 ostream &IppIntegerAttribute::print(ostream &os) const
229 IppNamedAttribute::print(os);
230 os << '\t' << "Value: " << dec << value << '\n';
231 return os;
234 /*----------------------------------------------------------------------*/
236 IppBooleanAttribute::IppBooleanAttribute(IPP_TAG t)
237 : IppNamedAttribute(t), value(false)
241 IppBooleanAttribute::IppBooleanAttribute(IPP_TAG t, const char *n, bool f)
242 : IppNamedAttribute(t, n), value(f)
246 int IppBooleanAttribute::length() const
248 return IppNamedAttribute::length() + 2 + 1;
252 istream &IppBooleanAttribute::input(istream &is)
254 IppNamedAttribute::input(is);
256 short len = readLength(is);
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);
266 return is;
269 ostream &IppBooleanAttribute::output(ostream &os) const
271 IppNamedAttribute::output(os);
273 writeLength(os, 1);
274 char c = (char)value;
275 os.write((char *)&c, sizeof(c));
277 return os;
280 ostream &IppBooleanAttribute::print(ostream &os) const
282 IppNamedAttribute::print(os);
283 os << '\t' << "Value: " << value << '\n';
284 return os;
287 /*----------------------------------------------------------------------*/
289 IppDatetimeAttribute::IppDatetimeAttribute(IPP_TAG t)
290 : IppNamedAttribute(t)
294 IppDatetimeAttribute::IppDatetimeAttribute(IPP_TAG t, const char *n, const DATETIME *dt)
295 : IppNamedAttribute(t, n), datetime(*dt)
299 int IppDatetimeAttribute::length() const
301 return IppNamedAttribute::length() + 2 + 11;
304 istream &IppDatetimeAttribute::input(istream &is)
306 IppNamedAttribute::input(is);
308 short len = readLength(is);
310 if (0 < len) {
311 if (len == 11) {
312 is >> datetime;
313 } else {
314 is.seekg(len, ios::cur);
318 return is;
321 ostream &IppDatetimeAttribute::output(ostream &os) const
323 IppNamedAttribute::output(os);
325 writeLength(os, 11);
326 os << datetime;
328 return os;
331 ostream &IppDatetimeAttribute::print(ostream &os) const
333 IppNamedAttribute::print(os);
334 os << '\t' << "Value(DateTime): " << datetime << '\n';
335 return os;
338 /*----------------------------------------------------------------------*/
340 IppStringAttribute::IppStringAttribute(IPP_TAG t)
341 : IppNamedAttribute(t)
345 IppStringAttribute::IppStringAttribute(IPP_TAG t, const char *n, const char *s)
346 : IppNamedAttribute(t, n), text(s ? s : "")
350 int IppStringAttribute::length() const
352 return IppNamedAttribute::length() + 2 + text.length();
355 istream &IppStringAttribute::input(istream &is)
357 IppNamedAttribute::input(is);
359 short len = readLength(is);
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;
369 return is;
372 ostream &IppStringAttribute::output(ostream &os) const
374 IppNamedAttribute::output(os);
376 writeLength(os, text.length());
377 os << text;
379 return os;
382 ostream &IppStringAttribute::print(ostream &os) const
384 IppNamedAttribute::print(os);
385 os << '\t' << "Value: " << text << '\n';
386 return os;
389 /*----------------------------------------------------------------------*/
391 IppDoubleStringAttribute::IppDoubleStringAttribute(IPP_TAG t)
392 : IppNamedAttribute(t)
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 : "")
401 int IppDoubleStringAttribute::length() const
403 return IppNamedAttribute::length() + 2 + text1.length() + 2 + text2.length();
406 istream &IppDoubleStringAttribute::input(istream &is)
408 IppNamedAttribute::input(is);
410 short len = readLength(is);
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;
420 len = readLength(is);
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;
430 return is;
433 ostream &IppDoubleStringAttribute::output(ostream &os) const
435 IppNamedAttribute::output(os);
437 writeLength(os, text1.length());
438 os << text1;
440 writeLength(os, text2.length());
441 os << text2;
443 return os;
446 ostream &IppDoubleStringAttribute::print(ostream &os) const
448 IppNamedAttribute::print(os);
449 os << '\t' << "Value1: " << text1 << '\n';
450 os << '\t' << "Value2: " << text2 << '\n';
451 return os;
454 /*----------------------------------------------------------------------*/
456 IppResolutionAttribute::IppResolutionAttribute(IPP_TAG t)
457 : IppNamedAttribute(t), xres(0), yres(0), resolution_units((IPP_RESOLUTION_UNITS)0)
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)
466 int IppResolutionAttribute::length() const
468 return IppNamedAttribute::length() + 2 + 4 + 2 + 4 + 2 + 1;
471 istream &IppResolutionAttribute::input(istream &is)
473 IppNamedAttribute::input(is);
475 short len = readLength(is);
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);
484 len = readLength(is);
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);
493 len = readLength(is);
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);
503 return is;
506 ostream &IppResolutionAttribute::output(ostream &os) const
508 IppNamedAttribute::output(os);
510 writeLength(os, 4);
511 unsigned long val = htonl(xres);
512 os.write((char *)&val, sizeof(val));
514 writeLength(os, 4);
515 val = htonl(yres);
516 os.write((char *)&val, sizeof(val));
518 writeLength(os, 1);
519 unsigned char c = (unsigned char)resolution_units;
520 os.write((char *)&c, sizeof(c));
522 return os;
525 ostream &IppResolutionAttribute::print(ostream &os) const
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;
534 /*----------------------------------------------------------------------*/
536 IppRangeOfIntegerAttribute::IppRangeOfIntegerAttribute(IPP_TAG t)
537 : IppNamedAttribute(t), lower(0), upper(0)
541 IppRangeOfIntegerAttribute::IppRangeOfIntegerAttribute(IPP_TAG t, const char *n, int l, int u)
542 : IppNamedAttribute(t, n), lower(l), upper(u)
546 int IppRangeOfIntegerAttribute::length() const
548 return IppNamedAttribute::length() + 2 + 4 + 2 + 4;
551 istream &IppRangeOfIntegerAttribute::input(istream &is)
553 IppNamedAttribute::input(is);
555 short len = readLength(is);
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);
564 len = readLength(is);
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);
573 return is;
576 ostream &IppRangeOfIntegerAttribute::output(ostream &os) const
578 IppNamedAttribute::output(os);
580 writeLength(os, 4);
581 unsigned long val = htonl(lower);
582 os.write((char *)&val, sizeof(val));
584 writeLength(os, 4);
585 val = htonl(upper);
586 os.write((char *)&val, sizeof(val));
588 return os;
591 ostream &IppRangeOfIntegerAttribute::print(ostream &os) const
593 IppNamedAttribute::print(os);
594 os << '\t' << "Value(lower): " << dec << lower << '\n';
595 os << '\t' << "Value(upper): " << dec << upper << '\n';
596 return os;
599 /*----------------------------------------------------------------------*/
601 IppContent::IppContent()
603 version = 0x0100;
604 operation_id = IPP_GET_PRINTER_ATTRIBUTES;
605 request_id = 0x00000001;
607 is = NULL;
608 size = -1;
611 IppContent::~IppContent()
613 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) {
614 delete (*it);
618 unsigned short IppContent::getVersion() const
620 return version;
623 void IppContent::setVersion(unsigned short i)
625 version = i;
629 IPP_OPERATION_ID IppContent::getOperationId() const
631 return (IPP_OPERATION_ID)operation_id;
634 void IppContent::setOperationId(IPP_OPERATION_ID i)
636 operation_id = i;
639 IPP_STATUS_CODE IppContent::getStatusCode() const
641 return (IPP_STATUS_CODE)operation_id;
644 unsigned long IppContent::getRequestId() const
646 return request_id;
649 void IppContent::setRequestId(unsigned long i)
651 request_id = i;
654 istream &IppContent::input(istream &is)
656 if (!is.read((char *)&version, sizeof(version))) {
657 return is;
660 version = ntohs(version);
662 if (!is.read((char *)&operation_id, sizeof(operation_id))) {
663 return is;
666 operation_id = ntohs(operation_id);
668 if (!is.read((char *)&request_id, sizeof(request_id))) {
669 return is;
672 request_id = ntohl(request_id);
673 char tag;
675 while (1) {
677 if (!is.read((char *)&tag, sizeof(tag))) {
678 return is;
681 if (tag <= 0x0F) { // delimiter
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:
689 attrs.push_back(new IppAttribute((IPP_TAG)tag));
690 if (tag == IPP_END_OF_ATTRIBUTES_TAG) {
691 break;
694 } else if (tag <= 0x1F) {
696 IppNoValueAttribute *attr = new IppNoValueAttribute((IPP_TAG)tag);
697 is >> *attr;
698 attrs.push_back(attr);
700 } else if (tag <= 0x2F) { // integer values
702 switch (tag) {
703 case IPP_INTEGER:
704 case IPP_ENUM:
706 IppIntegerAttribute *attr = new IppIntegerAttribute((IPP_TAG)tag);
707 is >> *attr;
708 attrs.push_back(attr);
710 break;
711 case IPP_BOOLEAN:
713 IppBooleanAttribute *attr = new IppBooleanAttribute((IPP_TAG)tag);
714 is >> *attr;
715 attrs.push_back(attr);
717 break;
718 default:
720 short len = readLength(is);
721 is.seekg(len, ios::cur);
722 len = readLength(is);
723 is.seekg(len, ios::cur);
725 break;
728 } else if (tag <= 0x3F) { // octetString values
730 switch (tag) {
731 case IPP_STRING:
733 IppStringAttribute *attr = new IppStringAttribute((IPP_TAG)tag);
734 is >> *attr;
735 attrs.push_back(attr);
737 break;
738 case IPP_DATETIME:
740 IppDatetimeAttribute *attr = new IppDatetimeAttribute((IPP_TAG)tag);
741 is >> *attr;
742 attrs.push_back(attr);
744 break;
745 case IPP_RESOLUTION:
747 IppResolutionAttribute *attr = new IppResolutionAttribute((IPP_TAG)tag);
748 is >> *attr;
749 attrs.push_back(attr);
751 break;
752 case IPP_RANGE_OF_INTEGER:
754 IppRangeOfIntegerAttribute *attr = new IppRangeOfIntegerAttribute((IPP_TAG)tag);
755 is >> *attr;
756 attrs.push_back(attr);
758 break;
759 case IPP_TEXT_WITH_LANGUAGE:
760 case IPP_NAME_WITH_LANGUAGE:
762 IppDoubleStringAttribute *attr = new IppDoubleStringAttribute((IPP_TAG)tag);
763 is >> *attr;
764 attrs.push_back(attr);
766 break;
767 default:
769 short len = readLength(is);
770 is.seekg(len, ios::cur);
771 len = readLength(is);
772 is.seekg(len, ios::cur);
774 break;
777 } else if (tag <= 0x5F) { // character-string values
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:
788 IppStringAttribute *attr = new IppStringAttribute((IPP_TAG)tag);
789 is >> *attr;
790 attrs.push_back(attr);
793 return is;
796 ostream &IppContent::output(ostream &os) const
798 unsigned short ns_version = htons(version); // version-number
799 os.write((char *)&ns_version, sizeof(ns_version)); // version-number
801 unsigned short ns_operation_id = htons(operation_id); // operation-id
802 os.write((char *)&ns_operation_id, sizeof(ns_operation_id)); // operation-id
804 unsigned long ns_request_id = htonl(request_id); // request-id
805 os.write((char *)&ns_request_id, sizeof(ns_request_id)); // request-id
807 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) {
808 os << *(*it);
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;
819 if (iss && iss->good()) {
820 if (iss->good()) {
821 char c;
822 while (iss->get(c)) {
823 os.put(c);
828 return os;
831 void IppContent::setDelimiter(IPP_TAG tag)
833 attrs.push_back(new IppAttribute(tag));
836 void IppContent::setInteger(const char *name, int value)
838 attrs.push_back(new IppIntegerAttribute(IPP_INTEGER, name, value));
841 void IppContent::setBoolean(const char *name, bool value)
843 attrs.push_back(new IppBooleanAttribute(IPP_BOOLEAN, name, value));
846 void IppContent::setString(const char *name, const char *value)
848 attrs.push_back(new IppStringAttribute(IPP_STRING, name, value));
851 void IppContent::setDateTime(const char *name, const DATETIME *dt)
853 attrs.push_back(new IppDatetimeAttribute(IPP_DATETIME, name, dt));
856 void IppContent::setResolution(const char *name, int x, int y, IPP_RESOLUTION_UNITS u)
858 attrs.push_back(new IppResolutionAttribute(IPP_RESOLUTION, name, x, y, u));
861 void IppContent::setRangeOfInteger(const char *name, int lower, int upper)
863 attrs.push_back(new IppRangeOfIntegerAttribute(IPP_RANGE_OF_INTEGER, name, lower, upper));
866 void IppContent::setTextWithLanguage(const char *name, const char *s1, const char *s2)
868 attrs.push_back(new IppDoubleStringAttribute(IPP_TEXT_WITH_LANGUAGE, name, s1, s2));
871 void IppContent::setNameWithLanguage(const char *name, const char *s1, const char *s2)
873 attrs.push_back(new IppDoubleStringAttribute(IPP_NAME_WITH_LANGUAGE, name, s1, s2));
876 void IppContent::setTextWithoutLanguage(const char *name, const char *value)
878 attrs.push_back(new IppStringAttribute(IPP_TEXT_WITHOUT_LANGUAGE, name, value));
881 void IppContent::setNameWithoutLanguage(const char *name, const char *value)
883 attrs.push_back(new IppStringAttribute(IPP_NAME_WITHOUT_LANGUAGE, name, value));
886 void IppContent::setKeyword(const char *name, const char *value)
888 attrs.push_back(new IppStringAttribute(IPP_KEYWORD, name, value));
891 void IppContent::setURI(const char *name, const char *value)
893 attrs.push_back(new IppStringAttribute(IPP_URI, name, value));
896 void IppContent::setURIScheme(const char *name, const char *value)
898 attrs.push_back(new IppStringAttribute(IPP_URISCHEME, name, value));
901 void IppContent::setCharset(const char *name, const char *value)
903 attrs.push_back(new IppStringAttribute(IPP_CHARSET, name, value));
906 void IppContent::setNaturalLanguage(const char *name, const char *value)
908 attrs.push_back(new IppStringAttribute(IPP_NATURAL_LANGUAGE, name, value));
911 void IppContent::setMimeMediaType(const char *name, const char *value)
913 attrs.push_back(new IppStringAttribute(IPP_MIME_MEDIA_TYPE, name, value));
916 int IppContent::length() const
918 int length = 8; // sizeof(version-number + operation-id + request-id)
920 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) {
921 length += (*it)->length();
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;
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);
940 if (fsize > 0) {
941 length += fsize;
945 return length;
948 void IppContent::setRawData(const char *file, int n)
950 file_path = file;
951 size = n;
954 void IppContent::setRawData(istream &ifs, int n)
956 is = &ifs;
957 size = n;
960 ostream &IppContent::print(ostream &os) const
962 os << "version: " << hex << version << '\n';
963 os << "operation_id: " << hex << operation_id << '\n';
964 os << "request_id: " << hex << request_id << '\n';
966 for (list<IppAttribute *>::const_iterator it = attrs.begin(); it != attrs.end(); it++) {
967 (*it)->print(os);
970 return os;
973 bool IppContent::fail() const
975 return !good();
978 bool IppContent::good() const
980 return /*operation_id >= IPP_SUCCESSFUL_OK_S &&*/ operation_id <= IPP_SUCCESSFUL_OK_E;
983 bool IppContent::operator !() const
985 return fail();
988 const char *IppContent::getStatusMessage() const
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-???";
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-???";
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-???";
1059 } else {
1060 return "unknown error.";