aboutsummaryrefslogtreecommitdiffstats
path: root/pack.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-06 11:57:35 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-06 11:57:35 +0000
commit9fea8758e98eed379bf406f2fea6c8403efe2590 (patch)
tree43b6d68224149d266a858e9ec18ac7ddf61f707a /pack.c
parentc247e62808211a8e3ef0f54718b4dfea3bc46e13 (diff)
downloadruby-9fea8758e98eed379bf406f2fea6c8403efe2590.tar.gz
* configure.in: Invoke RUBY_REPLACE_TYPE for size_t.
Don't invoke RUBY_CHECK_PRINTF_PREFIX for size_t to avoid conflict with RUBY_REPLACE_TYPE. * internal.h (rb_absint_size): Declared. (rb_absint_size_in_word): Ditto. (rb_int_export): Ditto. * bignum.c (rb_absint_size): New function. (rb_absint_size_in_word): Ditto. (int_export_fill_dd): Ditto. (int_export_take_lowbits): Ditto. (rb_int_export): Ditto. * pack.c (pack_pack): Use rb_int_export for BER compressed integer. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41106 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c65
1 files changed, 25 insertions, 40 deletions
diff --git a/pack.c b/pack.c
index ea83b0c037..1d51bebe48 100644
--- a/pack.c
+++ b/pack.c
@@ -1011,50 +1011,35 @@ pack_pack(VALUE ary, VALUE fmt)
case 'w': /* BER compressed integer */
while (len-- > 0) {
- unsigned long ul;
VALUE buf = rb_str_new(0, 0);
- char c, *bufs, *bufe;
+ size_t numbytes;
+ int sign;
+ size_t count;
+ char *cp;
from = NEXTFROM;
- if (RB_TYPE_P(from, T_BIGNUM)) {
- VALUE big128 = rb_uint2big(128);
- while (RB_TYPE_P(from, T_BIGNUM)) {
- from = rb_big_divmod(from, big128);
- c = castchar(NUM2INT(RARRAY_AREF(from, 1)) | 0x80); /* mod */
- rb_str_buf_cat(buf, &c, sizeof(char));
- from = RARRAY_AREF(from, 0); /* div */
- }
- }
-
- {
- long l = NUM2LONG(from);
- if (l < 0) {
- rb_raise(rb_eArgError, "can't compress negative numbers");
- }
- ul = l;
- }
-
- while (ul) {
- c = castchar((ul & 0x7f) | 0x80);
- rb_str_buf_cat(buf, &c, sizeof(char));
- ul >>= 7;
- }
+ from = rb_to_int(from);
+ numbytes = rb_absint_size_in_word(from, 7, NULL);
+ if (numbytes == 0)
+ numbytes = 1;
+ buf = rb_str_new(NULL, numbytes);
+
+ count = RSTRING_LEN(buf);
+ rb_int_export(from, &sign, RSTRING_PTR(buf), &count, 1, 1, 1, 1);
+
+ if (sign < 0)
+ rb_raise(rb_eArgError, "can't compress negative numbers");
+ if (sign == 2)
+ rb_bug("buffer size problem?");
+
+ cp = RSTRING_PTR(buf);
+ while (1 < numbytes) {
+ *cp |= 0x80;
+ cp++;
+ numbytes--;
+ }
- if (RSTRING_LEN(buf)) {
- bufs = RSTRING_PTR(buf);
- bufe = bufs + RSTRING_LEN(buf) - 1;
- *bufs &= 0x7f; /* clear continue bit */
- while (bufs < bufe) { /* reverse */
- c = *bufs;
- *bufs++ = *bufe;
- *bufe-- = c;
- }
- rb_str_buf_cat(res, RSTRING_PTR(buf), RSTRING_LEN(buf));
- }
- else {
- c = 0;
- rb_str_buf_cat(res, &c, sizeof(char));
- }
+ rb_str_buf_cat(res, RSTRING_PTR(buf), RSTRING_LEN(buf));
}
break;