json 2.7.2 → 2.9.1
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/BSDL +22 -0
- data/CHANGES.md +86 -17
- data/LEGAL +60 -0
- data/README.md +15 -236
- data/ext/json/ext/fbuffer/fbuffer.h +112 -85
- data/ext/json/ext/generator/extconf.rb +8 -2
- data/ext/json/ext/generator/generator.c +818 -830
- data/ext/json/ext/parser/extconf.rb +7 -27
- data/ext/json/ext/parser/parser.c +1698 -671
- data/ext/json/ext/parser/parser.rl +833 -339
- data/json.gemspec +45 -49
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +1 -1
- data/lib/json/add/core.rb +1 -1
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +1 -1
- data/lib/json/add/regexp.rb +1 -1
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -2
- data/lib/json/add/time.rb +3 -10
- data/lib/json/common.rb +299 -101
- data/lib/json/ext/generator/state.rb +116 -0
- data/lib/json/ext.rb +13 -5
- data/lib/json/generic_object.rb +1 -1
- data/lib/json/{pure → truffle_ruby}/generator.rb +242 -126
- data/lib/json/version.rb +3 -7
- data/lib/json.rb +16 -21
- metadata +19 -21
- data/ext/json/ext/generator/depend +0 -1
- data/ext/json/ext/generator/generator.h +0 -177
- data/ext/json/ext/parser/depend +0 -1
- data/ext/json/ext/parser/parser.h +0 -96
- data/ext/json/extconf.rb +0 -3
- data/lib/json/pure/parser.rb +0 -337
- data/lib/json/pure.rb +0 -15
- /data/{LICENSE → COPYING} +0 -0
| @@ -1,89 +1,91 @@ | |
| 1 | 
            -
             | 
| 2 1 | 
             
            #ifndef _FBUFFER_H_
         | 
| 3 2 | 
             
            #define _FBUFFER_H_
         | 
| 4 3 |  | 
| 5 4 | 
             
            #include "ruby.h"
         | 
| 5 | 
            +
            #include "ruby/encoding.h"
         | 
| 6 6 |  | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 7 | 
            +
            /* shims */
         | 
| 8 | 
            +
            /* This is the fallback definition from Ruby 3.4 */
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            #ifndef RBIMPL_STDBOOL_H
         | 
| 11 | 
            +
            #if defined(__cplusplus)
         | 
| 12 | 
            +
            # if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L)
         | 
| 13 | 
            +
            #  include <cstdbool>
         | 
| 14 | 
            +
            # endif
         | 
| 15 | 
            +
            #elif defined(HAVE_STDBOOL_H)
         | 
| 16 | 
            +
            # include <stdbool.h>
         | 
| 17 | 
            +
            #elif !defined(HAVE__BOOL)
         | 
| 18 | 
            +
            typedef unsigned char _Bool;
         | 
| 19 | 
            +
            # define bool  _Bool
         | 
| 20 | 
            +
            # define true  ((_Bool)+1)
         | 
| 21 | 
            +
            # define false ((_Bool)+0)
         | 
| 22 | 
            +
            # define __bool_true_false_are_defined
         | 
| 9 23 | 
             
            #endif
         | 
| 10 | 
            -
             | 
| 11 | 
            -
            #ifndef RFLOAT_VALUE
         | 
| 12 | 
            -
            #define RFLOAT_VALUE(val) (RFLOAT(val)->value)
         | 
| 13 24 | 
             
            #endif
         | 
| 14 25 |  | 
| 15 | 
            -
            #ifndef  | 
| 16 | 
            -
            #define  | 
| 17 | 
            -
            #endif
         | 
| 18 | 
            -
            #ifndef RSTRING_PTR
         | 
| 19 | 
            -
            #define RSTRING_PTR(string) RSTRING(string)->ptr
         | 
| 20 | 
            -
            #endif
         | 
| 21 | 
            -
            #ifndef RSTRING_LEN
         | 
| 22 | 
            -
            #define RSTRING_LEN(string) RSTRING(string)->len
         | 
| 26 | 
            +
            #ifndef RB_UNLIKELY
         | 
| 27 | 
            +
            #define RB_UNLIKELY(expr) expr
         | 
| 23 28 | 
             
            #endif
         | 
| 24 29 |  | 
| 25 | 
            -
            # | 
| 26 | 
            -
            # | 
| 27 | 
            -
            # define RB_OBJ_STRING(obj) (obj)
         | 
| 28 | 
            -
            #else
         | 
| 29 | 
            -
            # define PRIsVALUE "s"
         | 
| 30 | 
            -
            # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
         | 
