@@ -608,6 +608,128 @@ PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
608
608
}
609
609
}
610
610
611
+ /*
612
+ * Specialized handling of the CLIENT LIST output so it comes out in a simple way for PHP userland code
613
+ * to handle.
614
+ */
615
+ PHPAPI void redis_client_list_reply (INTERNAL_FUNCTION_PARAMETERS , RedisSock * redis_sock , zval * z_tab ) {
616
+ char * resp ;
617
+ int resp_len ;
618
+ zval * z_result , * z_sub_result ;
619
+
620
+ // Make sure we can read a response from Redis
621
+ if ((resp = redis_sock_read (redis_sock , & resp_len TSRMLS_CC )) == NULL ) {
622
+ RETURN_FALSE ;
623
+ }
624
+
625
+ // Allocate memory for our response
626
+ MAKE_STD_ZVAL (z_result );
627
+ array_init (z_result );
628
+
629
+ // Allocate memory for one user (there should be at least one, namely us!)
630
+ ALLOC_INIT_ZVAL (z_sub_result );
631
+ array_init (z_sub_result );
632
+
633
+ // Pointers for parsing
634
+ char * p = resp , * lpos = resp , * kpos = NULL , * vpos = NULL , * p2 , * key , * value ;
635
+
636
+ // Key length, done flag
637
+ int klen , done = 0 , is_numeric ;
638
+
639
+ // While we've got more to parse
640
+ while (!done ) {
641
+ // What character are we on
642
+ switch (* p ) {
643
+ /* We're done */
644
+ case '\0' :
645
+ done = 1 ;
646
+ break ;
647
+ /* \n, ' ' mean we can pull a k/v pair */
648
+ case '\n' :
649
+ case ' ' :
650
+ // Grab our value
651
+ vpos = lpos ;
652
+
653
+ // There is some communication error or Redis bug if we don't
654
+ // have a key and value, but check anyway.
655
+ if (kpos && vpos ) {
656
+ // Allocate, copy in our key
657
+ key = emalloc (klen + 1 );
658
+ strncpy (key , kpos , klen );
659
+ key [klen ] = 0 ;
660
+
661
+ // Allocate, copy in our value
662
+ value = emalloc (p - lpos + 1 );
663
+ strncpy (value ,lpos ,p - lpos + 1 );
664
+ value [p - lpos ]= 0 ;
665
+
666
+ // Treat numbers as numbers, strings as strings
667
+ is_numeric = 1 ;
668
+ for (p2 = value ; * p ; ++ p ) {
669
+ if (* p < '0' || * p > '9' ) {
670
+ is_numeric = 0 ;
671
+ break ;
672
+ }
673
+ }
674
+
675
+ // Add as a long or string, depending
676
+ if (is_numeric == 1 ) {
677
+ add_assoc_long (z_sub_result , key , atol (value ));
678
+ efree (value );
679
+ } else {
680
+ add_assoc_string (z_sub_result , key , value , 0 );
681
+ }
682
+
683
+ // If we hit a '\n', then we can add this user to our list
684
+ if (* p == '\n' ) {
685
+ // Add our user
686
+ add_next_index_zval (z_result , z_sub_result );
687
+
688
+ // If we have another user, make another one
689
+ if (* (p + 1 ) != '\0' ) {
690
+ ALLOC_INIT_ZVAL (z_sub_result );
691
+ array_init (z_sub_result );
692
+ }
693
+ }
694
+
695
+ // Free our key
696
+ efree (key );
697
+ } else {
698
+ // Something is wrong
699
+ efree (resp );
700
+ return -1 ;
701
+ }
702
+
703
+ // Move forward
704
+ lpos = p + 1 ;
705
+
706
+ break ;
707
+ /* We can pull the key and null terminate at our sep */
708
+ case '=' :
709
+ // Key, key length
710
+ kpos = lpos ;
711
+ klen = p - lpos ;
712
+
713
+ // Move forward
714
+ lpos = p + 1 ;
715
+
716
+ break ;
717
+ }
718
+
719
+ // Increment
720
+ p ++ ;
721
+ }
722
+
723
+ // Free our respoonse
724
+ efree (resp );
725
+
726
+ IF_MULTI_OR_PIPELINE () {
727
+ add_next_index_zval (z_tab , z_result );
728
+ } else {
729
+ RETVAL_ZVAL (z_result , 0 , 1 );
730
+ }
731
+ }
732
+
611
733
PHPAPI void redis_boolean_response_impl (INTERNAL_FUNCTION_PARAMETERS , RedisSock * redis_sock , zval * z_tab , void * ctx , SuccessCallback success_callback ) {
612
734
613
735
char * response ;
0 commit comments