Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichael-grunder <michael.grunder@gmail.com>2014-03-03 18:23:38 +0400
committermichael-grunder <michael.grunder@gmail.com>2014-03-03 18:23:38 +0400
commite74ffe036643265b18e864a9a4139cdb3d072d65 (patch)
treeceaf4e25dac1bce1f4382447be7d0ee358d6a812
parent8f006cba2d20479a3b15741fc1a0c801aec4c246 (diff)
Implemented BITPOS command
This commit introduces the new BITPOS redis command http://redis.io/commands/bitpos
-rw-r--r--php_redis.h1
-rw-r--r--redis.c54
-rw-r--r--tests/TestRedis.php19
3 files changed, 74 insertions, 0 deletions
diff --git a/php_redis.h b/php_redis.h
index 176ba2b6..12eb7462 100644
--- a/php_redis.h
+++ b/php_redis.h
@@ -129,6 +129,7 @@ PHP_METHOD(Redis, slaveof);
PHP_METHOD(Redis, object);
PHP_METHOD(Redis, bitop);
PHP_METHOD(Redis, bitcount);
+PHP_METHOD(Redis, bitpos);
PHP_METHOD(Redis, eval);
PHP_METHOD(Redis, evalsha);
diff --git a/redis.c b/redis.c
index 0b199f9d..cb3ed2de 100644
--- a/redis.c
+++ b/redis.c
@@ -177,6 +177,7 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, object, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, bitop, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, bitcount, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Redis, bitpos, NULL, ZEND_ACC_PUBLIC)
/* 1.1 */
PHP_ME(Redis, mset, NULL, ZEND_ACC_PUBLIC)
@@ -820,6 +821,59 @@ PHP_METHOD(Redis, bitcount)
}
/* }}} */
+/* {{{ proto integer Redis::bitpos(string key, int bit, [int start], [int end]) */
+PHP_METHOD(Redis, bitpos)
+{
+ zval *object;
+ RedisSock *redis_sock;
+ char *key, *cmd;
+ int key_len, cmd_len, argc, key_free=0;
+ long bit, start, end;
+
+ argc = ZEND_NUM_ARGS();
+
+ if(zend_parse_method_parameters(argc TSRMLS_CC, getThis(), "Osl|ll",
+ &object, redis_ce, &key, &key_len, &bit,
+ &start, &end)==FAILURE)
+ {
+ RETURN_FALSE;
+ }
+
+ if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
+ RETURN_FALSE;
+ }
+
+ // We can prevalidate the first argument
+ if(bit != 0 && bit != 1) {
+ RETURN_FALSE;
+ }
+
+ // Prefix our key
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+
+ // Various command semantics
+ if(argc == 2) {
+ cmd_len = redis_cmd_format_static(&cmd, "BITPOS", "sd", key, key_len,
+ bit);
+ } else if(argc == 3) {
+ cmd_len = redis_cmd_format_static(&cmd, "BITPOS", "sdd", key, key_len,
+ bit, start);
+ } else {
+ cmd_len = redis_cmd_format_static(&cmd, "BITPOS", "sddd", key, key_len,
+ bit, start, end);
+ }
+
+ // Free our key if it was prefixed
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+ IF_ATOMIC() {
+ redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
+ }
+ REDIS_PROCESS_RESPONSE(redis_long_response);
+}
+/* }}} */
+
/* {{{ proto boolean Redis::close()
*/
PHP_METHOD(Redis, close)
diff --git a/tests/TestRedis.php b/tests/TestRedis.php
index 94ebfc9d..9fa220ae 100644
--- a/tests/TestRedis.php
+++ b/tests/TestRedis.php
@@ -118,6 +118,25 @@ class Redis_Test extends TestSuite
$this->assertFalse($this->redis->setBit('key', 4294967296, 1));
}
+ public function testBitPos() {
+ if(version_compare($this->version, "2.8.7", "lt")) {
+ $this->MarkTestSkipped();
+ return;
+ }
+
+ $this->redis->del('bpkey');
+
+ $this->redis->set('bpkey', "\xff\xf0\x00");
+ $this->assertEquals($this->redis->bitpos('bpkey', 0), 12);
+
+ $this->redis->set('bpkey', "\x00\xff\xf0");
+ $this->assertEquals($this->redis->bitpos('bpkey', 1, 0), 8);
+ $this->assertEquals($this->redis->bitpos('bpkey', 1, 1), 8);
+
+ $this->redis->set('bpkey', "\x00\x00\x00");
+ $this->assertEquals($this->redis->bitpos('bpkey', 1), -1);
+ }
+
public function test1000() {
$s = str_repeat('A', 1000);