| 31 | 
            -
            # define RB_OBJ_STRING(obj) StringValueCStr(obj)
         | 
| 30 | 
            +
            #ifndef RB_LIKELY
         | 
| 31 | 
            +
            #define RB_LIKELY(expr) expr
         | 
| 32 32 | 
             
            #endif
         | 
| 33 33 |  | 
| 34 | 
            -
            # | 
| 35 | 
            -
            # | 
| 36 | 
            -
            #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
         | 
| 37 | 
            -
            #else
         | 
| 38 | 
            -
            #define FORCE_UTF8(obj)
         | 
| 34 | 
            +
            #ifndef MAYBE_UNUSED
         | 
| 35 | 
            +
            # define MAYBE_UNUSED(x) x
         | 
| 39 36 | 
             
            #endif
         | 
| 40 37 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 38 | 
            +
            enum fbuffer_type {
         | 
| 39 | 
            +
                FBUFFER_HEAP_ALLOCATED = 0,
         | 
| 40 | 
            +
                FBUFFER_STACK_ALLOCATED = 1,
         | 
| 41 | 
            +
            };
         | 
| 45 42 |  | 
| 46 43 | 
             
            typedef struct FBufferStruct {
         | 
| 44 | 
            +
                enum fbuffer_type type;
         | 
| 47 45 | 
             
                unsigned long initial_length;
         | 
| 48 | 
            -
                char *ptr;
         | 
| 49 46 | 
             
                unsigned long len;
         | 
| 50 47 | 
             
                unsigned long capa;
         | 
| 48 | 
            +
                char *ptr;
         | 
| 49 | 
            +
                VALUE io;
         | 
| 51 50 | 
             
            } FBuffer;
         | 
| 52 51 |  | 
| 52 | 
            +
            #define FBUFFER_STACK_SIZE 512
         | 
| 53 | 
            +
            #define FBUFFER_IO_BUFFER_SIZE (16384 - 1)
         | 
| 53 54 | 
             
            #define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
         | 
| 54 55 |  | 
| 55 | 
            -
            #define FBUFFER_PTR(fb) (fb->ptr)
         | 
| 56 | 
            -
            #define FBUFFER_LEN(fb) (fb->len)
         | 
| 57 | 
            -
            #define FBUFFER_CAPA(fb) (fb->capa)
         | 
| 56 | 
            +
            #define FBUFFER_PTR(fb) ((fb)->ptr)
         | 
| 57 | 
            +
            #define FBUFFER_LEN(fb) ((fb)->len)
         | 
| 58 | 
            +
            #define FBUFFER_CAPA(fb) ((fb)->capa)
         | 
| 58 59 | 
             
            #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
         | 
| 59 60 |  | 
| 60 | 
            -
            static FBuffer *fbuffer_alloc(unsigned long initial_length);
         | 
| 61 61 | 
             
            static void fbuffer_free(FBuffer *fb);
         | 
| 62 | 
            +
            #ifndef JSON_GENERATOR
         | 
| 62 63 | 
             
            static void fbuffer_clear(FBuffer *fb);
         | 
| 64 | 
            +
            #endif
         | 
| 63 65 | 
             
            static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
         | 
| 64 66 | 
             
            #ifdef JSON_GENERATOR
         | 
| 65 67 | 
             
            static void fbuffer_append_long(FBuffer *fb, long number);
         | 
| 66 68 | 
             
            #endif
         | 
| 67 | 
            -
            static void fbuffer_append_char(FBuffer *fb, char newchr);
         | 
| 69 | 
            +
            static inline void fbuffer_append_char(FBuffer *fb, char newchr);
         | 
| 68 70 | 
             
            #ifdef JSON_GENERATOR
         | 
| 69 | 
            -
            static  | 
| 70 | 
            -
            static VALUE fbuffer_to_s(FBuffer *fb);
         | 
| 71 | 
            +
            static VALUE fbuffer_finalize(FBuffer *fb);
         | 
| 71 72 | 
             
            #endif
         | 
| 72 73 |  | 
| 73 | 
            -
            static FBuffer * | 
| 74 | 
            +
            static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size)
         | 
