Skip to content

Commit df20b8a

Browse files
committed
Convert float to ascii using g_fmt and zend_dtoa.
This procudes much smaller textual representations and also ignores locales.
1 parent 37e46ec commit df20b8a

File tree

4 files changed

+161
-20
lines changed

4 files changed

+161
-20
lines changed

config.m4

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ if test "$PHP_MEMCACHED" != "no"; then
242242

243243
PHP_SUBST(MEMCACHED_SHARED_LIBADD)
244244

245-
PHP_MEMCACHED_FILES="php_memcached.c fastlz/fastlz.c"
245+
PHP_MEMCACHED_FILES="php_memcached.c fastlz/fastlz.c g_fmt.c"
246246

247247
if test "$PHP_MEMCACHED_SESSION" != "no"; then
248248
PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_session.c"

g_fmt.c

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/****************************************************************
2+
*
3+
* The author of this software is David M. Gay.
4+
*
5+
* Copyright (c) 1991, 1996 by Lucent Technologies.
6+
*
7+
* Permission to use, copy, modify, and distribute this software for any
8+
* purpose without fee is hereby granted, provided that this entire notice
9+
* is included in all copies of any software which is or includes a copy
10+
* or modification of this software and in all copies of the supporting
11+
* documentation for such software.
12+
*
13+
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14+
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
15+
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16+
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17+
*
18+
***************************************************************/
19+
20+
/* g_fmt(buf,x) stores the closest decimal approximation to x in buf;
21+
* it suffices to declare buf
22+
* char buf[32];
23+
*/
24+
25+
/* Modified for use with php in the memcached client extension.
26+
*
27+
* // Teddy Grenman <[email protected]>, 2010-05-18.
28+
*/
29+
30+
#include <zend_operators.h>
31+
32+
char *php_memcached_g_fmt(register char *b, double x) {
33+
register int i, k;
34+
register char *s;
35+
int decpt, j, sign;
36+
char *b0, *s0, *se;
37+
38+
b0 = b;
39+
#ifdef IGNORE_ZERO_SIGN
40+
if (!x) {
41+
*b++ = '0';
42+
*b = 0;
43+
goto done;
44+
}
45+
#endif
46+
47+
s = s0 = zend_dtoa(x, 0, 0, &decpt, &sign, &se);
48+
if (sign)
49+
*b++ = '-';
50+
if (decpt == 9999) /* Infinity or Nan */ {
51+
while(*b++ = *s++);
52+
goto done0;
53+
}
54+
if (decpt <= -4 || decpt > se - s + 5) {
55+
*b++ = *s++;
56+
if (*s) {
57+
*b++ = '.';
58+
while(*b = *s++)
59+
b++;
60+
}
61+
*b++ = 'e';
62+
/* sprintf(b, "%+.2d", decpt - 1); */
63+
if (--decpt < 0) {
64+
*b++ = '-';
65+
decpt = -decpt;
66+
}
67+
else
68+
*b++ = '+';
69+
for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10);
70+
for(;;) {
71+
i = decpt / k;
72+
*b++ = i + '0';
73+
if (--j <= 0)
74+
break;
75+
decpt -= i*k;
76+
decpt *= 10;
77+
}
78+
*b = 0;
79+
} else if (decpt <= 0) {
80+
*b++ = '.';
81+
for(; decpt < 0; decpt++)
82+
*b++ = '0';
83+
while(*b++ = *s++);
84+
} else {
85+
while(*b = *s++) {
86+
b++;
87+
if (--decpt == 0 && *s)
88+
*b++ = '.';
89+
}
90+
for(; decpt > 0; decpt--)
91+
*b++ = '0';
92+
*b = 0;
93+
}
94+
95+
done0:
96+
zend_freedtoa(s0);
97+
done:
98+
return b0;
99+
}

