Skip to content
Browse files

fixed a few bugs and added options

  • Loading branch information...
1 parent 47ec1c4 commit 57afd74e1f75d307e9930809e2add4d845279b2d Peter Ohler committed Feb 19, 2012
Showing with 67 additions and 50 deletions.
  1. +1 −1 .gitignore
  2. +3 −1 README.md
  3. +1 −1 ext/oj/dump.c
  4. +7 −4 ext/oj/load.c
  5. +40 −21 ext/oj/oj.c
  6. +1 −1 lib/oj/version.rb
  7. +2 −9 notes
  8. +2 −6 oj.gemspec
  9. +10 −6 test/simple.rb
View
2 .gitignore
@@ -1,4 +1,4 @@
-ox-*.gem
+oj-*.gem
.DS_Store
\#*\#
.\#*
View
4 README.md
@@ -18,7 +18,9 @@ A fast JSON parser and Object marshaller as a Ruby gem.
## <a name="release">Release Notes</a>
-### Release 0.5
+### Release 0.5.2
+
+- Release 0.5.2 fixes encoding and float encoding.
This is the first release sith a version of 0.5 indicating it is only half
done. Basic load() and dump() is supported for Hash, Array, NilClass,
View
2 ext/oj/dump.c
@@ -158,7 +158,7 @@ grow(Out out, size_t len) {
inline static void
dump_hex(u_char c, Out out) {
- u_char d = c & 0xF0;
+ u_char d = (c >> 4) & 0x0F;
if (9 < d) {
*out->cur++ = (d - 10) + 'a';
View
11 ext/oj/load.c
@@ -116,7 +116,7 @@ parse(char *json, Options options) {
/* initialize parse info */
pi.str = json;
pi.s = json;
- pi.encoding = 0;
+ pi.encoding = ('\0' == *options->encoding) ? 0 : rb_enc_find(options->encoding);
pi.options = options;
if (Qundef == (obj = read_next(&pi))) {
raise_error("no object read", pi.str, pi.s);
@@ -298,14 +298,17 @@ read_num(ParseInfo pi) {
e = e * 10 + (*pi->s - '0');
}
}
- if (neg) {
- n = -n;
- }
if (0 == e && 0 == a && 1 == div) {
+ if (neg) {
+ n = -n;
+ }
return LONG2NUM(n);
} else {
double d = (double)n + (double)a / (double)div;
+ if (neg) {
+ d = -d;
+ }
if (0 != e) {
if (eneg) {
e = -e;
View
61 ext/oj/oj.c
@@ -41,14 +41,6 @@ typedef struct _YesNoOpt {
char *attr;
} *YesNoOpt;
-struct _Options default_options = {
- { '\0' }, // encoding
- 2, // indent
- No, // circular
- NoMode, // mode
- TolerantEffort, // effort
-};
-
void Init_oj();
VALUE Oj = Qnil;
@@ -64,6 +56,13 @@ VALUE simple_sym;
VALUE strict_sym;
VALUE tolerant_sym;
+static struct _Options default_options = {
+ { '\0' }, // encoding
+ 0, // indent
+ No, // circular
+ NoMode, // mode
+ TolerantEffort, // effort
+};
/* call-seq: default_options() => Hash
*
@@ -106,8 +105,13 @@ get_def_opts(VALUE self) {
* @param [Fixnum] :indent number of spaces to indent each element in an XML document
* @param [String] :encoding character encoding for the JSON file
* @param [true|false|nil] :circular support circular references while dumping
- * @param [:object|:simple|nil] :mode load method to use for JSON
- * @param [:strict|:tolerant|:lazy] :effort set the tolerance level for loading
+ * @param [:object|:simple|nil] :mode load and dump methods to use for JSON
+ * @param [:strict|:tolerant|:lazy] :effort set the tolerance level for
+ * loading. :strict raises an exception when a non-supported Object is
+ * encountered. :tolerant attempts to extract variable values from an
+ * Object using to_json() then it walks the Object's variables. The
+ * :lazy mode ignores non-supported Objects and replaces them with a
+ * null.
* @return [nil]
*/
static VALUE
@@ -121,8 +125,10 @@ set_def_opts(VALUE self, VALUE opts) {
Check_Type(opts, T_HASH);
- v = rb_hash_aref(opts, encoding_sym);
- if (Qnil == v) {
+ v = rb_hash_lookup2(opts, encoding_sym, Qundef);
+ if (Qundef == v) {
+ // no change
+ } else if (Qnil == v) {
*default_options.encoding = '\0';
} else {
Check_Type(v, T_STRING);
@@ -135,8 +141,10 @@ set_def_opts(VALUE self, VALUE opts) {
default_options.indent = FIX2INT(v);
}
- v = rb_hash_aref(opts, mode_sym);
- if (Qnil == v) {
+ v = rb_hash_lookup2(opts, mode_sym, Qundef);
+ if (Qundef == v) {
+ // no change
+ } else if (Qnil == v) {
default_options.mode = NoMode;
} else if (object_sym == v) {
default_options.mode = ObjectMode;
@@ -146,8 +154,10 @@ set_def_opts(VALUE self, VALUE opts) {
rb_raise(rb_eArgError, ":mode must be :object, :simple, or nil.\n");
}
- v = rb_hash_aref(opts, effort_sym);
- if (Qnil == v) {
+ v = rb_hash_lookup2(opts, effort_sym, Qundef);
+ if (Qundef == v) {
+ // no change
+ } else if (Qnil == v) {
default_options.effort = NoEffort;
} else if (strict_sym == v) {
default_options.effort = StrictEffort;
@@ -159,8 +169,10 @@ set_def_opts(VALUE self, VALUE opts) {
rb_raise(rb_eArgError, ":effort must be :strict, :tolerant, :lazy, or nil.\n");
}
for (o = ynos; 0 != o->attr; o++) {
- v = rb_hash_lookup(opts, o->sym);
- if (Qnil == v) {
+ v = rb_hash_lookup2(opts, o->sym, Qundef);
+ if (Qundef == v) {
+ // no change
+ } else if (Qnil == v) {
*o->attr = NotSet;
} else if (Qtrue == v) {
*o->attr = Yes;
@@ -246,13 +258,13 @@ load(char *json, int argc, VALUE *argv, VALUE self) {
return obj;
}
-/* call-seq: load(xml, options) => Hash, Array, String, Fixnum, Float, true, false, or nil
+/* call-seq: load(json, options) => Hash, Array, String, Fixnum, Float, true, false, or nil
*
* Parses a JSON document String into a Hash, Array, String, Fixnum, Float,
- * true, false, or nil Raises an exception if the JSON is * malformed or the
+ * true, false, or nil. Raises an exception if the JSON is malformed or the
* classes specified are not valid.
* @param [String] json JSON String
- * @param [Hash] options load options
+ * @param [Hash] options load options (same as default_options)
*/
static VALUE
load_str(int argc, VALUE *argv, VALUE self) {
@@ -294,6 +306,12 @@ load_file(int argc, VALUE *argv, VALUE self) {
return load(json, argc - 1, argv + 1, self);
}
+/* call-seq: dump(obj, options) => json-string
+ *
+ * Dumps an Object (obj) to a string.
+ * @param [Object] obj Object to serialize as an JSON document String
+ * @param [Hash] options same as default_options
+ */
static VALUE
dump(int argc, VALUE *argv, VALUE self) {
char *json;
@@ -340,6 +358,7 @@ void Init_oj() {
simple_sym = ID2SYM(rb_intern("simple")); rb_ary_push(keep, simple_sym);
strict_sym = ID2SYM(rb_intern("strict")); rb_ary_push(keep, strict_sym);
tolerant_sym = ID2SYM(rb_intern("tolerant")); rb_ary_push(keep, tolerant_sym);
+ default_options.effort = TolerantEffort;
}
void
View
2 lib/oj/version.rb
@@ -1,5 +1,5 @@
module Oj
# Current version of the module.
- VERSION = '0.5.1'
+ VERSION = '0.5.2'
end
View
11 notes
@@ -6,17 +6,10 @@
- yajl-ruby is fastest out there until now
- next
- - document
- - tests
- - add options
- - indent
- - mode (object or simple)
- - effort (strict, tolerant, lazy)
+ - implement effort
+ - sax
- load
- - options
- - encoding
- - object or raw/simple
- todo
- bignum
View
8 oj.gemspec
@@ -10,14 +10,10 @@ Gem::Specification.new do |s|
s.email = "peter@ohler.com"
s.homepage = "https://github.com/ohler55/oj"
s.summary = "A fast JSON parser and serializer."
- s.description = %{A fast JSON parser and object serializer that uses only standard C lib.
-
-Optimized JSON (Oj), as the name implies was written to provide speed optimized
-JSON handling. It was designed to be an alternative to Yajl and other Ruby
-JSON parsers and as an alternative to Marshal for Object serialization. }
+ s.description = %{The fastest JSON parser and object serializer. }
# s.files = Dir["{lib,ext,test}/**/*.{rb,h,c}"] + ['LICENSE', 'README.md']
- s.files = Dir["{lib,ext}/**/*.{rb,h,c}"] + ['LICENSE', 'README.md']
+ s.files = Dir["{lib,ext,test}/**/*.{rb,h,c}"] + ['LICENSE', 'README.md']
s.extensions = ["ext/oj/extconf.rb"]
# s.executables = []
View
16 test/simple.rb
@@ -13,7 +13,7 @@ def test_get_options
opts = Oj.default_options()
assert_equal(opts, {
:encoding=>nil,
- :indent=>2,
+ :indent=>0,
:circular=>false,
:mode=>nil,
:effort=>:tolerant})
@@ -22,16 +22,16 @@ def test_get_options
def test_set_options
orig = {
:encoding=>nil,
- :indent=>2,
+ :indent=>0,
:circular=>false,
:mode=>nil,
- :effort=>:strict}
+ :effort=>:tolerant}
o2 = {
:encoding=>"UTF-8",
:indent=>4,
:circular=>true,
:mode=>:object,
- :effort=>:tolerant }
+ :effort=>:strict }
o3 = { :indent => 4 }
Oj.default_options = o2
opts = Oj.default_options()
@@ -86,9 +86,13 @@ def test_hash
dump_and_load({ 'true' => true, 'false' => false}, false)
dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
end
-
-
+ def test_encode
+ Oj.default_options = { :encoding => 'UTF-8' }
+ dump_and_load("ぴーたー", false)
+ Oj.default_options = { :encoding => nil }
+ end
+
def dump_and_load(obj, trace=false)
json = Oj.dump(obj, :indent => 2)
puts json if trace

0 comments on commit 57afd74

Please sign in to comment.
Something went wrong with that request. Please try again.