33#include <sys/types.h>
44#include <netinet/tcp.h> /* TCP_NODELAY */
55#include <sys/socket.h>
6- #include <ext/standard/php_smart_str_public .h>
6+ #include <ext/standard/php_smart_str .h>
77#include <ext/standard/php_var.h>
88
99#include "igbinary/igbinary.h"
@@ -185,242 +185,137 @@ void add_constant_long(zend_class_entry *ce, char *name, int value) {
185185
186186int
187187integer_length (int i ) {
188- int sz = 0 ;
189- int ci = abs (i );
190- while (ci > 0 ) {
191- ci = (ci /10 );
192- sz += 1 ;
193- }
194- if (i == 0 ) { /* log 0 doesn't make sense. */
195- sz = 1 ;
196- } else if (i < 0 ) { /* allow for neg sign as well. */
197- sz ++ ;
198- }
199- return sz ;
200- }
201-
202- int
203- double_length (double d ) {
204- char * s ;
205- int ret ;
206- s = _php_math_number_format (d , 8 , '.' , '\x00' );
207- ret = strlen (s );
208- efree (s );
209- return ret ;
188+ int sz = 0 ;
189+ int ci = abs (i );
190+ while (ci > 0 ) {
191+ ci /= 10 ;
192+ sz ++ ;
193+ }
194+ if (i == 0 ) { /* log 0 doesn't make sense. */
195+ sz = 1 ;
196+ } else if (i < 0 ) { /* allow for neg sign as well. */
197+ sz ++ ;
198+ }
199+ return sz ;
210200}
211201
212-
213202int
214203redis_cmd_format_static (char * * ret , char * keyword , char * format , ...) {
215204
216- char * p , * s ;
205+ char * p = format ;
217206 va_list ap ;
218-
219- int total = 0 , sz , ret_sz ;
220- int i ;
221- double dbl ;
222-
223- int stage ; /* 0: count & alloc. 1: copy. */
224- int elements = strlen (format );
225- int keyword_len = strlen (keyword );
226- int header_sz = 1 + integer_length (1 + elements ) + 2 /* star + elements + CRLF */
227- + 1 + integer_length (keyword_len ) + 2 /* dollar + command length + CRLF */
228- + keyword_len + 2 ; /* command + CRLF */
229-
230- for (stage = 0 ; stage < 2 ; ++ stage ) {
231- va_start (ap , format );
232- if (stage == 0 ) {
233- total = 0 ;
234- } else {
235- total = header_sz ;
207+ smart_str buf = {0 };
208+ int l = strlen (keyword );
209+
210+ va_start (ap , format );
211+
212+ /* add header */
213+ smart_str_appendc (& buf , '*' );
214+ smart_str_append_long (& buf , strlen (format ) + 1 );
215+ smart_str_appendl (& buf , _NL , sizeof (_NL ) - 1 );
216+ smart_str_appendc (& buf , '$' );
217+ smart_str_append_long (& buf , l );
218+ smart_str_appendl (& buf , _NL , sizeof (_NL ) - 1 );
219+ smart_str_appendl (& buf , keyword , l );
220+ smart_str_appendl (& buf , _NL , sizeof (_NL ) - 1 );
221+
222+ while (* p ) {
223+ smart_str_appendc (& buf , '$' );
224+
225+ switch (* p ) {
226+ case 's' : {
227+ char * val = va_arg (ap , char * );
228+ int val_len = va_arg (ap , int );
229+ smart_str_append_long (& buf , val_len );
230+ smart_str_appendl (& buf , _NL , sizeof (_NL ) - 1 );
231+ smart_str_appendl (& buf , val , val_len );
232+ }
233+ break ;
234+
235+ case 'f' :
236+ case 'F' : {
237+ char tmp [100 ];
238+ double d = va_arg (ap , double );
239+ int tmp_len = snprintf (tmp , sizeof (tmp ), "%.8f" , d );
240+ smart_str_append_long (& buf , tmp_len );
241+ smart_str_appendl (& buf , _NL , sizeof (_NL ) - 1 );
242+ smart_str_appendl (& buf , tmp , tmp_len );
243+ }
244+ break ;
245+
246+ case 'i' :
247+ case 'd' : {
248+ int i = va_arg (ap , int );
249+ char tmp [32 ];
250+ int tmp_len = snprintf (tmp , sizeof (tmp ), "%d" , i );
251+ smart_str_append_long (& buf , tmp_len );
252+ smart_str_appendl (& buf , _NL , sizeof (_NL ) - 1 );
253+ smart_str_appendl (& buf , tmp , tmp_len );
254+ }
255+ break ;
256+ }
257+ p ++ ;
258+ smart_str_appendl (& buf , _NL , sizeof (_NL ) - 1 );
236259 }
237- for (p = format ; * p ; ) {
238- switch (* p ) {
239- case 's' :
240- s = va_arg (ap , char * );
241- sz = va_arg (ap , int );
242- if (stage == 1 ) {
243- memcpy ((* ret ) + total , "$" , 1 ); /* dollar */
244- total ++ ;
245-
246- sprintf ((* ret ) + total , "%d" , sz ); /* size */
247- total += integer_length (sz );
248-
249- memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
250- total += 2 ;
251-
252- memcpy ((* ret ) + total , s , sz ); /* string */
253- total += sz ;
254-
255- memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
256- total += 2 ;
257- } else {
258- total += 1 + integer_length (sz ) + 2 + sz + 2 ;
259- }
260- break ;
261-
262- case 'F' :
263- case 'f' :
264- /* use spprintf here */
265- dbl = va_arg (ap , double );
266- sz = double_length (dbl );
267- char * dbl_str ;
268- if (stage == 1 ) {
269- memcpy ((* ret ) + total , "$" , 1 ); /* dollar */
270- total ++ ;
271-
272- sprintf ((* ret ) + total , "%d" , sz ); /* size */
273- total += integer_length (sz );
274-
275- memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
276- total += 2 ;
277-
278- /* float value */
279- dbl_str = _php_math_number_format (dbl , 8 , '.' , '\x00' );
280- memcpy ((* ret ) + total , dbl_str , sz );
281- efree (dbl_str );
282- total += sz ;
283-
284- memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
285- total += 2 ;
286- } else {
287- total += 1 + integer_length (sz ) + 2 + sz + 2 ;
288- }
289- break ;
290-
291- case 'i' :
292- case 'd' :
293- i = va_arg (ap , int );
294- /* compute display size of integer value */
295- sz = integer_length (i );
296- if (stage == 1 ) {
297- memcpy ((* ret ) + total , "$" , 1 ); /* dollar */
298- total ++ ;
299-
300- sprintf ((* ret ) + total , "%d" , sz ); /* size */
301- total += integer_length (sz );
302-
303- memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
304- total += 2 ;
305-
306- sprintf ((* ret ) + total , "%d" , i ); /* int */
307- total += sz ;
308-
309- memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
310- total += 2 ;
311- } else {
312- total += 1 + integer_length (sz ) + 2 + sz + 2 ;
313- }
314- break ;
315- }
316- p ++ ;
317- }
318- if (stage == 0 ) {
319- ret_sz = total + header_sz ;
320- (* ret ) = emalloc (ret_sz + 1 );
321- sprintf (* ret , "*%d" _NL "$%d" _NL "%s" _NL , elements + 1 , keyword_len , keyword );
322- } else {
323- (* ret )[ret_sz ] = 0 ;
324- // printf("cmd(%d)=[%s]\n", ret_sz, *ret);
325- return ret_sz ;
326- }
327- }
328- return 0 ;
260+ smart_str_0 (& buf );
261+
262+ * ret = buf .c ;
263+
264+ return buf .len ;
329265}
330266
331267/**
332268 * This command behave somehow like printf, except that strings need 2 arguments:
333269 * Their data and their size (strlen).
334270 * Supported formats are: %d, %i, %s
335271 */
336- //static /!\ problem with static commands !!
337272int
338273redis_cmd_format (char * * ret , char * format , ...) {
339274
340- char * p , * s ;
341- va_list ap ;
275+ smart_str buf = {0 };
276+ va_list ap ;
277+ char * p = format ;
278+
279+ while (* p ) {
280+ if (* p == '%' ) {
281+ switch (* (++ p )) {
282+ case 's' : {
283+ char * tmp = va_arg (ap , char * );
284+ int tmp_len = va_arg (ap , int );
285+ smart_str_appendl (& buf , tmp , tmp_len );
286+ }
287+ break ;
342288
343- int total = 0 , sz , ret_sz ;
344- int i , ci ;
345- double dbl ;
346- char * double_str ;
347- int double_len ;
348-
349- int stage ; /* 0: count & alloc. 1: copy. */
350-
351- for (stage = 0 ; stage < 2 ; ++ stage ) {
352- va_start (ap , format );
353- total = 0 ;
354- for (p = format ; * p ; ) {
355-
356- if (* p == '%' ) {
357- switch (* (p + 1 )) {
358- case 's' :
359- s = va_arg (ap , char * );
360- sz = va_arg (ap , int );
361- if (stage == 1 ) {
362- memcpy ((* ret ) + total , s , sz );
363- }
364- total += sz ;
365- break ;
366-
367- case 'F' :
368- case 'f' :
369- /* use spprintf here */
370- dbl = va_arg (ap , double );
371- double_len = double_length (dbl );
372-
373- if (stage == 1 ) {
374- /* float value */
375- char * dbl_str = _php_math_number_format (dbl , 8 , '.' , '\x00' );
376- memcpy ((* ret ) + total , dbl_str , sz );
377- total += sz ;
378- efree (dbl_str );
379- }
380- total += double_len ;
381- efree (double_str );
382- break ;
383-
384- case 'i' :
385- case 'd' :
386- i = va_arg (ap , int );
387- /* compute display size of integer value */
388- sz = 0 ;
389- ci = abs (i );
390- while (ci > 0 ) {
391- ci = (ci /10 );
392- sz += 1 ;
393- }
394- if (i == 0 ) { /* log 0 doesn't make sense. */
395- sz = 1 ;
396- } else if (i < 0 ) { /* allow for neg sign as well. */
397- sz ++ ;
398- }
399- if (stage == 1 ) {
400- sprintf ((* ret ) + total , "%d" , i );
401- }
402- total += sz ;
403- break ;
404- }
405- p ++ ;
406- } else {
407- if (stage == 1 ) {
408- (* ret )[total ] = * p ;
409- }
410- total ++ ;
411- }
289+ case 'F' :
290+ case 'f' : {
291+ char tmp [100 ];
292+ double d = va_arg (ap , double );
293+ int tmp_len = snprintf (tmp , sizeof (tmp ), "%.8f" , d );
294+ smart_str_appendl (& buf , tmp , tmp_len );
295+ }
296+ break ;
412297
413- p ++ ;
414- }
415- if (stage == 0 ) {
416- ret_sz = total ;
417- (* ret ) = emalloc (ret_sz + 1 );
418- } else {
419- (* ret )[ret_sz ] = 0 ;
420- return ret_sz ;
421- }
422- }
423- return 0 ;
298+ case 'd' :
299+ case 'i' : {
300+ int i = va_arg (ap , int );
301+ char tmp [32 ];
302+ int tmp_len = snprintf (tmp , sizeof (tmp ), "%d" , i );
303+ smart_str_appendl (& buf , tmp , tmp_len );
304+ }
305+ break ;
306+ }
307+ } else {
308+ smart_str_appendc (& buf , * p );
309+ }
310+
311+ p ++ ;
312+ }
313+
314+ smart_str_0 (& buf );
315+
316+ * ret = buf .c ;
317+
318+ return buf .len ;
424319}
425320
426321PHPAPI void redis_bulk_double_response (INTERNAL_FUNCTION_PARAMETERS , RedisSock * redis_sock , zval * z_tab , void * ctx ) {
@@ -742,7 +637,6 @@ PHPAPI void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
742637 RETURN_FALSE ;
743638 }
744639 IF_MULTI_OR_PIPELINE () {
745- zval * z = NULL ;
746640 add_next_index_stringl (z_tab , response , response_len , 0 );
747641 } else {
748642 RETURN_STRINGL (response , response_len , 0 );
@@ -759,15 +653,12 @@ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short por
759653 RedisSock * redis_sock ;
760654
761655 redis_sock = ecalloc (1 , sizeof (RedisSock ));
762- redis_sock -> host = ecalloc ( host_len + 1 , 1 );
656+ redis_sock -> host = strndup ( host , host_len );
763657 redis_sock -> stream = NULL ;
764658 redis_sock -> status = REDIS_SOCK_STATUS_DISCONNECTED ;
765659
766660 redis_sock -> persistent = persistent ;
767661
768- memcpy (redis_sock -> host , host , host_len );
769- redis_sock -> host [host_len ] = '\0' ;
770-
771662 redis_sock -> port = port ;
772663 redis_sock -> timeout = timeout ;
773664
0 commit comments