oj 3.11.3 → 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 +1 -0
- 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 +405 -401
- 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 +1121 -921
- data/ext/oj/oj.h +286 -298
- data/ext/oj/parse.c +938 -930
- 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 +770 -730
- 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/mimic.rb +0 -12
- data/lib/oj/version.rb +1 -1
- data/test/activerecord/result_test.rb +7 -2
- data/test/foo.rb +35 -32
- data/test/test_scp.rb +1 -1
- metadata +2 -2
    
        data/ext/oj/string_writer.c
    CHANGED
    
    | @@ -1,251 +1,232 @@ | |
| 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 "dump.h"
         | 
| 4 5 | 
             
            #include "encode.h"
         | 
| 5 6 |  | 
| 6 | 
            -
            extern VALUE | 
| 7 | 
            +
            extern VALUE Oj;
         | 
| 7 8 |  | 
| 8 | 
            -
            bool | 
| 9 | 
            +
            bool string_writer_optimized = false;
         | 
| 9 10 |  | 
| 10 | 
            -
            static void
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                DumpType	type = sw->types[sw->depth];
         | 
| 11 | 
            +
            static void key_check(StrWriter sw, const char *key) {
         | 
| 12 | 
            +
                DumpType type = sw->types[sw->depth];
         | 
| 13 13 |  | 
| 14 14 | 
             
                if (0 == key && (ObjectNew == type || ObjectType == type)) {
         | 
| 15 | 
            -
             | 
| 15 | 
            +
                    rb_raise(rb_eStandardError, "Can not push onto an Object without a key.");
         | 
| 16 16 | 
             
                }
         | 
| 17 17 | 
             
            }
         | 
| 18 18 |  | 
| 19 | 
            -
            static void
         | 