| 74 75 | 
             
            {
         | 
| 75 | 
            -
                 | 
| 76 | 
            -
                if ( | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
                 | 
| 76 | 
            +
                fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
         | 
| 77 | 
            +
                if (stack_buffer) {
         | 
| 78 | 
            +
                    fb->type = FBUFFER_STACK_ALLOCATED;
         | 
| 79 | 
            +
                    fb->ptr = stack_buffer;
         | 
| 80 | 
            +
                    fb->capa = stack_buffer_size;
         | 
| 81 | 
            +
                }
         | 
| 81 82 | 
             
            }
         | 
| 82 83 |  | 
| 83 84 | 
             
            static void fbuffer_free(FBuffer *fb)
         | 
| 84 85 | 
             
            {
         | 
| 85 | 
            -
                if (fb->ptr | 
| 86 | 
            -
             | 
| 86 | 
            +
                if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) {
         | 
| 87 | 
            +
                    ruby_xfree(fb->ptr);
         | 
| 88 | 
            +
                }
         | 
| 87 89 | 
             
            }
         | 
| 88 90 |  | 
| 89 91 | 
             
            static void fbuffer_clear(FBuffer *fb)
         | 
| @@ -91,20 +93,57 @@ static void fbuffer_clear(FBuffer *fb) | |
| 91 93 | 
             
                fb->len = 0;
         | 
| 92 94 | 
             
            }
         | 
| 93 95 |  | 
| 94 | 
            -
            static void  | 
| 96 | 
            +
            static void fbuffer_flush(FBuffer *fb)
         | 
| 97 | 
            +
            {
         | 
| 98 | 
            +
                rb_io_write(fb->io, rb_utf8_str_new(fb->ptr, fb->len));
         | 
| 99 | 
            +
                fbuffer_clear(fb);
         | 
| 100 | 
            +
            }
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            static void fbuffer_realloc(FBuffer *fb, unsigned long required)
         | 
| 103 | 
            +
            {
         | 
| 104 | 
            +
                if (required > fb->capa) {
         | 
| 105 | 
            +
                    if (fb->type == FBUFFER_STACK_ALLOCATED) {
         | 
| 106 | 
            +
                        const char *old_buffer = fb->ptr;
         | 
| 107 | 
            +
                        fb->ptr = ALLOC_N(char, required);
         | 
| 108 | 
            +
                        fb->type = FBUFFER_HEAP_ALLOCATED;
         | 
| 109 | 
            +
                        MEMCPY(fb->ptr, old_buffer, char, fb->len);
         | 
| 110 | 
            +
                    } else {
         | 
| 111 | 
            +
                        REALLOC_N(fb->ptr, char, required);
         | 
| 112 | 
            +
                    }
         | 
| 113 | 
            +
                    fb->capa = required;
         | 
| 114 | 
            +
                }
         | 
| 115 | 
            +
            }
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
         | 
| 95 118 | 
             
            {
         | 
| 119 | 
            +
                if (RB_UNLIKELY(fb->io)) {
         | 
| 120 | 
            +
                    if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
         | 
| 121 | 
            +
                        fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
         | 
| 122 | 
            +
                    } else {
         | 
| 123 | 
            +
                        fbuffer_flush(fb);
         | 
| 124 | 
            +
                    }
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    if (RB_LIKELY(requested < fb->capa)) {
         | 
| 127 | 
            +
                        return;
         | 
| 128 | 
            +
                    }
         | 
| 129 | 
            +
                }
         | 
| 130 | 
            +
             | 
| 96 131 | 
             
                unsigned long required;
         | 
| 97 132 |  | 
| 98 | 
            -
                if (!fb->ptr) {
         | 
| 133 | 
            +
                if (RB_UNLIKELY(!fb->ptr)) {
         | 
| 99 134 | 
             
                    fb->ptr = ALLOC_N(char, fb->initial_length);
         | 
| 100 135 | 
             
                    fb->capa = fb->initial_length;
         | 
| 101 136 | 
             
                }
         | 
| 102 137 |  | 
| 103 138 | 
             
                for (required = fb->capa; requested > required - fb->len; required <<= 1);
         | 
| 104 139 |  | 
| 105 | 
            -
                 | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 140 | 
            +
                fbuffer_realloc(fb, required);
         | 
| 141 | 
            +
            }
         | 
| 142 | 
            +
             | 
| 143 | 
            +
            static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
         | 
| 144 | 
            +
            {
         | 
| 145 | 
            +
                if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
         | 
| 146 | 
            +
                    fbuffer_do_inc_capa(fb, requested);
         | 
| 108 147 | 
             
                }
         | 
| 109 148 | 
             
            }
         | 
| 110 149 |  | 
| @@ -129,7 +168,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str) | |
| 129 168 | 
             
            }
         | 
| 130 169 | 
             
            #endif
         | 
| 131 170 |  | 
| 132 | 
            -
            static void fbuffer_append_char(FBuffer *fb, char newchr)
         | 
| 171 | 
            +
            static inline void fbuffer_append_char(FBuffer *fb, char newchr)
         | 
