[前][次][番号順一覧][スレッド一覧]

ruby-changes:29054

From: akr <ko1@a...>
Date: Thu, 6 Jun 2013 20:57:56 +0900 (JST)
Subject: [ruby-changes:29054] akr:r41106 (trunk): * configure.in: Invoke RUBY_REPLACE_TYPE for size_t.

akr	2013-06-06 20:57:35 +0900 (Thu, 06 Jun 2013)

  New Revision: 41106

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41106

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

  Added files:
    trunk/ext/-test-/bignum/export.c
    trunk/test/-ext-/bignum/test_export.rb
  Modified files:
    trunk/ChangeLog
    trunk/bignum.c
    trunk/configure.in
    trunk/ext/-test-/bignum/extconf.rb
    trunk/internal.h
    trunk/pack.c

Index: configure.in
===================================================================
--- configure.in	(revision 41105)
+++ configure.in	(revision 41106)
@@ -1234,6 +1234,7 @@ RUBY_REPLACE_TYPE(gid_t, int, GIDT) https://github.com/ruby/ruby/blob/trunk/configure.in#L1234
 RUBY_REPLACE_TYPE(time_t, [], TIMET, [@%:@include <time.h>])
 RUBY_REPLACE_TYPE(dev_t, [int long "long long"], DEVT)
 RUBY_REPLACE_TYPE(mode_t, ["unsigned int" long], MODET, [@%:@include <sys/stat.h>])
+RUBY_REPLACE_TYPE(size_t, ["unsigned int" "unsigned long" "unsigned long long"], SIZE)
 RUBY_REPLACE_TYPE(rlim_t, [int long "long long"], RLIM, [
 @%:@ifdef HAVE_SYS_TYPES_H
 @%:@include <sys/types.h>
@@ -1482,7 +1483,6 @@ fi https://github.com/ruby/ruby/blob/trunk/configure.in#L1483
 AC_TYPE_SIZE_T
 RUBY_CHECK_SIZEOF(size_t, [int long void*], [], [@%:@include <sys/types.h>])
 RUBY_CHECK_SIZEOF(ptrdiff_t, size_t, [], [@%:@include <stddef.h>])
-RUBY_CHECK_PRINTF_PREFIX(size_t, z)
 RUBY_CHECK_PRINTF_PREFIX(ptrdiff_t, t)
 AC_STRUCT_ST_BLKSIZE
 AC_STRUCT_ST_BLOCKS
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41105)
+++ ChangeLog	(revision 41106)
@@ -1,3 +1,21 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jun  6 20:40:17 2013  Tanaka Akira  <akr@f...>
+
+	* 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.
+
 Thu Jun  6 19:31:33 2013  Tadayoshi Funaba  <tadf@d...>
 
 	* ext/date/date_core.c: fixed coding error [ruby-core:55337].
Index: pack.c
===================================================================
--- pack.c	(revision 41105)
+++ pack.c	(revision 41106)
@@ -1011,50 +1011,35 @@ pack_pack(VALUE ary, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L1011
 
 	  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;
-		}
-
-		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));
-		}
+                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--;
+                }
+
+                rb_str_buf_cat(res, RSTRING_PTR(buf), RSTRING_LEN(buf));
 	    }
 	    break;
 
Index: ext/-test-/bignum/export.c
===================================================================
--- ext/-test-/bignum/export.c	(revision 0)
+++ ext/-test-/bignum/export.c	(revision 41106)
@@ -0,0 +1,29 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/bignum/export.c#L1
+#include "ruby.h"
+#include "internal.h"
+
+static VALUE
+rb_int_export_m(VALUE val, VALUE buf, VALUE wordorder, VALUE wordsize_arg, VALUE endian, VALUE nails)
+{
+  int sign;
+  size_t count;
+  void *ret;
+  size_t wordsize = NUM2SIZE(wordsize_arg);
+
+  if (!NIL_P(buf)) {
+      StringValue(buf);
+      rb_str_modify(buf);
+      count = RSTRING_LEN(buf) / wordsize;
+  }
+
+  ret = rb_int_export(val,
+      &sign, NIL_P(buf) ? NULL : RSTRING_PTR(buf), &count,
+      NUM2INT(wordorder), wordsize, NUM2INT(endian), NUM2INT(nails));
+
+  return rb_ary_new_from_args(3, INT2NUM(sign), ret ? rb_str_new(ret, wordsize * count) : Qnil, SIZE2NUM(count));
+}
+
+void
+Init_export(VALUE klass)
+{
+    rb_define_method(rb_cInteger, "test_export", rb_int_export_m, 5);
+}

