Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4d8afd3

Browse files
Refactor BITPOS and implement BIT/BYTE option.
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
1 parent 872ae10 commit 4d8afd3

8 files changed

Lines changed: 74 additions & 35 deletions

redis.stub.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,19 @@ public function bitcount(string $key, int $start = 0, int $end = -1, bool $bybit
4141

4242
public function bitop(string $operation, string $deskey, string $srckey, string ...$other_keys): Redis|int|false;
4343

44-
public function bitpos(string $key, int $bit, int $start = 0, int $end = -1): Redis|int|false;
44+
/**
45+
Return the position of the first bit set to 0 or 1 in a string.
46+
47+
@see https://https://redis.io/commands/bitpos/
48+
49+
@param string $key The key to check (must be a string)
50+
@param bool $bit Whether to look for an unset (0) or set (1) bit.
51+
@param int $start Where in the string to start looking.
52+
@param int $end Where in the string to stop looking.
53+
@param bool $bybit If true, Redis will treat $start and $end as BIT values and not bytes, so if start
54+
was 0 and end was 2, Redis would only search the first two bits.
55+
*/
56+
public function bitpos(string $key, bool $bit, int $start = 0, int $end = -1, bool $bybit = false): Redis|int|false;
4557

4658
public function blPop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false;
4759

redis_arginfo.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: b53146f6b329f404b4bfa9e5df9dde9c36b50440 */
2+
* Stub hash: a8ddcde8e8af5201d72bfe8b463afc0c9dafb73d */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
@@ -65,9 +65,10 @@ ZEND_END_ARG_INFO()
6565

6666
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_bitpos, 0, 2, Redis, MAY_BE_LONG|MAY_BE_FALSE)
6767
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
68-
ZEND_ARG_TYPE_INFO(0, bit, IS_LONG, 0)
68+
ZEND_ARG_TYPE_INFO(0, bit, _IS_BOOL, 0)
6969
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "0")
7070
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, end, IS_LONG, 0, "-1")
71+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, bybit, _IS_BOOL, 0, "false")
7172
ZEND_END_ARG_INFO()
7273

7374
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)

redis_cluster.stub.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,19 @@ public function bitcount(string $key, int $start = 0, int $end = -1, bool $bybit
4040

4141
public function bitop(string $operation, string $deskey, string $srckey, string ...$otherkeys): RedisCluster|bool|int;
4242

43-
public function bitpos(string $key, int $bit, int $start = NULL, int $end = NULL): RedisCluster|bool|int;
43+
/**
44+
Return the position of the first bit set to 0 or 1 in a string.
45+
46+
@see https://https://redis.io/commands/bitpos/
47+
48+
@param string $key The key to check (must be a string)
49+
@param bool $bit Whether to look for an unset (0) or set (1) bit.
50+
@param int $start Where in the string to start looking.
51+
@param int $end Where in the string to stop looking.
52+
@param bool $bybit If true, Redis will treat $start and $end as BIT values and not bytes, so if start
53+
was 0 and end was 2, Redis would only search the first two bits.
54+
*/
55+
public function bitpos(string $key, bool $bit, int $start = 0, int $end = -1, bool $bybit = false): RedisCluster|int|false;
4456

4557
public function blpop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): RedisCluster|array|null|false;
4658
public function brpop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): RedisCluster|array|null|false;

redis_cluster_arginfo.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 6b41f3c801e587509bc5c7cab302dc6c1e0f7d56 */
2+
* Stub hash: ccb418a312ff22f03e2354de508ff8bd9e4d266e */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
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,
7272
ZEND_ARG_VARIADIC_TYPE_INFO(0, otherkeys, IS_STRING, 0)
7373
ZEND_END_ARG_INFO()
7474

75-
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_bitpos, 0, 2, RedisCluster, MAY_BE_BOOL|MAY_BE_LONG)
75+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_bitpos, 0, 2, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE)
7676
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
77-
ZEND_ARG_TYPE_INFO(0, bit, IS_LONG, 0)
78-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "NULL")
79-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, end, IS_LONG, 0, "NULL")
77+
ZEND_ARG_TYPE_INFO(0, bit, _IS_BOOL, 0)
78+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "0")
79+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, end, IS_LONG, 0, "-1")
80+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, bybit, _IS_BOOL, 0, "false")
8081
ZEND_END_ARG_INFO()
8182

8283
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)

