oj 3.10.18 → 3.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/ext/oj/buf.h +34 -38
- data/ext/oj/cache8.c +59 -62
- data/ext/oj/cache8.h +8 -7
- data/ext/oj/circarray.c +33 -35
- data/ext/oj/circarray.h +11 -9
- data/ext/oj/code.c +170 -174
- data/ext/oj/code.h +21 -20
- data/ext/oj/compat.c +159 -166
- data/ext/oj/custom.c +802 -851
- data/ext/oj/dump.c +766 -778
- data/ext/oj/dump.h +49 -51
- data/ext/oj/dump_compat.c +1 -0
- data/ext/oj/dump_leaf.c +116 -157
- data/ext/oj/dump_object.c +609 -628
- data/ext/oj/dump_strict.c +318 -327
- data/ext/oj/encode.h +3 -4
- data/ext/oj/err.c +39 -25
- data/ext/oj/err.h +24 -15
- data/ext/oj/extconf.rb +2 -1
- data/ext/oj/fast.c +1008 -1038
- data/ext/oj/hash.c +62 -66
- data/ext/oj/hash.h +7 -6
- data/ext/oj/hash_test.c +450 -443
- data/ext/oj/mimic_json.c +406 -407
- data/ext/oj/object.c +559 -528
- data/ext/oj/odd.c +123 -128
- data/ext/oj/odd.h +27 -25
- data/ext/oj/oj.c +1132 -918
- data/ext/oj/oj.h +286 -297
- data/ext/oj/parse.c +943 -926
- data/ext/oj/parse.h +70 -69
- data/ext/oj/rails.c +836 -839
- data/ext/oj/rails.h +7 -7
- data/ext/oj/reader.c +135 -140
- data/ext/oj/reader.h +66 -79
- data/ext/oj/resolve.c +43 -43
- data/ext/oj/resolve.h +3 -2
- data/ext/oj/rxclass.c +67 -68
- data/ext/oj/rxclass.h +12 -10
- data/ext/oj/saj.c +451 -479
- data/ext/oj/scp.c +93 -103
- data/ext/oj/sparse.c +781 -716
- data/ext/oj/stream_writer.c +120 -149
- data/ext/oj/strict.c +71 -86
- data/ext/oj/string_writer.c +198 -243
- data/ext/oj/trace.c +29 -33
- data/ext/oj/trace.h +14 -11
- data/ext/oj/util.c +103 -103
- data/ext/oj/util.h +3 -2
- data/ext/oj/val_stack.c +47 -47
- data/ext/oj/val_stack.h +79 -86
- data/ext/oj/wab.c +291 -309
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/mimic.rb +0 -12
- data/lib/oj/version.rb +1 -1
- data/pages/Modes.md +2 -1
- data/pages/Options.md +8 -0
- data/test/activerecord/result_test.rb +7 -2
- data/test/foo.rb +35 -32
- data/test/helper.rb +10 -0
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/test_compat.rb +3 -3
- data/test/test_hash.rb +10 -0
- data/test/test_scp.rb +1 -1
- data/test/test_various.rb +1 -0
- metadata +82 -82
    
        data/ext/oj/stream_writer.c
    CHANGED
    
    | @@ -1,19 +1,18 @@ | |
| 1 1 | 
             
            // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
         | 
| 2 | 
            +
            // Licensed under the MIT License. See LICENSE file in the project root for license details.
         | 
| 2 3 |  | 
| 3 4 | 
             
            #include <errno.h>
         | 
| 4 | 
            -
             | 
| 5 5 | 
             
            #include <ruby.h>
         | 
| 6 6 |  | 
| 7 7 | 
             
            #include "encode.h"
         | 
| 8 8 |  | 
| 9 | 
            -
            extern VALUE | 
| 9 | 
            +
            extern VALUE Oj;
         | 
| 10 10 |  | 
| 11 | 
            -
            static void
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                StreamWriter	sw;
         | 
