}
/* }}} */
+/* {{{ php_pack_reverse_int32
+ */
+inline uint32_t php_pack_reverse_int32(uint32_t arg)
+{
+ uint32_t result;
+ result = ((arg & 0xFF) << 24) | ((arg & 0xFF00) << 8) | ((arg >> 8) & 0xFF00) | ((arg >> 24) & 0xFF);
-/* {{{ php_pack_is_little_endian
+ return result;
+}
+/* }}} */
+
+/* {{{ php_pack
*/
-static int php_pack_is_little_endian()
+inline uint64_t php_pack_reverse_int64(uint64_t arg)
{
- int machine_endian_check = 1;
-
- return ((char *)&machine_endian_check)[0];
+ union Swap64 {
+ uint64_t i;
+ uint32_t ul[2];
+ } tmp, result;
+ tmp.i = arg;
+ result.ul[0] = php_pack_reverse_int32(tmp.ul[1]);
+ result.ul[1] = php_pack_reverse_int32(tmp.ul[0]);
+
+ return result.i;
}
/* }}} */
+/* {{{ php_pack_copy_float
+ */
+static void php_pack_copy_float(int is_little_endian, void * dst, float f)
+{
+ union Copy32 {
+ float f;
+ uint32_t i;
+ } m;
+ m.f = f;
+
+#ifdef WORDS_BIGENDIAN
+ if (is_little_endian) {
+ m.i = php_pack_reverse_int32(m.i);
+ }
+#else /* WORDS_BIGENDIAN */
+ if (!is_little_endian) {
+ m.i = php_pack_reverse_int32(m.i);
+ }
+#endif /* WORDS_BIGENDIAN */
+
+ memcpy(dst, &m.f, sizeof(float));
+}
+/* }}} */
-/* {{{ php_pack_memcpy
+/* {{{ php_pack_copy_double
*/
-static void php_pack_memcpy(int is_little_endian, void * dst, void * src, size_t size)
+static void php_pack_copy_double(int is_little_endian, void * dst, double d)
{
- int is_sys_little_endian = php_pack_is_little_endian();
-
- if (is_little_endian == is_sys_little_endian) {
- /*
- System and input uses same endian, simply perform memcpy
- */
- memcpy(dst, src, size);
- } else {
- /*
- Copy to dst from last to first
- */
- src = src + size - 1;
- do {
- *(char *) dst = *(char *)src;
- ++dst;
- --src;
- } while (-- size);
+ union Copy64 {
+ double d;
+ uint64_t i;
+ } m;
+ m.d = d;
+
+#ifdef WORDS_BIGENDIAN
+ if (is_little_endian) {
+ m.i = php_pack_reverse_int64(m.i);
}
-
+#else /* WORDS_BIGENDIAN */
+ if (!is_little_endian) {
+ m.i = php_pack_reverse_int64(m.i);
+ }
+#endif /* WORDS_BIGENDIAN */
+
+ memcpy(dst, &m.d, sizeof(double));
+}
+/* }}} */
+
+/* {{{ php_pack_parse_float
+ */
+static float php_pack_parse_float(int is_little_endian, void * src)
+{
+ union Copy32 {
+ float f;
+ uint32_t i;
+ } m;
+ memcpy(&m.i, src, sizeof(float));
+
+#ifdef WORDS_BIGENDIAN
+ if (is_little_endian) {
+ m.i = php_pack_reverse_int32(m.i);
+ }
+#else /* WORDS_BIGENDIAN */
+ if (!is_little_endian) {
+ m.i = php_pack_reverse_int32(m.i);
+ }
+#endif /* WORDS_BIGENDIAN */
+
+ return m.f;
+}
+/* }}} */
+
+/* {{{ php_pack_parse_double
+ */
+static double php_pack_parse_double(int is_little_endian, void * src)
+{
+ union Copy64 {
+ double d;
+ uint64_t i;
+ } m;
+ memcpy(&m.i, src, sizeof(double));
+
+#ifdef WORDS_BIGENDIAN
+ if (is_little_endian) {
+ m.i = php_pack_reverse_int64(m.i);
+ }
+#else /* WORDS_BIGENDIAN */
+ if (!is_little_endian) {
+ m.i = php_pack_reverse_int64(m.i);
+ }
+#endif /* WORDS_BIGENDIAN */
+
+ return m.d;
}
/* }}} */
/* pack little endian float */
while (arg-- > 0) {
float v = (float) zval_get_double(&argv[currentarg++]);
- php_pack_memcpy(1, &ZSTR_VAL(output)[outputpos], &v, sizeof(float));
+ php_pack_copy_float(1, &ZSTR_VAL(output)[outputpos], v);
outputpos += sizeof(v);
}
/* pack big endian float */
while (arg-- > 0) {
float v = (float) zval_get_double(&argv[currentarg++]);
- php_pack_memcpy(0, &ZSTR_VAL(output)[outputpos], &v, sizeof(float));
+ php_pack_copy_float(0, &ZSTR_VAL(output)[outputpos], v);
outputpos += sizeof(v);
}
break;
/* pack little endian double */
while (arg-- > 0) {
double v = (double) zval_get_double(&argv[currentarg++]);
- php_pack_memcpy(1, &ZSTR_VAL(output)[outputpos], &v, sizeof(double));
+ php_pack_copy_double(1, &ZSTR_VAL(output)[outputpos], v);
outputpos += sizeof(v);
}
break;
/* pack big endian double */
while (arg-- > 0) {
double v = (double) zval_get_double(&argv[currentarg++]);
- php_pack_memcpy(0, &ZSTR_VAL(output)[outputpos], &v, sizeof(double));
+ php_pack_copy_double(0, &ZSTR_VAL(output)[outputpos], v);
outputpos += sizeof(v);
}
break;
float v;
if (type == 'g') {
- php_pack_memcpy(1, &v, &input[inputpos], sizeof(float));
+ v = php_pack_parse_float(1, &input[inputpos]);
} else if (type == 'G') {
- php_pack_memcpy(0, &v, &input[inputpos], sizeof(float));
+ v = php_pack_parse_float(0, &input[inputpos]);
} else {
memcpy(&v, &input[inputpos], sizeof(float));
}
{
double v;
if (type == 'e') {
- php_pack_memcpy(1, &v, &input[inputpos], sizeof(double));
+ v = php_pack_parse_double(1, &input[inputpos]);
} else if (type == 'E') {
- php_pack_memcpy(0, &v, &input[inputpos], sizeof(double));
+ v = php_pack_parse_double(0, &input[inputpos]);
} else {
memcpy(&v, &input[inputpos], sizeof(double));
}