@@ -2522,100 +2522,115 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
2522
2522
return 1 ;
2523
2523
}
2524
2524
2525
- /* {{{ Memcached::setBucket(array host_map, array forward_map, long buckets, long replicas)
2525
+ static
2526
+ uint32_t * s_zval_to_uint32_array (zval * input , size_t * num_elements TSRMLS_DC )
2527
+ {
2528
+ zval * * ppzval ;
2529
+ uint32_t * retval ;
2530
+ size_t i = 0 ;
2531
+
2532
+ * num_elements = zend_hash_num_elements (Z_ARRVAL_P (input ));
2533
+
2534
+ if (!* num_elements ) {
2535
+ return NULL ;
2536
+ }
2537
+
2538
+ retval = ecalloc (* num_elements , sizeof (uint32_t ));
2539
+
2540
+ for (zend_hash_internal_pointer_reset (Z_ARRVAL_P (input ));
2541
+ zend_hash_get_current_data (Z_ARRVAL_P (input ), (void * * ) & ppzval ) == SUCCESS ;
2542
+ zend_hash_move_forward (Z_ARRVAL_P (input )), i ++ ) {
2543
+
2544
+ long value = 0 ;
2545
+
2546
+ if (Z_TYPE_PP (ppzval ) == IS_LONG ) {
2547
+ value = Z_LVAL_PP (ppzval );
2548
+ }
2549
+ else {
2550
+ zval tmp_zval , * tmp_pzval ;
2551
+ tmp_zval = * * ppzval ;
2552
+ zval_copy_ctor (& tmp_zval );
2553
+ tmp_pzval = & tmp_zval ;
2554
+ convert_to_long (tmp_pzval );
2555
+
2556
+ value = (Z_LVAL_P (tmp_pzval ) > 0 ) ? Z_LVAL_P (tmp_pzval ) : 0 ;
2557
+ zval_dtor (tmp_pzval );
2558
+ }
2559
+
2560
+ if (value < 0 ) {
2561
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "the map must contain positive integers" );
2562
+ efree (retval );
2563
+ * num_elements = 0 ;
2564
+ return NULL ;
2565
+ }
2566
+ retval [i ] = (uint32_t ) value ;
2567
+ }
2568
+ return retval ;
2569
+ }
2570
+
2571
+ /* {{{ Memcached::setBucket(array host_map, array forward_map, integer replicas)
2526
2572
Sets the memcached virtual buckets */
2527
2573
2528
2574
PHP_METHOD (Memcached , setBucket )
2529
2575
{
2530
- zval * host_map ;
2531
- zval * forward_map ;
2532
- long buckets ;
2533
- long replicas ;
2534
-
2535
- uint32_t * hm = NULL ,* fm = NULL ;
2536
- zend_bool ok = 1 ;
2537
- uint key_len ;
2538
- char * key ;
2539
- ulong key_index ;
2540
- zval * * value ;
2576
+ zval * zserver_map ;
2577
+ zval * zforward_map = NULL ;
2578
+ long replicas = 0 ;
2579
+ zend_bool retval = 1 ;
2580
+
2581
+ uint32_t * server_map = NULL , * forward_map = NULL ;
2582
+ size_t server_map_len = 0 , forward_map_len = 0 ;
2583
+ memcached_return rc ;
2541
2584
MEMC_METHOD_INIT_VARS ;
2542
-
2543
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "aa!ll " , & host_map , & forward_map , & buckets , & replicas ) == FAILURE ) {
2585
+
2586
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "aa!l " , & zserver_map , & zforward_map , & replicas ) == FAILURE ) {
2544
2587
return ;
2545
2588
}
2546
-
2547
-
2548
- hm = (uint32_t * )malloc (buckets * sizeof (uint32_t ));
2549
-
2550
- int i = 0 ;
2551
- for (zend_hash_internal_pointer_reset (Z_ARRVAL_P (host_map ));
2552
- zend_hash_get_current_data (Z_ARRVAL_P (host_map ), (void * ) & value ) == SUCCESS ;
2553
- zend_hash_move_forward (Z_ARRVAL_P (host_map ))) {
2554
-
2555
- if (i < buckets ) {
2556
- if (zend_hash_get_current_key_ex (Z_ARRVAL_P (host_map ), & key , & key_len , & key_index , 0 , NULL ) == HASH_KEY_IS_LONG ) {
2557
- zval copy = * * value ;
2558
- zval_copy_ctor (& copy );
2559
- INIT_PZVAL (& copy );
2560
- convert_to_long (& copy );
2561
- hm [i ] = Z_LVAL_P (& copy );
2562
- ++ i ;
2563
- zval_dtor (& copy );
2564
- } else {
2565
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "invalid configuration option ");
2566
- ok = 0 ;
2567
- }
2568
- } else {
2569
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "array size mismatch ");
2570
- ok = 0 ;
2571
- break ;
2572
- }
2589
+
2590
+ MEMC_METHOD_FETCH_OBJECT ;
2591
+
2592
+ if (zend_hash_num_elements (Z_ARRVAL_P (zserver_map )) == 0 ) {
2593
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "server map cannot be empty" );
2594
+ RETURN_FALSE ;
2573
2595
}
2574
2596
2575
- if (i != buckets ) {
2576
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "array size mismatch ");
2577
- ok = 0 ;
2578
- }
2579
-
2580
- i = 0 ;
2581
- if (ok != 0 && forward_map != NULL ) {
2582
- fm = (uint32_t * )malloc (buckets * sizeof (uint32_t ));
2583
- for (zend_hash_internal_pointer_reset (Z_ARRVAL_P (forward_map ));
2584
- zend_hash_get_current_data (Z_ARRVAL_P (forward_map ), (void * ) & value ) == SUCCESS ;
2585
- zend_hash_move_forward (Z_ARRVAL_P (forward_map ))) {
2586
-
2587
- if (i < buckets ) {
2588
- if (zend_hash_get_current_key_ex (Z_ARRVAL_P (forward_map ), & key , & key_len , & key_index , 0 , NULL ) == HASH_KEY_IS_LONG ) {
2589
- zval copy = * * value ;
2590
- zval_copy_ctor (& copy );
2591
- INIT_PZVAL (& copy );
2592
-
2593
- convert_to_long (& copy );
2594
- fm [i ] = Z_LVAL_P (& copy );
2595
- ++ i ;
2596
- zval_dtor (& copy );
2597
- } else {
2598
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "invalid configuration option ");
2599
- ok = 0 ;
2600
- }
2601
- } else {
2602
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "array size mismatch ");
2603
- ok = 0 ;
2604
- }
2597
+ if (zforward_map && zend_hash_num_elements (Z_ARRVAL_P (zserver_map )) != zend_hash_num_elements (Z_ARRVAL_P (zforward_map ))) {
2598
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "forward_map length must match the server_map length" );
2599
+ RETURN_FALSE ;
2600
+ }
2601
+
2602
+ if (replicas < 0 ) {
2603
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "replicas must be larger than zero" );
2604
+ RETURN_FALSE ;
2605
+ }
2606
+
2607
+ server_map = s_zval_to_uint32_array (zserver_map , & server_map_len TSRMLS_CC );
2608
+
2609
+ if (!server_map ) {
2610
+ RETURN_FALSE ;
2611
+ }
2612
+
2613
+ if (zforward_map ) {
2614
+ forward_map = s_zval_to_uint32_array (zforward_map , & forward_map_len TSRMLS_CC );
2615
+
2616
+ if (!forward_map ) {
2617
+ efree (server_map );
2618
+ RETURN_FALSE ;
2605
2619
}
2606
2620
}
2607
-
2608
- MEMC_METHOD_FETCH_OBJECT ;
2609
-
2610
- if (memcached_bucket_set (m_obj -> memc , hm , fm , buckets , replicas ) != MEMCACHED_SUCCESS )
2611
- {
2612
- ok = 0 ;
2613
- php_error_docref (NULL TSRMLS_CC , E_WARNING ,"memcached_bucket_set don't returned MEMCACHED_SUCCESS" );
2621
+
2622
+ rc = memcached_bucket_set (m_obj -> memc , server_map , forward_map , (uint32_t ) server_map_len , replicas );
2623
+
2624
+ if (php_memc_handle_error (i_obj , rc TSRMLS_CC ) < 0 ) {
2625
+ retval = 0 ;;
2614
2626
}
2615
- free (hm );
2616
- free (fm );
2617
- RETURN_BOOL (ok );
2618
-
2627
+
2628
+ efree (server_map );
2629
+
2630
+ if (forward_map ) {
2631
+ efree (forward_map );
2632
+ }
2633
+ RETURN_BOOL (retval );
2619
2634
}
2620
2635
/* }}} */
2621
2636
@@ -3869,10 +3884,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_setOptions, 0)
3869
3884
ZEND_ARG_INFO (0 , options )
3870
3885
ZEND_END_ARG_INFO ()
3871
3886
3872
- ZEND_BEGIN_ARG_INFO (arginfo_setBucket , 0 )
3887
+ ZEND_BEGIN_ARG_INFO (arginfo_setBucket , 3 )
3873
3888
ZEND_ARG_INFO (0 , host_map )
3874
3889
ZEND_ARG_INFO (0 , forward_map )
3875
- ZEND_ARG_INFO (0 , buckets )
3876
3890
ZEND_ARG_INFO (0 , replicas )
3877
3891
ZEND_END_ARG_INFO ()
3878
3892
@@ -3963,7 +3977,7 @@ static zend_function_entry memcached_class_methods[] = {
3963
3977
MEMC_ME (getOption , arginfo_getOption )
3964
3978
MEMC_ME (setOption , arginfo_setOption )
3965
3979
MEMC_ME (setOptions , arginfo_setOptions )
3966
- MEMC_ME (setBucket , arginfo_setBucket )
3980
+ MEMC_ME (setBucket , arginfo_setBucket )
3967
3981
#ifdef HAVE_MEMCACHED_SASL
3968
3982
MEMC_ME (setSaslAuthData , arginfo_setSaslAuthData )
3969
3983
#endif
0 commit comments