| 11 | 
            +
            static void stream_writer_free(void *ptr) {
         | 
| 12 | 
            +
                StreamWriter sw;
         | 
| 14 13 |  | 
| 15 14 | 
             
                if (0 == ptr) {
         | 
| 16 | 
            -
             | 
| 15 | 
            +
                    return;
         | 
| 17 16 | 
             
                }
         | 
| 18 17 | 
             
                sw = (StreamWriter)ptr;
         | 
| 19 18 | 
             
                xfree(sw->sw.out.buf);
         | 
| @@ -21,41 +20,38 @@ stream_writer_free(void *ptr) { | |
| 21 20 | 
             
                xfree(ptr);
         | 
| 22 21 | 
             
            }
         | 
| 23 22 |  | 
| 24 | 
            -
            static void
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                sw->sw.out.cur = sw->sw.out.buf;
         | 
| 23 | 
            +
            static void stream_writer_reset_buf(StreamWriter sw) {
         | 
| 24 | 
            +
                sw->sw.out.cur  = sw->sw.out.buf;
         | 
| 27 25 | 
             
                *sw->sw.out.cur = '\0';
         | 
| 28 26 | 
             
            }
         | 
| 29 27 |  | 
| 30 | 
            -
            static void
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                ssize_t	size = sw->sw.out.cur - sw->sw.out.buf;
         | 
| 28 | 
            +
            static void stream_writer_write(StreamWriter sw) {
         | 
| 29 | 
            +
                ssize_t size = sw->sw.out.cur - sw->sw.out.buf;
         | 
| 33 30 |  | 
| 34 31 | 
             
                switch (sw->type) {
         | 
| 35 32 | 
             
                case STRING_IO:
         | 
| 36 33 | 
             
                case STREAM_IO: {
         | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 34 | 
            +
                    volatile VALUE rs = rb_str_new(sw->sw.out.buf, size);
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    // Oddly enough, when pushing ASCII characters with UTF-8 encoding or
         | 
| 37 | 
            +
                    // even ASCII-8BIT does not change the output encoding. Pushing any
         | 
| 38 | 
            +
                    // non-ASCII no matter what the encoding changes the output encoding
         | 
| 39 | 
            +
                    // to ASCII-8BIT if it the string is not forced to UTF-8 here.
         | 
| 40 | 
            +
                    rs = oj_encode(rs);
         | 
| 41 | 
            +
                    rb_funcall(sw->stream, oj_write_id, 1, rs);
         | 
| 42 | 
            +
                    break;
         | 
| 46 43 | 
             
                }
         | 
| 47 44 | 
             
                case FILE_IO:
         | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
                default:
         | 
| 53 | 
            -
            	rb_raise(rb_eArgError, "expected an IO Object.");
         | 
| 45 | 
            +
                    if (size != write(sw->fd, sw->sw.out.buf, size)) {
         | 
| 46 | 
            +
                        rb_raise(rb_eIOError, "Write failed. [_%d_:%s]\n", errno, strerror(errno));
         | 
| 47 | 
            +
                    }
         | 
| 48 | 
            +
                    break;
         | 
| 49 | 
            +
                default: rb_raise(rb_eArgError, "expected an IO Object.");
         | 
| 54 50 | 
             
                }
         | 
| 55 51 | 
             
                stream_writer_reset_buf(sw);
         | 
| 56 52 | 
             
            }
         | 
| 57 53 |  | 
| 58 | 
            -
            static VALUE | 
| 54 | 
            +
            static VALUE buffer_size_sym = Qundef;
         | 
| 59 55 |  | 
| 60 56 | 
             
            /* Document-method: new
         | 
| 61 57 | 
             
             * call-seq: new(io, options)
         | 
| @@ -73,62 +69,60 @@ static VALUE	buffer_size_sym = Qundef; | |
| 73 69 | 
             
             * - *io* [_IO_] stream to write to
         | 
| 74 70 | 
             
             * - *options* [_Hash_] formating options
         | 
| 75 71 | 
             
             */
         | 
| 76 | 
            -
            static VALUE
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                 | 
| 79 | 
            -
                 | 
| 80 | 
            -
                VALUE | 
| 81 | 
            -
                 | 
| 82 | 
            -
                StreamWriter	sw;
         | 
| 72 | 
            +
            static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
         | 
| 73 | 
            +
                StreamWriterType type   = STREAM_IO;
         | 
| 74 | 
            +
                int              fd     = 0;
         | 
| 75 | 
            +
                VALUE            stream = argv[0];
         | 
| 76 | 
            +
                VALUE            clas   = rb_obj_class(stream);
         | 
| 77 | 
            +
                StreamWriter     sw;
         | 
| 83 78 | 
             
            #if !IS_WINDOWS
         | 
| 84 | 
            -
                VALUE | 
| 79 | 
            +
                VALUE s;
         | 
| 85 80 | 
             
            #endif
         | 
| 86 81 |  | 
| 87 82 | 
             
                if (oj_stringio_class == clas) {
         | 
| 88 | 
            -
             | 
| 83 | 
            +
                    type = STRING_IO;
         | 
| 89 84 | 
             
            #if !IS_WINDOWS
         | 
| 90 85 | 
             
                } else if (rb_respond_to(stream, oj_fileno_id) &&
         | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
            	type = FILE_IO;
         | 
| 86 | 
            +
                           Qnil != (s = rb_funcall(stream, oj_fileno_id, 0)) && 0 != (fd = FIX2INT(s))) {
         | 
| 87 | 
            +
                    type = FILE_IO;
         | 
| 94 88 | 
             
            #endif
         | 
| 95 89 | 
             
                } else if (rb_respond_to(stream, oj_write_id)) {
         | 
| 96 | 
            -
             | 
| 90 | 
            +
                    type = STREAM_IO;
         | 
| 97 91 | 
             
                } else {
         | 
| 98 | 
            -
             | 
| 92 | 
            +
                    rb_raise(rb_eArgError, "expected an IO Object.");
         | 
| 99 93 | 
             
                }
         | 
| 100 94 | 
             
                sw = ALLOC(struct _streamWriter);
         | 
| 101 95 | 
             
                if (2 == argc && T_HASH == rb_type(argv[1])) {
         | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 96 | 
            +
                    volatile VALUE v;
         | 
| 97 | 
            +
                    int            buf_size = 0;
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    if (Qundef == buffer_size_sym) {
         | 
| 100 | 
            +
                        buffer_size_sym = ID2SYM(rb_intern("buffer_size"));
         | 
| 101 | 
            +
                        rb_gc_register_address(&buffer_size_sym);
         | 
| 102 | 
            +
                    }
         | 
| 103 | 
            +
                    if (Qnil != (v = rb_hash_lookup(argv[1], buffer_size_sym))) {
         | 
| 110 104 | 
             
            #ifdef RUBY_INTEGER_UNIFICATION
         | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 105 | 
            +
                        if (rb_cInteger != rb_obj_class(v)) {
         | 
| 106 | 
            +
                            rb_raise(rb_eArgError, ":buffer size must be a Integer.");
         | 
| 107 | 
            +
                        }
         | 
| 114 108 | 
             
            #else
         | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 109 | 
            +
                        if (T_FIXNUM != rb_type(v)) {
         | 
| 110 | 
            +
                            rb_raise(rb_eArgError, ":buffer size must be a Integer.");
         | 
| 111 | 
            +
                        }
         | 
| 118 112 | 
             
            #endif
         | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 113 | 
            +
                        buf_size = FIX2INT(v);
         | 
| 114 | 
            +
                    }
         | 
| 115 | 
            +
                    oj_str_writer_init(&sw->sw, buf_size);
         | 
| 116 | 
            +
                    oj_parse_options(argv[1], &sw->sw.opts);
         | 
| 117 | 
            +
                    sw->flush_limit = buf_size;
         | 
| 124 118 | 
             
                } else {
         | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 119 | 
            +
                    oj_str_writer_init(&sw->sw, 4096);
         | 
| 120 | 
            +
                    sw->flush_limit = 0;
         | 
| 127 121 | 
             
                }
         | 
| 128 122 | 
             
                sw->sw.out.indent = sw->sw.opts.indent;
         | 
| 129 | 
            -
                sw->stream | 
| 130 | 
            -
                sw->type | 
| 131 | 
            -
                sw->fd | 
| 123 | 
            +
                sw->stream        = stream;
         | 
| 124 | 
            +
                sw->type          = type;
         | 
| 125 | 
            +
                sw->fd            = fd;
         | 
| 132 126 |  | 
| 133 127 | 
             
                return Data_Wrap_Struct(oj_stream_writer_class, 0, stream_writer_free, sw);
         | 
| 134 128 | 
             
            }
         | 
