* 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.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5075 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-12-01 08:42:53 +00:00
parent 0f54ad5f6c
commit b0acbc4c9a
4 changed files with 117 additions and 66 deletions

View File

@ -1,3 +1,18 @@
Mon Dec 1 17:33:47 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <nobu.nakada@nifty.ne.jp>
* sample/optparse/opttest.rb: added.

View File

@ -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;
{

126
pack.c
View File

@ -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);

8
ruby.h
View File

@ -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))