summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 895a569)
raw | patch | inline | side by side (parent: 895a569)
author | Sebastian Harl <sh@tokkee.org> | |
Tue, 23 Dec 2014 17:16:13 +0000 (18:16 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Tue, 23 Dec 2014 17:16:13 +0000 (18:16 +0100) |
For this, determine the memory layout of doubles in 'configure' and then use
IEEE-754 big-endian encoding on the wire. For now, only little- and big-endian
IEEE-754 doubles are supported but that'll cover the vast majority of all
systems.
IEEE-754 big-endian encoding on the wire. For now, only little- and big-endian
IEEE-754 doubles are supported but that'll cover the vast majority of all
systems.
configure.ac | patch | blob | history | |
src/utils/proto.c | patch | blob | history | |
t/unit/utils/proto_test.c | patch | blob | history |
diff --git a/configure.ac b/configure.ac
index baf1137b530197b1689be9106ff4f9751b70377b..59f4ee7c413c0e5c5cdfeb2f66309d0e86d5d89e 100644 (file)
--- a/configure.ac
+++ b/configure.ac
AC_SUBST([PROFILING_CFLAGS])
AC_SUBST([PROFILING_LDFLAGS])
+ieee754_layout="unknown"
+AC_MSG_CHECKING([the memory layout of double precision values])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <string.h>
+#include <inttypes.h>
+ ]],
+ [[
+double d = 3.141592653e130;
+char c[8];
+if (sizeof(d) != 8)
+ return 2;
+memcpy(&c, &d, 8);
+if (c[0] == '\x04' && c[1] == '\x10' && c[2] == '\x1E' && c[3] == '\x66' &&
+ c[4] == '\x40' && c[5] == '\xA9' && c[6] == '\x06' && c[7] == '\x5B')
+ return 0;
+else
+ return 1;
+ ]]
+ )],
+ [ieee754_layout="little-endian"], [ieee754_layout="unknown"])
+if test "x$ieee754_layout" = "xunknown"; then
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <string.h>
+#include <inttypes.h>
+ ]],
+ [[
+double d = 3.141592653e130;
+char c[8];
+if (sizeof(d) != 8)
+ return 2;
+memcpy(&c, &d, 8);
+if (c[7] == '\x04' && c[6] == '\x10' && c[5] == '\x1E' && c[4] == '\x66' &&
+ c[3] == '\x40' && c[2] == '\xA9' && c[1] == '\x06' && c[0] == '\x5B')
+ return 0;
+else
+ return 1;
+ ]]
+ )],
+ [ieee754_layout="big-endian"], [ieee754_layout="unknown"])
+fi
+AC_MSG_RESULT([IEEE-754 $ieee754_layout])
+
+AC_DEFINE([IEEE754_DOUBLE_LITTLE_ENDIAN], 1234,
+ [Identifier for IEEE-754 little-endian encoding of double precision values])
+AC_DEFINE([IEEE754_DOUBLE_BIG_ENDIAN], 4321,
+ [Identifier for IEEE-754 big-endian encoding of double precision values])
+if test "x$ieee754_layout" = "xlittle-endian"; then
+ AC_DEFINE([IEEE754_DOUBLE_BYTE_ORDER], 1234,
+ [Define to 1 if double precision values use IEEE-754 little-endian encoding])
+else if test "x$ieee754_layout" = "xbig-endian"; then
+ AC_DEFINE([IEEE754_DOUBLE_BYTE_ORDER], 4321,
+ [Define to 1 if double precision values use IEEE-754 little-endian encoding])
+else
+ AC_MSG_ERROR([Unknown memory layout of double precision values])
+fi; fi
+
m4_divert_once([HELP_ENABLE], [
Build dependencies:])
diff --git a/src/utils/proto.c b/src/utils/proto.c
index cb88887d1f1313cd0797dcf9a5fbec9c63404277..af4215b8f987a32c5c0c264f9b5f43bbec56ed5f 100644 (file)
--- a/src/utils/proto.c
+++ b/src/utils/proto.c
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include "core/data.h"
#include "core/time.h"
#include "utils/error.h"
#include "utils/proto.h"
-#include <arpa/inet.h>
+#include <assert.h>
#include <errno.h>
+#include <arpa/inet.h>
#include <limits.h>
#include <string.h>
} /* marshal_int */
static ssize_t
-marshal_double(char __attribute__((unused)) *buf,
- size_t __attribute__((unused)) buf_len,
- double __attribute__((unused)) v)
+marshal_double(char *buf, size_t buf_len, double v)
{
- /* XXX: find a good network representation */
- errno = ENOTSUP;
- return -1;
+ uint64_t t = 0;
+ assert(sizeof(v) == sizeof(t));
+ memcpy(&t, &v, sizeof(v));
+#if IEEE754_DOUBLE_BYTE_ORDER != IEEE754_DOUBLE_BIG_ENDIAN
+ t = (((int64_t)ntohl((int32_t)t)) << 32)
+ + ((int64_t)ntohl((int32_t)(t >> 32)));
+#endif
+ if (buf_len >= sizeof(t))
+ memcpy(buf, &t, sizeof(t));
+ return sizeof(t);
} /* marshal_double */
static ssize_t
index d0516b306b483cc4fe32c5cd502463014c9eff22..1ec0615fa33fd7a7f29c2796a9c2c369e92afebe 100644 (file)
regex_t dummy_re;
int64_t int_values[] = { 47, 11, 23 };
+ double dec_values[] = { 47.11, .5 };
char *string_values[] = { "foo", "abcd" };
struct {
12, INT_TYPE "\0\0\0\0\0\0\x12\x67",
},
{
- { SDB_TYPE_DECIMAL, { .integer = 4711 } },
- -1, NULL, /* not supported yet */
+ { SDB_TYPE_DECIMAL, { .decimal = 3.141592653e130 } },
+ 12, DECIMAL_TYPE "\x5b\x6\xa9\x40\x66\x1e\x10\x4",
},
{
{ SDB_TYPE_STRING, { .string = "some string" } },
32, INT_ARRAY "\0\0\0\x3" "\0\0\0\0\0\0\0\x2f"
"\0\0\0\0\0\0\0\xb" "\0\0\0\0\0\0\0\x17"
},
+ {
+ { SDB_TYPE_DECIMAL | SDB_TYPE_ARRAY, { .array = {
+ 2, dec_values } } },
+ 24, DECIMAL_ARRAY "\0\0\0\x2" "\x40\x47\x8e\x14\x7a\xe1\x47\xae"
+ "\x3f\xe0\0\0\0\0\0\0"
+ },
{
{ SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = {
2, string_values } } },