diff options
author | michael-grunder <michael.grunder@gmail.com> | 2022-10-13 04:15:32 +0300 |
---|---|---|
committer | michael-grunder <michael.grunder@gmail.com> | 2022-10-13 04:15:32 +0300 |
commit | 2b03c4f9413a573a690391d114be5c8664144573 (patch) | |
tree | c0684652044697d08b5806abd474fac3ce1b956f | |
parent | e392dd88dd89780633da3dd9ea6fb33dd187ff05 (diff) |
Refactor BITPOS and implement BIT/BYTE option.issue.2068-bitpos-additions
Update BITPOS to use the new argument parsing macros as well as
implement Redis 7.0.0's BIT/BYTE modifier.
Additionally I changed `int $bit` to `bool $bit` as its a more
appropriate datatype.
See #2068
-rw-r--r-- | redis.stub.php | 2 | ||||
-rw-r--r-- | redis_arginfo.h | 7 | ||||
-rw-r--r-- | redis_cluster.stub.php | 2 | ||||
-rw-r--r-- | redis_cluster_arginfo.h | 11 | ||||
-rw-r--r-- | redis_cluster_legacy_arginfo.h | 3 | ||||
-rw-r--r-- | redis_commands.c | 51 | ||||
-rw-r--r-- | redis_legacy_arginfo.h | 3 | ||||
-rw-r--r-- | tests/RedisTest.php | 8 |
8 files changed, 51 insertions, 36 deletions
diff --git a/redis.stub.php b/redis.stub.php index 8cdede95..e1358abc 100644 --- a/redis.stub.php +++ b/redis.stub.php @@ -41,7 +41,7 @@ class Redis { public function bitop(string $operation, string $deskey, string $srckey, string ...$other_keys): Redis|int|false; - public function bitpos(string $key, int $bit, int $start = 0, int $end = -1): Redis|int|false; + public function bitpos(string $key, bool $bit, int $start = 0, int $end = -1, bool $bybit = false): Redis|int|false; public function blPop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false; diff --git a/redis_arginfo.h b/redis_arginfo.h index 37241bbf..27f05838 100644 --- a/redis_arginfo.h +++ b/redis_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1810caef11b38440e073059e2d9c65f92fa8a9a5 */ + * Stub hash: a0649ff8be33990940a8017c1de2259c03b0f46c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null") @@ -65,9 +65,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_bitpos, 0, 2, Redis, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, bit, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, bit, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, end, IS_LONG, 0, "-1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, bybit, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_blPop, 0, 2, Redis, MAY_BE_ARRAY|MAY_BE_NULL|MAY_BE_FALSE) @@ -287,7 +288,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_geosearchstore, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_get, 0, 1, Redis, MAY_BE_ANY|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_get, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_END_ARG_INFO() diff --git a/redis_cluster.stub.php b/redis_cluster.stub.php index 517ca4c8..a8ce379a 100644 --- a/redis_cluster.stub.php +++ b/redis_cluster.stub.php @@ -40,7 +40,7 @@ class RedisCluster { public function bitop(string $operation, string $deskey, string $srckey, string ...$otherkeys): RedisCluster|bool|int; - public function bitpos(string $key, int $bit, int $start = NULL, int $end = NULL): RedisCluster|bool|int; + public function bitpos(string $key, bool $bit, int $start = 0, int $end = -1, bool $bybit = false): RedisCluster|int|false; public function blpop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): RedisCluster|array|null|false; public function brpop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): RedisCluster|array|null|false; diff --git a/redis_cluster_arginfo.h b/redis_cluster_arginfo.h index 4b02f3e6..1269bcd2 100644 --- a/redis_cluster_arginfo.h +++ b/redis_cluster_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 280323a9e3fc028641ad1d8bcba2514dfa90fac9 */ + * Stub hash: d6b71614200b243d1e31025234140aae2c39085c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1) @@ -72,11 +72,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_bitop, 0, ZEND_ARG_VARIADIC_TYPE_INFO(0, otherkeys, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_bitpos, 0, 2, RedisCluster, MAY_BE_BOOL|MAY_BE_LONG) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_bitpos, 0, 2, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, bit, IS_LONG, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, end, IS_LONG, 0, "NULL") + ZEND_ARG_TYPE_INFO(0, bit, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, end, IS_LONG, 0, "-1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, bybit, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_blpop, 0, 2, RedisCluster, MAY_BE_ARRAY|MAY_BE_NULL|MAY_BE_FALSE) diff --git a/redis_cluster_legacy_arginfo.h b/redis_cluster_legacy_arginfo.h index c1552291..3bc06391 100644 --- a/redis_cluster_legacy_arginfo.h +++ b/redis_cluster_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 280323a9e3fc028641ad1d8bcba2514dfa90fac9 */ + * Stub hash: d6b71614200b243d1e31025234140aae2c39085c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1) ZEND_ARG_INFO(0, name) @@ -70,6 +70,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_bitpos, 0, 0, 2) ZEND_ARG_INFO(0, bit) ZEND_ARG_INFO(0, start) ZEND_ARG_INFO(0, end) + ZEND_ARG_INFO(0, bybit) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_blpop, 0, 0, 2) diff --git a/redis_commands.c b/redis_commands.c index 3c56f892..66048f0e 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -2523,38 +2523,41 @@ int redis_restore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, return SUCCESS; } -/* BITPOS */ +/* BITPOS key bit [start [end [BYTE | BIT]]] */ int redis_bitpos_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx) { - char *key; - int argc; - zend_long bit, start, end; - size_t key_len; + zend_long start = 0, end = -1; + zend_bool bit = 0, bybit = 0; + smart_string cmdstr = {0}; + zend_string *key = NULL; - argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc, "sl|ll", &key, &key_len, &bit, - &start, &end) == FAILURE) - { - return FAILURE; - } + ZEND_PARSE_PARAMETERS_START(2, 5) + Z_PARAM_STR(key) + Z_PARAM_BOOL(bit) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(start) + Z_PARAM_LONG(end) + Z_PARAM_BOOL(bybit) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - // Prevalidate bit - if (bit != 0 && bit != 1) { - return FAILURE; - } + REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 2 + (ZEND_NUM_ARGS() > 2 ? 2 : 0) + !!bybit, "BITPOS"); - // Construct command based on arg count - if (argc == 2) { - *cmd_len = REDIS_CMD_SPPRINTF(cmd, "BITPOS", "kd", key, key_len, bit); - } else if (argc == 3) { - *cmd_len = REDIS_CMD_SPPRINTF(cmd, "BITPOS", "kdd", key, key_len, bit, - start); - } else { - *cmd_len = REDIS_CMD_SPPRINTF(cmd, "BITPOS", "kddd", key, key_len, bit, - start, end); + redis_cmd_append_sstr_key_zstr(&cmdstr, key, redis_sock, slot); + redis_cmd_append_sstr_long(&cmdstr, bit); + + /* Start and length if we were passed either */ + if (ZEND_NUM_ARGS() > 2) { + redis_cmd_append_sstr_long(&cmdstr, start); + redis_cmd_append_sstr_long(&cmdstr, end); } + /* Finally, BIT or BYTE if we were passed that argument */ + REDIS_CMD_APPEND_SSTR_OPT_STATIC(&cmdstr, !!bybit, "BIT"); + + *cmd = cmdstr.c; + *cmd_len = cmdstr.len; + return SUCCESS; } diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h index 66a63b32..9fbc2d2e 100644 --- a/redis_legacy_arginfo.h +++ b/redis_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1810caef11b38440e073059e2d9c65f92fa8a9a5 */ + * Stub hash: a0649ff8be33990940a8017c1de2259c03b0f46c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_INFO(0, options) @@ -63,6 +63,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_bitpos, 0, 0, 2) ZEND_ARG_INFO(0, bit) ZEND_ARG_INFO(0, start) ZEND_ARG_INFO(0, end) + ZEND_ARG_INFO(0, bybit) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_blPop, 0, 0, 2) diff --git a/tests/RedisTest.php b/tests/RedisTest.php index e2c8b559..ec36085c 100644 --- a/tests/RedisTest.php +++ b/tests/RedisTest.php @@ -409,6 +409,14 @@ class Redis_Test extends TestSuite $this->redis->set('bpkey', "\x00\x00\x00"); $this->assertEquals($this->redis->bitpos('bpkey', 1), -1); + + if (!$this->minVersionCheck("7.0.0")) + return; + + $this->redis->set('bpkey', "\xF"); + $this->assertEquals(4, $this->redis->bitpos('bpkey', 1, 0, -1, true)); + $this->assertEquals(-1, $this->redis->bitpos('bpkey', 1, 1, -1)); + $this->assertEquals(-1, $this->redis->bitpos('bpkey', 1, 1, -1, false)); } public function test1000() { |