| @@ -142,14 +136,13 @@ stream_writer_new(int argc, VALUE *argv, VALUE self) { | |
| 142 136 | 
             
             *
         | 
| 143 137 | 
             
             * - *key* [_String_] the key pending for the next push
         | 
| 144 138 | 
             
             */
         | 
| 145 | 
            -
            static VALUE
         | 
| 146 | 
            -
             | 
| 147 | 
            -
                StreamWriter	sw = (StreamWriter)DATA_PTR(self);
         | 
| 139 | 
            +
            static VALUE stream_writer_push_key(VALUE self, VALUE key) {
         | 
| 140 | 
            +
                StreamWriter sw = (StreamWriter)DATA_PTR(self);
         | 
| 148 141 |  | 
| 149 142 | 
             
                rb_check_type(key, T_STRING);
         | 
| 150 143 | 
             
                oj_str_writer_push_key(&sw->sw, StringValuePtr(key));
         | 
| 151 144 | 
             
                if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
         | 
| 152 | 
            -
             | 
| 145 | 
            +
                    stream_writer_write(sw);
         | 
| 153 146 | 
             
                }
         | 
| 154 147 | 
             
                return Qnil;
         | 
| 155 148 | 
             
            }
         | 
| @@ -162,28 +155,23 @@ stream_writer_push_key(VALUE self, VALUE key) { | |
| 162 155 | 
             
             *
         | 
| 163 156 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 164 157 | 
             
             */
         | 
| 165 | 
            -
            static VALUE
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                StreamWriter	sw = (StreamWriter)DATA_PTR(self);
         | 
| 158 | 
            +
            static VALUE stream_writer_push_object(int argc, VALUE *argv, VALUE self) {
         | 
| 159 | 
            +
                StreamWriter sw = (StreamWriter)DATA_PTR(self);
         | 
| 168 160 |  | 
| 169 161 | 
             
                switch (argc) {
         | 
| 170 | 
            -
                case 0:
         | 
| 171 | 
            -
            	oj_str_writer_push_object(&sw->sw, 0);
         | 
| 172 | 
            -
            	break;
         | 
| 162 | 
            +
                case 0: oj_str_writer_push_object(&sw->sw, 0); break;
         | 
| 173 163 | 
             
                case 1:
         | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 176 | 
            -
             | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 181 | 
            -
                default:
         | 
| 182 | 
            -
            	rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
         | 
| 183 | 
            -
            	break;
         | 
| 164 | 
            +
                    if (Qnil == argv[0]) {
         | 
| 165 | 
            +
                        oj_str_writer_push_object(&sw->sw, 0);
         | 
| 166 | 
            +
                    } else {
         | 
| 167 | 
            +
                        rb_check_type(argv[0], T_STRING);
         | 
| 168 | 
            +
                        oj_str_writer_push_object(&sw->sw, StringValuePtr(argv[0]));
         | 
| 169 | 
            +
                    }
         | 
| 170 | 
            +
                    break;
         | 
| 171 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'."); break;
         | 
| 184 172 | 
             
                }
         | 
| 185 173 | 
             
                if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
         | 
| 186 | 
            -
             | 
| 174 | 
            +
                    stream_writer_write(sw);
         | 
| 187 175 | 
             
                }
         | 
| 188 176 | 
             
                return Qnil;
         | 
| 189 177 | 
             
            }
         | 
