summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2019-04-15 17:05:34 +0200
committerRemi Collet <remi@remirepo.net>2019-04-15 17:05:34 +0200
commit21b86b690a502beb352c93361ae656542d184fb6 (patch)
tree6f65f374f8c7b1ba276aa3700e5ffd2875908f07
parent0690e15edd5e33815a50ae86fa40526278483d07 (diff)
test build for Stream implementation, from https://github.com/kjdev/php-ext-zstd/pull/17
-rw-r--r--17.patch465
-rw-r--r--php-zstd.spec12
2 files changed, 475 insertions, 2 deletions
diff --git a/17.patch b/17.patch
new file mode 100644
index 0000000..ff4f26c
--- /dev/null
+++ b/17.patch
@@ -0,0 +1,465 @@
+From e6f5924867dbe40d07a2befa383e49ade425295c Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Mon, 15 Apr 2019 16:34:33 +0200
+Subject: [PATCH 1/2] implement Streams support
+
+---
+ tests/streams.phpt | 49 +++++++
+ zstd.c | 349 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 398 insertions(+)
+ create mode 100644 tests/streams.phpt
+
+diff --git a/tests/streams.phpt b/tests/streams.phpt
+new file mode 100644
+index 0000000..3f68b99
+--- /dev/null
++++ b/tests/streams.phpt
+@@ -0,0 +1,49 @@
++--TEST--
++compress.zstd stream
++--FILE--
++<?php
++include(dirname(__FILE__) . '/data.inc');
++
++$file = dirname(__FILE__) . '/data.out';
++
++echo "Compression with defaul level\n";
++
++var_dump(file_put_contents('compress.zstd://' . $file, $data) == strlen($data));
++var_dump($size1 = filesize($file));
++var_dump($size1 > 1 && $size1 < strlen($data));
++
++echo "Compression with specfic level\n";
++
++$ctx = stream_context_create(
++ array(
++ "zstd" => array(
++ "level" => ZSTD_COMPRESS_LEVEL_MAX,
++ )
++ )
++);
++
++var_dump(file_put_contents('compress.zstd://' . $file, $data, 0, $ctx) == strlen($data));
++var_dump($size2 = filesize($file));
++var_dump($size1 > 1 && $size2 <= $size1);
++
++
++echo "Decompression\n";
++
++$decomp = file_get_contents('compress.zstd://' . $file);
++var_dump($decomp == $data);
++
++@unlink($file);
++?>
++===Done===
++--EXPECTF--
++Compression with defaul level
++bool(true)
++int(%d)
++bool(true)
++Compression with specfic level
++bool(true)
++int(%d)
++bool(true)
++Decompression
++bool(true)
++===Done===
+diff --git a/zstd.c b/zstd.c
+index 92896e2..a8d0663 100644
+--- a/zstd.c
++++ b/zstd.c
+@@ -363,6 +363,352 @@ ZEND_FUNCTION(zstd_uncompress_dict)
+ efree(rBuff);
+ }
+
++
++typedef struct _php_zstd_stream_data {
++ char *bufin, *bufout;
++ size_t sizein, sizeout;
++ ZSTD_CCtx* cctx;
++ ZSTD_DCtx* dctx;
++ ZSTD_inBuffer input;
++ ZSTD_outBuffer output;
++ php_stream *stream;
++} php_zstd_stream_data;
++
++
++#define STREAM_DATA_FROM_STREAM() \
++ php_zstd_stream_data *self = (php_zstd_stream_data *) stream->abstract
++
++#define STREAM_NAME "compress.zstd"
++
++static int php_zstd_decomp_close(php_stream *stream, int close_handle TSRMLS_DC)
++{
++ STREAM_DATA_FROM_STREAM();
++
++ if (!self) {
++ return EOF;
++ }
++
++ if (close_handle) {
++ if (self->stream) {
++ php_stream_close(self->stream);
++ self->stream = NULL;
++ }
++ }
++
++ ZSTD_freeDCtx(self->dctx);
++ efree(self->bufin);
++ efree(self->bufout);
++ efree(self);
++ stream->abstract = NULL;
++
++ return EOF;
++}
++
++static int php_zstd_comp_close(php_stream *stream, int close_handle TSRMLS_DC)
++{
++ size_t x, res;
++ STREAM_DATA_FROM_STREAM();
++
++ if (!self) {
++ return EOF;
++ }
++
++ /* Compress remaining data */
++ if (self->input.size) {
++ self->input.pos = 0;
++ do {
++ self->output.size = self->sizeout;
++ self->output.pos = 0;
++ res = ZSTD_compressStream(self->cctx, &self->output, &self->input);
++ if (ZSTD_isError(res)) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "libzstd error %s\n", ZSTD_getErrorName(res));
++ }
++ php_stream_write(self->stream, self->bufout, self->output.pos);
++ } while (self->input.pos != self->input.size);
++ }
++
++ /* Flush */
++ do {
++ self->output.size = self->sizeout;
++ self->output.pos = 0;
++ x = ZSTD_endStream(self->cctx, &self->output);
++ if (ZSTD_isError(x)) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "libzstd error %s\n", ZSTD_getErrorName(x));
++ }
++ php_stream_write(self->stream, self->bufout, self->output.pos);
++ } while (x > 0);
++
++ if (close_handle) {
++ if (self->stream) {
++ php_stream_close(self->stream);
++ self->stream = NULL;
++ }
++ }
++
++ ZSTD_freeCCtx(self->cctx);
++ efree(self->bufin);
++ efree(self->bufout);
++ efree(self);
++ stream->abstract = NULL;
++
++ return EOF;
++}
++
++
++static int php_zstd_flush(php_stream *stream TSRMLS_DC)
++{
++ return 0;
++}
++
++
++static size_t php_zstd_decomp_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
++{
++ size_t x, res, ret = 0;
++ STREAM_DATA_FROM_STREAM();
++
++ while (count > 0) {
++ x = self->output.size - self->output.pos;
++ /* enough available */
++ if (x >= count) {
++ memcpy(buf, self->bufout + self->output.pos, count);
++ self->output.pos += count;
++ ret += count;
++ return ret;
++ }
++ /* take remaining from out */
++ if (x) {
++ memcpy(buf, self->bufout + self->output.pos, x);
++ self->output.pos += x;
++ ret += x;
++ buf += x;
++ count -= x;
++ }
++ /* decompress */
++ if (self->input.pos < self->input.size) {
++ /* for zstd */
++ self->output.pos = 0;
++ self->output.size = self->sizeout;
++ res = ZSTD_decompressStream(self->dctx, &self->output , &self->input);
++ if (ZSTD_isError(res)) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "libzstd error %s\n", ZSTD_getErrorName(res));
++ }
++ /* for us */
++ self->output.size = self->output.pos;
++ self->output.pos = 0;
++ } else {
++ /* read */
++ self->input.pos = 0;
++ self->input.size = php_stream_read(self->stream, self->bufin, self->sizein);
++ if (!self->input.size) {
++ /* EOF */
++ count = 0;
++ }
++ }
++ }
++ return ret;
++}
++
++
++static size_t php_zstd_comp_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
++{
++ size_t res, x, ret = 0;
++
++ STREAM_DATA_FROM_STREAM();
++
++ while(count > 0) {
++ /* enough room for full data */
++ if (self->input.size + count < self->sizein) {
++ memcpy(self->bufin + self->input.size, buf, count);
++ self->input.size += count;
++ ret += count;
++ count = 0;
++ break;
++ }
++
++ /* fill input buffer */
++ x = self->sizein - self->input.size;
++ memcpy(self->bufin + self->input.size, buf, x);
++ self->input.size += x;
++ buf += x;
++ count -= x;
++ ret += x;
++
++ /* compress and write */
++ self->input.pos = 0;
++ do {
++ self->output.size = self->sizeout;
++ self->output.pos = 0;
++ res = ZSTD_compressStream(self->cctx, &self->output, &self->input);
++ if (ZSTD_isError(res)) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "libzstd error %s\n", ZSTD_getErrorName(res));
++ }
++ php_stream_write(self->stream, self->bufout, self->output.pos);
++ } while (self->input.pos != self->input.size);
++
++ self->input.pos = 0;
++ self->input.size = 0;
++ }
++ return ret;
++}
++
++
++static php_stream_ops php_stream_zstd_read_ops = {
++ NULL, /* write */
++ php_zstd_decomp_read,
++ php_zstd_decomp_close,
++ php_zstd_flush,
++ STREAM_NAME,
++ NULL, /* seek */
++ NULL, /* cast */
++ NULL, /* stat */
++ NULL /* set_option */
++};
++
++
++static php_stream_ops php_stream_zstd_write_ops = {
++ php_zstd_comp_write,
++ NULL, /* read */
++ php_zstd_comp_close,
++ php_zstd_flush,
++ STREAM_NAME,
++ NULL, /* seek */
++ NULL, /* cast */
++ NULL, /* stat */
++ NULL /* set_option */
++};
++
++
++static php_stream *
++php_stream_zstd_opener(
++ php_stream_wrapper *wrapper,
++#if PHP_VERSION_ID < 50600
++ char *path,
++ char *mode,
++#else
++ const char *path,
++ const char *mode,
++#endif
++ int options,
++#if PHP_MAJOR_VERSION < 7
++ char **opened_path,
++#else
++ zend_string **opened_path,
++#endif
++ php_stream_context *context
++ STREAMS_DC TSRMLS_DC)
++{
++ php_zstd_stream_data *self;
++ int level = ZSTD_CLEVEL_DEFAULT;
++
++ if (strncasecmp(STREAM_NAME, path, sizeof(STREAM_NAME)-1) == 0) {
++ path += sizeof(STREAM_NAME)-1;
++ if (strncmp("://", path, 3) == 0) {
++ path += 3;
++ }
++ }
++
++ if (php_check_open_basedir(path)) {
++ return NULL;
++ }
++
++ if (context) {
++#if PHP_MAJOR_VERSION >= 7
++ zval *tmpzval;
++
++ if (NULL != (tmpzval = php_stream_context_get_option(context, "zstd", "level"))) {
++ level = zval_get_long(tmpzval);
++ }
++#else
++ zval **tmpzval;
++
++ if (php_stream_context_get_option(context, "zstd", "level", &tmpzval) == SUCCESS) {
++ convert_to_long_ex(tmpzval);
++ level = Z_LVAL_PP(tmpzval);
++ }
++#endif
++ }
++
++ if (level > ZSTD_maxCLevel()) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "zstd: compression level (%d) must be less than %d", level, ZSTD_maxCLevel());
++ level = ZSTD_maxCLevel();
++ }
++
++ self = ecalloc(sizeof(*self), 1);
++ self->stream = php_stream_open_wrapper(path, mode, REPORT_ERRORS, NULL);
++ /* File */
++ if (!strcmp(mode, "w") || !strcmp(mode, "wb")) {
++ self->dctx = NULL;
++ self->cctx = ZSTD_createCCtx();
++ if (!self->cctx) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "zstd: compression context failed");
++ php_stream_close(self->stream);
++ efree(self);
++ return NULL;
++ }
++ ZSTD_initCStream(self->cctx, level);
++ self->bufin = emalloc(self->sizein = ZSTD_CStreamInSize());
++ self->bufout = emalloc(self->sizeout = ZSTD_CStreamOutSize());
++ self->input.src = self->bufin;
++ self->input.pos = 0;
++ self->input.size = 0;
++ self->output.dst = self->bufout;
++ self->output.pos = 0;
++ self->output.size = 0;
++
++ return php_stream_alloc(&php_stream_zstd_write_ops, self, NULL, mode);
++
++ } else if (!strcmp(mode, "r") || !strcmp(mode, "rb")) {
++ self->dctx = ZSTD_createDCtx();
++ if (!self->dctx) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "zstd: compression context failed");
++ php_stream_close(self->stream);
++ efree(self);
++ return NULL;
++ }
++ self->cctx = NULL;
++ self->bufin = emalloc(self->sizein = ZSTD_DStreamInSize());
++ self->bufout = emalloc(self->sizeout = ZSTD_DStreamOutSize());
++ ZSTD_initDStream(self->dctx);
++ self->input.src = self->bufin;
++ self->input.pos = 0;
++ self->input.size = 0;
++ self->output.dst = self->bufout;
++ self->output.pos = 0;
++ self->output.size = 0;
++
++ return php_stream_alloc(&php_stream_zstd_read_ops, self, NULL, mode);
++
++ } else {
++ php_error_docref(NULL, E_ERROR, "zstd: invalid open mode");
++ }
++ return NULL;
++}
++
++
++static php_stream_wrapper_ops zstd_stream_wops = {
++ php_stream_zstd_opener,
++ NULL, /* close */
++ NULL, /* fstat */
++ NULL, /* stat */
++ NULL, /* opendir */
++ STREAM_NAME,
++ NULL, /* unlink */
++ NULL, /* rename */
++ NULL, /* mkdir */
++ NULL /* rmdir */
++#if PHP_VERSION_ID >= 50400
++ , NULL
++#endif
++};
++
++
++php_stream_wrapper php_stream_zstd_wrapper = {
++ &zstd_stream_wops,
++ NULL,
++ 0 /* is_url */
++};
++
++
+ ZEND_MINIT_FUNCTION(zstd)
+ {
+ REGISTER_LONG_CONSTANT("ZSTD_COMPRESS_LEVEL_MIN",
+@@ -374,6 +720,9 @@ ZEND_MINIT_FUNCTION(zstd)
+ REGISTER_LONG_CONSTANT("ZSTD_COMPRESS_LEVEL_DEFAULT",
+ DEFAULT_COMPRESS_LEVEL,
+ CONST_CS | CONST_PERSISTENT);
++
++ php_register_url_stream_wrapper(STREAM_NAME, &php_stream_zstd_wrapper TSRMLS_CC);
++
+ return SUCCESS;
+ }
+
+
+From 6e68f9d36b0d66f6b36999bf84c5883fbf67c513 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Mon, 15 Apr 2019 16:57:08 +0200
+Subject: [PATCH 2/2] fix ZTS
+
+---
+ zstd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/zstd.c b/zstd.c
+index a8d0663..1a82bda 100644
+--- a/zstd.c
++++ b/zstd.c
+@@ -607,7 +607,7 @@ php_stream_zstd_opener(
+ }
+ }
+
+- if (php_check_open_basedir(path)) {
++ if (php_check_open_basedir(path TSRMLS_CC)) {
+ return NULL;
+ }
+
+@@ -679,7 +679,7 @@ php_stream_zstd_opener(
+ return php_stream_alloc(&php_stream_zstd_read_ops, self, NULL, mode);
+
+ } else {
+- php_error_docref(NULL, E_ERROR, "zstd: invalid open mode");
++ php_error_docref(NULL TSRMLS_CC, E_ERROR, "zstd: invalid open mode");
+ }
+ return NULL;
+ }
diff --git a/php-zstd.spec b/php-zstd.spec
index 055014a..9de7a11 100644
--- a/php-zstd.spec
+++ b/php-zstd.spec
@@ -21,8 +21,8 @@
%global with_libzstd 1
%else
%global with_libzstd 0
-%global zstdver 1.3.8
%endif
+%global zstdver 1.3.8
%global gh_commit 17ea4c3957f3d637b461a7aa375f2b4889a3ad77
%global gh_short %(c=%{gh_commit}; echo ${c:0:7})
@@ -39,7 +39,7 @@ Version: 0.6.1
%if 0%{?gh_date:1}
Release: 1%{gh_date}git%{gh_short}%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}}
%else
-Release: 1%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}}
+Release: 2%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}}
%endif
%if %{?with_libzstd}
License: MIT
@@ -52,6 +52,8 @@ Source0: %{pkg_name}-%{version}-%{gh_short}.tgz
# retrieve a recursive git snapshot with submodule
Source1: makesrc.sh
+Patch0: https://github.com/kjdev/php-ext-zstd/pull/17.patch
+
BuildRequires: %{?dtsprefix}gcc
BuildRequires: %{?scl_prefix}php-devel
%if %{?with_libzstd}
@@ -108,6 +110,8 @@ These are the files needed to compile programs using %{name}.
mv %{gh_project}-%{gh_commit} NTS
cd NTS
+%patch0 -p1 -b .pr17
+
# replace symlink
rm LICENSE-zstd
mv zstd/LICENSE LICENSE-zstd
@@ -242,6 +246,10 @@ TEST_PHP_ARGS="-n -d extension=%{buildroot}%{php_ztsextdir}/%{pecl_name}.so" \
%changelog
+* Mon Apr 15 2019 Remi Collet <remi@remirepo.net> - 0.6.1-2
+- test build for Stream implementation, from
+ https://github.com/kjdev/php-ext-zstd/pull/17
+
* Thu Apr 4 2019 Remi Collet <remi@remirepo.net> - 0.6.1-1
- update to 0.6.1