| 133 172 | 
             
            {
         | 
| 134 173 | 
             
                fbuffer_inc_capa(fb, 1);
         | 
| 135 174 | 
             
                *(fb->ptr + fb->len) = newchr;
         | 
| @@ -137,51 +176,39 @@ static void fbuffer_append_char(FBuffer *fb, char newchr) | |
| 137 176 | 
             
            }
         | 
| 138 177 |  | 
| 139 178 | 
             
            #ifdef JSON_GENERATOR
         | 
| 140 | 
            -
            static void freverse(char *start, char *end)
         | 
| 141 | 
            -
            {
         | 
| 142 | 
            -
                char c;
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                while (end > start) {
         | 
| 145 | 
            -
                    c = *end, *end-- = *start, *start++ = c;
         | 
| 146 | 
            -
                }
         | 
| 147 | 
            -
            }
         | 
| 148 | 
            -
             | 
| 149 179 | 
             
            static long fltoa(long number, char *buf)
         | 
| 150 180 | 
             
            {
         | 
| 151 | 
            -
                static char digits[] = "0123456789";
         | 
| 181 | 
            +
                static const char digits[] = "0123456789";
         | 
| 152 182 | 
             
                long sign = number;
         | 
| 153 183 | 
             
                char* tmp = buf;
         | 
| 154 184 |  | 
| 155 185 | 
             
                if (sign < 0) number = -number;
         | 
| 156 | 
            -
                do *tmp | 
| 157 | 
            -
                if (sign < 0) *tmp | 
| 158 | 
            -
                 | 
| 159 | 
            -
                return tmp - buf;
         | 
| 186 | 
            +
                do *tmp-- = digits[number % 10]; while (number /= 10);
         | 
| 187 | 
            +
                if (sign < 0) *tmp-- = '-';
         | 
| 188 | 
            +
                return buf - tmp;
         | 
| 160 189 | 
             
            }
         | 
| 161 190 |  | 
| 191 | 
            +
            #define LONG_BUFFER_SIZE 20
         | 
| 162 192 | 
             
            static void fbuffer_append_long(FBuffer *fb, long number)
         | 
| 163 193 | 
             
            {
         | 
| 164 | 
            -
                char buf[ | 
| 165 | 
            -
                 | 
| 166 | 
            -
                 | 
| 194 | 
            +
                char buf[LONG_BUFFER_SIZE];
         | 
| 195 | 
            +
                char *buffer_end = buf + LONG_BUFFER_SIZE;
         | 
| 196 | 
            +
                long len = fltoa(number, buffer_end - 1);
         | 
| 197 | 
            +
                fbuffer_append(fb, buffer_end - len, len);
         | 
| 167 198 | 
             
            }
         | 
| 168 199 |  | 
| 169 | 
            -
            static  | 
| 200 | 
            +
            static VALUE fbuffer_finalize(FBuffer *fb)
         | 
| 170 201 | 
             
            {
         | 
| 171 | 
            -
                 | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 176 | 
            -
                 | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 181 | 
            -
                VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
         | 
| 182 | 
            -
                fbuffer_free(fb);
         | 
| 183 | 
            -
                FORCE_UTF8(result);
         | 
| 184 | 
            -
                return result;
         | 
| 202 | 
            +
                if (fb->io) {
         | 
| 203 | 
            +
                    fbuffer_flush(fb);
         | 
| 204 | 
            +
                    fbuffer_free(fb);
         | 
| 205 | 
            +
                    rb_io_flush(fb->io);
         | 
| 206 | 
            +
                    return fb->io;
         | 
| 207 | 
            +
                } else {
         | 
| 208 | 
            +
                    VALUE result = rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
         | 
| 209 | 
            +
                    fbuffer_free(fb);
         | 
| 210 | 
            +
                    return result;
         | 
| 211 | 
            +
                }
         | 
| 185 212 | 
             
            }
         | 
| 186 213 | 
             
            #endif
         | 
| 187 214 | 
             
            #endif
         | 
| @@ -1,4 +1,10 @@ | |
| 1 1 | 
             
            require 'mkmf'
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 3 | 
            +
            if RUBY_ENGINE == 'truffleruby'
         | 
| 4 | 
            +
              # The pure-Ruby generator is faster on TruffleRuby, so skip compiling the generator extension
         | 
| 5 | 
            +
              File.write('Makefile', dummy_makefile("").join)
         | 
| 6 | 
            +
            else
         | 
| 7 | 
            +
              append_cflags("-std=c99")
         | 
| 8 | 
            +
              $defs << "-DJSON_GENERATOR"
         | 
| 9 | 
            +
              create_makefile 'json/ext/generator'
         | 
| 10 | 
            +
            end
         |