* pack.c: all features are backport from 1.9. [ruby-dev:24826]

* bignum.c (rb_big2ulong_pack): new function to pack Bignums.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@7291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
gotoyuzo 2004-11-16 19:43:24 +00:00
parent 73deb73392
commit b86269e445
3 changed files with 35 additions and 57 deletions

View file

@ -1,3 +1,9 @@
Wed Nov 17 04:33:01 2004 GOTOU Yuuzou <gotoyuzo@notwork.org>
* pack.c: all features are backport from 1.9. [ruby-dev:24826]
* bignum.c (rb_big2ulong_pack): new function to pack Bignums.
Tue Nov 16 23:45:07 2004 Yukihiro Matsumoto <matz@ruby-lang.org> Tue Nov 16 23:45:07 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* numeric.c (flo_divmod): protect float values from GC by * numeric.c (flo_divmod): protect float values from GC by

View file

@ -747,6 +747,17 @@ big2ulong(x, type)
return num; return num;
} }
unsigned long
rb_big2ulong_pack(x)
VALUE x;
{
unsigned long num = big2ulong(x, "unsigned long", Qfalse);
if (!RBIGNUM(x)->sign) {
return -num;
}
return num;
}
unsigned long unsigned long
rb_big2ulong(x) rb_big2ulong(x)
VALUE x; VALUE x;

75
pack.c
View file

@ -331,52 +331,21 @@ endian()
#define VTOHD(x,y) vtohd(x) #define VTOHD(x,y) vtohd(x)
#endif #endif
#if SIZEOF_LONG == SIZE32 unsigned long rb_big2ulong_pack _((VALUE x));
typedef long I32;
typedef unsigned long U32;
#define NUM2I32(x) NUM2LONG(x)
#define NUM2U32(x) NUM2ULONG(x)
#else
typedef int I32;
typedef unsigned int U32;
# if SIZEOF_INT == SIZE32
# define NUM2I32(x) NUM2INT(x)
# define NUM2U32(x) NUM2UINT(x)
# else
#define I32_MAX 2147483647 static unsigned long
#define I32_MIN (-I32_MAX-1)
static I32
num2i32(x) num2i32(x)
VALUE x; VALUE x;
{ {
long num = NUM2LONG(x); x = rb_to_int(x); /* is nil OK? (should not) */
if (num < I32_MIN || I32_MAX < num) { if (FIXNUM_P(x)) return FIX2LONG(x);
rb_raise(rb_eRangeError, "integer %ld too big to convert to `I32'", num); if (TYPE(x) == T_BIGNUM) {
return rb_big2ulong_pack(x);
} }
return (I32)num; rb_raise(rb_eTypeError, "cannot convert %s to `integer'", rb_obj_classname(x));
return 0; /* not reached */
} }
#define U32_MAX 4294967295
static U32
num2u32(x)
VALUE x;
{
unsigned long num = NUM2ULONG(x);
if (U32_MAX < num) {
rb_raise(rb_eRangeError, "integer %ld too big to convert to `U32'", num);
}
return (U32)num;
}
# define NUM2I32(x) num2i32(x)
# define NUM2U32(x) num2u32(x)
# endif
#endif
#if SIZEOF_LONG == SIZE32 || SIZEOF_INT == SIZE32 #if SIZEOF_LONG == SIZE32 || SIZEOF_INT == SIZE32
# define EXTEND32(x) # define EXTEND32(x)
@ -704,7 +673,7 @@ pack_pack(ary, fmt)
char c; char c;
from = NEXTFROM; from = NEXTFROM;
c = NUM2I32(from); c = num2i32(from);
rb_str_buf_cat(res, &c, sizeof(char)); rb_str_buf_cat(res, &c, sizeof(char));
} }
break; break;
@ -715,7 +684,7 @@ pack_pack(ary, fmt)
short s; short s;
from = NEXTFROM; from = NEXTFROM;
s = NUM2I32(from); s = num2i32(from);
rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));
} }
break; break;
@ -726,26 +695,18 @@ pack_pack(ary, fmt)
long i; long i;
from = NEXTFROM; from = NEXTFROM;
i = NUM2I32(from); i = num2i32(from);
rb_str_buf_cat(res, OFF32(&i), NATINT_LEN(int,4)); rb_str_buf_cat(res, OFF32(&i), NATINT_LEN(int,4));
} }
break; break;
case 'l': /* signed long */ case 'l': /* signed long */
while (len-- > 0) {
long l;
from = NEXTFROM;
l = NUM2I32(from);
rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));
}
break;
case 'L': /* unsigned long */ case 'L': /* unsigned long */
while (len-- > 0) { while (len-- > 0) {
long l; long l;
from = NEXTFROM; from = NEXTFROM;
l = NUM2U32(from); l = num2i32(from);
rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));
} }
break; break;
@ -766,7 +727,7 @@ pack_pack(ary, fmt)
unsigned short s; unsigned short s;
from = NEXTFROM; from = NEXTFROM;
s = NUM2I32(from); s = num2i32(from);
s = NATINT_HTONS(s); s = NATINT_HTONS(s);
rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));
} }
@ -777,7 +738,7 @@ pack_pack(ary, fmt)
unsigned long l; unsigned long l;
from = NEXTFROM; from = NEXTFROM;
l = NUM2U32(from); l = num2i32(from);
l = NATINT_HTONL(l); l = NATINT_HTONL(l);
rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));
} }
@ -788,7 +749,7 @@ pack_pack(ary, fmt)
unsigned short s; unsigned short s;
from = NEXTFROM; from = NEXTFROM;
s = NUM2I32(from); s = num2i32(from);
s = NATINT_HTOVS(s); s = NATINT_HTOVS(s);
rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));
} }
@ -799,7 +760,7 @@ pack_pack(ary, fmt)
unsigned long l; unsigned long l;
from = NEXTFROM; from = NEXTFROM;
l = NUM2U32(from); l = num2i32(from);
l = NATINT_HTOVL(l); l = NATINT_HTOVL(l);
rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));
} }
@ -912,7 +873,7 @@ pack_pack(ary, fmt)
from = NEXTFROM; from = NEXTFROM;
from = rb_to_int(from); from = rb_to_int(from);
l = NUM2UINT(from); l = NUM2INT(from);
if (l < 0) { if (l < 0) {
rb_raise(rb_eRangeError, "pack(U): value out of range"); rb_raise(rb_eRangeError, "pack(U): value out of range");
} }
@ -2072,7 +2033,7 @@ uv_to_utf8(buf, uv)
buf[5] = (uv&0x3f)|0x80; buf[5] = (uv&0x3f)|0x80;
return 6; return 6;
} }
rb_raise(rb_eArgError, "pack(U): value out of range"); rb_raise(rb_eRangeError, "pack(U): value out of range");
} }
static const long utf8_limits[] = { static const long utf8_limits[] = {