| @@ -196,28 +184,23 @@ stream_writer_push_object(int argc, VALUE *argv, VALUE self) { | |
| 196 184 | 
             
             *
         | 
| 197 185 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 198 186 | 
             
             */
         | 
| 199 | 
            -
            static VALUE
         | 
| 200 | 
            -
             | 
| 201 | 
            -
                StreamWriter	sw = (StreamWriter)DATA_PTR(self);
         | 
| 187 | 
            +
            static VALUE stream_writer_push_array(int argc, VALUE *argv, VALUE self) {
         | 
| 188 | 
            +
                StreamWriter sw = (StreamWriter)DATA_PTR(self);
         | 
| 202 189 |  | 
| 203 190 | 
             
                switch (argc) {
         | 
| 204 | 
            -
                case 0:
         | 
| 205 | 
            -
            	oj_str_writer_push_array(&sw->sw, 0);
         | 
| 206 | 
            -
            	break;
         | 
| 191 | 
            +
                case 0: oj_str_writer_push_array(&sw->sw, 0); break;
         | 
| 207 192 | 
             
                case 1:
         | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
| 215 | 
            -
                default:
         | 
| 216 | 
            -
            	rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
         | 
| 217 | 
            -
            	break;
         | 
| 193 | 
            +
                    if (Qnil == argv[0]) {
         | 
| 194 | 
            +
                        oj_str_writer_push_array(&sw->sw, 0);
         | 
| 195 | 
            +
                    } else {
         | 
| 196 | 
            +
                        rb_check_type(argv[0], T_STRING);
         | 
| 197 | 
            +
                        oj_str_writer_push_array(&sw->sw, StringValuePtr(argv[0]));
         | 
| 198 | 
            +
                    }
         | 
| 199 | 
            +
                    break;
         | 
| 200 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'."); break;
         | 
| 218 201 | 
             
                }
         | 
| 219 202 | 
             
                if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
         | 
| 220 | 
            -
             | 
| 203 | 
            +
                    stream_writer_write(sw);
         | 
| 221 204 | 
             
                }
         | 
| 222 205 | 
             
                return Qnil;
         | 
| 223 206 | 
             
            }
         | 
| @@ -229,28 +212,23 @@ stream_writer_push_array(int argc, VALUE *argv, VALUE self) { | |
| 229 212 | 
             
             * - *value* [_Object_] value to add to the JSON document
         | 
| 230 213 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 231 214 | 
             
             */
         | 
| 232 | 
            -
            static VALUE
         | 
| 233 | 
            -
             | 
| 234 | 
            -
                StreamWriter	sw = (StreamWriter)DATA_PTR(self);
         | 
| 215 | 
            +
            static VALUE stream_writer_push_value(int argc, VALUE *argv, VALUE self) {
         | 
| 216 | 
            +
                StreamWriter sw = (StreamWriter)DATA_PTR(self);
         | 
| 235 217 |  | 
| 236 218 | 
             
                switch (argc) {
         | 
| 237 | 
            -
                case 1:
         | 
| 238 | 
            -
            	oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
         | 
| 239 | 
            -
            	break;
         | 
| 219 | 
            +
                case 1: oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); break;
         | 
| 240 220 | 
             
                case 2:
         | 
| 241 | 
            -
             | 
| 242 | 
            -
             | 
| 243 | 
            -
             | 
| 244 | 
            -
             | 
| 245 | 
            -
             | 
| 246 | 
            -
             | 
| 247 | 
            -
             | 
| 248 | 
            -
                default:
         | 
| 249 | 
            -
            	rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'.");
         | 
| 250 | 
            -
            	break;
         | 
| 221 | 
            +
                    if (Qnil == argv[1]) {
         | 
| 222 | 
            +
                        oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
         | 
| 223 | 
            +
                    } else {
         | 
| 224 | 
            +
                        rb_check_type(argv[1], T_STRING);
         | 
| 225 | 
            +
                        oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
         | 
| 226 | 
            +
                    }
         | 
| 227 | 
            +
                    break;
         | 
| 228 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'."); break;
         | 
| 251 229 | 
             
                }
         | 
| 252 230 | 
             
                if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
         | 
| 253 | 
            -
             | 
| 231 | 
            +
                    stream_writer_write(sw);
         | 
| 254 232 | 
             
                }
         | 
| 255 233 | 
             
                return Qnil;
         | 
| 256 234 | 
             
            }
         | 