Property changes on: ext/-test-/bignum/export.c
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/bignum/extconf.rb
===================================================================
--- ext/-test-/bignum/extconf.rb	(revision 41105)
+++ ext/-test-/bignum/extconf.rb	(revision 41106)
@@ -1,3 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/bignum/extconf.rb#L1
+$INCFLAGS << " -I$(topdir) -I$(top_srcdir)"
 $srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
 inits = $srcs.map {|s| File.basename(s, ".*")}
 inits.delete("init")
Index: internal.h
===================================================================
--- internal.h	(revision 41105)
+++ internal.h	(revision 41106)
@@ -99,6 +99,8 @@ VALUE rb_big_fdiv(VALUE x, VALUE y); https://github.com/ruby/ruby/blob/trunk/internal.h#L99
 VALUE rb_big_uminus(VALUE x);
 VALUE rb_integer_float_cmp(VALUE x, VALUE y);
 VALUE rb_integer_float_eq(VALUE x, VALUE y);
+size_t rb_absint_size(VALUE val, int *number_of_leading_zero_bits);
+size_t rb_absint_size_in_word(VALUE val, size_t word_numbits, size_t *number_of_leading_zero_bits);
 
 /* class.c */
 VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj);
@@ -423,6 +425,9 @@ const char *rb_objspace_data_type_name(V https://github.com/ruby/ruby/blob/trunk/internal.h#L425
 /* Temporary.  This API will be removed (renamed). */
 VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
 
+/* bignum.c */
+void *rb_int_export(VALUE val, int *signp, void *bufarg, size_t *countp, int wordorder, size_t wordsize, int endian, size_t nails);
+
 /* io.c */
 void rb_maygvl_fd_fix_cloexec(int fd);
 
Index: bignum.c
===================================================================
--- bignum.c	(revision 41105)
+++ bignum.c	(revision 41106)
@@ -50,6 +50,8 @@ static VALUE big_three = Qnil; https://github.com/ruby/ruby/blob/trunk/bignum.c#L50
 		     (BDIGITS(x)[0] == 0 && \
 		      (RBIGNUM_LEN(x) == 1 || bigzero_p(x))))
 
+static int nlz(BDIGIT x);
+
 #define BIGNUM_DEBUG 0
 #if BIGNUM_DEBUG
 #define ON_DEBUG(x) do { x; } while (0)
@@ -449,6 +451,325 @@ rb_big_unpack(unsigned long *buf, long n https://github.com/ruby/ruby/blob/trunk/bignum.c#L451
     }
 }
 
