📄 ipp.c
字号:
* Then write the collection attribute... */ value->collection->state = IPP_IDLE; if (ippWriteIO(dst, cb, 1, ipp, value->collection) == IPP_ERROR) return (IPP_ERROR); } break; default : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if (i) { /* * Arrays and sets are done by sending additional * values with a zero-length name... */ if ((sizeof(buffer) - (bufptr - buffer)) < 3) { if ((*cb)(dst, buffer, bufptr - buffer) < 0) { DEBUG_puts("ippWrite: Could not write IPP attribute..."); return (IPP_ERROR); } bufptr = buffer; } *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } /* * An unknown value might some new value that a * vendor has come up with. It consists of a * 2-byte length and the bytes in the unknown * value buffer. */ n = value->unknown.length; if (n > (sizeof(buffer) - 2)) return (IPP_ERROR); if ((int)(sizeof(buffer) - (bufptr - buffer)) < (n + 2)) { if ((*cb)(dst, buffer, bufptr - buffer) < 0) { DEBUG_puts("ippWrite: Could not write IPP attribute..."); return (IPP_ERROR); } bufptr = buffer; } /* Length of unknown value */ *bufptr++ = n >> 8; *bufptr++ = n; /* Value */ if (n > 0) { memcpy(bufptr, value->unknown.data, n); bufptr += n; } } break; } /* * Write the data out... */ if ((*cb)(dst, buffer, bufptr - buffer) < 0) { DEBUG_puts("ippWrite: Could not write IPP attribute..."); return (IPP_ERROR); } DEBUG_printf(("ippWrite: wrote %d bytes\n", bufptr - buffer)); /* * If blocking is disabled, stop here... */ if (!blocking) break; } if (ipp->current == NULL) { /* * Done with all of the attributes; add the end-of-attributes * tag or end-collection attribute... */ if (parent == NULL) { buffer[0] = IPP_TAG_END; n = 1; } else { buffer[0] = IPP_TAG_END_COLLECTION; buffer[1] = 0; /* empty name */ buffer[2] = 0; buffer[3] = 0; /* empty value */ buffer[4] = 0; n = 5; } if ((*cb)(dst, buffer, n) < 0) { DEBUG_puts("ippWrite: Could not write IPP end-tag..."); return (IPP_ERROR); } ipp->state = IPP_DATA; } break; case IPP_DATA : break; default : break; /* anti-compiler-warning-code */ } return (ipp->state);}/* * '_ipp_add_attr()' - Add a new attribute to the request. */ipp_attribute_t * /* O - New attribute */_ipp_add_attr(ipp_t *ipp, /* I - IPP request */ int num_values) /* I - Number of values */{ ipp_attribute_t *attr; /* New attribute */ DEBUG_printf(("_ipp_add_attr(%p, %d)\n", ipp, num_values)); if (ipp == NULL || num_values < 0) return (NULL); attr = calloc(sizeof(ipp_attribute_t) + (num_values - 1) * sizeof(ipp_value_t), 1); attr->num_values = num_values; if (attr == NULL) return (NULL); if (ipp->last == NULL) ipp->attrs = attr; else ipp->last->next = attr; ipp->last = attr; DEBUG_printf(("_ipp_add_attr(): %p\n", attr)); return (attr);}/* * '_ipp_free_attr()' - Free an attribute. */void_ipp_free_attr(ipp_attribute_t *attr) /* I - Attribute to free */{ int i; /* Looping var */ ipp_value_t *value; /* Current value */ DEBUG_printf(("_ipp_free_attr(): %p\n", attr)); switch (attr->value_tag) { case IPP_TAG_TEXT : case IPP_TAG_NAME : case IPP_TAG_KEYWORD : case IPP_TAG_STRING : case IPP_TAG_URI : case IPP_TAG_URISCHEME : case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) free(value->string.text); break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if (value->string.charset && i == 0) free(value->string.charset); free(value->string.text); } break; default : break; /* anti-compiler-warning-code */ } if (attr->name != NULL) free(attr->name); free(attr);}/* * 'ipp_length()' - Compute the length of an IPP request or collection value. */static size_t /* O - Size of IPP request */ipp_length(ipp_t *ipp, /* I - IPP request or collection */ int collection) /* I - 1 if a collection, 0 otherwise */{ int i; /* Looping var */ int bytes; /* Number of bytes */ ipp_attribute_t *attr; /* Current attribute */ ipp_tag_t group; /* Current group */ ipp_value_t *value; /* Current value */ if (ipp == NULL) return (0); /* * Start with 8 bytes for the IPP request or status header... */ bytes = collection ? 0 : 8; /* * Then add the lengths of each attribute... */ group = IPP_TAG_ZERO; for (attr = ipp->attrs; attr != NULL; attr = attr->next) { if (attr->group_tag != group && !collection) { group = attr->group_tag; if (group == IPP_TAG_ZERO) continue; bytes ++; /* Group tag */ } DEBUG_printf(("attr->name = %s, attr->num_values = %d, bytes = %d\n", attr->name, attr->num_values, bytes)); bytes += strlen(attr->name); /* Name */ bytes += attr->num_values; /* Value tag for each value */ bytes += 2 * attr->num_values; /* Name lengths */ bytes += 2 * attr->num_values; /* Value lengths */ if (collection) bytes += 5; /* Add membername overhead */ switch (attr->value_tag & ~IPP_TAG_COPY) { case IPP_TAG_INTEGER : case IPP_TAG_ENUM : bytes += 4 * attr->num_values; break; case IPP_TAG_BOOLEAN : bytes += attr->num_values; break; case IPP_TAG_TEXT : case IPP_TAG_NAME : case IPP_TAG_KEYWORD : case IPP_TAG_STRING : case IPP_TAG_URI : case IPP_TAG_URISCHEME : case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) if (value->string.text != NULL) bytes += strlen(value->string.text); break; case IPP_TAG_DATE : bytes += 11 * attr->num_values; break; case IPP_TAG_RESOLUTION : bytes += 9 * attr->num_values; break; case IPP_TAG_RANGE : bytes += 8 * attr->num_values; break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : bytes += 4 * attr->num_values;/* Charset + text length */ for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if (value->string.charset != NULL) bytes += strlen(value->string.charset); if (value->string.text != NULL) bytes += strlen(value->string.text); } break; case IPP_TAG_BEGIN_COLLECTION : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) {/* bytes += 5;*/ /* Overhead of begCollection */ bytes += ipp_length(attr->values[i].collection, 1);/* bytes += 5;*/ /* Overhead of endCollection */ } break; default : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) bytes += attr->values[0].unknown.length; break; } } /* * Finally, add 1 byte for the "end of attributes" tag or 5 bytes * for the "end of collection" tag and return... */ if (collection) bytes += 5; else bytes ++; DEBUG_printf(("bytes = %d\n", bytes)); return (bytes);}/* * 'ipp_read_http()' - Semi-blocking read on a HTTP connection... */static int /* O - Number of bytes read */ipp_read_http(http_t *http, /* I - Client connection */ ipp_uchar_t *buffer, /* O - Buffer for data */ int length) /* I - Total length */{ int tbytes, /* Total bytes read */ bytes; /* Bytes read this pass */ char len[32]; /* Length string */ DEBUG_printf(("ipp_read_http(http=%p, buffer=%p, length=%d)\n", http, buffer, length)); /* * Loop until all bytes are read... */ for (tbytes = 0, bytes = 0; tbytes < length; tbytes += bytes, buffer += bytes) { DEBUG_printf(("tbytes = %d, http->state = %d\n", tbytes, http->state)); if (http->state == HTTP_WAITING) break; if (http->used > 0 && http->data_encoding == HTTP_ENCODE_LENGTH) { /* * Do "fast read" from HTTP buffer directly... */ if (http->used > (length - tbytes)) bytes = length - tbytes; else bytes = http->used; if (bytes == 1) buffer[0] = http->buffer[0]; else memcpy(buffer, http->buffer, bytes); http->used -= bytes; http->data_remaining -= bytes; if (http->used > 0) memmove(http->buffer, http->buffer + bytes, http->used); if (http->data_remaining == 0) { if (http->data_encoding == HTTP_ENCODE_CHUNKED) { /* * Get the trailing CR LF after the chunk... */ if (!httpGets(len, sizeof(len), http)) return (-1); } if (http->data_encoding != HTTP_ENCODE_CHUNKED) { if (http->state == HTTP_POST_RECV) http->state ++; else http->state = HTTP_WAITING; } } } else { /* * Wait a maximum of 1 second for data... */ if (!http->blocking) { /* * Wait up to 1 second for more data on non-blocking sockets... */ if (!httpWait(http, 1000)) { /* * Signal no data... */ bytes = -1; break; } } if ((bytes = httpRead(http, (char *)buffer, length - tbytes)) <= 0) break; } } /* * Return the number of bytes read... */ if (tbytes == 0 && bytes < 0) tbytes = -1; DEBUG_printf(("returning %d bytes...\n", tbytes)); return (tbytes);}/* * 'ipp_read_file()' - Read IPP data from a file. */static int /* O - Number of bytes read */ipp_read_file(int *fd, /* I - File descriptor */ ipp_uchar_t *buffer, /* O - Read buffer */ int length) /* I - Number of bytes to read */{ return (read(*fd, buffer, length));}/* * 'ipp_write_file()' - Write IPP data to a file. */static int /* O - Number of bytes written */ipp_write_file(int *fd, /* I - File descriptor */ ipp_uchar_t *buffer, /* I - Data to write */ int length) /* I - Number of bytes to write */{ return (write(*fd, buffer, length));}/* * End of "$Id: ipp.c,v 1.98 2005/01/03 19:29:45 mike Exp $". */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -