Skip to content

Commit

Permalink
Convert float to ascii using g_fmt and zend_dtoa.
Browse files Browse the repository at this point in the history
This procudes much smaller textual representations and also ignores
locales.
  • Loading branch information
tricky committed May 2, 2011
1 parent 37e46ec commit df20b8a
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 20 deletions.
2 changes: 1 addition & 1 deletion config.m4
Expand Up @@ -242,7 +242,7 @@ if test "$PHP_MEMCACHED" != "no"; then


PHP_SUBST(MEMCACHED_SHARED_LIBADD) PHP_SUBST(MEMCACHED_SHARED_LIBADD)


PHP_MEMCACHED_FILES="php_memcached.c fastlz/fastlz.c" PHP_MEMCACHED_FILES="php_memcached.c fastlz/fastlz.c g_fmt.c"


if test "$PHP_MEMCACHED_SESSION" != "no"; then if test "$PHP_MEMCACHED_SESSION" != "no"; then
PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_session.c" PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_session.c"
Expand Down
99 changes: 99 additions & 0 deletions g_fmt.c
@@ -0,0 +1,99 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991, 1996 by Lucent Technologies.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/

/* g_fmt(buf,x) stores the closest decimal approximation to x in buf;
* it suffices to declare buf
* char buf[32];
*/

/* Modified for use with php in the memcached client extension.
*
* // Teddy Grenman <teddy.grenman@iki.fi>, 2010-05-18.
*/

#include <zend_operators.h>

char *php_memcached_g_fmt(register char *b, double x) {
register int i, k;
register char *s;
int decpt, j, sign;
char *b0, *s0, *se;

b0 = b;
#ifdef IGNORE_ZERO_SIGN
if (!x) {
*b++ = '0';
*b = 0;
goto done;
}
#endif

s = s0 = zend_dtoa(x, 0, 0, &decpt, &sign, &se);
if (sign)
*b++ = '-';
if (decpt == 9999) /* Infinity or Nan */ {
while(*b++ = *s++);
goto done0;
}
if (decpt <= -4 || decpt > se - s + 5) {
*b++ = *s++;
if (*s) {
*b++ = '.';
while(*b = *s++)
b++;
}
*b++ = 'e';
/* sprintf(b, "%+.2d", decpt - 1); */
if (--decpt < 0) {
*b++ = '-';
decpt = -decpt;
}
else
*b++ = '+';
for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10);
for(;;) {
i = decpt / k;
*b++ = i + '0';
if (--j <= 0)
break;
decpt -= i*k;
decpt *= 10;
}
*b = 0;
} else if (decpt <= 0) {
*b++ = '.';
for(; decpt < 0; decpt++)
*b++ = '0';
while(*b++ = *s++);
} else {
while(*b = *s++) {
b++;
if (--decpt == 0 && *s)
*b++ = '.';
}
for(; decpt > 0; decpt--)
*b++ = '0';
*b = 0;
}

done0:
zend_freedtoa(s0);
done:
return b0;
}
34 changes: 34 additions & 0 deletions g_fmt.h
@@ -0,0 +1,34 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991, 1996 by Lucent Technologies.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/

/* g_fmt(buf,x) stores the closest decimal approximation to x in buf;
* it suffices to declare buf
* char buf[32];
*/

/* Modified for use with php in the memcached client
* extension by Teddy Grenman, 2010.
*/

#ifndef MEMC_G_FMT_H
#define MEMC_G_FMT_H

char *php_memcached_g_fmt(register char *b, double x);

#endif
46 changes: 27 additions & 19 deletions php_memcached.c
Expand Up @@ -42,9 +42,11 @@
#include <zend_exceptions.h> #include <zend_exceptions.h>
#include <ext/standard/php_smart_str.h> #include <ext/standard/php_smart_str.h>
#include <ext/standard/php_var.h> #include <ext/standard/php_var.h>
#include <ext/standard/basic_functions.h>
#include <libmemcached/memcached.h> #include <libmemcached/memcached.h>


#include "php_memcached.h" #include "php_memcached.h"
#include "g_fmt.h"


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


case IS_LONG: case IS_LONG:
smart_str_append_long(&buf, Z_LVAL_P(value));
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG);
break;

case IS_DOUBLE: case IS_DOUBLE:
case IS_BOOL:
{ {
zval value_copy; char dstr[40] = {0};


value_copy = *value; php_memcached_g_fmt(dstr, Z_DVAL_P(value));
zval_copy_ctor(&value_copy); smart_str_appends(&buf, dstr);
convert_to_string(&value_copy); MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE);
smart_str_appendl(&buf, Z_STRVAL(value_copy), Z_STRLEN(value_copy)); break;
zval_dtor(&value_copy); }


*flags &= ~MEMC_VAL_COMPRESSED; case IS_BOOL:
if (Z_TYPE_P(value) == IS_LONG) { if (Z_BVAL_P(value)) {
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG); smart_str_appendc(&buf, '1');
} else if (Z_TYPE_P(value) == IS_DOUBLE) { } else {
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE); smart_str_appendl(&buf, "", 0);
} else if (Z_TYPE_P(value) == IS_BOOL) {
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL);
} }
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL);
break; break;
}


default: default:
switch (serializer) { switch (serializer) {
Expand Down Expand Up @@ -2690,11 +2693,16 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
} }


case MEMC_VAL_IS_DOUBLE: case MEMC_VAL_IS_DOUBLE:
{ if (payload_len == 8 && memcmp(payload, "Infinity", 8) == 0) {
double dval = zend_strtod(payload, NULL); ZVAL_DOUBLE(value, php_get_inf());
ZVAL_DOUBLE(value, dval); } else if (payload_len == 9 && memcmp(payload, "-Infinity", 9) == 0) {
ZVAL_DOUBLE(value, -php_get_inf());
} else if (payload_len == 3 && memcmp(payload, "NaN", 3) == 0) {
ZVAL_DOUBLE(value, php_get_nan());
} else {
ZVAL_DOUBLE(value, zend_strtod(payload, NULL));
}
break; break;
}


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

0 comments on commit df20b8a

Please sign in to comment.