summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-07 12:06:09 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-07 12:06:09 +0000
commit8f7a3075881cc057fa70639729e0073a12bfe55c (patch)
treec557ed102332131c60de67244493c699dd6ade9e /bignum.c
parentde1b0c96f0a2f00c8bd3cc5d5fb054bff9905680 (diff)
* bignum.c (integer_format_loop_setup): Extracted from rb_int_export
and rb_int_import. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41145 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c154
1 files changed, 82 insertions, 72 deletions
diff --git a/bignum.c b/bignum.c
index 293af85604..5eef0b0d6b 100644
--- a/bignum.c
+++ b/bignum.c
@@ -552,6 +552,76 @@ validate_integer_format(int wordorder, size_t wordsize, int endian, size_t nails
rb_raise(rb_eArgError, "too big nails: %"PRI_SIZE_PREFIX"u", nails);
}
+static void
+integer_format_loop_setup(size_t wordcount, int wordorder, size_t wordsize, int endian, size_t nails,
+ size_t *word_num_fullbytes_ret,
+ int *word_num_partialbits_ret,
+ size_t *word_num_nailbytes_ret,
+ size_t *word_start_ret,
+ ssize_t *word_step_ret,
+ size_t *word_last_ret,
+ size_t *byte_start_ret,
+ int *byte_step_ret)
+{
+ size_t word_num_fullbytes;
+ int word_num_partialbits;
+ size_t word_num_nailbytes;
+ size_t word_start;
+ ssize_t word_step;
+ size_t word_last;
+ size_t byte_start;
+ int byte_step;
+
+ 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_start = wordsize*(wordcount-1);
+ word_step = -(ssize_t)wordsize;
+ word_last = 0;
+ }
+ else {
+ word_start = 0;
+ word_step = wordsize;
+ word_last = wordsize*(wordcount-1);
+ }
+
+ if (endian == 0) {
+#ifdef WORDS_BIGENDIAN
+ endian = 1;
+#else
+ endian = -1;
+#endif
+ }
+ if (endian == 1) {
+ byte_step = -1;
+ byte_start = wordsize-1;
+ }
+ else {
+ byte_step = 1;
+ byte_start = 0;
+ }
+
+ *word_num_partialbits_ret = word_num_partialbits;
+ *word_num_fullbytes_ret = word_num_fullbytes;
+ if (word_num_nailbytes_ret)
+ *word_num_nailbytes_ret = word_num_nailbytes;
+ *word_start_ret = word_start;
+ *word_step_ret = word_step;
+ *word_last_ret = word_last;
+ *byte_start_ret = byte_start;
+ *byte_step_ret = byte_step;
+}
+
static inline void
int_export_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
{
@@ -611,14 +681,6 @@ rb_int_export(VALUE val, int *signp, size_t *wordcount_allocated, void *words, s
if (words && SIZE_MAX / wordsize < wordcount)
rb_raise(rb_eArgError, "too big count * wordsize: %"PRI_SIZE_PREFIX"u * %"PRI_SIZE_PREFIX"u", wordcount, wordsize);
- if (endian == 0) {
-#ifdef WORDS_BIGENDIAN
- endian = 1;
-#else
- endian = -1;
-#endif
- }
-
if (FIXNUM_P(val)) {
long v = FIX2LONG(val);
if (v < 0) {
@@ -695,42 +757,18 @@ rb_int_export(VALUE val, int *signp, size_t *wordcount_allocated, void *words, s
size_t byte_start;
int byte_step;
+ size_t word_start, word_last;
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;
- }
+ integer_format_loop_setup(wordcount, wordorder, wordsize, endian, nails,
+ &word_num_fullbytes, &word_num_partialbits, &word_num_nailbytes,
+ &word_start, &word_step, &word_last, &byte_start, &byte_step);
- 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;
- }
+ wordp = buf + word_start;
+ last_wordp = buf + word_last;
dd = 0;
numbits_in_dd = 0;
@@ -824,6 +862,7 @@ rb_int_import(int sign, const void *words, size_t wordcount, int wordorder, size
size_t byte_start;
int byte_step;
+ size_t word_start, word_last;
const unsigned char *bytep, *wordp, *last_wordp;
size_t index_in_word;
BDIGIT_DBL dd;
@@ -835,14 +874,6 @@ rb_int_import(int sign, const void *words, size_t wordcount, int wordorder, size
if (sign != 1 && sign != 0 && sign != -1)
rb_raise(rb_eArgError, "unexpected sign: %d", sign);
- if (endian == 0) {
-#ifdef WORDS_BIGENDIAN
- endian = 1;
-#else
- endian = -1;
-#endif
- }
-
/*
* num_bits = (wordsize * CHAR_BIT - nails) * count
* num_bdigits = (num_bits + SIZEOF_BDIGITS*CHAR_BIT - 1) / (SIZEOF_BDIGITS*CHAR_BIT)
@@ -863,33 +894,12 @@ rb_int_import(int sign, const void *words, size_t wordcount, int wordorder, size
dp = BDIGITS(result);
de = dp + RBIGNUM_LEN(result);
- 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--;
- }
-
- 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);
- }
+ integer_format_loop_setup(wordcount, wordorder, wordsize, endian, nails,
+ &word_num_fullbytes, &word_num_partialbits, NULL,
+ &word_start, &word_step, &word_last, &byte_start, &byte_step);
- if (endian == 1) {
- byte_step = -1;
- byte_start = wordsize-1;
- }
- else {
- byte_step = 1;
- byte_start = 0;
- }
+ wordp = buf + word_start;
+ last_wordp = buf + word_last;
dd = 0;
numbits_in_dd = 0;