| @@ -264,29 +242,26 @@ stream_writer_push_value(int argc, VALUE *argv, VALUE self) { | |
| 264 242 | 
             
             * - *value* [_Object_] value to add to the JSON document
         | 
| 265 243 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 266 244 | 
             
             */
         | 
| 267 | 
            -
            static VALUE
         | 
| 268 | 
            -
             | 
| 269 | 
            -
                StreamWriter	sw = (StreamWriter)DATA_PTR(self);
         | 
| 245 | 
            +
            static VALUE stream_writer_push_json(int argc, VALUE *argv, VALUE self) {
         | 
| 246 | 
            +
                StreamWriter sw = (StreamWriter)DATA_PTR(self);
         | 
| 270 247 |  | 
| 271 248 | 
             
                rb_check_type(argv[0], T_STRING);
         | 
| 272 249 | 
             
                switch (argc) {
         | 
| 273 | 
            -
                case 1:
         | 
| 274 | 
            -
            	oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
         | 
| 275 | 
            -
            	break;
         | 
| 250 | 
            +
                case 1: oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); break;
         | 
| 276 251 | 
             
                case 2:
         | 
| 277 | 
            -
             | 
| 278 | 
            -
             | 
| 279 | 
            -
             | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 252 | 
            +
                    if (Qnil == argv[1]) {
         | 
| 253 | 
            +
                        oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
         | 
| 254 | 
            +
                    } else {
         | 
| 255 | 
            +
                        rb_check_type(argv[1], T_STRING);
         | 
| 256 | 
            +
                        oj_str_writer_push_json((StrWriter)DATA_PTR(self),
         | 
| 257 | 
            +
                                                StringValuePtr(*argv),
         | 
| 258 | 
            +
                                                StringValuePtr(argv[1]));
         | 
| 259 | 
            +
                    }
         | 
| 260 | 
            +
                    break;
         | 
| 261 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
         | 
| 287 262 | 
             
                }
         | 
| 288 263 | 
             
                if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
         | 
| 289 | 
            -
             | 
| 264 | 
            +
                    stream_writer_write(sw);
         | 
| 290 265 | 
             
                }
         | 
| 291 266 | 
             
                return Qnil;
         | 
| 292 267 | 
             
            }
         | 
| @@ -297,13 +272,12 @@ stream_writer_push_json(int argc, VALUE *argv, VALUE self) { | |
| 297 272 | 
             
             * Pops up a level in the JSON document closing the array or object that is
         | 
| 298 273 | 
             
             * currently open.
         | 
| 299 274 | 
             
             */
         | 
| 300 | 
            -
            static VALUE
         | 
| 301 | 
            -
             | 
| 302 | 
            -
                StreamWriter	sw = (StreamWriter)DATA_PTR(self);
         | 
| 275 | 
            +
            static VALUE stream_writer_pop(VALUE self) {
         | 
| 276 | 
            +
                StreamWriter sw = (StreamWriter)DATA_PTR(self);
         | 
| 303 277 |  | 
| 304 278 | 
             
                oj_str_writer_pop(&sw->sw);
         | 
| 305 279 | 
             
                if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
         | 
| 306 | 
            -
             | 
| 280 | 
            +
                    stream_writer_write(sw);
         | 
| 307 281 | 
             
                }
         | 
| 308 282 | 
             
                return Qnil;
         | 
| 309 283 | 
             
            }
         | 
