ごとけんです

In message "[ruby-dev:4371] Re: pack("F") for bigendian float"
    on 99/01/26, Yukihiro Matsumoto <matz / netlab.co.jp> writes:

>|>  e  リトルエンディアンの単精度浮動小数点数(機種依存)
>|>  E  リトルエンディアンの倍精度浮動小数点数(機種依存)
>|>  g  ビッグエンディアンの単精度浮動小数点数(機種依存)
>|>  G  ビッグエンディアンの倍精度浮動小数点数(機種依存)
>|
>|これを実装しました.とりこんでもらえますか??
>
>取り込む方向で検討しましょう.後はdoubleとlongのサイズなどの
>暗黙の前提を明確化して,移植性をあげたら本採用ですね.

既存のテンプレートも含めて short, long, long, double の
大きさに依存しないようにしました.

pack_pack などの本体で ifdef しないようにしたかったため,
特に拡張部分は多少分かりにくいマクロを使ってます.

-- gotoken

diff -u0 ruby-1.3.1-990128/configure.orig ruby-1.3.1-990128/configure --- ruby-1.3.1-990128/configure.orig Wed Jan 27 16:26:06 1999 +++ ruby-1.3.1-990128/configure Sun Jan 31 00:54:00 1999 @@ -1351,0 +1352,39 @@ +echo $ac_n "checking size of short""... $ac_c" 1>&6 +echo "configure:1314: checking size of short" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <<EOF +#line 1322 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short)); + exit(0); +} +EOF +if { (eval echo configure:1333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +EOF + + diff -u0 ruby-1.3.1-990128/pack.c.orig ruby-1.3.1-990128/pack.c --- ruby-1.3.1-990128/pack.c.orig Tue Jan 26 19:08:13 1999 +++ ruby-1.3.1-990128/pack.c Sun Jan 31 00:39:17 1999 @@ -16,0 +17,24 @@ +#define define_swapx(x, xtype) \ +static xtype \ +swap##x(z) \ + xtype z; \ +{ \ + xtype r; \ + xtype *zp; \ + unsigned char *s, *t; \ + int i; \ + \ + zp = (xtype *)malloc(sizeof(xtype));\ + *zp = z; \ + s = (char *)zp; \ + t = (char *)malloc(sizeof(xtype)); \ + for (i=0 ; i<sizeof(xtype); i++) { \ + t[sizeof(xtype)-i-1] = s[i]; \ + } \ + r = *(xtype *)t; \ + free(t); \ + free(zp); \ + return r; \ +} + +#if SIZEOF_SHORT == 2 @@ -17,0 +42,12 @@ +#else +#if SIZEOF_SHORT == 4 +#define swaps(x) ((((x)&0xFF)<<24) \ + +(((x)>>24)&0xFF) \ + +(((x)&0x0000FF00)<<8) \ + +(((x)&0x00FF0000)>>8) ) +#else +define_swapx(s,short); +#endif +#endif + +#if SIZEOF_LONG == 4 @@ -21,0 +58,82 @@ +#else +#if SIZEOF_LONG == 8 +#define swapl(x) ((((x)&0x00000000000000FF)<<56) \ + +(((x)&0xFF00000000000000)>>56) \ + +(((x)&0x000000000000FF00)<<40) \ + +(((x)&0x00FF000000000000)>>40) \ + +(((x)&0x0000000000FF0000)<<24) \ + +(((x)&0x0000FF0000000000)>>24) \ + +(((x)&0x00000000FF000000)<<8) \ + +(((x)&0x000000FF00000000)>>8) +#else + +define_swapx(l,long); +#endif +#endif + +#if SIZEOF_FLOAT == 4 +#if SIZEOF_LONG == 4 /* SIZEOF_FLOAT == 4 == SIZEOF_LONG */ +#define swapf(x) swapl(x) +#define FLOAT_SWAPPER unsigned long +#else +#if SIZEOF_SHORT == 4 /* SIZEOF_FLOAT == 4 == SIZEOF_SHORT */ +#define swapf(x) swaps(x) +#define FLOAT_SWAPPER unsigned short +#else /* SIZEOF_FLOAT == 4 but undivide by known size of int */ +#define_swapx(f,float); +#endif /* #if SIZEOF_SHORT == 4 */ +#endif /* #if SIZEOF_LONG == 4 */ +#else /* SIZEOF_FLOAT != 4 */ +define_swapx(f,float); +#endif /* #if SIZEOF_FLOAT == 4 */ + +#if SIZEOF_DOUBLE == 8 +#if SIZEOF_LONG == 8 /* SIZEOF_DOUBLE == 8 == SIZEOF_LONG */ +#define swapd(x) swapl(x) +#define DOUBLE_SWAPPER unsigned long +#else +#if SIZEOF_LONG == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_LONG */ +static double +swapd(d) + const double d; +{ + double dtmp = d; + unsigned long utmp[2]; + unsigned long utmp0; + + utmp[0] = 0; utmp[1] = 0; + memcpy(utmp,&dtmp,sizeof(double)); + utmp0 = utmp[0]; + utmp[0] = swapl(utmp[1]); + utmp[1] = swapl(utmp0); + memcpy(&dtmp,utmp,sizeof(double)); + return dtmp; +} +#else +#if SIZEOF_SHORT == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_SHORT */ +static double +swapd(d) + const double d; +{ + double dtmp = d; + unsigned short utmp[2]; + unsigned short utmp0; + + utmp[0] = 0; utmp[1] = 0; + memcpy(utmp,&dtmp,sizeof(double)); + utmp0 = utmp[0]; + utmp[0] = swaps(utmp[1]); + utmp[1] = swaps(utmp0); + memcpy(&dtmp,utmp,sizeof(double)); + return dtmp; +} +#else /* SIZEOF_DOUBLE == 8 but undivied by known size of int */ +define_swapx(d, double); +#endif /* #if SIZEOF_SHORT == 4 */ +#endif /* #if SIZEOF_LONG == 4 */ +#endif /* #if SIZEOF_LONG == 8 */ +#else /* SIZEOF_DOUBLE != 8 */ +define_swapx(d, double); +#endif /* #if SIZEOF_DPOUBLE == 8 */ + +#undef define_swapx @@ -44,0 +163,2 @@ +#define ntohf(x) (endian()?(x):swapf(x)) +#define ntohd(x) (endian()?(x):swapd(x)) @@ -46,0 +167,2 @@ +#define htonf(x) (endian()?(x):swapf(x)) +#define htond(x) (endian()?(x):swapd(x)) @@ -48,0 +171,2 @@ +#define htovf(x) (endian()?swapf(x):(x)) +#define htovd(x) (endian()?swapd(x):(x)) @@ -50,0 +175,2 @@ +#define vtohf(x) (endian()?swapf(x):(x)) +#define vtohd(x) (endian()?swapd(x):(x)) @@ -58,0 +185,4 @@ +#define ntohf(x) (x) +#define ntohd(x) (x) +#define htonf(x) (x) +#define htond(x) (x) @@ -60,0 +191,2 @@ +#define htovf(x) swapf(x) +#define htovd(x) swapd(x) @@ -62,0 +195,2 @@ +#define vtohf(x) swapf(x) +#define vtohd(x) swapd(x) @@ -64,0 +199,4 @@ +#undef ntohs +#undef ntohl +#undef htons +#undef htonl @@ -69,0 +208,4 @@ +#define ntohf(x) swapf(x) +#define ntohd(x) swapd(x) +#define htonf(x) swapf(x) +#define htond(x) swapd(x) @@ -71,0 +214,2 @@ +#define htovf(x) (x) +#define htovd(x) (x) @@ -73,0 +218,2 @@ +#define vtohf(x) (x) +#define vtohd(x) (x) @@ -76,0 +223,52 @@ +#ifdef FLOAT_SWAPPER +#define FLOAT_CONVWITH(y) FLOAT_SWAPPER y; +#define HTONF(x,y) (memcpy(&y,&x,sizeof(float)), \ + x = htonf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#define HTOVF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = htovf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#define NTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = ntohf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#define VTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = vtohf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#else +#define FLOAT_CONVWITH(y) +#define HTONF(x,y) htonf(x) +#define HTOVF(x,y) htovf(x) +#define NTOHF(x,y) ntohf(x) +#define VTOHF(x,y) vtohf(x) +#endif + +#ifdef DOUBLE_SWAPPER +#define DOUBLE_CONVWITH(y) DOUBLE_SWAPPER y; +#dedine HTOND(x,y) (memcpy(&y,&x,sizeof(double)), \ + x = htond((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#dedine HTOVD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = htovd((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#dedine NTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = ntohd((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#dedine VTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = vtohd((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#else +#define DOUBLE_CONVWITH(y) +#define HTOND(x,y) htond(x) +#define HTOVD(x,y) htovd(x) +#define NTOHD(x,y) ntohd(x) +#define VTOHD(x,y) vtohd(x) +#endif + @@ -401,0 +600,42 @@ + case 'e': + while (len-- > 0) { + float f; + FLOAT_CONVWITH(ftmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + f = RFLOAT(from)->value; + break; + case T_STRING: + f = atof(RSTRING(from)->ptr); + default: + f = (float)NUM2INT(from); + break; + } + f = HTOVF(f,ftmp); + rb_str_cat(res, (char*)&f, sizeof(float)); + } + break; + + case 'E': + while (len-- > 0) { + double d; + DOUBLE_CONVWITH(dtmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + d = RFLOAT(from)->value; + break; + case T_STRING: + d = atof(RSTRING(from)->ptr); + default: + d = (double)NUM2INT(from); + break; + } + d = HTOVD(d,dtmp); + rb_str_cat(res, (char*)&d, sizeof(double)); + } + break; + @@ -421,0 +662,42 @@ + case 'g': + while (len-- > 0) { + float f; + FLOAT_CONVWITH(ftmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + f = RFLOAT(from)->value; + break; + case T_STRING: + f = atof(RSTRING(from)->ptr); + default: + f = (float)NUM2INT(from); + break; + } + f = HTONF(f,ftmp); + rb_str_cat(res, (char*)&f, sizeof(float)); + } + break; + + case 'G': + while (len-- > 0) { + double d; + DOUBLE_CONVWITH(dtmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + d = RFLOAT(from)->value; + break; + case T_STRING: + d = atof(RSTRING(from)->ptr); + default: + d = (double)NUM2INT(from); + break; + } + d = HTOND(d,dtmp); + rb_str_cat(res, (char*)&d, sizeof(double)); + } + break; + @@ -913,0 +1196,28 @@ + case 'e': + if (len >= (send - s) / sizeof(float)) + len = (send - s) / sizeof(float); + while (len-- > 0) { + float tmp; + FLOAT_CONVWITH(ftmp); + + memcpy(&tmp, s, sizeof(float)); + s += sizeof(float); + tmp = VTOHF(tmp,ftmp); + rb_ary_push(ary, rb_float_new((double)tmp)); + } + break; + + case 'E': + if (len >= (send - s) / sizeof(double)) + len = (send - s) / sizeof(double); + while (len-- > 0) { + double tmp; + DOUBLE_CONVWITH(dtmp); + + memcpy(&tmp, s, sizeof(double)); + s += sizeof(double); + tmp = VTOHD(tmp,dtmp); + rb_ary_push(ary, rb_float_new(tmp)); + } + break; + @@ -925,0 +1236,28 @@ + case 'g': + if (len >= (send - s) / sizeof(float)) + len = (send - s) / sizeof(float); + while (len-- > 0) { + float tmp; + FLOAT_CONVWITH(ftmp;) + + memcpy(&tmp, s, sizeof(float)); + s += sizeof(float); + tmp = NTOHF(tmp,ftmp); + rb_ary_push(ary, rb_float_new((double)tmp)); + } + break; + + case 'G': + if (len >= (send - s) / sizeof(double)) + len = (send - s) / sizeof(double); + while (len-- > 0) { + double tmp; + DOUBLE_CONVWITH(dtmp); + + memcpy(&tmp, s, sizeof(double)); + s += sizeof(double); + tmp = NTOHD(tmp,dtmp); + rb_ary_push(ary, rb_float_new(tmp)); + } + break; +