+/* number of bytes of abs(val). additionaly number of leading zeros can be returned. */
+size_t
+rb_absint_size(VALUE val, int *number_of_leading_zero_bits)
+{
+    BDIGIT *dp;
+    BDIGIT *de;
+    BDIGIT fixbuf[(sizeof(long) + SIZEOF_BDIGITS - 1) / SIZEOF_BDIGITS];
+    int i;
+    int num_leading_zeros;
+
+    val = rb_to_int(val);
+
+    if (FIXNUM_P(val)) {
+        long v = FIX2LONG(val);
+        if (v < 0) {
+            v = -v;
+        }
+#if SIZEOF_BDIGITS == SIZEOF_LONG
+        fixbuf[0] = v;
+#else
+        for (i = 0; i < (int)(sizeof(fixbuf)/sizeof(*fixbuf)); i++) {
+            fixbuf[i] = v & ((1L << (SIZEOF_BDIGITS * CHAR_BIT)) - 1);
+            v >>= SIZEOF_BDIGITS * CHAR_BIT;
+        }
+#endif
+        dp = fixbuf;
+        de = fixbuf + sizeof(fixbuf)/sizeof(*fixbuf);
+    }
+    else {
+        dp = BDIGITS(val);
+        de = dp + RBIGNUM_LEN(val);
+    }
+    while (dp < de && de[-1] == 0)
+        de--;
+    if (dp == de) {
+        if (number_of_leading_zero_bits)
+            *number_of_leading_zero_bits = 0;
+        return 0;
+    }
+    num_leading_zeros = nlz(de[-1]);
+    if (number_of_leading_zero_bits)
+        *number_of_leading_zero_bits = num_leading_zeros % CHAR_BIT;
+    return (de - dp) * SIZEOF_BDIGITS - num_leading_zeros / CHAR_BIT;
+}
+
+size_t
+rb_absint_size_in_word(VALUE val, size_t word_numbits_arg, size_t *number_of_leading_zero_bits)
+{
+    size_t numbytes;
+    size_t numwords;
+    int zerobits_in_byte;
+    VALUE val_numbits, word_numbits;
+    VALUE div_mod, div, mod;
+
+    numbytes = rb_absint_size(val, &zerobits_in_byte);
+
+    /*
+     * val_numbits = numbytes * CHAR_BIT - zerobits_in_byte
+     * div, mod = val_numbits.divmod(word_numbits)
+     * numwords = mod == 0 ? div : div + 1
+     * number_of_leading_zero_bits_in_word = mod == 0 ? 0 : word_numbits - mod
+     */
+    val_numbits = SIZET2NUM(numbytes);
+    val_numbits = rb_funcall(val_numbits, '*', 1, LONG2FIX(CHAR_BIT));
+    if (zerobits_in_byte)
+        val_numbits = rb_funcall(val_numbits, '-', 1, LONG2FIX(zerobits_in_byte));
+    word_numbits = SIZET2NUM(word_numbits_arg);
+    div_mod = rb_funcall(val_numbits, rb_intern("divmod"), 1, word_numbits);
+    div = RARRAY_AREF(div_mod, 0);
+    mod = RARRAY_AREF(div_mod, 1);
+    if (mod == LONG2FIX(0)) {
+        numwords = NUM2SIZE(div);
+        if (number_of_leading_zero_bits)
+            *number_of_leading_zero_bits = 0;
+    }
+    else {
+        numwords = NUM2SIZE(rb_funcall(div, '+', 1, LONG2FIX(1)));
+        if (number_of_leading_zero_bits)
+            *number_of_leading_zero_bits = word_numbits_arg - NUM2SIZE(mod);
+    }
+    return numwords;
+}
+
+static inline void
+int_export_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
+{
+    if (*dpp < *dep && SIZEOF_BDIGITS * CHAR_BIT <= (int)sizeof(*ddp) * CHAR_BIT - *numbits_in_dd_p) {
+        *ddp |= (BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
+        *numbits_in_dd_p += SIZEOF_BDIGITS * CHAR_BIT;
+    }
+    else if (*dpp == *dep) {
+        /* higher bits are infinity zeros */
+        *numbits_in_dd_p = (int)sizeof(*ddp) * CHAR_BIT;
+    }
+}
+
+static inline BDIGIT_DBL
+int_export_take_lowbits(int n, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
+{
+    BDIGIT_DBL ret;
+    ret = (*ddp) & (((BDIGIT_DBL)1 << n) - 1);
+    *ddp >>= n;
+    *numbits_in_dd_p -= n;
+    return ret;
+}
+
+/*
+ * Export an integer into a buffer.
+ *
+ * [val] Fixnum, Bignum or another object which has to_int.
+ * [signp] signedness is returned in *signp if it is not NULL.
+ *   0 for zero.
+ *   -1 for negative without overflow.  1 for positive without overflow.
+ *   -2 for negative overflow.  2 for positive overflow.
+ * [buf] buffer to export abs(val).  allocated by xmalloc if it is NULL.
+ * [countp] the size of given buffer as number of words (only meaningful when buf is not NULL).
+ *   *countp is overwritten as the number of allocated words when buf is NULL and allocated.
+ * [wordorder] order of words: 1 for most significant word first.  -1 for least significant word first.
+ * [wordsize] the size of word as number of bytes.
+ * [endian] order of bytes in a word: 1 for most significant byte first.  -1 for least significant byte first.  0 for native endian.
+ * [nails] number of padding bits in a word.  Most significant nails bits of each word are filled by zero.
+ *
+ * This function returns buf or the allocated buffer if buf is NULL.
+ *
+ */
+void *
+rb_int_export(VALUE val, int *signp, void *bufarg, size_t *countp, int wordorder, size_t wordsize, int endian, size_t nails)
+{
+    int sign;
+    BDIGIT *dp;
+    BDIGIT *de;
+    BDIGIT fixbuf[(sizeof(long) + SIZEOF_BDIGITS - 1) / SIZEOF_BDIGITS];
+    int i;
+    unsigned char *buf = bufarg;
+    unsigned char *bufend;
+    size_t wordcount;
+
+    val = rb_to_int(val);
+
+    if (wordorder != 1 && wordorder != -1)
+        rb_raise(rb_eArgError, "unexpected wordorder: %d", wordorder);
+    if (endian != 1 && endian != -1 && endian != 0)
+        rb_raise(rb_eArgError, "unexpected endian: %d", endian);
+    if (wordsize == 0)
+        rb_raise(rb_eArgError, "invalid wordsize: %"PRI_SIZE_PREFIX"u", wordsize);
+    if (SSIZE_MAX < wordsize)
+        rb_raise(rb_eArgError, "too big wordsize: %"PRI_SIZE_PREFIX"u", wordsize);
+    if (buf && SIZE_MAX / wordsize < *countp)
+        rb_raise(rb_eArgError, "too big count * wordsize: %"PRI_SIZE_PREFIX"u * %"PRI_SIZE_PREFIX"u", *countp, wordsize);
+    if (wordsize <= nails / CHAR_BIT)
+        rb_raise(rb_eArgError, "too big nails: %"PRI_SIZE_PREFIX"u", nails);
+
+    if (endian == 0) {
+#ifdef WORDS_BIGENDIAN
+        endian = 1;
+#else
+        endian = 0;
+#endif
+    }
+
+    if (FIXNUM_P(val)) {
+        long v = FIX2LONG(val);
+        if (v < 0) {
+            sign = -1;
+            v = -v;
+        }
+        else {
+            sign = 1;
+        }
+#if SIZEOF_BDIGITS == SIZEOF_LONG
+        fixbuf[0] = v;
+#else
+        for (i = 0; i < (int)(sizeof(fixbuf)/sizeof(*fixbuf)); i++) {
+            fixbuf[i] = v & ((1L << (SIZEOF_BDIGITS * CHAR_BIT)) - 1);
+            v >>= SIZEOF_BDIGITS * CHAR_BIT;
+        }
+#endif
+        dp = fixbuf;
+        de = fixbuf + sizeof(fixbuf)/sizeof(*fixbuf);
+    }
+    else {
+        sign = RBIGNUM_POSITIVE_P(val) ? 1 : -1;
+        dp = BDIGITS(val);
+        de = dp + RBIGNUM_LEN(val);
+    }
+    while (dp < de && de[-1] == 0)
+        de--;
+    if (dp == de) {
+        sign = 0;
+    }
+
+    if (buf) {
+        wordcount = *countp;
+        bufend = buf + wordcount * wordsize;
+    }
+    else {
+        /*
+         * val_numbits = (de - dp) * SIZEOF_BDIGITS * CHAR_BIT - nlz(de[-1])
+         * word_numbits = wordsize * CHAR_BIT - nails
+         * wordcount = (val_numbits + word_numbits - 1) / word_numbits
+         */
+        VALUE val_numbits, word_numbits, wordcountv;
+        val_numbits = SIZET2NUM((de - dp) * SIZEOF_BDIGITS);
+        val_numbits = rb_funcall(val_numbits, '*', 1, LONG2FIX(CHAR_BIT));
+        if (dp != de)
+            val_numbits = rb_funcall(val_numbits, '-', 1, LONG2FIX(nlz(de[-1])));
+        word_numbits = SIZET2NUM(wordsize);
+        word_numbits = rb_funcall(word_numbits, '*', 1, LONG2FIX(CHAR_BIT));
+        if (nails != 0)
+            word_numbits = rb_funcall(word_numbits, '-', 1, SIZET2NUM(nails));
+        wordcountv = rb_funcall(val_numbits, '+', 1, word_numbits);
+        wordcountv = rb_funcall(wordcountv, '-', 1, LONG2FIX(1));
+        wordcountv = rb_funcall(wordcountv, rb_intern("div"), 1, word_numbits);
+        wordcount = NUM2SIZE(wordcountv);
+        buf = xmalloc(wordcount * wordsize);
+        bufend = buf + wordcount * wordsize;
+    }
+
+    if (buf == bufend) {
+        sign *= 2; /* overflow if non-zero*/
+    }
+    else if (dp == de) {
+        memset(buf, '\0', bufend - buf);
+    }
+    else if (dp < de && buf < bufend) {
+        int word_num_partialbits;
+        size_t word_num_fullbytes;
+        size_t word_num_nailbytes;
+
+        ssize_t word_step;
+        size_t byte_start;
+        int byte_step;
+
+        unsigned char *bytep, *wordp, *last_wordp;
+        size_t index_in_word;
+        BDIGIT_DBL dd;
+        int numbits_in_dd;
+
+        word_num_partialbits = CHAR_BIT - (int)(nails % CHAR_BIT);
+        if (word_num_partialbits == CHAR_BIT)
+            word_num_partialbits = 0;
+        word_num_fullbytes = wordsize - (nails / CHAR_BIT);
+        if (word_num_partialbits != 0) {
+            word_num_fullbytes--;
+            word_num_nailbytes = wordsize - word_num_fullbytes - 1;
+        }
+        else {
+            word_num_nailbytes = wordsize - word_num_fullbytes;
+        }
+
+        if (wordorder == 1) {
+            word_step = -(ssize_t)wordsize;
+            wordp = buf + wordsize*(wordcount-1);
+            last_wordp = buf;
+        }
+        else {
+            word_step = wordsize;
+            wordp = buf;
+            last_wordp = buf + wordsize*(wordcount-1);
+        }
+
+        if (endian == 1) {
+            byte_step = -1;
+            byte_start = wordsize-1;
+        }
+        else {
+            byte_step = 1;
+            byte_start = 0;
+        }
+
+        dd = 0;
+        numbits_in_dd = 0;
+
+#define FILL_DD \
+    int_export_fill_dd(&dp, &de, &dd, &numbits_in_dd)
+#define TAKE_LOWBITS(n) \
+    int_export_take_lowbits(n, &dd, &numbits_in_dd)
+
+        while (1) {
+            index_in_word = 0;
+            bytep = wordp + byte_start;
+            while (index_in_word < word_num_fullbytes) {
+                FILL_DD;
+                *bytep = TAKE_LOWBITS(CHAR_BIT);
+                bytep += byte_step;
+                index_in_word++;
+            }
+            if (word_num_partialbits) {
+                FILL_DD;
+                *bytep = TAKE_LOWBITS(word_num_partialbits);
+                bytep += byte_step;
+                index_in_word++;
+            }
+            while (wordsize - word_num_nailbytes <= index_in_word && index_in_word < wordsize) {
+                *bytep = 0;
+                bytep += byte_step;
+                index_in_word++;
+            }
+
+            if (wordp == last_wordp)
+                break;
+
+            wordp += word_step;
+        }
+        if (dp != de || dd)
+            sign *= 2; /* overflow */
+    }
+
+    if (signp)
+        *signp = sign;
+
+    if (!bufarg)
+        *countp = wordcount;
+
+    return buf;
+#undef FILL_DD
+#undef TAKE_LOWBITS
+}
+
 #define QUAD_SIZE 8
 
 #if SIZEOF_LONG_LONG == QUAD_SIZE && SIZEOF_BDIGITS*2 == SIZEOF_LONG_LONG
Index: test/-ext-/bignum/test_export.rb
===================================================================
--- test/-ext-/bignum/test_export.rb	(revision 0)
+++ test/-ext-/bignum/test_export.rb	(revision 41106)
@@ -0,0 +1,67 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/bignum/test_export.rb#L1
+# coding: ASCII-8BIT
+
+require 'test/unit'
+require "-test-/bignum"
+
+class TestBignum < Test::Unit::TestCase
+  class TestExport < Test::Unit::TestCase
+    def test_export_zero
+      assert_equal([0, "", 0], 0.test_export(nil, 1, 1, 1, 0))
+    end
+
+    def test_argument_check
+      assert_raise(ArgumentError) { 0.test_export(nil, 0, 1, 1, 0) }
+      assert_raise(ArgumentError) { 0.test_export(nil, 1, 1, 2, 0) }
+      assert_raise(ArgumentError) { 0.test_export(nil, 1, 0, 1, 0) }
+      assert_raise(ArgumentError) { 0.test_export(nil, 1, 1, 1, 8) }
+
+      # assume sizeof(ssize_t) == sizeof(intptr_t)
+      assert_raise(ArgumentError) { 0.test_export(nil, 1, 1 << ([""].pack("p").length * 8 - 1), 1, 0) }
+    end
+
+    def test_export_wordsize
+      assert_equal([1, "\x01", 1], 1.test_export(nil, 1, 1, 1, 0))
+      assert_equal([1, "\x00\x01", 1], 1.test_export(nil, 1, 2, 1, 0))
+      assert_equal([1, "\x00\x00\x01", 1], 1.test_export(nil, 1, 3, 1, 0))
+      assert_equal([1, "\x01", 1], 1.test_export(nil, 1, 1, -1, 0))
+      assert_equal([1, "\x01\x00", 1], 1.test_export(nil, 1, 2, -1, 0))
+      assert_equal([1, "\x01\x00\x00", 1], 1.test_export(nil, 1, 3, -1, 0))
+    end
+
+    def test_export_fixed_buffer
+      assert_equal([0, "\x00\x00", 2], 0.test_export("xx", 1, 1, 1, 0))
+      assert_equal([1, "\x00\x01", 2], 0x01.test_export("xx", 1, 1, 1, 0))
+      (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]