Skip to content

Commit c0e1970

Browse files
authored
Merge pull request #8 from casperisfine/generate-bignum
Handle serializing integers larger than 64bits.
2 parents e53ee31 + c29c018 commit c0e1970

File tree

2 files changed

+12
-13
lines changed

2 files changed

+12
-13
lines changed

ext/rapidjson/encoder.hh

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,14 @@ class RubyObjectEncoder {
6060
}
6161

6262
void encode_bignum(VALUE b) {
63-
b = rb_big_norm(b);
64-
if (FIXNUM_P(b)) {
65-
return encode_fixnum(b);
66-
}
67-
68-
bool negative = rb_big_cmp(b, INT2FIX(0)) == INT2FIX(-1);
69-
if (negative) {
70-
long long ll = rb_big2ll(b);
71-
writer.Int64(ll);
72-
} else {
73-
unsigned long long ull = rb_big2ull(b);
74-
writer.Uint64(ull);
75-
}
63+
// Some T_BIGNUM might be small enough to fit in long long or unsigned long long
64+
// but this being the slow path, it's not really worth it.
65+
VALUE str = rb_funcall(b, id_to_s, 0);
66+
Check_Type(str, T_STRING);
67+
68+
// We should be able to use RawNumber here, but it's buggy
69+
// https://github.com/Tencent/rapidjson/issues/852
70+
writer.RawValue(RSTRING_PTR(str), RSTRING_LEN(str), kNumberType);
7671
}
7772

7873
void encode_float(VALUE v) {

test/test_encoder.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ def test_encode_bignum
3333
assert_equal "18446744073709551615", encode(2**64 - 1)
3434
end
3535

36+
def test_encore_arbitrary_size_num
37+
assert_equal "340282366920938463463374607431768211456", encode(2**128)
38+
end
39+
3640
def test_encode_fixnum_exponents
3741
tests = []
3842
0.upto(65) do |exponent|

0 commit comments

Comments
 (0)