g_fmt.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/****************************************************************
2+
*
3+
* The author of this software is David M. Gay.
4+
*
5+
* Copyright (c) 1991, 1996 by Lucent Technologies.
6+
*
7+
* Permission to use, copy, modify, and distribute this software for any
8+
* purpose without fee is hereby granted, provided that this entire notice
9+
* is included in all copies of any software which is or includes a copy
10+
* or modification of this software and in all copies of the supporting
11+
* documentation for such software.
12+
*
13+
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14+
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
15+
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16+
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17+
*
18+
***************************************************************/
19+
20+
/* g_fmt(buf,x) stores the closest decimal approximation to x in buf;
21+
* it suffices to declare buf
22+
* char buf[32];
23+
*/
24+
25+
/* Modified for use with php in the memcached client
26+
* extension by Teddy Grenman, 2010.
27+
*/
28+
29+
#ifndef MEMC_G_FMT_H
30+
#define MEMC_G_FMT_H
31+
32+
char *php_memcached_g_fmt(register char *b, double x);
33+
34+
#endif

php_memcached.c

+27-19
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@
4242
#include <zend_exceptions.h>
4343
#include <ext/standard/php_smart_str.h>
4444
#include <ext/standard/php_var.h>
45+
#include <ext/standard/basic_functions.h>
4546
#include <libmemcached/memcached.h>
4647

4748
#include "php_memcached.h"
49+
#include "g_fmt.h"
4850

4951
#ifdef HAVE_MEMCACHED_SESSION
5052
# include "php_memcached_session.h"
@@ -2480,27 +2482,28 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
24802482
break;
24812483

24822484
case IS_LONG:
2485+
smart_str_append_long(&buf, Z_LVAL_P(value));
2486+
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG);
2487+
break;
2488+
24832489
case IS_DOUBLE:
2484-
case IS_BOOL:
24852490
{
2486-
zval value_copy;
2491+
char dstr[40] = {0};
24872492

2488-
value_copy = *value;
2489-
zval_copy_ctor(&value_copy);
2490-
convert_to_string(&value_copy);
2491-
smart_str_appendl(&buf, Z_STRVAL(value_copy), Z_STRLEN(value_copy));
2492-
zval_dtor(&value_copy);
2493+
php_memcached_g_fmt(dstr, Z_DVAL_P(value));
2494+
smart_str_appends(&buf, dstr);
2495+
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE);
2496+
break;
2497+
}
24932498

2494-
*flags &= ~MEMC_VAL_COMPRESSED;
2495-
if (Z_TYPE_P(value) == IS_LONG) {
2496-
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG);
2497-
} else if (Z_TYPE_P(value) == IS_DOUBLE) {
2498-
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE);
2499-
} else if (Z_TYPE_P(value) == IS_BOOL) {
2500-
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL);
2499+
case IS_BOOL:
2500+
if (Z_BVAL_P(value)) {
2501+
smart_str_appendc(&buf, '1');
2502+
} else {
2503+
smart_str_appendl(&buf, "", 0);
25012504
}
2505+
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL);
25022506
break;
2503-
}
25042507

25052508
default:
25062509
switch (serializer) {
@@ -2690,11 +2693,16 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
26902693
}
26912694

26922695
case MEMC_VAL_IS_DOUBLE:
2693-
{
2694-
double dval = zend_strtod(payload, NULL);
2695-
ZVAL_DOUBLE(value, dval);
2696+
if (payload_len == 8 && memcmp(payload, "Infinity", 8) == 0) {
2697+
ZVAL_DOUBLE(value, php_get_inf());
2698+
} else if (payload_len == 9 && memcmp(payload, "-Infinity", 9) == 0) {
2699+
ZVAL_DOUBLE(value, -php_get_inf());
2700+
} else if (payload_len == 3 && memcmp(payload, "NaN", 3) == 0) {
2701+
ZVAL_DOUBLE(value, php_get_nan());
2702+
} else {
2703+
ZVAL_DOUBLE(value, zend_strtod(payload, NULL));
2704+
}
26962705
break;
2697-
}
26982706

26992707
case MEMC_VAL_IS_BOOL:
27002708
ZVAL_BOOL(value, payload_len > 0 && payload[0] == '1');

0 commit comments

Comments
 (0)