-#define HTTP_ENCODING_STREAM_ERROR(status, tofree) \
- { \
- if (tofree) efree(tofree); \
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "GZIP stream error: %s", zError(status)); \
- return FAILURE; \
- }
-
-PHP_HTTP_API STATUS _http_encoding_stream_init(http_encoding_stream *s, int flags, int level, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status;
- int wbits = (flags & HTTP_ENCODING_STREAM_ZLIB_HEADER) ? MAX_WBITS : -MAX_WBITS;
-
- memset(s, 0, sizeof(http_encoding_stream));
- if (Z_OK != (status = deflateInit2(&s->Z, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
- HTTP_ENCODING_STREAM_ERROR(status, NULL);
- }
-
- s->persistent = (flags & HTTP_ENCODING_STREAM_PERSISTENT);
- if ((s->gzip = (flags & HTTP_ENCODING_STREAM_GZIP_HEADER))) {
- s->crc = crc32(0L, Z_NULL, 0);
- *encoded_len = sizeof(http_encoding_gzip_header);
- *encoded = pemalloc(*encoded_len, s->persistent);
- memcpy(*encoded, http_encoding_gzip_header, *encoded_len);
- } else {
- *encoded_len = 0;
- *encoded = NULL;
- }
-
- return SUCCESS;
-}
-
-PHP_HTTP_API STATUS _http_encoding_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status;
-
- *encoded_len = HTTP_ENCODING_BUFLEN(data_len);
- *encoded = pemalloc(*encoded_len, s->persistent);
-
- s->Z.next_in = (Bytef *) data;
- s->Z.avail_in = data_len;
- s->Z.next_out = (Bytef *) *encoded;
- s->Z.avail_out = *encoded_len;
-
- status = deflate(&s->Z, Z_SYNC_FLUSH);
-
- if (Z_OK != status && Z_STREAM_END != status) {
- HTTP_ENCODING_STREAM_ERROR(status, *encoded);
- }
- *encoded_len -= s->Z.avail_out;
-
- if (s->gzip) {
- s->crc = crc32(s->crc, (const Bytef *) data, data_len);
- }
-
- return SUCCESS;
-}
-
-PHP_HTTP_API STATUS _http_encoding_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len TSRMLS_DC)
-{
- STATUS status;
-
- *encoded_len = 1024;
- *encoded = pemalloc(*encoded_len, s->persistent);
-
- s->Z.next_out = (Bytef *) *encoded;
- s->Z.avail_out = *encoded_len;
-
- if (Z_STREAM_END != (status = deflate(&s->Z, Z_FINISH)) || Z_OK != (status = deflateEnd(&s->Z))) {
- HTTP_ENCODING_STREAM_ERROR(status, *encoded);
- }
-
- *encoded_len -= s->Z.avail_out;
- if (s->gzip) {
- if (s->Z.avail_out < 8) {
- *encoded = perealloc(*encoded, *encoded_len + 8, s->persistent);
- }
- (*encoded)[(*encoded_len)++] = (char) (s->crc & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->crc >> 8) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->crc >> 16) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->crc >> 24) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in >> 8) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in >> 16) & 0xFF);
- (*encoded)[(*encoded_len)++] = (char) ((s->Z.total_in >> 24) & 0xFF);
- }
-
- return SUCCESS;
-}
-