redis_cluster_legacy_arginfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 6b41f3c801e587509bc5c7cab302dc6c1e0f7d56 */
2+
* Stub hash: ccb418a312ff22f03e2354de508ff8bd9e4d266e */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_INFO(0, name)
@@ -70,6 +70,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_bitpos, 0, 0, 2)
7070
ZEND_ARG_INFO(0, bit)
7171
ZEND_ARG_INFO(0, start)
7272
ZEND_ARG_INFO(0, end)
73+
ZEND_ARG_INFO(0, bybit)
7374
ZEND_END_ARG_INFO()
7475

7576
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_blpop, 0, 0, 2)

redis_commands.c

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,38 +2523,41 @@ int redis_restore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
25232523
return SUCCESS;
25242524
}
25252525

2526-
/* BITPOS */
2526+
/* BITPOS key bit [start [end [BYTE | BIT]]] */
25272527
int redis_bitpos_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
25282528
char **cmd, int *cmd_len, short *slot, void **ctx)
25292529
{
2530-
char *key;
2531-
int argc;
2532-
zend_long bit, start, end;
2533-
size_t key_len;
2530+
zend_long start = 0, end = -1;
2531+
zend_bool bit = 0, bybit = 0;
2532+
smart_string cmdstr = {0};
2533+
zend_string *key = NULL;
25342534

2535-
argc = ZEND_NUM_ARGS();
2536-
if (zend_parse_parameters(argc, "sl|ll", &key, &key_len, &bit,
2537-
&start, &end) == FAILURE)
2538-
{
2539-
return FAILURE;
2540-
}
2535+
ZEND_PARSE_PARAMETERS_START(2, 5)
2536+
Z_PARAM_STR(key)
2537+
Z_PARAM_BOOL(bit)
2538+
Z_PARAM_OPTIONAL
2539+
Z_PARAM_LONG(start)
2540+
Z_PARAM_LONG(end)
2541+
Z_PARAM_BOOL(bybit)
2542+
ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
25412543

2542-
// Prevalidate bit
2543-
if (bit != 0 && bit != 1) {
2544-
return FAILURE;
2545-
}
2544+
REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 2 + (ZEND_NUM_ARGS() > 2 ? 2 : 0) + !!bybit, "BITPOS");
25462545

2547-
// Construct command based on arg count
2548-
if (argc == 2) {
2549-
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "BITPOS", "kd", key, key_len, bit);
2550-
} else if (argc == 3) {
2551-
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "BITPOS", "kdd", key, key_len, bit,
2552-
start);
2553-
} else {
2554-
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "BITPOS", "kddd", key, key_len, bit,
2555-
start, end);
2546+
redis_cmd_append_sstr_key_zstr(&cmdstr, key, redis_sock, slot);
2547+
redis_cmd_append_sstr_long(&cmdstr, bit);
2548+
2549+
/* Start and length if we were passed either */
2550+
if (ZEND_NUM_ARGS() > 2) {
2551+
redis_cmd_append_sstr_long(&cmdstr, start);
2552+
redis_cmd_append_sstr_long(&cmdstr, end);
25562553
}
25572554

2555+
/* Finally, BIT or BYTE if we were passed that argument */
2556+
REDIS_CMD_APPEND_SSTR_OPT_STATIC(&cmdstr, !!bybit, "BIT");
2557+
2558+
*cmd = cmdstr.c;
2559+
*cmd_len = cmdstr.len;
2560+
25582561
return SUCCESS;
25592562
}
25602563

redis_legacy_arginfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: b53146f6b329f404b4bfa9e5df9dde9c36b50440 */
2+
* Stub hash: a8ddcde8e8af5201d72bfe8b463afc0c9dafb73d */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_INFO(0, options)
@@ -63,6 +63,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_bitpos, 0, 0, 2)
6363
ZEND_ARG_INFO(0, bit)
6464
ZEND_ARG_INFO(0, start)
6565
ZEND_ARG_INFO(0, end)
66+
ZEND_ARG_INFO(0, bybit)
6667
ZEND_END_ARG_INFO()
6768

6869
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_blPop, 0, 0, 2)

tests/RedisTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,14 @@ public function testBitPos() {
409409

410410
$this->redis->set('bpkey', "\x00\x00\x00");
411411
$this->assertEquals($this->redis->bitpos('bpkey', 1), -1);
412+
413+
if (!$this->minVersionCheck("7.0.0"))
414+
return;
415+
416+
$this->redis->set('bpkey', "\xF");
417+
$this->assertEquals(4, $this->redis->bitpos('bpkey', 1, 0, -1, true));
418+
$this->assertEquals(-1, $this->redis->bitpos('bpkey', 1, 1, -1));
419+
$this->assertEquals(-1, $this->redis->bitpos('bpkey', 1, 1, -1, false));
412420
}
413421

414422
public function test1000() {

0 commit comments

Comments
 (0)