| @@ -314,9 +288,8 @@ stream_writer_pop(VALUE self) { | |
| 314 288 | 
             
             * Pops all level in the JSON document closing all the array or object that is
         | 
| 315 289 | 
             
             * currently open.
         | 
| 316 290 | 
             
             */
         | 
| 317 | 
            -
            static VALUE
         | 
| 318 | 
            -
             | 
| 319 | 
            -
                StreamWriter	sw = (StreamWriter)DATA_PTR(self);
         | 
| 291 | 
            +
            static VALUE stream_writer_pop_all(VALUE self) {
         | 
| 292 | 
            +
                StreamWriter sw = (StreamWriter)DATA_PTR(self);
         | 
| 320 293 |  | 
| 321 294 | 
             
                oj_str_writer_pop_all(&sw->sw);
         | 
| 322 295 | 
             
                stream_writer_write(sw);
         | 
| @@ -329,8 +302,7 @@ stream_writer_pop_all(VALUE self) { | |
| 329 302 | 
             
             *
         | 
| 330 303 | 
             
             * Flush any remaining characters in the buffer.
         | 
| 331 304 | 
             
             */
         | 
| 332 | 
            -
            static VALUE
         | 
| 333 | 
            -
            stream_writer_flush(VALUE self) {
         | 
| 305 | 
            +
            static VALUE stream_writer_flush(VALUE self) {
         | 
| 334 306 | 
             
                stream_writer_write((StreamWriter)DATA_PTR(self));
         | 
| 335 307 |  | 
| 336 308 | 
             
                return Qnil;
         | 
| @@ -343,8 +315,7 @@ stream_writer_flush(VALUE self) { | |
| 343 315 | 
             
             * will create that element in the JSON document and subsequent pushes will add
         | 
| 344 316 | 
             
             * the elements to that array or object until a pop() is called.
         | 
| 345 317 | 
             
             */
         | 
| 346 | 
            -
            void
         | 
| 347 | 
            -
            oj_stream_writer_init() {
         | 
| 318 | 
            +
            void oj_stream_writer_init() {
         | 
| 348 319 | 
             
                oj_stream_writer_class = rb_define_class_under(Oj, "StreamWriter", rb_cObject);
         | 
| 349 320 | 
             
                rb_define_module_function(oj_stream_writer_class, "new", stream_writer_new, -1);
         | 
| 350 321 | 
             
                rb_define_method(oj_stream_writer_class, "push_key", stream_writer_push_key, 1);
         | 
    
        data/ext/oj/strict.c
    CHANGED
    
    | @@ -1,207 +1,192 @@ | |
| 1 1 | 
             
            // Copyright (c) 2012 Peter Ohler. All rights reserved.
         | 
| 2 | 
            +
            // Licensed under the MIT License. See LICENSE file in the project root for license details.
         | 
| 2 3 |  | 
| 3 | 
            -
            #include <stdlib.h>
         | 
| 4 4 | 
             
            #include <stdio.h>
         | 
| 5 | 
            +
            #include <stdlib.h>
         | 
| 5 6 | 
             
            #include <string.h>
         | 
| 6 7 | 
             
            #include <unistd.h>
         | 
| 7 8 |  | 
| 8 | 
            -
            #include " | 
| 9 | 
            +
            #include "encode.h"
         | 
| 9 10 | 
             
            #include "err.h"
         | 
| 11 | 
            +
            #include "oj.h"
         | 
| 10 12 | 
             
            #include "parse.h"
         | 
| 11 | 
            -
            #include "encode.h"
         | 
| 12 13 | 
             
            #include "trace.h"
         | 
| 13 14 |  | 
| 14 | 
            -
            static void
         | 
| 15 | 
            -
            hash_end(ParseInfo pi) {
         | 
| 15 | 
            +
            static void hash_end(ParseInfo pi) {
         | 
| 16 16 | 
             
                if (Yes == pi->options.trace) {
         | 
| 17 | 
            -
             | 
| 17 | 
            +
                    oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
         | 
| 18 18 | 
             
                }
         | 
| 19 19 | 
             
            }
         | 
| 20 20 |  | 
| 21 | 
            -
            static void
         | 
| 22 | 
            -
            array_end(ParseInfo pi) {
         | 
| 21 | 
            +
            static void array_end(ParseInfo pi) {
         | 
| 23 22 | 
             
                if (Yes == pi->options.trace) {
         | 
| 24 | 
            -
             | 
| 23 | 
            +
                    oj_trace_parse_array_end(pi, __FILE__, __LINE__);
         | 
| 25 24 | 
             
                }
         | 
| 26 25 | 
             
            }
         | 
| 27 26 |  | 
| 28 | 
            -
            static VALUE
         | 
| 29 | 
            -
            noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
         | 
| 27 | 
            +
            static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
         | 
| 30 28 | 
             
                return Qundef;
         | 
| 31 29 | 
             
            }
         | 
| 32 30 |  | 
| 33 | 
            -
            static void
         | 
| 34 | 
            -
            add_value(ParseInfo pi, VALUE val) {
         | 
| 31 | 
            +
            static void add_value(ParseInfo pi, VALUE val) {
         | 
| 35 32 | 
             
                if (Yes == pi->options.trace) {
         | 
| 36 | 
            -
             | 
| 33 | 
            +
                    oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
         | 
| 37 34 | 
             
                }
         | 
| 38 35 | 
             
                pi->stack.head->val = val;
         | 
| 39 36 | 
             
            }
         | 
| 40 37 |  | 
| 41 | 
            -
            static void
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                volatile VALUE	rstr = rb_str_new(str, len);
         | 
| 38 | 
            +
            static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
         | 
| 39 | 
            +
                volatile VALUE rstr = rb_str_new(str, len);
         | 
| 44 40 |  | 
| 45 | 
            -
                rstr | 
| 41 | 
            +
                rstr                = oj_encode(rstr);
         | 
| 46 42 | 
             
                pi->stack.head->val = rstr;
         | 
| 47 43 | 
             
                if (Yes == pi->options.trace) {
         | 
| 48 | 
            -
             | 
| 44 | 
            +
                    oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
         | 
| 49 45 | 
             
                }
         | 
| 50 46 | 
             
            }
         | 
| 51 47 |  | 
| 52 | 
            -
            static void
         | 
| 53 | 
            -
            add_num(ParseInfo pi, NumInfo ni) {
         | 
| 48 | 
            +
            static void add_num(ParseInfo pi, NumInfo ni) {
         | 
| 54 49 | 
             
                if (ni->infinity || ni->nan) {
         | 
| 55 | 
            -
             | 
| 50 | 
            +
                    oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
         | 
| 56 51 | 
             
                }
         | 
| 57 52 | 
             
                pi->stack.head->val = oj_num_as_value(ni);
         | 
| 58 53 | 
             
                if (Yes == pi->options.trace) {
         | 
| 59 | 
            -
             | 
| 54 | 
            +
                    oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
         | 
| 60 55 | 
             
                }
         | 
| 61 56 | 
             
            }
         | 
| 62 57 |  | 
| 63 | 
            -
            static VALUE
         | 
| 64 | 
            -
            start_hash(ParseInfo pi) {
         | 
| 58 | 
            +
            static VALUE start_hash(ParseInfo pi) {
         | 
| 65 59 | 
             
                if (Qnil != pi->options.hash_class) {
         | 
| 66 | 
            -
             | 
| 60 | 
            +
                    return rb_class_new_instance(0, NULL, pi->options.hash_class);
         | 
| 67 61 | 
             
                }
         | 
| 68 62 | 
             
                if (Yes == pi->options.trace) {
         | 
| 69 | 
            -
             | 
| 63 | 
            +
                    oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
         | 
| 70 64 | 
             
                }
         | 
| 71 65 | 
             
                return rb_hash_new();
         | 
| 72 66 | 
             
            }
         | 
| 73 67 |  | 
| 74 | 
            -
            static VALUE
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                volatile VALUE	rkey = parent->key_val;
         | 
| 68 | 
            +
            static VALUE calc_hash_key(ParseInfo pi, Val parent) {
         | 
| 69 | 
            +
                volatile VALUE rkey = parent->key_val;
         | 
| 77 70 |  | 
| 78 71 | 
             
                if (Qundef == rkey) {
         | 
| 79 | 
            -
             | 
| 72 | 
            +
                    rkey = rb_str_new(parent->key, parent->klen);
         | 
| 80 73 | 
             
                }
         | 
| 81 74 | 
             
                rkey = oj_encode(rkey);
         | 
| 82 75 | 
             
                if (Yes == pi->options.sym_key) {
         | 
| 83 | 
            -
             | 
| 76 | 
            +
                    rkey = rb_str_intern(rkey);
         | 
| 84 77 | 
             
                }
         | 
| 85 78 | 
             
                return rkey;
         | 
| 86 79 | 
             
            }
         | 
| 87 80 |  | 
| 88 | 
            -
            static void
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                volatile VALUE	rstr = rb_str_new(str, len);
         | 
| 81 | 
            +
            static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
         | 
| 82 | 
            +
                volatile VALUE rstr = rb_str_new(str, len);
         | 
| 91 83 |  | 
| 92 84 | 
             
                rstr = oj_encode(rstr);
         | 
| 93 85 | 
             
                rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rstr);
         | 
| 94 86 | 
             
                if (Yes == pi->options.trace) {
         | 
| 95 | 
            -
             | 
| 87 | 
            +
                    oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
         | 
| 96 88 | 
             
                }
         | 
| 97 89 | 
             
            }
         | 
| 98 90 |  | 
| 99 | 
            -
            static void
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                volatile VALUE	v;
         | 
| 91 | 
            +
            static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
         | 
| 92 | 
            +
                volatile VALUE v;
         | 
| 102 93 |  | 
| 103 94 | 
             
                if (ni->infinity || ni->nan) {
         | 
| 104 | 
            -
             | 
| 95 | 
            +
                    oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
         | 
| 105 96 | 
             
                }
         | 
| 106 97 | 
             
                v = oj_num_as_value(ni);
         | 
| 107 98 | 
             
                rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), v);
         | 
| 108 99 | 
             
                if (Yes == pi->options.trace) {
         | 
| 109 | 
            -
             | 
| 100 | 
            +
                    oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, v);
         | 
| 110 101 | 
             
                }
         | 
| 111 102 | 
             
            }
         | 
| 112 103 |  | 
| 113 | 
            -
            static void
         | 
| 114 | 
            -
            hash_set_value(ParseInfo pi, Val parent, VALUE value) {
         | 
| 104 | 
            +
            static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
         | 
| 115 105 | 
             
                rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
         | 
| 116 106 | 
             
                if (Yes == pi->options.trace) {
         | 
| 117 | 
            -
             | 
| 107 | 
            +
                    oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
         | 
| 118 108 | 
             
                }
         | 
| 119 109 | 
             
            }
         | 
| 120 110 |  | 
| 121 | 
            -
            static VALUE
         | 
| 122 | 
            -
            start_array(ParseInfo pi) {
         | 
| 111 | 
            +
            static VALUE start_array(ParseInfo pi) {
         | 
| 123 112 | 
             
                if (Yes == pi->options.trace) {
         | 
| 124 | 
            -
             | 
| 113 | 
            +
                    oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
         | 
| 125 114 | 
             
                }
         | 
| 126 115 | 
             
                return rb_ary_new();
         | 
| 127 116 | 
             
            }
         | 
| 128 117 |  | 
| 129 | 
            -
            static void
         | 
| 130 | 
            -
             | 
| 131 | 
            -
                volatile VALUE	rstr = rb_str_new(str, len);
         | 
| 118 | 
            +
            static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
         | 
| 119 | 
            +
                volatile VALUE rstr = rb_str_new(str, len);
         | 
| 132 120 |  | 
| 133 121 | 
             
                rstr = oj_encode(rstr);
         | 
| 134 122 | 
             
                rb_ary_push(stack_peek(&pi->stack)->val, rstr);
         | 
| 135 123 | 
             
                if (Yes == pi->options.trace) {
         | 
| 136 | 
            -
             | 
| 124 | 
            +
                    oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
         | 
| 137 125 | 
             
                }
         | 
| 138 126 | 
             
            }
         | 
| 139 127 |  | 
| 140 | 
            -
            static void
         | 
| 141 | 
            -
             | 
| 142 | 
            -
                volatile VALUE	v;
         | 
| 128 | 
            +
            static void array_append_num(ParseInfo pi, NumInfo ni) {
         | 
| 129 | 
            +
                volatile VALUE v;
         | 
| 143 130 |  | 
| 144 131 | 
             
                if (ni->infinity || ni->nan) {
         | 
| 145 | 
            -
             | 
| 132 | 
            +
                    oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
         | 
| 146 133 | 
             
                }
         | 
| 147 134 | 
             
                v = oj_num_as_value(ni);
         | 
| 148 135 | 
             
                rb_ary_push(stack_peek(&pi->stack)->val, v);
         | 
| 149 136 | 
             
                if (Yes == pi->options.trace) {
         | 
| 150 | 
            -
             | 
| 137 | 
            +
                    oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, v);
         | 
| 151 138 | 
             
                }
         | 
| 152 139 | 
             
            }
         | 
| 153 140 |  | 
| 154 | 
            -
            static void
         | 
| 155 | 
            -
            array_append_value(ParseInfo pi, VALUE value) {
         | 
| 141 | 
            +
            static void array_append_value(ParseInfo pi, VALUE value) {
         | 
| 156 142 | 
             
                rb_ary_push(stack_peek(&pi->stack)->val, value);
         | 
| 157 143 | 
             
                if (Yes == pi->options.trace) {
         | 
| 158 | 
            -
             | 
| 159 | 
            -
                }
         | 
| 160 | 
            -
            }
         | 
| 161 | 
            -
             | 
| 162 | 
            -
            void
         | 
| 163 | 
            -
             | 
| 164 | 
            -
                pi-> | 
| 165 | 
            -
                pi-> | 
| 166 | 
            -
                pi-> | 
| 167 | 
            -
                pi-> | 
| 168 | 
            -
                pi-> | 
| 169 | 
            -
                pi-> | 
| 170 | 
            -
                pi-> | 
| 171 | 
            -
                pi-> | 
| 172 | 
            -
                pi-> | 
| 173 | 
            -
                pi->array_append_num = array_append_num;
         | 
| 144 | 
            +
                    oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
         | 
| 145 | 
            +
                }
         | 
| 146 | 
            +
            }
         | 
| 147 | 
            +
             | 
| 148 | 
            +
            void oj_set_strict_callbacks(ParseInfo pi) {
         | 
| 149 | 
            +
                pi->start_hash         = start_hash;
         | 
| 150 | 
            +
                pi->end_hash           = hash_end;
         | 
| 151 | 
            +
                pi->hash_key           = noop_hash_key;
         | 
| 152 | 
            +
                pi->hash_set_cstr      = hash_set_cstr;
         | 
| 153 | 
            +
                pi->hash_set_num       = hash_set_num;
         | 
| 154 | 
            +
                pi->hash_set_value     = hash_set_value;
         | 
| 155 | 
            +
                pi->start_array        = start_array;
         | 
| 156 | 
            +
                pi->end_array          = array_end;
         | 
| 157 | 
            +
                pi->array_append_cstr  = array_append_cstr;
         | 
| 158 | 
            +
                pi->array_append_num   = array_append_num;
         | 
| 174 159 | 
             
                pi->array_append_value = array_append_value;
         | 
| 175 | 
            -
                pi->add_cstr | 
| 176 | 
            -
                pi->add_num | 
| 177 | 
            -
                pi->add_value | 
| 178 | 
            -
                pi->expect_value | 
| 160 | 
            +
                pi->add_cstr           = add_cstr;
         | 
| 161 | 
            +
                pi->add_num            = add_num;
         | 
| 162 | 
            +
                pi->add_value          = add_value;
         | 
| 163 | 
            +
                pi->expect_value       = 1;
         | 
| 179 164 | 
             
            }
         | 
| 180 165 |  | 
| 181 166 | 
             
            VALUE
         | 
| 182 167 | 
             
            oj_strict_parse(int argc, VALUE *argv, VALUE self) {
         | 
| 183 | 
            -
                struct _parseInfo | 
| 168 | 
            +
                struct _parseInfo pi;
         | 
| 184 169 |  | 
| 185 170 | 
             
                parse_info_init(&pi);
         | 
| 186 | 
            -
                pi.options | 
| 187 | 
            -
                pi.handler | 
| 171 | 
            +
                pi.options   = oj_default_options;
         | 
| 172 | 
            +
                pi.handler   = Qnil;
         | 
| 188 173 | 
             
                pi.err_class = Qnil;
         | 
| 189 174 | 
             
                oj_set_strict_callbacks(&pi);
         | 
| 190 175 |  | 
| 191 176 | 
             
                if (T_STRING == rb_type(*argv)) {
         | 
| 192 | 
            -
             | 
| 177 | 
            +
                    return oj_pi_parse(argc, argv, &pi, 0, 0, true);
         | 
| 193 178 | 
             
                } else {
         | 
| 194 | 
            -
             | 
| 179 | 
            +
                    return oj_pi_sparse(argc, argv, &pi, 0);
         | 
| 195 180 | 
             
                }
         | 
| 196 181 | 
             
            }
         | 
| 197 182 |  | 
| 198 183 | 
             
            VALUE
         | 
| 199 184 | 
             
            oj_strict_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
         | 
| 200 | 
            -
                struct _parseInfo | 
| 185 | 
            +
                struct _parseInfo pi;
         | 
| 201 186 |  | 
| 202 187 | 
             
                parse_info_init(&pi);
         | 
| 203 | 
            -
                pi.options | 
| 204 | 
            -
                pi.handler | 
| 188 | 
            +
                pi.options   = oj_default_options;
         | 
| 189 | 
            +
                pi.handler   = Qnil;
         | 
| 205 190 | 
             
                pi.err_class = Qnil;
         | 
| 206 191 | 
             
                oj_set_strict_callbacks(&pi);
         | 
| 207 192 |  |