Skip to content

Commit

Permalink
added support for bigdecimal
Browse files Browse the repository at this point in the history
  • Loading branch information
ohler55 committed Oct 11, 2013
1 parent 5e488ff commit b5338fa
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 5 deletions.
6 changes: 2 additions & 4 deletions README.md
Expand Up @@ -34,11 +34,9 @@ A fast XML parser and Object marshaller as a Ruby gem.


## <a name="release">Release Notes</a> ## <a name="release">Release Notes</a>


### Release 2.0.10 ### Release 2.0.11


- Small fix to not create an empty element from a closed element when using locate(). - Added support for BigDecimals in :object mode.

- Fixed to keep objects from being garbages collected in Ruby 2.x.


## <a name="description">Description</a> ## <a name="description">Description</a>


Expand Down
8 changes: 8 additions & 0 deletions ext/ox/dump.c
Expand Up @@ -739,6 +739,14 @@ dump_obj(ID aid, VALUE obj, int depth, Out out) {
dump_date(out, obj); dump_date(out, obj);
e.indent = -1; e.indent = -1;
out->w_end(out, &e); out->w_end(out, &e);
} else if (0 == strcmp("BigDecimal", classname)) {
VALUE rs = rb_funcall(obj, ox_to_s_id, 0);

e.type = BigDecimalCode;
out->w_start(out, &e);
dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs));
e.indent = -1;
out->w_end(out, &e);
} else { } else {
if (StrictEffort == out->opts->effort) { if (StrictEffort == out->opts->effort) {
rb_raise(rb_eNotImpError, "Failed to dump T_DATA %s\n", classname); rb_raise(rb_eNotImpError, "Failed to dump T_DATA %s\n", classname);
Expand Down
1 change: 1 addition & 0 deletions ext/ox/extconf.rb
Expand Up @@ -31,6 +31,7 @@
'HAS_IVAR_HELPERS' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0, 'HAS_IVAR_HELPERS' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0,
'HAS_PROC_WITH_BLOCK' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0, 'HAS_PROC_WITH_BLOCK' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0,
'HAS_GC_GUARD' => ('jruby' != type && 'rubinius' != type) ? 1 : 0, 'HAS_GC_GUARD' => ('jruby' != type && 'rubinius' != type) ? 1 : 0,
'HAS_BIGDECIMAL' => ('jruby' != type) ? 1 : 0,
'HAS_TOP_LEVEL_ST_H' => ('ree' == type || ('ruby' == type && '1' == version[0] && '8' == version[1])) ? 1 : 0, 'HAS_TOP_LEVEL_ST_H' => ('ree' == type || ('ruby' == type && '1' == version[0] && '8' == version[1])) ? 1 : 0,
'NEEDS_UIO' => (RUBY_PLATFORM =~ /(win|w)32$/) ? 0 : 1, 'NEEDS_UIO' => (RUBY_PLATFORM =~ /(win|w)32$/) ? 0 : 1,
} }
Expand Down
8 changes: 8 additions & 0 deletions ext/ox/obj_load.c
Expand Up @@ -557,6 +557,13 @@ add_text(PInfo pi, char *text, int closed) {
case BignumCode: case BignumCode:
h->obj = rb_cstr_to_inum(text, 10, 1); h->obj = rb_cstr_to_inum(text, 10, 1);
break; break;
case BigDecimalCode:
#if HAS_BIGDECIMAL
h->obj = rb_funcall(ox_bigdecimal_class, ox_new_id, 1, rb_str_new2(text));
#else
h->obj = Qnil;
#endif
break;
default: default:
h->obj = Qnil; h->obj = Qnil;
break; break;
Expand Down Expand Up @@ -623,6 +630,7 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
case Symbol64Code: case Symbol64Code:
case RegexpCode: case RegexpCode:
case BignumCode: case BignumCode:
case BigDecimalCode:
case ComplexCode: case ComplexCode:
case DateCode: case DateCode:
case TimeCode: case TimeCode:
Expand Down
5 changes: 5 additions & 0 deletions ext/ox/ox.c
Expand Up @@ -80,6 +80,7 @@ ID ox_local_id;
ID ox_mesg_id; ID ox_mesg_id;
ID ox_message_id; ID ox_message_id;
ID ox_nodes_id; ID ox_nodes_id;
ID ox_new_id;
ID ox_num_id; ID ox_num_id;
ID ox_parse_id; ID ox_parse_id;
ID ox_read_id; ID ox_read_id;
Expand All @@ -102,6 +103,7 @@ VALUE ox_zero_fixnum;


VALUE ox_arg_error_class; VALUE ox_arg_error_class;
VALUE ox_bag_clas; VALUE ox_bag_clas;
VALUE ox_bigdecimal_class;
VALUE ox_cdata_clas; VALUE ox_cdata_clas;
VALUE ox_comment_clas; VALUE ox_comment_clas;
VALUE ox_date_class; VALUE ox_date_class;
Expand Down Expand Up @@ -868,6 +870,7 @@ void Init_ox() {


rb_require("time"); rb_require("time");
rb_require("date"); rb_require("date");
rb_require("bigdecimal");
rb_require("stringio"); rb_require("stringio");


ox_at_column_id = rb_intern("@column"); ox_at_column_id = rb_intern("@column");
Expand Down Expand Up @@ -900,6 +903,7 @@ void Init_ox() {
ox_mesg_id = rb_intern("mesg"); ox_mesg_id = rb_intern("mesg");
ox_message_id = rb_intern("message"); ox_message_id = rb_intern("message");
ox_nodes_id = rb_intern("@nodes"); ox_nodes_id = rb_intern("@nodes");
ox_new_id = rb_intern("new");
ox_num_id = rb_intern("@num"); ox_num_id = rb_intern("@num");
ox_parse_id = rb_intern("parse"); ox_parse_id = rb_intern("parse");
ox_read_id = rb_intern("read"); ox_read_id = rb_intern("read");
Expand All @@ -921,6 +925,7 @@ void Init_ox() {
ox_arg_error_class = rb_const_get_at(Ox, rb_intern("ArgError")); ox_arg_error_class = rb_const_get_at(Ox, rb_intern("ArgError"));
ox_struct_class = rb_const_get(rb_cObject, rb_intern("Struct")); ox_struct_class = rb_const_get(rb_cObject, rb_intern("Struct"));
ox_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO")); ox_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO"));
ox_bigdecimal_class = rb_const_get(rb_cObject, rb_intern("BigDecimal"));


auto_define_sym = ID2SYM(rb_intern("auto_define")); rb_gc_register_address(&auto_define_sym); auto_define_sym = ID2SYM(rb_intern("auto_define")); rb_gc_register_address(&auto_define_sym);
auto_sym = ID2SYM(rb_intern("auto")); rb_gc_register_address(&auto_sym); auto_sym = ID2SYM(rb_intern("auto")); rb_gc_register_address(&auto_sym);
Expand Down
2 changes: 2 additions & 0 deletions ext/ox/ox.h
Expand Up @@ -214,6 +214,7 @@ extern ID ox_local_id;
extern ID ox_mesg_id; extern ID ox_mesg_id;
extern ID ox_message_id; extern ID ox_message_id;
extern ID ox_nodes_id; extern ID ox_nodes_id;
extern ID ox_new_id;
extern ID ox_num_id; extern ID ox_num_id;
extern ID ox_parse_id; extern ID ox_parse_id;
extern ID ox_read_id; extern ID ox_read_id;
Expand All @@ -237,6 +238,7 @@ extern VALUE ox_utf8_encoding;
extern void *ox_utf8_encoding; extern void *ox_utf8_encoding;
#endif #endif


extern VALUE ox_bigdecimal_class;
extern VALUE ox_date_class; extern VALUE ox_date_class;
extern VALUE ox_empty_string; extern VALUE ox_empty_string;
extern VALUE ox_encoding_sym; extern VALUE ox_encoding_sym;
Expand Down
1 change: 1 addition & 0 deletions ext/ox/type.h
Expand Up @@ -38,6 +38,7 @@ typedef enum {
ClassCode = 'c', ClassCode = 'c',
Symbol64Code = 'd', /* base64 encoded Symbol */ Symbol64Code = 'd', /* base64 encoded Symbol */
DateCode = 'D', DateCode = 'D',
BigDecimalCode = 'B',
ExceptionCode = 'e', ExceptionCode = 'e',
FloatCode = 'f', FloatCode = 'f',
RegexpCode = 'g', RegexpCode = 'g',
Expand Down
2 changes: 1 addition & 1 deletion lib/ox/version.rb
@@ -1,5 +1,5 @@


module Ox module Ox
# Current version of the module. # Current version of the module.
VERSION = '2.0.10' VERSION = '2.0.11'
end end
10 changes: 10 additions & 0 deletions test/tests.rb
Expand Up @@ -13,6 +13,7 @@
require 'test/unit' require 'test/unit'
require 'optparse' require 'optparse'
require 'date' require 'date'
require 'bigdecimal'
require 'ox' require 'ox'


$ruby = RUBY_DESCRIPTION.split(' ')[0] $ruby = RUBY_DESCRIPTION.split(' ')[0]
Expand Down Expand Up @@ -162,6 +163,15 @@ def test_bignum
dump_and_load(-7 ** 55, false) dump_and_load(-7 ** 55, false)
end end


def test_bigdecimal
if 'jruby' == RUBY_ENGINE
assert(true)
else
bd = BigDecimal.new('7.123456789')
dump_and_load(bd, false)
end
end

def test_complex_number def test_complex_number
if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby || 'jruby' == RUBY_ENGINE if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby || 'jruby' == RUBY_ENGINE
assert(true) assert(true)
Expand Down

0 comments on commit b5338fa

Please sign in to comment.