static int yac_add_multi_impl(char *prefix, uint prefix_len, zval *kvs, int ttl, int add TSRMLS_DC) /* {{{ */ { HashTable *ht = Z_ARRVAL_P(kvs); for (zend_hash_internal_pointer_reset(ht); zend_hash_has_more_elements(ht) == SUCCESS; zend_hash_move_forward(ht)) { char *key; ulong idx; zval **value; uint len, should_free = 0; if (zend_hash_get_current_data(ht, (void **)&value) == FAILURE) { continue; } switch (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) { case HASH_KEY_IS_LONG: len = spprintf(&key, 0, "%lu", idx) + 1; should_free = 1; case HASH_KEY_IS_STRING: if (yac_add_impl(prefix, prefix_len, key, len - 1, *value, ttl, add TSRMLS_CC)) { if (should_free) { efree(key); } continue; } else { if (should_free) { efree(key); } return 0; } default: continue; } } return 1; }
static int yac_add_multi_impl(char *prefix, uint prefix_len, zval *kvs, int ttl, int add tsrmls_dc) { HashTable *ht = z_arrval_p(kvs); for (zend_hash_internal_pointer_reset(ht); zend_hash_has_more_elements(ht) == success; zend_hash_move_forward(ht)) { char *key; ulong idx; zval **value; uint len, should_free = 0; if (zend_hash_get_current_data(ht, (void **)&value) == FAILURE) { continue; } switch (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, null)) { case hash_key_is_long: len = spprintf(&key, 0, "%lu", idx) + 1; should_free = 1; case hash_key_is_string: if (yac_add_impl(prefix, prefix_len, key, len - 1, *value, ttl, add tsrmls_cc)) { if (should_free) { efree(key); } continue; } else { if (should_free) { efree(key); } return 0; } default: continue; } } return 1; }
static int yac_add_multi_impl(zend_string *prefix, zval *kvs, int ttl, int add) /* {{{ */ { HashTable *ht = Z_ARRVAL_P(kvs); zend_string *key; zend_ulong idx; zval *value; ZEND_HASH_FOREACH_KEY_VAL(ht, idx, key, value) { uint32_t should_free = 0; if (!key) { key = strpprintf(0, "%lu", idx); should_free = 1; } if (yac_add_impl(prefix, key, value, ttl, add)) { if (should_free) { zend_string_release(key); } continue; } else { if (should_free) { zend_string_release(key); } return 0; } } ZEND_HASH_FOREACH_END();
static int yac_add_impl(char *prefix, uint prefix_len, char *key, uint len, zval *value, int ttl, int add TSRMLS_DC) /* {{{ */ { int ret = 0, flag = Z_TYPE_P(value); char *msg, buf[YAC_STORAGE_MAX_KEY_LEN]; time_t tv; if ((len + prefix_len) > YAC_STORAGE_MAX_KEY_LEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key%s can not be longer than %d bytes", prefix_len? "(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN); return ret; } if (prefix_len) { len = snprintf(buf, sizeof(buf), "%s%s", prefix, key); key = (char *)buf; } tv = time(NULL); switch (Z_TYPE_P(value)) { case IS_NULL: ret = yac_storage_update(key, len, (char *)&flag, sizeof(int), flag, ttl, add, tv); break; case IS_BOOL: case IS_LONG: ret = yac_storage_update(key, len, (char *)&Z_LVAL_P(value), sizeof(long), flag, ttl, add, tv); break; case IS_DOUBLE: ret = yac_storage_update(key, len, (char *)&Z_DVAL_P(value), sizeof(double), flag, ttl, add, tv); break; case IS_STRING: case IS_CONSTANT: { if (Z_STRLEN_P(value) > YAC_G(compress_threshold) || Z_STRLEN_P(value) > YAC_STORAGE_MAX_ENTRY_LEN) { int compressed_len; char *compressed; /* if longer than this, then we can not stored the length in flag */ if (Z_STRLEN_P(value) > YAC_ENTRY_MAX_ORIG_LEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too long(%d bytes) to be stored", Z_STRLEN_P(value)); return ret; } compressed = emalloc(Z_STRLEN_P(value) * 1.05); compressed_len = fastlz_compress(Z_STRVAL_P(value), Z_STRLEN_P(value), compressed); if (!compressed_len || compressed_len > Z_STRLEN_P(value)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compression failed"); efree(compressed); return ret; } if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too long(%d bytes) to be stored", Z_STRLEN_P(value)); efree(compressed); return ret; } flag |= YAC_ENTRY_COMPRESSED; flag |= (Z_STRLEN_P(value) << YAC_ENTRY_ORIG_LEN_SHIT); ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add, tv); efree(compressed); } else { ret = yac_storage_update(key, len, Z_STRVAL_P(value), Z_STRLEN_P(value), flag, ttl, add, tv); } } break; case IS_ARRAY: case IS_CONSTANT_ARRAY: case IS_OBJECT: { smart_str buf = {0}; #if ENABLE_MSGPACK if (yac_serializer_msgpack_pack(value, &buf, &msg TSRMLS_CC)) { #else if (yac_serializer_php_pack(value, &buf, &msg TSRMLS_CC)) { #endif if (buf.len > YAC_G(compress_threshold) || buf.len > YAC_STORAGE_MAX_ENTRY_LEN) { int compressed_len; char *compressed; if (buf.len > YAC_ENTRY_MAX_ORIG_LEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored"); return ret; } compressed = emalloc(buf.len * 1.05); compressed_len = fastlz_compress(buf.c, buf.len, compressed); if (!compressed_len || compressed_len > buf.len) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compression failed"); efree(compressed); return ret; } if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored"); efree(compressed); return ret; } flag |= YAC_ENTRY_COMPRESSED; flag |= (buf.len << YAC_ENTRY_ORIG_LEN_SHIT); ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add, tv); efree(compressed); } else { ret = yac_storage_update(key, len, buf.c, buf.len, flag, ttl, add, tv); } smart_str_free(&buf); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serialization failed"); smart_str_free(&buf); } } break; case IS_RESOURCE: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type 'IS_RESOURCE' cannot be stored"); break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported valued type to be stored '%d'", flag); break; } return ret; } /* }}} */ static int yac_add_multi_impl(char *prefix, uint prefix_len, zval *kvs, int ttl, int add TSRMLS_DC) /* {{{ */ { HashTable *ht = Z_ARRVAL_P(kvs); for (zend_hash_internal_pointer_reset(ht); zend_hash_has_more_elements(ht) == SUCCESS; zend_hash_move_forward(ht)) { char *key; ulong idx; zval **value; uint len, should_free = 0; if (zend_hash_get_current_data(ht, (void **)&value) == FAILURE) { continue; } switch (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) { case HASH_KEY_IS_LONG: len = spprintf(&key, 0, "%lu", idx) + 1; should_free = 1; case HASH_KEY_IS_STRING: if (yac_add_impl(prefix, prefix_len, key, len - 1, *value, ttl, add TSRMLS_CC)) { if (should_free) { efree(key); } continue; } else { if (should_free) { efree(key); } return 0; } default: continue; } } return 1; }