diff --git a/ChangeLog b/ChangeLog index 3948a51091..c0957fea82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Mon Dec 1 17:33:47 2003 Yukihiro Matsumoto + + * pack.c (htov16): converts endian using swap16. htov32(), hton16, + hton32 as well. [ruby-talk:85377] + + * pack.c (swap16): swap 2 bytes no matter how big short is on the + platform. swap32() is also prepared. + + * numeric.c (rb_num2int): returns long to preserve information. + rb_fix2int(), rb_num2uint(), rb_fix2uint() as well. + [ruby-talk:85377] + + * numeric.c (rb_num2uint): should not check for value range if the + source value is negative. + Mon Dec 1 17:14:34 2003 Nobuyoshi Nakada * sample/optparse/opttest.rb: added. diff --git a/numeric.c b/numeric.c index 7d373e4083..b030d8795a 100644 --- a/numeric.c +++ b/numeric.c @@ -1029,54 +1029,62 @@ check_uint(num) } } -int +long rb_num2int(val) VALUE val; { long num = rb_num2long(val); check_int(num); - return (int)num; + return num; } -int +long rb_fix2int(val) VALUE val; { long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val); check_int(num); - return (int)num; + return num; } -unsigned int +unsigned long rb_num2uint(val) VALUE val; { unsigned long num = rb_num2ulong(val); - check_uint(num); - return (int)num; + if (RTEST(rb_funcall(INT2FIX(0), '<', 1, val))) { + check_uint(num); + } + return num; } -unsigned int +unsigned long rb_fix2uint(val) VALUE val; { - unsigned long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2ulong(val); + unsigned long num; - check_uint(num); - return (int)num; + if (!FIXNUM_P(val)) { + return rb_num2uint(val); + } + num = FIX2ULONG(val); + if (FIX2LONG(val) > 0) { + check_uint(num); + } + return num; } #else -int +long rb_num2int(val) VALUE val; { return rb_num2long(val); } -int +long rb_fix2int(val) VALUE val; { diff --git a/pack.c b/pack.c index 553668de3f..780923f02b 100644 --- a/pack.c +++ b/pack.c @@ -31,10 +31,18 @@ # define OFF16(p) OFF16B(p) # define OFF32(p) OFF32B(p) # endif +# define NATINT_HTOVS(x) (natint?htovs(x):htov16(x)) +# define NATINT_HTOVL(x) (natint?htovl(x):htov32(x)) +# define NATINT_HTONS(x) (natint?htons(x):hton16(x)) +# define NATINT_HTONL(x) (natint?htonl(x):hton32(x)) #else # define NATINT_I32(x) NUM2I32(x) # define NATINT_U32(x) NUM2U32(x) # define NATINT_LEN(type,len) sizeof(type) +# define NATINT_HTOVS(x) htovs(x) +# define NATINT_HTOVL(x) htovl(x) +# define NATINT_HTONS(x) htons(x) +# define NATINT_HTONL(x) htonl(x) #endif #ifndef OFF16 @@ -70,8 +78,9 @@ TOKEN_PASTE(swap,x)(z) \ return r; \ } +#define swap16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) #if SIZEOF_SHORT == 2 -#define swaps(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) +#define swaps(x) swap16(x) #else #if SIZEOF_SHORT == 4 #define swaps(x) ((((x)&0xFF)<<24) \ @@ -83,11 +92,12 @@ define_swapx(s,short); #endif #endif -#if SIZEOF_LONG == 4 -#define swapl(x) ((((x)&0xFF)<<24) \ +#define swap32(x) ((((x)&0xFF)<<24) \ |(((x)>>24)&0xFF) \ |(((x)&0x0000FF00)<<8) \ |(((x)&0x00FF0000)>>8) ) +#if SIZEOF_LONG == 4 +#define swapl(x) swap32(x) #else #if SIZEOF_LONG == 8 #define swapl(x) ((((x)&0x00000000000000FF)<<56) \ @@ -206,6 +216,12 @@ endian() #define vtohl(x) (endian()?swapl(x):(x)) #define vtohf(x) (endian()?swapf(x):(x)) #define vtohd(x) (endian()?swapd(x):(x)) +# ifdef NATINT_PACK +#define htov16(x) (endian()?swap16(x):(x)) +#define htov32(x) (endian()?swap32(x):(x)) +#define hton16(x) (endian()?(x):swap16(x)) +#define hton32(x) (endian()?(x):swap32(x)) +# endif #else #ifdef WORDS_BIGENDIAN #ifndef ntohs @@ -226,6 +242,12 @@ endian() #define vtohl(x) swapl(x) #define vtohf(x) swapf(x) #define vtohd(x) swapd(x) +# ifdef NATINT_PACK +#define htov16(x) swap16(x) +#define htov32(x) swap32(x) +#define hton16(x) (x) +#define hton32(x) (x) +# endif #else /* LITTLE ENDIAN */ #ifndef ntohs #undef ntohs @@ -249,6 +271,12 @@ endian() #define vtohl(x) (x) #define vtohf(x) (x) #define vtohd(x) (x) +# ifdef NATINT_PACK +#define htov16(x) (x) +#define htov32(x) (x) +#define hton16(x) swap16(x) +#define hton32(x) swap32(x) +# endif #endif #endif @@ -459,9 +487,9 @@ pack_pack(ary, fmt) len = plen; switch (type) { - case 'a': - case 'A': - case 'Z': + case 'a': /* arbitrary binary string (null padded) */ + case 'A': /* ASCII string (space padded) */ + case 'Z': /* null terminated ASCII string */ if (plen >= len) rb_str_buf_cat(res, ptr, len); else { @@ -475,7 +503,7 @@ pack_pack(ary, fmt) } break; - case 'b': + case 'b': /* bit string (ascending) */ { int byte = 0; long i, j = 0; @@ -506,7 +534,7 @@ pack_pack(ary, fmt) } break; - case 'B': + case 'B': /* bit string (descending) */ { int byte = 0; long i, j = 0; @@ -536,7 +564,7 @@ pack_pack(ary, fmt) } break; - case 'h': + case 'h': /* hex string (low nibble first) */ { int byte = 0; long i, j = 0; @@ -567,7 +595,7 @@ pack_pack(ary, fmt) } break; - case 'H': + case 'H': /* hex string (high nibble first) */ { int byte = 0; long i, j = 0; @@ -600,8 +628,8 @@ pack_pack(ary, fmt) } break; - case 'c': - case 'C': + case 'c': /* signed char */ + case 'C': /* unsigned char */ while (len-- > 0) { char c; @@ -614,8 +642,8 @@ pack_pack(ary, fmt) } break; - case 's': - case 'S': + case 's': /* signed short */ + case 'S': /* unsigned short */ while (len-- > 0) { short s; @@ -628,22 +656,22 @@ pack_pack(ary, fmt) } break; - case 'i': - case 'I': + case 'i': /* signed int */ + case 'I': /* unsigned int */ while (len-- > 0) { - int i; + long i; from = NEXTFROM; if (NIL_P(from)) i = 0; else { - i = NUM2UINT(from); + i = NATINT_I32(from); } - rb_str_buf_cat(res, (char*)&i, sizeof(int)); + rb_str_buf_cat(res, OFF32(&i), NATINT_LEN(int,4)); } break; - case 'l': - case 'L': + case 'l': /* signed long */ + case 'L': /* unsigned long */ while (len-- > 0) { long l; @@ -656,8 +684,8 @@ pack_pack(ary, fmt) } break; - case 'q': - case 'Q': + case 'q': /* signed quad (64bit) int */ + case 'Q': /* unsigned quad (64bit) int */ while (len-- > 0) { char tmp[QUAD_SIZE]; @@ -668,7 +696,7 @@ pack_pack(ary, fmt) } break; - case 'n': + case 'n': /* unsigned short (network byte-order) */ while (len-- > 0) { unsigned short s; @@ -677,12 +705,12 @@ pack_pack(ary, fmt) else { s = NUM2INT(from); } - s = htons(s); + s = NATINT_HTONS(s); rb_str_buf_cat(res, OFF16B(&s), NATINT_LEN(short,2)); } break; - case 'N': + case 'N': /* unsigned long (network byte-order) */ while (len-- > 0) { unsigned long l; @@ -691,12 +719,12 @@ pack_pack(ary, fmt) else { l = NATINT_U32(from); } - l = htonl(l); + l = NATINT_HTONL(l); rb_str_buf_cat(res, OFF32B(&l), NATINT_LEN(long,4)); } break; - case 'v': + case 'v': /* unsigned short (VAX byte-order) */ while (len-- > 0) { unsigned short s; @@ -705,12 +733,12 @@ pack_pack(ary, fmt) else { s = NUM2INT(from); } - s = htovs(s); + s = NATINT_HTOVS(s); rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); } break; - case 'V': + case 'V': /* unsigned long (VAX byte-order) */ while (len-- > 0) { unsigned long l; @@ -719,13 +747,13 @@ pack_pack(ary, fmt) else { l = NATINT_U32(from); } - l = htovl(l); + l = NATINT_HTOVL(l); rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); } break; - case 'f': - case 'F': + case 'f': /* single precision float in native format */ + case 'F': /* ditto */ while (len-- > 0) { float f; @@ -735,7 +763,7 @@ pack_pack(ary, fmt) } break; - case 'e': + case 'e': /* single precision float in VAX byte-order */ while (len-- > 0) { float f; FLOAT_CONVWITH(ftmp); @@ -747,7 +775,7 @@ pack_pack(ary, fmt) } break; - case 'E': + case 'E': /* double precision float in VAX byte-order */ while (len-- > 0) { double d; DOUBLE_CONVWITH(dtmp); @@ -759,8 +787,8 @@ pack_pack(ary, fmt) } break; - case 'd': - case 'D': + case 'd': /* double precision float in native format */ + case 'D': /* ditto */ while (len-- > 0) { double d; @@ -770,7 +798,7 @@ pack_pack(ary, fmt) } break; - case 'g': + case 'g': /* single precision float in network byte-order */ while (len-- > 0) { float f; FLOAT_CONVWITH(ftmp); @@ -782,7 +810,7 @@ pack_pack(ary, fmt) } break; - case 'G': + case 'G': /* double precision float in network byte-order */ while (len-- > 0) { double d; DOUBLE_CONVWITH(dtmp); @@ -794,7 +822,7 @@ pack_pack(ary, fmt) } break; - case 'x': + case 'x': /* null byte */ grow: while (len >= 10) { rb_str_buf_cat(res, nul10, 10); @@ -803,7 +831,7 @@ pack_pack(ary, fmt) rb_str_buf_cat(res, nul10, len); break; - case 'X': + case 'X': /* back up byte */ shrink: plen = RSTRING(res)->len; if (plen < len) @@ -812,7 +840,7 @@ pack_pack(ary, fmt) RSTRING(res)->ptr[plen - len] = '\0'; break; - case '@': + case '@': /* null fill to absolute position */ len -= RSTRING(res)->len; if (len > 0) goto grow; len = -len; @@ -823,7 +851,7 @@ pack_pack(ary, fmt) rb_raise(rb_eArgError, "%% is not supported"); break; - case 'U': + case 'U': /* Unicode character */ while (len-- > 0) { long l; char buf[8]; @@ -842,8 +870,8 @@ pack_pack(ary, fmt) } break; - case 'u': - case 'm': + case 'u': /* uuencoded string */ + case 'm': /* base64 encoded string */ from = NEXTFROM; StringValue(from); ptr = RSTRING(from)->ptr; @@ -866,14 +894,14 @@ pack_pack(ary, fmt) } break; - case 'M': + case 'M': /* quoted-printable encoded string */ from = rb_obj_as_string(NEXTFROM); if (len <= 1) len = 72; qpencode(res, from, len); break; - case 'P': + case 'P': /* pointer to packed byte string */ from = THISFROM; if (!NIL_P(from)) { StringValue(from); @@ -884,7 +912,7 @@ pack_pack(ary, fmt) } len = 1; /* FALL THROUGH */ - case 'p': + case 'p': /* pointer to string */ while (len-- > 0) { char *t; from = NEXTFROM; @@ -902,7 +930,7 @@ pack_pack(ary, fmt) } break; - case 'w': + case 'w': /* BER compressed integer */ while (len-- > 0) { unsigned long ul; VALUE buf = rb_str_new(0, 0); diff --git a/ruby.h b/ruby.h index 4791398b1e..d90eaffe60 100644 --- a/ruby.h +++ b/ruby.h @@ -239,13 +239,13 @@ unsigned long rb_num2ulong _((VALUE)); #define NUM2LONG(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2long((VALUE)x)) #define NUM2ULONG(x) rb_num2ulong((VALUE)x) #if SIZEOF_INT < SIZEOF_LONG -int rb_num2int _((VALUE)); +long rb_num2int _((VALUE)); #define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):rb_num2int((VALUE)x)) -int rb_fix2int _((VALUE)); +long rb_fix2int _((VALUE)); #define FIX2INT(x) rb_fix2int((VALUE)x) -unsigned int rb_num2uint _((VALUE)); +unsigned long rb_num2uint _((VALUE)); #define NUM2UINT(x) rb_num2uint(x) -unsigned int rb_fix2uint _((VALUE)); +unsigned long rb_fix2uint _((VALUE)); #define FIX2UINT(x) rb_fix2uint(x) #else #define NUM2INT(x) ((int)NUM2LONG(x))