diff options
author | Pavlo Yatsukhnenko <yatsukhnenko@gmail.com> | 2022-06-18 19:46:28 +0300 |
---|---|---|
committer | Pavlo Yatsukhnenko <yatsukhnenko@gmail.com> | 2022-06-18 19:46:28 +0300 |
commit | 68136a297287afff98417f62ef6bfe1449d03c49 (patch) | |
tree | 614f9fffabaaee861afa2ca0be5a312153e517c0 | |
parent | 39e7c096bac35cd3c6a279394df8ce4bd062e837 (diff) |
Refactor redis_parse_client_list_response
-rw-r--r-- | library.c | 117 |
1 files changed, 33 insertions, 84 deletions
@@ -1193,95 +1193,44 @@ redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zva PHP_REDIS_API void redis_parse_client_list_response(char *response, zval *z_ret) { - char *p, *lpos, *kpos = NULL, *vpos = NULL, *p2, *key, *value; - int klen = 0, done = 0, is_numeric; - zval z_sub_result; + char *p1, *s1 = NULL; - /* Allocate for response and our user */ - array_init(z_ret); - array_init(&z_sub_result); - - // Pointers for parsing - p = response; - lpos = response; - - /* While we've got more to parse */ - while(!done) { - /* What character are we on */ - switch(*p) { - /* We're done */ - case '\0': - done = 1; - break; - /* \n, ' ' mean we can pull a k/v pair */ - case '\n': - case ' ': - /* Grab our value */ - vpos = lpos; - - /* There is some communication error or Redis bug if we don't - have a key and value, but check anyway. */ - if(kpos && vpos) { - /* Allocate, copy in our key */ - key = estrndup(kpos, klen); - - /* Allocate, copy in our value */ - value = estrndup(lpos, p - lpos); - - /* Treat numbers as numbers, strings as strings */ - is_numeric = 1; - for(p2 = value; *p2; ++p2) { - if(*p2 < '0' || *p2 > '9') { - is_numeric = 0; + if ((p1 = strtok_r(response, _NL, &s1)) != NULL) { + array_init(z_ret); + do { + char *p2, *s2 = NULL; + zval z_sub; + + if ((p2 = strtok_r(p1, " ", &s2)) != NULL) { + array_init(&z_sub); + do { + char *p; + zend_uchar type; + zend_long lval; + double dval; + if ((p = strchr(p2, '=')) != NULL) { + type = is_numeric_string(p + 1, s2 - p - 1, &lval, &dval, 0); + switch (type) { + case IS_LONG: + add_assoc_long_ex(&z_sub, p2, p - p2, lval); + break; + case IS_DOUBLE: + add_assoc_double_ex(&z_sub, p2, p - p2, dval); break; + default: + add_assoc_stringl_ex(&z_sub, p2, p - p2, p + 1, s2 - p - 1); } - } - - /* Add as a long or string, depending */ - if(is_numeric == 1) { - add_assoc_long(&z_sub_result, key, atol(value)); } else { - add_assoc_string(&z_sub_result, key, value); - } - efree(value); - // If we hit a '\n', then we can add this user to our list - if(*p == '\n') { - /* Add our user */ - add_next_index_zval(z_ret, &z_sub_result); - - /* If we have another user, make another one */ - if(*(p+1) != '\0') { - array_init(&z_sub_result); - } + add_next_index_string(&z_sub, p2); } - - // Free our key - efree(key); - } else { - // Something is wrong - zval_dtor(z_ret); - ZVAL_BOOL(z_ret, 0); - return; - } - - /* Move forward */ - lpos = p + 1; - - break; - /* We can pull the key and null terminate at our sep */ - case '=': - /* Key, key length */ - kpos = lpos; - klen = p - lpos; - - /* Move forward */ - lpos = p + 1; - - break; - } - - /* Increment */ - p++; + } while ((p2 = strtok_r(NULL, " ", &s2)) != NULL); + } else { + ZVAL_FALSE(&z_sub); + } + add_next_index_zval(z_ret, &z_sub); + } while ((p1 = strtok_r(NULL, _NL, &s1)) != NULL); + } else { + ZVAL_FALSE(z_ret); } } |