ipp_state_t ippWrite(http_t *http, ipp_t *ipp) { if (!http) return (IPP_ERROR); return (ippWriteIO(http, (ipp_iocb_t)httpWrite2, http->blocking, NULL, ipp)); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { _ippdata_t data; /* IPP buffer */ ipp_uchar_t buffer[8192]; /* Write buffer data */ ipp_t *cols[2], /* Collections */ *size; /* media-size collection */ ipp_t *request; /* Request */ ipp_attribute_t *media_col, /* media-col attribute */ *media_size, /* media-size attribute */ *attr; /* Other attribute */ ipp_state_t state; /* State */ size_t length; /* Length of data */ cups_file_t *fp; /* File pointer */ size_t i; /* Looping var */ int status; /* Status of tests (0 = success, 1 = fail) */ #ifdef DEBUG const char *name; /* Option name */ #endif /* DEBUG */ status = 0; if (argc == 1) { /* * Test request generation code... */ printf("Create Sample Request: "); request = ippNew(); request->request.op.version[0] = 0x01; request->request.op.version[1] = 0x01; request->request.op.operation_id = IPP_OP_PRINT_JOB; request->request.op.request_id = 1; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, "en"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/printers/foo"); cols[0] = ippNew(); size = ippNew(); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940); ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size); ippDelete(size); ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL, "blue"); ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL, "plain"); cols[1] = ippNew(); size = ippNew(); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700); ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size); ippDelete(size); ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL, "plaid"); ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL, "glossy"); ippAddCollections(request, IPP_TAG_JOB, "media-col", 2, (const ipp_t **)cols); ippDelete(cols[0]); ippDelete(cols[1]); length = ippLength(request); if (length != sizeof(collection)) { printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", (int)length, (int)sizeof(collection)); status = 1; } else puts("PASS"); /* * Write test #1... */ printf("Write Sample to Memory: "); data.wused = 0; data.wsize = sizeof(buffer); data.wbuffer = buffer; while ((state = ippWriteIO(&data, (ipp_iocb_t)write_cb, 1, NULL, request)) != IPP_STATE_DATA) if (state == IPP_STATE_ERROR) break; if (state != IPP_STATE_DATA) { printf("FAIL - %d bytes written.\n", (int)data.wused); status = 1; } else if (data.wused != sizeof(collection)) { printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data.wused, (int)sizeof(collection)); hex_dump("Bytes Written", data.wbuffer, data.wused); hex_dump("Baseline", collection, sizeof(collection)); status = 1; } else if (memcmp(data.wbuffer, collection, data.wused)) { for (i = 0; i < data.wused; i ++) if (data.wbuffer[i] != collection[i]) break; printf("FAIL - output does not match baseline at 0x%04x!\n", (unsigned)i); hex_dump("Bytes Written", data.wbuffer, data.wused); hex_dump("Baseline", collection, sizeof(collection)); status = 1; } else puts("PASS"); ippDelete(request); /* * Read the data back in and confirm... */ printf("Read Sample from Memory: "); request = ippNew(); data.rpos = 0; while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL, request)) != IPP_STATE_DATA) if (state == IPP_STATE_ERROR) break; length = ippLength(request); if (state != IPP_STATE_DATA) { printf("FAIL - %d bytes read.\n", (int)data.rpos); status = 1; } else if (data.rpos != data.wused) { printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos, (int)data.wused); print_attributes(request, 8); status = 1; } else if (length != sizeof(collection)) { printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", (int)length, (int)sizeof(collection)); print_attributes(request, 8); status = 1; } else puts("PASS"); fputs("ippFindAttribute(media-col): ", stdout); if ((media_col = ippFindAttribute(request, "media-col", IPP_TAG_BEGIN_COLLECTION)) == NULL) { if ((media_col = ippFindAttribute(request, "media-col", IPP_TAG_ZERO)) == NULL) puts("FAIL (not found)"); else printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag)); status = 1; } else if (media_col->num_values != 2) { printf("FAIL (wrong count - %d)\n", media_col->num_values); status = 1; } else puts("PASS"); if (media_col) { fputs("ippFindAttribute(media-size 1): ", stdout); if ((media_size = ippFindAttribute(media_col->values[0].collection, "media-size", IPP_TAG_BEGIN_COLLECTION)) == NULL) { if ((media_size = ippFindAttribute(media_col->values[0].collection, "media-col", IPP_TAG_ZERO)) == NULL) puts("FAIL (not found)"); else printf("FAIL (wrong type - %s)\n", ippTagString(media_size->value_tag)); status = 1; } else { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing x-dimension)"); else printf("FAIL (wrong type for x-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 21590) { printf("FAIL (wrong value for x-dimension - %d)\n", attr->values[0].integer); status = 1; } else if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing y-dimension)"); else printf("FAIL (wrong type for y-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 27940) { printf("FAIL (wrong value for y-dimension - %d)\n", attr->values[0].integer); status = 1; } else puts("PASS"); } fputs("ippFindAttribute(media-size 2): ", stdout); if ((media_size = ippFindAttribute(media_col->values[1].collection, "media-size", IPP_TAG_BEGIN_COLLECTION)) == NULL) { if ((media_size = ippFindAttribute(media_col->values[1].collection, "media-col", IPP_TAG_ZERO)) == NULL) puts("FAIL (not found)"); else printf("FAIL (wrong type - %s)\n", ippTagString(media_size->value_tag)); status = 1; } else { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing x-dimension)"); else printf("FAIL (wrong type for x-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 21000) { printf("FAIL (wrong value for x-dimension - %d)\n", attr->values[0].integer); status = 1; } else if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing y-dimension)"); else printf("FAIL (wrong type for y-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 29700) { printf("FAIL (wrong value for y-dimension - %d)\n", attr->values[0].integer); status = 1; } else puts("PASS"); } } /* * Test hierarchical find... */ fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout); if ((attr = ippFindAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL) { if (ippGetInteger(attr, 0) != 21590) { printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0)); status = 1; } else puts("PASS"); } else { puts("FAIL (not found)"); status = 1; } fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout); if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL) { if (ippGetInteger(attr, 0) != 21000) { printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0)); status = 1; } else puts("PASS"); } else { puts("FAIL (not found)"); status = 1; } fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout); if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL) { printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr, 0)); status = 1; } else puts("PASS"); ippDelete(request); /* * Read the mixed data and confirm we converted everything to rangeOfInteger * values... */ printf("Read Mixed integer/rangeOfInteger from Memory: "); request = ippNew(); data.rpos = 0; data.wused = sizeof(mixed); data.wsize = sizeof(mixed); data.wbuffer = mixed; while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL, request)) != IPP_STATE_DATA) if (state == IPP_STATE_ERROR) break; length = ippLength(request); if (state != IPP_STATE_DATA) { printf("FAIL - %d bytes read.\n", (int)data.rpos); status = 1; } else if (data.rpos != sizeof(mixed)) { printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos, (int)sizeof(mixed)); print_attributes(request, 8); status = 1; } else if (length != (sizeof(mixed) + 4)) { printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", (int)length, (int)sizeof(mixed) + 4); print_attributes(request, 8); status = 1; } else puts("PASS"); fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout); if ((attr = ippFindAttribute(request, "notify-lease-duration-supported", IPP_TAG_ZERO)) == NULL) { puts("FAIL (not found)"); status = 1; } else if (attr->value_tag != IPP_TAG_RANGE) { printf("FAIL (wrong type - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->num_values != 2) { printf("FAIL (wrong count - %d)\n", attr->num_values); status = 1; } else if (attr->values[0].range.lower != 1 || attr->values[0].range.upper != 1 || attr->values[1].range.lower != 16 || attr->values[1].range.upper != 32) { printf("FAIL (wrong values - %d,%d and %d,%d)\n", attr->values[0].range.lower, attr->values[0].range.upper, attr->values[1].range.lower, attr->values[1].range.upper); status = 1; } else puts("PASS"); ippDelete(request); #ifdef DEBUG /* * Test that private option array is sorted... */ fputs("_ippCheckOptions: ", stdout); if ((name = _ippCheckOptions()) == NULL) puts("PASS"); else { printf("FAIL (\"%s\" out of order)\n", name); status = 1; } #endif /* DEBUG */ /* * Test _ippFindOption() private API... */ fputs("_ippFindOption(\"printer-type\"): ", stdout); if (_ippFindOption("printer-type")) puts("PASS"); else { puts("FAIL"); status = 1; } /* * Summarize... */ putchar('\n'); if (status) puts("Core IPP tests failed."); else puts("Core IPP tests passed."); } else { /* * Read IPP files... */ for (i = 1; i < (size_t)argc; i ++) { if ((fp = cupsFileOpen(argv[i], "r")) == NULL) { printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno)); status = 1; continue; } request = ippNew(); while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, request)) == IPP_STATE_ATTRIBUTE); if (state != IPP_STATE_DATA) { printf("Error reading IPP message from \"%s\"!\n", argv[i]); status = 1; } else { printf("\n%s:\n", argv[i]); print_attributes(request, 4); } ippDelete(request); cupsFileClose(fp); } } return (status); }
ipp_state_t ippWriteIO(void *dst, ipp_iocb_t cb, int blocking,ipp_t *parent, ipp_t *ipp) { int i; int n; unsigned char *buffer, *bufptr; ipp_attribute_t *attr; ipp_value_t *value; if (!dst || !ipp) return (IPP_ERROR); if ((buffer = ipp_buffer_get()) == NULL) { return (IPP_ERROR); } switch (ipp->state) { case IPP_IDLE : ipp->state = (ipp_state_t)(ipp->state+1); case IPP_HEADER : if (parent == NULL) { bufptr = buffer; *bufptr++ = ipp->request.any.version[0]; *bufptr++ = ipp->request.any.version[1]; *bufptr++ = ipp->request.any.op_status >> 8; *bufptr++ = ipp->request.any.op_status; *bufptr++ = ipp->request.any.request_id >> 24; *bufptr++ = ipp->request.any.request_id >> 16; *bufptr++ = ipp->request.any.request_id >> 8; *bufptr++ = ipp->request.any.request_id; if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } } ipp->state = IPP_ATTRIBUTE; ipp->current = ipp->attrs; ipp->curtag = IPP_TAG_ZERO; // if (!blocking) //break; case IPP_ATTRIBUTE : while (ipp->current != NULL) { bufptr = buffer; attr = ipp->current; ipp->current = ipp->current->next; if (!parent) { if (ipp->curtag != attr->group_tag) { ipp->curtag = attr->group_tag; if (attr->group_tag == IPP_TAG_ZERO) continue; *bufptr++ = attr->group_tag; } else if (attr->group_tag == IPP_TAG_ZERO) continue; } if (parent == NULL) { if ((n = (int)strlen(attr->name)) > (IPP_BUF_SIZE - 4)) { ipp_buffer_release(buffer); return (IPP_ERROR); } *bufptr++ = attr->value_tag; *bufptr++ = n >> 8; *bufptr++ = n; memcpy(bufptr, attr->name, n); bufptr += n; } else { if ((n = (int)strlen(attr->name)) > (IPP_BUF_SIZE - 7)) { ipp_buffer_release(buffer); return (IPP_ERROR); } *bufptr++ = IPP_TAG_MEMBERNAME; *bufptr++ = 0; *bufptr++ = 0; *bufptr++ = n >> 8; *bufptr++ = n; memcpy(bufptr, attr->name, n); bufptr += n; *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } switch (attr->value_tag & ~IPP_TAG_COPY) { case IPP_TAG_INTEGER : case IPP_TAG_ENUM : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 9) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } if (i) { *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } *bufptr++ = 0; *bufptr++ = 4; *bufptr++ = value->integer >> 24; *bufptr++ = value->integer >> 16; *bufptr++ = value->integer >> 8; *bufptr++ = value->integer; } break; case IPP_TAG_BOOLEAN : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 6) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } if (i) { *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } *bufptr++ = 0; *bufptr++ = 1; *bufptr++ = value->boolean; } break; case IPP_TAG_TEXT : case IPP_TAG_NAME : case IPP_TAG_KEYWORD : 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 (i) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 3) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } if (value->string.text != NULL) n = (int)strlen(value->string.text); else n = 0; if (n > (IPP_BUF_SIZE - 2)) { ipp_buffer_release(buffer); return (IPP_ERROR); } if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2)) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } *bufptr++ = n >> 8; *bufptr++ = n; if (n > 0) { memcpy(bufptr, value->string.text, n); bufptr += n; } } break; case IPP_TAG_DATE : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 16) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } if (i) { *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } *bufptr++ = 0; *bufptr++ = 11; memcpy(bufptr, value->date, 11); bufptr += 11; } break; case IPP_TAG_RESOLUTION : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 14) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } if (i) { *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } *bufptr++ = 0; *bufptr++ = 9; *bufptr++ = value->resolution.xres >> 24; *bufptr++ = value->resolution.xres >> 16; *bufptr++ = value->resolution.xres >> 8; *bufptr++ = value->resolution.xres; *bufptr++ = value->resolution.yres >> 24; *bufptr++ = value->resolution.yres >> 16; *bufptr++ = value->resolution.yres >> 8; *bufptr++ = value->resolution.yres; *bufptr++ = value->resolution.units; } break; case IPP_TAG_RANGE : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 13) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } if (i) { *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } *bufptr++ = 0; *bufptr++ = 8; *bufptr++ = value->range.lower >> 24; *bufptr++ = value->range.lower >> 16; *bufptr++ = value->range.lower >> 8; *bufptr++ = value->range.lower; *bufptr++ = value->range.upper >> 24; *bufptr++ = value->range.upper >> 16; *bufptr++ = value->range.upper >> 8; *bufptr++ = value->range.upper; } break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if (i) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 3) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } n = 4; if (value->string.charset != NULL) n += (int)strlen(value->string.charset); if (value->string.text != NULL) n += (int)strlen(value->string.text); if (n > (IPP_BUF_SIZE - 2)) { ipp_buffer_release(buffer); return (IPP_ERROR); } if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2)) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } *bufptr++ = n >> 8; *bufptr++ = n; if (value->string.charset != NULL) n = (int)strlen(value->string.charset); else n = 0; *bufptr++ = n >> 8; *bufptr++ = n; if (n > 0) { memcpy(bufptr, value->string.charset, n); bufptr += n; } if (value->string.text != NULL) n = (int)strlen(value->string.text); else n = 0; *bufptr++ = n >> 8; *bufptr++ = n; if (n > 0) { memcpy(bufptr, value->string.text, n); bufptr += n; } } break; case IPP_TAG_BEGIN_COLLECTION : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 5) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } if (i) { *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } *bufptr++ = 0; *bufptr++ = 0; if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; value->collection->state = IPP_IDLE; if (ippWriteIO(dst, cb, 1, ipp, value->collection) == IPP_ERROR) { ipp_buffer_release(buffer); return (IPP_ERROR); } } break; default : for (i = 0, value = attr->values; i < attr->num_values; i ++, value ++) { if (i) { if ((IPP_BUF_SIZE - (bufptr - buffer)) < 3) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } *bufptr++ = attr->value_tag; *bufptr++ = 0; *bufptr++ = 0; } n = value->unknown.length; if (n > (IPP_BUF_SIZE - 2)) { ipp_buffer_release(buffer); return (IPP_ERROR); } if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2)) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } bufptr = buffer; } *bufptr++ = n >> 8; *bufptr++ = n; if (n > 0) { memcpy(bufptr, value->unknown.data, n); bufptr += n; } } break; } if (bufptr > buffer) { if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) { ipp_buffer_release(buffer); return (IPP_ERROR); } } // if (!blocking) //break; }