summaryrefslogtreecommitdiff
path: root/pack.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-12 15:18:00 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-12 15:18:00 +0000
commitaaa1461d7b1508c12e9aaa3f2c2681ddc82fa0f4 (patch)
treeb9c7a602b2756d9a17c55d8701b889b481440a8a /pack.c
parent17f1cdaa00ff51470b934c99f6e54a24bf377b71 (diff)
* bignum.c (rb_integer_unpack_2comp): New function.
(rb_integer_unpack_internal): Extracted from rb_integer_unpack and nlp_bits_ret argument added. (integer_unpack_num_bdigits_small): nlp_bits_ret argument added to return number of leading padding bits. (integer_unpack_num_bdigits_generic): Ditto. * internal.h (rb_integer_unpack_2comp): Declared. * pack.c (pack_unpack): Use rb_integer_unpack_2comp and rb_integer_unpack. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41264 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c34
1 files changed, 6 insertions, 28 deletions
diff --git a/pack.c b/pack.c
index 66aa08f178..6cc79a2607 100644
--- a/pack.c
+++ b/pack.c
@@ -1725,38 +1725,16 @@ pack_unpack(VALUE str, VALUE fmt)
#endif
default:
- if (integer_size > MAX_INTEGER_PACK_SIZE)
- rb_bug("unexpected integer size for pack: %d", integer_size);
PACK_LENGTH_ADJUST_SIZE(integer_size);
while (len-- > 0) {
- union {
- unsigned long i[(MAX_INTEGER_PACK_SIZE+SIZEOF_LONG)/SIZEOF_LONG];
- char a[(MAX_INTEGER_PACK_SIZE+SIZEOF_LONG)/SIZEOF_LONG*SIZEOF_LONG];
- } v;
- int num_longs = (integer_size+SIZEOF_LONG)/SIZEOF_LONG;
- int i;
-
- if (signed_p && (signed char)s[bigendian_p ? 0 : (integer_size-1)] < 0)
- memset(v.a, 0xff, sizeof(long)*num_longs);
+ int flags = bigendian_p ? INTEGER_PACK_BIG_ENDIAN : INTEGER_PACK_LITTLE_ENDIAN;
+ VALUE val;
+ if (signed_p)
+ val = rb_integer_unpack_2comp(s, integer_size, 1, 0, flags);
else
- memset(v.a, 0, sizeof(long)*num_longs);
- if (bigendian_p)
- memcpy(v.a + sizeof(long)*num_longs - integer_size, s, integer_size);
- else
- memcpy(v.a, s, integer_size);
- if (bigendian_p) {
- for (i = 0; i < num_longs/2; i++) {
- unsigned long t = v.i[i];
- v.i[i] = v.i[num_longs-1-i];
- v.i[num_longs-1-i] = t;
- }
- }
- if (bigendian_p != BIGENDIAN_P()) {
- for (i = 0; i < num_longs; i++)
- v.i[i] = swapl(v.i[i]);
- }
+ val = rb_integer_unpack(s, integer_size, 1, 0, flags);
+ UNPACK_PUSH(val);
s += integer_size;
- UNPACK_PUSH(rb_big_unpack(v.i, num_longs));
}
PACK_ITEM_ADJUST();
break;