| 20 | 
            -
            push_type(StrWriter sw, DumpType type) {
         | 
| 19 | 
            +
            static void push_type(StrWriter sw, DumpType type) {
         | 
| 21 20 | 
             
                if (sw->types_end <= sw->types + sw->depth + 1) {
         | 
| 22 | 
            -
             | 
| 21 | 
            +
                    size_t size = (sw->types_end - sw->types) * 2;
         | 
| 23 22 |  | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 23 | 
            +
                    REALLOC_N(sw->types, char, size);
         | 
| 24 | 
            +
                    sw->types_end = sw->types + size;
         | 
| 26 25 | 
             
                }
         | 
| 27 26 | 
             
                sw->depth++;
         | 
| 28 27 | 
             
                sw->types[sw->depth] = type;
         | 
| 29 28 | 
             
            }
         | 
| 30 29 |  | 
| 31 | 
            -
            static void
         | 
| 32 | 
            -
            maybe_comma(StrWriter sw) {
         | 
| 30 | 
            +
            static void maybe_comma(StrWriter sw) {
         | 
| 33 31 | 
             
                switch (sw->types[sw->depth]) {
         | 
| 34 | 
            -
                case ObjectNew:
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            	break;
         | 
| 37 | 
            -
                case ArrayNew:
         | 
| 38 | 
            -
            	sw->types[sw->depth] = ArrayType;
         | 
| 39 | 
            -
            	break;
         | 
| 32 | 
            +
                case ObjectNew: sw->types[sw->depth] = ObjectType; break;
         | 
| 33 | 
            +
                case ArrayNew: sw->types[sw->depth] = ArrayType; break;
         | 
| 40 34 | 
             
                case ObjectType:
         | 
| 41 35 | 
             
                case ArrayType:
         | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 36 | 
            +
                    // Always have a few characters available in the out.buf.
         | 
| 37 | 
            +
                    *sw->out.cur++ = ',';
         | 
| 38 | 
            +
                    break;
         | 
| 45 39 | 
             
                }
         | 
| 46 40 | 
             
            }
         | 
| 47 41 |  | 
| 48 42 | 
             
            // Used by stream writer also.
         | 
| 49 | 
            -
            void
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                sw-> | 
| 52 | 
            -
                sw-> | 
| 53 | 
            -
                sw->types  | 
| 54 | 
            -
                sw-> | 
| 55 | 
            -
                *sw->types = '\0';
         | 
| 43 | 
            +
            void oj_str_writer_init(StrWriter sw, int buf_size) {
         | 
| 44 | 
            +
                sw->opts       = oj_default_options;
         | 
| 45 | 
            +
                sw->depth      = 0;
         | 
| 46 | 
            +
                sw->types      = ALLOC_N(char, 256);
         | 
| 47 | 
            +
                sw->types_end  = sw->types + 256;
         | 
| 48 | 
            +
                *sw->types     = '\0';
         | 
| 56 49 | 
             
                sw->keyWritten = 0;
         | 
| 57 50 |  | 
| 58 51 | 
             
                if (0 == buf_size) {
         | 
| 59 | 
            -
             | 
| 52 | 
            +
                    buf_size = 4096;
         | 
| 60 53 | 
             
                } else if (buf_size < 1024) {
         | 
| 61 | 
            -
             | 
| 54 | 
            +
                    buf_size = 1024;
         | 
| 62 55 | 
             
                }
         | 
| 63 | 
            -
                sw->out.buf | 
| 64 | 
            -
                sw->out.end | 
| 65 | 
            -
                sw->out.allocated | 
| 66 | 
            -
                sw->out.cur | 
| 67 | 
            -
                *sw->out.cur | 
| 56 | 
            +
                sw->out.buf        = ALLOC_N(char, buf_size);
         | 
| 57 | 
            +
                sw->out.end        = sw->out.buf + buf_size - 10;
         | 
| 58 | 
            +
                sw->out.allocated  = true;
         | 
| 59 | 
            +
                sw->out.cur        = sw->out.buf;
         | 
| 60 | 
            +
                *sw->out.cur       = '\0';
         | 
| 68 61 | 
             
                sw->out.circ_cache = NULL;
         | 
| 69 | 
            -
                sw->out.circ_cnt | 
| 70 | 
            -
                sw->out.hash_cnt | 
| 71 | 
            -
                sw->out.opts | 
| 72 | 
            -
                sw->out.indent | 
| 73 | 
            -
                sw->out.depth | 
| 74 | 
            -
                sw->out.argc | 
| 75 | 
            -
                sw->out.argv | 
| 76 | 
            -
                sw->out.caller | 
| 77 | 
            -
                sw->out.ropts | 
| 78 | 
            -
                sw->out.omit_nil | 
| 62 | 
            +
                sw->out.circ_cnt   = 0;
         | 
| 63 | 
            +
                sw->out.hash_cnt   = 0;
         | 
| 64 | 
            +
                sw->out.opts       = &sw->opts;
         | 
| 65 | 
            +
                sw->out.indent     = sw->opts.indent;
         | 
| 66 | 
            +
                sw->out.depth      = 0;
         | 
| 67 | 
            +
                sw->out.argc       = 0;
         | 
| 68 | 
            +
                sw->out.argv       = NULL;
         | 
| 69 | 
            +
                sw->out.caller     = 0;
         | 
| 70 | 
            +
                sw->out.ropts      = NULL;
         | 
| 71 | 
            +
                sw->out.omit_nil   = oj_default_options.dump_opts.omit_nil;
         | 
| 79 72 | 
             
            }
         | 
| 80 73 |  | 
| 81 | 
            -
            void
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                 | 
| 84 | 
            -
                long	size;
         | 
| 74 | 
            +
            void oj_str_writer_push_key(StrWriter sw, const char *key) {
         | 
| 75 | 
            +
                DumpType type = sw->types[sw->depth];
         | 
| 76 | 
            +
                long     size;
         | 
| 85 77 |  | 
| 86 78 | 
             
                if (sw->keyWritten) {
         | 
| 87 | 
            -
             | 
| 79 | 
            +
                    rb_raise(rb_eStandardError, "Can not push more than one key before pushing a non-key.");
         | 
| 88 80 | 
             
                }
         | 
| 89 81 | 
             
                if (ObjectNew != type && ObjectType != type) {
         | 
| 90 | 
            -
             | 
| 82 | 
            +
                    rb_raise(rb_eStandardError, "Can only push a key onto an Object.");
         | 
| 91 83 | 
             
                }
         | 
| 92 84 | 
             
                size = sw->depth * sw->out.indent + 3;
         | 
| 93 85 | 
             
                assure_size(&sw->out, size);
         | 
| 94 86 | 
             
                maybe_comma(sw);
         | 
| 95 87 | 
             
                if (0 < sw->depth) {
         | 
| 96 | 
            -
             | 
| 88 | 
            +
                    fill_indent(&sw->out, sw->depth);
         | 
| 97 89 | 
             
                }
         | 
| 98 90 | 
             
                oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
         | 
| 99 91 | 
             
                *sw->out.cur++ = ':';
         | 
| 100 92 | 
             
                sw->keyWritten = 1;
         | 
| 101 93 | 
             
            }
         | 
| 102 94 |  | 
| 103 | 
            -
            void
         | 
| 104 | 
            -
            oj_str_writer_push_object(StrWriter sw, const char *key) {
         | 
| 95 | 
            +
            void oj_str_writer_push_object(StrWriter sw, const char *key) {
         | 
| 105 96 | 
             
                if (sw->keyWritten) {
         | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 97 | 
            +
                    sw->keyWritten = 0;
         | 
| 98 | 
            +
                    assure_size(&sw->out, 1);
         | 
| 108 99 | 
             
                } else {
         | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 100 | 
            +
                    long size;
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                    key_check(sw, key);
         | 
| 103 | 
            +
                    size = sw->depth * sw->out.indent + 3;
         | 
| 104 | 
            +
                    assure_size(&sw->out, size);
         | 
| 105 | 
            +
                    maybe_comma(sw);
         | 
| 106 | 
            +
                    if (0 < sw->depth) {
         | 
| 107 | 
            +
                        fill_indent(&sw->out, sw->depth);
         | 
| 108 | 
            +
                    }
         | 
| 109 | 
            +
                    if (0 != key) {
         | 
| 110 | 
            +
                        oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
         | 
| 111 | 
            +
                        *sw->out.cur++ = ':';
         | 
| 112 | 
            +
                    }
         | 
| 122 113 | 
             
                }
         | 
| 123 114 | 
             
                *sw->out.cur++ = '{';
         | 
| 124 115 | 
             
                push_type(sw, ObjectNew);
         | 
| 125 116 | 
             
            }
         | 
| 126 117 |  | 
| 127 | 
            -
            void
         | 
| 128 | 
            -
            oj_str_writer_push_array(StrWriter sw, const char *key) {
         | 
| 118 | 
            +
            void oj_str_writer_push_array(StrWriter sw, const char *key) {
         | 
| 129 119 | 
             
                if (sw->keyWritten) {
         | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 120 | 
            +
                    sw->keyWritten = 0;
         | 
| 121 | 
            +
                    assure_size(&sw->out, 1);
         | 
| 132 122 | 
             
                } else {
         | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 123 | 
            +
                    long size;
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                    key_check(sw, key);
         | 
| 126 | 
            +
                    size = sw->depth * sw->out.indent + 3;
         | 
| 127 | 
            +
                    assure_size(&sw->out, size);
         | 
| 128 | 
            +
                    maybe_comma(sw);
         | 
| 129 | 
            +
                    if (0 < sw->depth) {
         | 
| 130 | 
            +
                        fill_indent(&sw->out, sw->depth);
         | 
| 131 | 
            +
                    }
         | 
| 132 | 
            +
                    if (0 != key) {
         | 
| 133 | 
            +
                        oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
         | 
| 134 | 
            +
                        *sw->out.cur++ = ':';
         | 
| 135 | 
            +
                    }
         | 
| 146 136 | 
             
                }
         | 
| 147 137 | 
             
                *sw->out.cur++ = '[';
         | 
| 148 138 | 
             
                push_type(sw, ArrayNew);
         | 
| 149 139 | 
             
            }
         | 
| 150 140 |  | 
| 151 | 
            -
            void
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                Out	out = &sw->out;
         | 
| 141 | 
            +
            void oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) {
         | 
| 142 | 
            +
                Out out = &sw->out;
         | 
| 154 143 |  | 
| 155 144 | 
             
                if (sw->keyWritten) {
         | 
| 156 | 
            -
             | 
| 145 | 
            +
                    sw->keyWritten = 0;
         | 
| 157 146 | 
             
                } else {
         | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
             | 
| 161 | 
            -
             | 
| 162 | 
            -
             | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 147 | 
            +
                    long size;
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                    key_check(sw, key);
         | 
| 150 | 
            +
                    size = sw->depth * out->indent + 3;
         | 
| 151 | 
            +
                    assure_size(out, size);
         | 
| 152 | 
            +
                    maybe_comma(sw);
         | 
| 153 | 
            +
                    if (0 < sw->depth) {
         | 
| 154 | 
            +
                        fill_indent(&sw->out, sw->depth);
         | 
| 155 | 
            +
                    }
         | 
| 156 | 
            +
                    if (0 != key) {
         | 
| 157 | 
            +
                        oj_dump_cstr(key, strlen(key), 0, 0, out);
         | 
| 158 | 
            +
                        *out->cur++ = ':';
         | 
| 159 | 
            +
                    }
         | 
| 171 160 | 
             
                }
         | 
| 172 161 | 
             
                switch (out->opts->mode) {
         | 
| 173 | 
            -
                case StrictMode: | 
| 174 | 
            -
                case NullMode: | 
| 175 | 
            -
                case ObjectMode: | 
| 176 | 
            -
                case CompatMode: | 
| 177 | 
            -
                case RailsMode: | 
| 178 | 
            -
                case CustomMode: | 
| 179 | 
            -
                default: | 
| 162 | 
            +
                case StrictMode: oj_dump_strict_val(val, sw->depth, out); break;
         | 
| 163 | 
            +
                case NullMode: oj_dump_null_val(val, sw->depth, out); break;
         | 
| 164 | 
            +
                case ObjectMode: oj_dump_obj_val(val, sw->depth, out); break;
         | 
| 165 | 
            +
                case CompatMode: oj_dump_compat_val(val, sw->depth, out, Yes == out->opts->to_json); break;
         | 
| 166 | 
            +
                case RailsMode: oj_dump_rails_val(val, sw->depth, out); break;
         | 
| 167 | 
            +
                case CustomMode: oj_dump_custom_val(val, sw->depth, out, true); break;
         | 
| 168 | 
            +
                default: oj_dump_custom_val(val, sw->depth, out, true); break;
         | 
| 180 169 | 
             
                }
         | 
| 181 170 | 
             
            }
         | 
| 182 171 |  | 
| 183 | 
            -
            void
         | 
| 184 | 
            -
            oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
         | 
| 172 | 
            +
            void oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
         | 
| 185 173 | 
             
                if (sw->keyWritten) {
         | 
| 186 | 
            -
             | 
| 174 | 
            +
                    sw->keyWritten = 0;
         | 
| 187 175 | 
             
                } else {
         | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 | 
            -
             | 
| 192 | 
            -
             | 
| 193 | 
            -
             | 
| 194 | 
            -
             | 
| 195 | 
            -
             | 
| 196 | 
            -
             | 
| 197 | 
            -
             | 
| 198 | 
            -
             | 
| 199 | 
            -
             | 
| 200 | 
            -
             | 
| 176 | 
            +
                    long size;
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                    key_check(sw, key);
         | 
| 179 | 
            +
                    size = sw->depth * sw->out.indent + 3;
         | 
| 180 | 
            +
                    assure_size(&sw->out, size);
         | 
| 181 | 
            +
                    maybe_comma(sw);
         | 
| 182 | 
            +
                    if (0 < sw->depth) {
         | 
| 183 | 
            +
                        fill_indent(&sw->out, sw->depth);
         | 
| 184 | 
            +
                    }
         | 
| 185 | 
            +
                    if (0 != key) {
         | 
| 186 | 
            +
                        oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
         | 
| 187 | 
            +
                        *sw->out.cur++ = ':';
         | 
| 188 | 
            +
                    }
         | 
| 201 189 | 
             
                }
         | 
| 202 190 | 
             
                oj_dump_raw(json, strlen(json), &sw->out);
         | 
| 203 191 | 
             
            }
         | 
| 204 192 |  | 
| 205 | 
            -
            void
         | 
| 206 | 
            -
             | 
| 207 | 
            -
                 | 
| 208 | 
            -
                DumpType	type = sw->types[sw->depth];
         | 
| 193 | 
            +
            void oj_str_writer_pop(StrWriter sw) {
         | 
| 194 | 
            +
                long     size;
         | 
| 195 | 
            +
                DumpType type = sw->types[sw->depth];
         | 
| 209 196 |  | 
| 210 197 | 
             
                if (sw->keyWritten) {
         | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 198 | 
            +
                    sw->keyWritten = 0;
         | 
| 199 | 
            +
                    rb_raise(rb_eStandardError, "Can not pop after writing a key but no value.");
         | 
| 213 200 | 
             
                }
         | 
| 214 201 | 
             
                sw->depth--;
         | 
| 215 202 | 
             
                if (0 > sw->depth) {
         | 
| 216 | 
            -
             | 
| 203 | 
            +
                    rb_raise(rb_eStandardError, "Can not pop with no open array or object.");
         | 
| 217 204 | 
             
                }
         | 
| 218 205 | 
             
                size = sw->depth * sw->out.indent + 2;
         | 
| 219 206 | 
             
                assure_size(&sw->out, size);
         | 
| 220 207 | 
             
                fill_indent(&sw->out, sw->depth);
         | 
| 221 208 | 
             
                switch (type) {
         | 
| 222 209 | 
             
                case ObjectNew:
         | 
| 223 | 
            -
                case ObjectType:
         | 
| 224 | 
            -
            	*sw->out.cur++ = '}';
         | 
| 225 | 
            -
            	break;
         | 
| 210 | 
            +
                case ObjectType: *sw->out.cur++ = '}'; break;
         | 
| 226 211 | 
             
                case ArrayNew:
         | 
| 227 | 
            -
                case ArrayType:
         | 
| 228 | 
            -
            	*sw->out.cur++ = ']';
         | 
| 229 | 
            -
            	break;
         | 
| 212 | 
            +
                case ArrayType: *sw->out.cur++ = ']'; break;
         | 
| 230 213 | 
             
                }
         | 
| 231 214 | 
             
                if (0 == sw->depth && 0 <= sw->out.indent) {
         | 
| 232 | 
            -
             | 
| 215 | 
            +
                    *sw->out.cur++ = '\n';
         | 
| 233 216 | 
             
                }
         | 
| 234 217 | 
             
            }
         | 
| 235 218 |  | 
| 236 | 
            -
            void
         | 
| 237 | 
            -
            oj_str_writer_pop_all(StrWriter sw) {
         | 
| 219 | 
            +
            void oj_str_writer_pop_all(StrWriter sw) {
         | 
| 238 220 | 
             
                while (0 < sw->depth) {
         | 
| 239 | 
            -
             | 
| 221 | 
            +
                    oj_str_writer_pop(sw);
         | 
| 240 222 | 
             
                }
         | 
| 241 223 | 
             
            }
         | 
| 242 224 |  | 
| 243 | 
            -
            static void
         | 
| 244 | 
            -
             | 
| 245 | 
            -
                StrWriter	sw;
         | 
| 225 | 
            +
            static void str_writer_free(void *ptr) {
         | 
| 226 | 
            +
                StrWriter sw;
         | 
| 246 227 |  | 
| 247 228 | 
             
                if (0 == ptr) {
         | 
| 248 | 
            -
             | 
| 229 | 
            +
                    return;
         | 
| 249 230 | 
             
                }
         | 
| 250 231 | 
             
                sw = (StrWriter)ptr;
         | 
| 251 232 | 
             
                xfree(sw->out.buf);
         | 
| @@ -269,16 +250,15 @@ str_writer_free(void *ptr) { | |
| 269 250 | 
             
             * - *io* [_IO_] stream to write to
         | 
| 270 251 | 
             
             * - *options* [_Hash_] formating options
         | 
| 271 252 | 
             
             */
         | 
| 272 | 
            -
            static VALUE
         | 
| 273 | 
            -
             | 
| 274 | 
            -
                StrWriter	sw = ALLOC(struct _strWriter);
         | 
| 253 | 
            +
            static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
         | 
| 254 | 
            +
                StrWriter sw = ALLOC(struct _strWriter);
         | 
| 275 255 |  | 
| 276 256 | 
             
                oj_str_writer_init(sw, 0);
         | 
| 277 257 | 
             
                if (1 == argc) {
         | 
| 278 | 
            -
             | 
| 258 | 
            +
                    oj_parse_options(argv[0], &sw->opts);
         | 
| 279 259 | 
             
                }
         | 
| 280 | 
            -
                sw->out.argc | 
| 281 | 
            -
                sw->out.argv | 
| 260 | 
            +
                sw->out.argc   = argc - 1;
         | 
| 261 | 
            +
                sw->out.argv   = argv + 1;
         | 
| 282 262 | 
             
                sw->out.indent = sw->opts.indent;
         | 
| 283 263 |  | 
| 284 264 | 
             
                return Data_Wrap_Struct(oj_string_writer_class, 0, str_writer_free, sw);
         | 
| @@ -292,9 +272,8 @@ str_writer_new(int argc, VALUE *argv, VALUE self) { | |
| 292 272 | 
             
             * the next push then that new key will be ignored.
         | 
| 293 273 | 
             
             * - *key* [_String_] the key pending for the next push
         | 
| 294 274 | 
             
             */
         | 
| 295 | 
            -
            static VALUE
         | 
| 296 | 
            -
             | 
| 297 | 
            -
                StrWriter	sw = (StrWriter)DATA_PTR(self);
         | 
| 275 | 
            +
            static VALUE str_writer_push_key(VALUE self, VALUE key) {
         | 
| 276 | 
            +
                StrWriter sw = (StrWriter)DATA_PTR(self);
         | 
| 298 277 |  | 
| 299 278 | 
             
                rb_check_type(key, T_STRING);
         | 
| 300 279 | 
             
                oj_str_writer_push_key(sw, StringValuePtr(key));
         | 
| @@ -309,29 +288,24 @@ str_writer_push_key(VALUE self, VALUE key) { | |
| 309 288 | 
             
             * until a pop() is called.
         | 
| 310 289 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 311 290 | 
             
             */
         | 
| 312 | 
            -
            static VALUE
         | 
| 313 | 
            -
             | 
| 314 | 
            -
                StrWriter	sw = (StrWriter)DATA_PTR(self);
         | 
| 291 | 
            +
            static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
         | 
| 292 | 
            +
                StrWriter sw = (StrWriter)DATA_PTR(self);
         | 
| 315 293 |  | 
| 316 294 | 
             
                switch (argc) {
         | 
| 317 | 
            -
                case 0:
         | 
| 318 | 
            -
            	oj_str_writer_push_object(sw, 0);
         | 
| 319 | 
            -
            	break;
         | 
| 295 | 
            +
                case 0: oj_str_writer_push_object(sw, 0); break;
         | 
| 320 296 | 
             
                case 1:
         | 
| 321 | 
            -
             | 
| 322 | 
            -
             | 
| 323 | 
            -
             | 
| 324 | 
            -
             | 
| 325 | 
            -
             | 
| 326 | 
            -
             | 
| 327 | 
            -
             | 
| 328 | 
            -
                default:
         | 
| 329 | 
            -
            	rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
         | 
| 330 | 
            -
            	break;
         | 
| 297 | 
            +
                    if (Qnil == argv[0]) {
         | 
| 298 | 
            +
                        oj_str_writer_push_object(sw, 0);
         | 
| 299 | 
            +
                    } else {
         | 
| 300 | 
            +
                        rb_check_type(argv[0], T_STRING);
         | 
| 301 | 
            +
                        oj_str_writer_push_object(sw, StringValuePtr(argv[0]));
         | 
| 302 | 
            +
                    }
         | 
| 303 | 
            +
                    break;
         | 
| 304 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'."); break;
         | 
| 331 305 | 
             
                }
         | 
| 332 306 | 
             
                if (rb_block_given_p()) {
         | 
| 333 | 
            -
             | 
| 334 | 
            -
             | 
| 307 | 
            +
                    rb_yield(Qnil);
         | 
| 308 | 
            +
                    oj_str_writer_pop(sw);
         | 
| 335 309 | 
             
                }
         | 
| 336 310 | 
             
                return Qnil;
         | 
| 337 311 | 
             
            }
         | 
| @@ -343,29 +317,24 @@ str_writer_push_object(int argc, VALUE *argv, VALUE self) { | |
| 343 317 | 
             
             * until a pop() is called.
         | 
| 344 318 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 345 319 | 
             
             */
         | 
| 346 | 
            -
            static VALUE
         | 
| 347 | 
            -
             | 
| 348 | 
            -
                StrWriter	sw = (StrWriter)DATA_PTR(self);
         | 
| 320 | 
            +
            static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
         | 
| 321 | 
            +
                StrWriter sw = (StrWriter)DATA_PTR(self);
         | 
| 349 322 |  | 
| 350 323 | 
             
                switch (argc) {
         | 
| 351 | 
            -
                case 0:
         | 
| 352 | 
            -
            	oj_str_writer_push_array(sw, 0);
         | 
| 353 | 
            -
            	break;
         | 
| 324 | 
            +
                case 0: oj_str_writer_push_array(sw, 0); break;
         | 
| 354 325 | 
             
                case 1:
         | 
| 355 | 
            -
             | 
| 356 | 
            -
             | 
| 357 | 
            -
             | 
| 358 | 
            -
             | 
| 359 | 
            -
             | 
| 360 | 
            -
             | 
| 361 | 
            -
             | 
| 362 | 
            -
                default:
         | 
| 363 | 
            -
            	rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
         | 
| 364 | 
            -
            	break;
         | 
| 326 | 
            +
                    if (Qnil == argv[0]) {
         | 
| 327 | 
            +
                        oj_str_writer_push_array(sw, 0);
         | 
| 328 | 
            +
                    } else {
         | 
| 329 | 
            +
                        rb_check_type(argv[0], T_STRING);
         | 
| 330 | 
            +
                        oj_str_writer_push_array(sw, StringValuePtr(argv[0]));
         | 
| 331 | 
            +
                    }
         | 
| 332 | 
            +
                    break;
         | 
| 333 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'."); break;
         | 
| 365 334 | 
             
                }
         | 
| 366 335 | 
             
                if (rb_block_given_p()) {
         | 
| 367 | 
            -
             | 
| 368 | 
            -
             | 
| 336 | 
            +
                    rb_yield(Qnil);
         | 
| 337 | 
            +
                    oj_str_writer_pop(sw);
         | 
| 369 338 | 
             
                }
         | 
| 370 339 | 
             
                return Qnil;
         | 
| 371 340 | 
             
            }
         | 
| @@ -377,23 +346,18 @@ str_writer_push_array(int argc, VALUE *argv, VALUE self) { | |
| 377 346 | 
             
             * - *value* [_Object_] value to add to the JSON document
         | 
| 378 347 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 379 348 | 
             
             */
         | 
| 380 | 
            -
            static VALUE
         | 
| 381 | 
            -
            str_writer_push_value(int argc, VALUE *argv, VALUE self) {
         | 
| 349 | 
            +
            static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) {
         | 
| 382 350 | 
             
                switch (argc) {
         | 
| 383 | 
            -
                case 1:
         | 
| 384 | 
            -
            	oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
         | 
| 385 | 
            -
            	break;
         | 
| 351 | 
            +
                case 1: oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); break;
         | 
| 386 352 | 
             
                case 2:
         | 
| 387 | 
            -
             | 
| 388 | 
            -
             | 
| 389 | 
            -
             | 
| 390 | 
            -
             | 
| 391 | 
            -
             | 
| 392 | 
            -
             | 
| 393 | 
            -
             | 
| 394 | 
            -
                default:
         | 
| 395 | 
            -
            	rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'.");
         | 
| 396 | 
            -
            	break;
         | 
| 353 | 
            +
                    if (Qnil == argv[1]) {
         | 
| 354 | 
            +
                        oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
         | 
| 355 | 
            +
                    } else {
         | 
| 356 | 
            +
                        rb_check_type(argv[1], T_STRING);
         | 
| 357 | 
            +
                        oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
         | 
| 358 | 
            +
                    }
         | 
| 359 | 
            +
                    break;
         | 
| 360 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'."); break;
         | 
| 397 361 | 
             
                }
         | 
| 398 362 | 
             
                return Qnil;
         | 
| 399 363 | 
             
            }
         | 
| @@ -407,24 +371,21 @@ str_writer_push_value(int argc, VALUE *argv, VALUE self) { | |
| 407 371 | 
             
             * - *value* [_Object_] value to add to the JSON document
         | 
| 408 372 | 
             
             * - *key* [_String_] the key if adding to an object in the JSON document
         | 
| 409 373 | 
             
             */
         | 
| 410 | 
            -
            static VALUE
         | 
| 411 | 
            -
            str_writer_push_json(int argc, VALUE *argv, VALUE self) {
         | 
| 374 | 
            +
            static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) {
         | 
| 412 375 | 
             
                rb_check_type(argv[0], T_STRING);
         | 
| 413 376 | 
             
                switch (argc) {
         | 
| 414 | 
            -
                case 1:
         | 
| 415 | 
            -
            	oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
         | 
| 416 | 
            -
            	break;
         | 
| 377 | 
            +
                case 1: oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); break;
         | 
| 417 378 | 
             
                case 2:
         | 
| 418 | 
            -
             | 
| 419 | 
            -
             | 
| 420 | 
            -
             | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 424 | 
            -
             | 
| 425 | 
            -
             | 
| 426 | 
            -
             | 
| 427 | 
            -
             | 
| 379 | 
            +
                    if (Qnil == argv[1]) {
         | 
| 380 | 
            +
                        oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
         | 
| 381 | 
            +
                    } else {
         | 
| 382 | 
            +
                        rb_check_type(argv[1], T_STRING);
         | 
| 383 | 
            +
                        oj_str_writer_push_json((StrWriter)DATA_PTR(self),
         | 
| 384 | 
            +
                                                StringValuePtr(*argv),
         | 
| 385 | 
            +
                                                StringValuePtr(argv[1]));
         | 
| 386 | 
            +
                    }
         | 
| 387 | 
            +
                    break;
         | 
| 388 | 
            +
                default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
         | 
| 428 389 | 
             
                }
         | 
| 429 390 | 
             
                return Qnil;
         | 
| 430 391 | 
             
            }
         | 
| @@ -434,8 +395,7 @@ str_writer_push_json(int argc, VALUE *argv, VALUE self) { | |
| 434 395 | 
             
             * Pops up a level in the JSON document closing the array or object that is
         | 
| 435 396 | 
             
             * currently open.
         | 
| 436 397 | 
             
             */
         | 
| 437 | 
            -
            static VALUE
         | 
| 438 | 
            -
            str_writer_pop(VALUE self) {
         | 
| 398 | 
            +
            static VALUE str_writer_pop(VALUE self) {
         | 
| 439 399 | 
             
                oj_str_writer_pop((StrWriter)DATA_PTR(self));
         | 
| 440 400 | 
             
                return Qnil;
         | 
| 441 401 | 
             
            }
         | 
| @@ -446,8 +406,7 @@ str_writer_pop(VALUE self) { | |
| 446 406 | 
             
             * Pops all level in the JSON document closing all the array or object that is
         | 
| 447 407 | 
             
             * currently open.
         | 
| 448 408 | 
             
             */
         | 
| 449 | 
            -
            static VALUE
         | 
| 450 | 
            -
            str_writer_pop_all(VALUE self) {
         | 
| 409 | 
            +
            static VALUE str_writer_pop_all(VALUE self) {
         | 
| 451 410 | 
             
                oj_str_writer_pop_all((StrWriter)DATA_PTR(self));
         | 
| 452 411 |  | 
| 453 412 | 
             
                return Qnil;
         | 
| @@ -458,15 +417,14 @@ str_writer_pop_all(VALUE self) { | |
| 458 417 | 
             
             *
         | 
| 459 418 | 
             
             * Reset the writer back to the empty state.
         | 
| 460 419 | 
             
             */
         | 
| 461 | 
            -
            static VALUE
         | 
| 462 | 
            -
             | 
| 463 | 
            -
                StrWriter	sw = (StrWriter)DATA_PTR(self);
         | 
| 420 | 
            +
            static VALUE str_writer_reset(VALUE self) {
         | 
| 421 | 
            +
                StrWriter sw = (StrWriter)DATA_PTR(self);
         | 
| 464 422 |  | 
| 465 | 
            -
                sw->depth | 
| 466 | 
            -
                *sw->types | 
| 423 | 
            +
                sw->depth      = 0;
         | 
| 424 | 
            +
                *sw->types     = '\0';
         | 
| 467 425 | 
             
                sw->keyWritten = 0;
         | 
| 468 | 
            -
                sw->out.cur | 
| 469 | 
            -
                *sw->out.cur | 
| 426 | 
            +
                sw->out.cur    = sw->out.buf;
         | 
| 427 | 
            +
                *sw->out.cur   = '\0';
         | 
| 470 428 |  | 
| 471 429 | 
             
                return Qnil;
         | 
| 472 430 | 
             
            }
         | 
| @@ -478,10 +436,9 @@ str_writer_reset(VALUE self) { | |
| 478 436 | 
             
             *
         | 
| 479 437 | 
             
             * *return* [_String_]
         | 
| 480 438 | 
             
             */
         | 
| 481 | 
            -
            static VALUE
         | 
| 482 | 
            -
             | 
| 483 | 
            -
                 | 
| 484 | 
            -
                VALUE	rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf);
         | 
| 439 | 
            +
            static VALUE str_writer_to_s(VALUE self) {
         | 
| 440 | 
            +
                StrWriter sw   = (StrWriter)DATA_PTR(self);
         | 
| 441 | 
            +
                VALUE     rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf);
         | 
| 485 442 |  | 
| 486 443 | 
             
                return oj_encode(rstr);
         | 
| 487 444 | 
             
            }
         | 
| @@ -496,10 +453,9 @@ str_writer_to_s(VALUE self) { | |
| 496 453 | 
             
             *
         | 
| 497 454 | 
             
             * *return* [_Hash_|_Array_|_String_|_Integer_|_Float_|_True_|_False_|_nil|)
         | 
| 498 455 | 
             
             */
         | 
| 499 | 
            -
            static VALUE
         | 
| 500 | 
            -
            str_writer_as_json(VALUE self) {
         | 
| 456 | 
            +
            static VALUE str_writer_as_json(VALUE self) {
         | 
| 501 457 | 
             
                if (string_writer_optimized) {
         | 
| 502 | 
            -
             | 
| 458 | 
            +
                    return self;
         | 
| 503 459 | 
             
                }
         | 
| 504 460 | 
             
                return rb_hash_new();
         | 
| 505 461 | 
             
            }
         | 
| @@ -513,8 +469,7 @@ str_writer_as_json(VALUE self) { | |
| 513 469 | 
             
             * calling to_s() will return the JSON document. Note tha calling to_s() before
         | 
| 514 470 | 
             
             * construction is complete will return the document in it's current state.
         | 
| 515 471 | 
             
             */
         | 
| 516 | 
            -
            void
         | 
| 517 | 
            -
            oj_string_writer_init() {
         | 
| 472 | 
            +
            void oj_string_writer_init() {
         | 
| 518 473 | 
             
                oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
         | 
| 519 474 | 
             
                rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
         | 
| 520 475 | 
             
                rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
         |