oj 3.11.3 → 3.11.8
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 +6 -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 +1042 -1041
 - 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 +412 -402
 - 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 +1123 -922
 - 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 -838
 - 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 +8 -40
 - data/test/test_fast.rb +32 -2
 - data/test/test_generate.rb +21 -0
 - data/test/test_scp.rb +1 -1
 - metadata +4 -2
 
    
        data/ext/oj/rails.h
    CHANGED
    
    | 
         @@ -1,18 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            // Copyright (c) 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 
     | 
    
         
             
            #ifndef OJ_RAILS_H
         
     | 
| 
       4 
5 
     | 
    
         
             
            #define OJ_RAILS_H
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            #include "dump.h"
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            extern void 
     | 
| 
       9 
     | 
    
         
            -
            extern ROpt 
     | 
| 
      
 9 
     | 
    
         
            +
            extern void oj_mimic_rails_init();
         
     | 
| 
      
 10 
     | 
    
         
            +
            extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            extern bool 
     | 
| 
       12 
     | 
    
         
            -
            extern bool 
     | 
| 
       13 
     | 
    
         
            -
            extern bool 
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            extern VALUE	oj_optimize_rails(VALUE self);
         
     | 
| 
      
 12 
     | 
    
         
            +
            extern bool oj_rails_hash_opt;
         
     | 
| 
      
 13 
     | 
    
         
            +
            extern bool oj_rails_array_opt;
         
     | 
| 
      
 14 
     | 
    
         
            +
            extern bool oj_rails_float_opt;
         
     | 
| 
       16 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
            extern VALUE oj_optimize_rails(VALUE self);
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
            #endif /* OJ_RAILS_H */
         
     | 
    
        data/ext/oj/reader.c
    CHANGED
    
    | 
         @@ -1,220 +1,215 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            // Copyright (c) 2011 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 <errno.h>
         
     | 
| 
       5 
5 
     | 
    
         
             
            #include <stdio.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
       6 
7 
     | 
    
         
             
            #include <strings.h>
         
     | 
| 
       7 
8 
     | 
    
         
             
            #include <sys/types.h>
         
     | 
| 
       8 
9 
     | 
    
         
             
            #if NEEDS_UIO
         
     | 
| 
       9 
10 
     | 
    
         
             
            #include <sys/uio.h>
         
     | 
| 
       10 
11 
     | 
    
         
             
            #endif
         
     | 
| 
       11 
     | 
    
         
            -
            #include <unistd.h>
         
     | 
| 
       12 
12 
     | 
    
         
             
            #include <time.h>
         
     | 
| 
      
 13 
     | 
    
         
            +
            #include <unistd.h>
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
            #include "ruby.h"
         
     | 
| 
       15 
15 
     | 
    
         
             
            #include "oj.h"
         
     | 
| 
       16 
16 
     | 
    
         
             
            #include "reader.h"
         
     | 
| 
      
 17 
     | 
    
         
            +
            #include "ruby.h"
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
            #define BUF_PAD 
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
            static VALUE 
     | 
| 
       21 
     | 
    
         
            -
            static VALUE 
     | 
| 
       22 
     | 
    
         
            -
            static VALUE 
     | 
| 
       23 
     | 
    
         
            -
            static int 
     | 
| 
       24 
     | 
    
         
            -
            static int 
     | 
| 
       25 
     | 
    
         
            -
            static int 
     | 
| 
       26 
     | 
    
         
            -
            //static int		read_from_str(Reader reader);
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            void
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                VALUE 
     | 
| 
       31 
     | 
    
         
            -
                VALUE 
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                reader->head =  
     | 
| 
       35 
     | 
    
         
            -
                 
     | 
| 
       36 
     | 
    
         
            -
                reader-> 
     | 
| 
       37 
     | 
    
         
            -
                reader-> 
     | 
| 
       38 
     | 
    
         
            -
                reader-> 
     | 
| 
       39 
     | 
    
         
            -
                reader-> 
     | 
| 
       40 
     | 
    
         
            -
                reader-> 
     | 
| 
       41 
     | 
    
         
            -
                reader-> 
     | 
| 
       42 
     | 
    
         
            -
                reader-> 
     | 
| 
       43 
     | 
    
         
            -
                reader-> 
     | 
| 
       44 
     | 
    
         
            -
                reader->free_head = 0;
         
     | 
| 
      
 19 
     | 
    
         
            +
            #define BUF_PAD 4
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            static VALUE rescue_cb(VALUE rdr, VALUE err);
         
     | 
| 
      
 22 
     | 
    
         
            +
            static VALUE io_cb(VALUE rdr);
         
     | 
| 
      
 23 
     | 
    
         
            +
            static VALUE partial_io_cb(VALUE rdr);
         
     | 
| 
      
 24 
     | 
    
         
            +
            static int   read_from_io(Reader reader);
         
     | 
| 
      
 25 
     | 
    
         
            +
            static int   read_from_fd(Reader reader);
         
     | 
| 
      
 26 
     | 
    
         
            +
            static int   read_from_io_partial(Reader reader);
         
     | 
| 
      
 27 
     | 
    
         
            +
            // static int		read_from_str(Reader reader);
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
         
     | 
| 
      
 30 
     | 
    
         
            +
                VALUE io_class = rb_obj_class(io);
         
     | 
| 
      
 31 
     | 
    
         
            +
                VALUE stat;
         
     | 
| 
      
 32 
     | 
    
         
            +
                VALUE ftype;
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                reader->head            = reader->base;
         
     | 
| 
      
 35 
     | 
    
         
            +
                *((char *)reader->head) = '\0';
         
     | 
| 
      
 36 
     | 
    
         
            +
                reader->end             = reader->head + sizeof(reader->base) - BUF_PAD;
         
     | 
| 
      
 37 
     | 
    
         
            +
                reader->tail            = reader->head;
         
     | 
| 
      
 38 
     | 
    
         
            +
                reader->read_end        = reader->head;
         
     | 
| 
      
 39 
     | 
    
         
            +
                reader->pro             = 0;
         
     | 
| 
      
 40 
     | 
    
         
            +
                reader->str             = 0;
         
     | 
| 
      
 41 
     | 
    
         
            +
                reader->pos             = 0;
         
     | 
| 
      
 42 
     | 
    
         
            +
                reader->line            = 1;
         
     | 
| 
      
 43 
     | 
    
         
            +
                reader->col             = 0;
         
     | 
| 
      
 44 
     | 
    
         
            +
                reader->free_head       = 0;
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                if (0 != fd) {
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 47 
     | 
    
         
            +
                    reader->read_func = read_from_fd;
         
     | 
| 
      
 48 
     | 
    
         
            +
                    reader->fd        = fd;
         
     | 
| 
       49 
49 
     | 
    
         
             
                } else if (rb_cString == io_class) {
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
                    reader->read_func = 0;
         
     | 
| 
      
 51 
     | 
    
         
            +
                    reader->in_str    = StringValuePtr(io);
         
     | 
| 
      
 52 
     | 
    
         
            +
                    reader->head      = (char *)reader->in_str;
         
     | 
| 
      
 53 
     | 
    
         
            +
                    reader->tail      = reader->head;
         
     | 
| 
      
 54 
     | 
    
         
            +
                    reader->read_end  = reader->head + RSTRING_LEN(io);
         
     | 
| 
       55 
55 
     | 
    
         
             
                } else if (oj_stringio_class == io_class) {
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                } else if (rb_cFile == io_class &&
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
            	reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
         
     | 
| 
      
 56 
     | 
    
         
            +
                    VALUE s = rb_funcall2(io, oj_string_id, 0, 0);
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    reader->read_func = 0;
         
     | 
| 
      
 59 
     | 
    
         
            +
                    reader->in_str    = StringValuePtr(s);
         
     | 
| 
      
 60 
     | 
    
         
            +
                    reader->head      = (char *)reader->in_str;
         
     | 
| 
      
 61 
     | 
    
         
            +
                    reader->tail      = reader->head;
         
     | 
| 
      
 62 
     | 
    
         
            +
                    reader->read_end  = reader->head + RSTRING_LEN(s);
         
     | 
| 
      
 63 
     | 
    
         
            +
                } else if (rb_cFile == io_class && Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
         
     | 
| 
      
 64 
     | 
    
         
            +
                           Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) &&
         
     | 
| 
      
 65 
     | 
    
         
            +
                           0 == strcmp("file", StringValuePtr(ftype)) &&
         
     | 
| 
      
 66 
     | 
    
         
            +
                           0 == FIX2INT(rb_funcall(io, oj_pos_id, 0))) {
         
     | 
| 
      
 67 
     | 
    
         
            +
                    reader->read_func = read_from_fd;
         
     | 
| 
      
 68 
     | 
    
         
            +
                    reader->fd        = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
         
     | 
| 
       70 
69 
     | 
    
         
             
                } else if (rb_respond_to(io, oj_readpartial_id)) {
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
      
 70 
     | 
    
         
            +
                    reader->read_func = read_from_io_partial;
         
     | 
| 
      
 71 
     | 
    
         
            +
                    reader->io        = io;
         
     | 
| 
       73 
72 
     | 
    
         
             
                } else if (rb_respond_to(io, oj_read_id)) {
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
      
 73 
     | 
    
         
            +
                    reader->read_func = read_from_io;
         
     | 
| 
      
 74 
     | 
    
         
            +
                    reader->io        = io;
         
     | 
| 
       76 
75 
     | 
    
         
             
                } else if (to_s) {
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
      
 76 
     | 
    
         
            +
                    volatile VALUE rstr = rb_funcall(io, oj_to_s_id, 0);
         
     | 
| 
       78 
77 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
      
 78 
     | 
    
         
            +
                    reader->read_func = 0;
         
     | 
| 
      
 79 
     | 
    
         
            +
                    reader->in_str    = StringValuePtr(rstr);
         
     | 
| 
      
 80 
     | 
    
         
            +
                    reader->head      = (char *)reader->in_str;
         
     | 
| 
      
 81 
     | 
    
         
            +
                    reader->tail      = reader->head;
         
     | 
| 
      
 82 
     | 
    
         
            +
                    reader->read_end  = reader->head + RSTRING_LEN(rstr);
         
     | 
| 
       84 
83 
     | 
    
         
             
                } else {
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
      
 84 
     | 
    
         
            +
                    rb_raise(rb_eArgError,
         
     | 
| 
      
 85 
     | 
    
         
            +
                             "parser io argument must be a String or respond to readpartial() or read().\n");
         
     | 
| 
       86 
86 
     | 
    
         
             
                }
         
     | 
| 
       87 
87 
     | 
    
         
             
            }
         
     | 
| 
       88 
88 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
            int
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                 
     | 
| 
       92 
     | 
    
         
            -
                size_t	shift = 0;
         
     | 
| 
      
 89 
     | 
    
         
            +
            int oj_reader_read(Reader reader) {
         
     | 
| 
      
 90 
     | 
    
         
            +
                int    err;
         
     | 
| 
      
 91 
     | 
    
         
            +
                size_t shift = 0;
         
     | 
| 
       93 
92 
     | 
    
         | 
| 
       94 
93 
     | 
    
         
             
                if (0 == reader->read_func) {
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
      
 94 
     | 
    
         
            +
                    return -1;
         
     | 
| 
       96 
95 
     | 
    
         
             
                }
         
     | 
| 
       97 
96 
     | 
    
         
             
                // if there is not much room to read into, shift or realloc a larger buffer.
         
     | 
| 
       98 
97 
     | 
    
         
             
                if (reader->head < reader->tail && 4096 > reader->end - reader->tail) {
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
      
 98 
     | 
    
         
            +
                    if (0 == reader->pro) {
         
     | 
| 
      
 99 
     | 
    
         
            +
                        shift = reader->tail - reader->head;
         
     | 
| 
      
 100 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 101 
     | 
    
         
            +
                        shift = reader->pro - reader->head - 1;  // leave one character so we can backup one
         
     | 
| 
      
 102 
     | 
    
         
            +
                    }
         
     | 
| 
      
 103 
     | 
    
         
            +
                    if (0 >= shift) { /* no space left so allocate more */
         
     | 
| 
      
 104 
     | 
    
         
            +
                        const char *old  = reader->head;
         
     | 
| 
      
 105 
     | 
    
         
            +
                        size_t      size = reader->end - reader->head + BUF_PAD;
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                        if (reader->head == reader->base) {
         
     | 
| 
      
 108 
     | 
    
         
            +
                            reader->head = ALLOC_N(char, size * 2);
         
     | 
| 
      
 109 
     | 
    
         
            +
                            memcpy((char *)reader->head, old, size);
         
     | 
| 
      
 110 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 111 
     | 
    
         
            +
                            REALLOC_N(reader->head, char, size * 2);
         
     | 
| 
      
 112 
     | 
    
         
            +
                        }
         
     | 
| 
      
 113 
     | 
    
         
            +
                        reader->free_head = 1;
         
     | 
| 
      
 114 
     | 
    
         
            +
                        reader->end       = reader->head + size * 2 - BUF_PAD;
         
     | 
| 
      
 115 
     | 
    
         
            +
                        reader->tail      = reader->head + (reader->tail - old);
         
     | 
| 
      
 116 
     | 
    
         
            +
                        reader->read_end  = reader->head + (reader->read_end - old);
         
     | 
| 
      
 117 
     | 
    
         
            +
                        if (0 != reader->pro) {
         
     | 
| 
      
 118 
     | 
    
         
            +
                            reader->pro = reader->head + (reader->pro - old);
         
     | 
| 
      
 119 
     | 
    
         
            +
                        }
         
     | 
| 
      
 120 
     | 
    
         
            +
                        if (0 != reader->str) {
         
     | 
| 
      
 121 
     | 
    
         
            +
                            reader->str = reader->head + (reader->str - old);
         
     | 
| 
      
 122 
     | 
    
         
            +
                        }
         
     | 
| 
      
 123 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 124 
     | 
    
         
            +
                        memmove((char *)reader->head,
         
     | 
| 
      
 125 
     | 
    
         
            +
                                reader->head + shift,
         
     | 
| 
      
 126 
     | 
    
         
            +
                                reader->read_end - (reader->head + shift));
         
     | 
| 
      
 127 
     | 
    
         
            +
                        reader->tail -= shift;
         
     | 
| 
      
 128 
     | 
    
         
            +
                        reader->read_end -= shift;
         
     | 
| 
      
 129 
     | 
    
         
            +
                        if (0 != reader->pro) {
         
     | 
| 
      
 130 
     | 
    
         
            +
                            reader->pro -= shift;
         
     | 
| 
      
 131 
     | 
    
         
            +
                        }
         
     | 
| 
      
 132 
     | 
    
         
            +
                        if (0 != reader->str) {
         
     | 
| 
      
 133 
     | 
    
         
            +
                            reader->str -= shift;
         
     | 
| 
      
 134 
     | 
    
         
            +
                        }
         
     | 
| 
      
 135 
     | 
    
         
            +
                    }
         
     | 
| 
       135 
136 
     | 
    
         
             
                }
         
     | 
| 
       136 
     | 
    
         
            -
                err 
     | 
| 
       137 
     | 
    
         
            -
                *(char*)reader->read_end = '\0';
         
     | 
| 
      
 137 
     | 
    
         
            +
                err                       = reader->read_func(reader);
         
     | 
| 
      
 138 
     | 
    
         
            +
                *(char *)reader->read_end = '\0';
         
     | 
| 
       138 
139 
     | 
    
         | 
| 
       139 
140 
     | 
    
         
             
                return err;
         
     | 
| 
       140 
141 
     | 
    
         
             
            }
         
     | 
| 
       141 
142 
     | 
    
         | 
| 
       142 
     | 
    
         
            -
            static VALUE
         
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
                VALUE	clas = rb_obj_class(err);
         
     | 
| 
      
 143 
     | 
    
         
            +
            static VALUE rescue_cb(VALUE rbuf, VALUE err) {
         
     | 
| 
      
 144 
     | 
    
         
            +
                VALUE clas = rb_obj_class(err);
         
     | 
| 
       145 
145 
     | 
    
         | 
| 
       146 
146 
     | 
    
         
             
                if (rb_eTypeError != clas && rb_eEOFError != clas) {
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
      
 147 
     | 
    
         
            +
                    Reader reader = (Reader)rbuf;
         
     | 
| 
       148 
148 
     | 
    
         | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
      
 149 
     | 
    
         
            +
                    rb_raise(clas, "at line %d, column %d\n", reader->line, reader->col);
         
     | 
| 
       150 
150 
     | 
    
         
             
                }
         
     | 
| 
       151 
151 
     | 
    
         
             
                return Qfalse;
         
     | 
| 
       152 
152 
     | 
    
         
             
            }
         
     | 
| 
       153 
153 
     | 
    
         | 
| 
       154 
     | 
    
         
            -
            static VALUE
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
                 
     | 
| 
       157 
     | 
    
         
            -
                VALUE 
     | 
| 
       158 
     | 
    
         
            -
                 
     | 
| 
       159 
     | 
    
         
            -
                 
     | 
| 
       160 
     | 
    
         
            -
                size_t	cnt;
         
     | 
| 
      
 154 
     | 
    
         
            +
            static VALUE partial_io_cb(VALUE rbuf) {
         
     | 
| 
      
 155 
     | 
    
         
            +
                Reader reader = (Reader)rbuf;
         
     | 
| 
      
 156 
     | 
    
         
            +
                VALUE  args[1];
         
     | 
| 
      
 157 
     | 
    
         
            +
                VALUE  rstr;
         
     | 
| 
      
 158 
     | 
    
         
            +
                char * str;
         
     | 
| 
      
 159 
     | 
    
         
            +
                size_t cnt;
         
     | 
| 
       161 
160 
     | 
    
         | 
| 
       162 
161 
     | 
    
         
             
                args[0] = ULONG2NUM(reader->end - reader->tail);
         
     | 
| 
       163 
     | 
    
         
            -
                rstr 
     | 
| 
      
 162 
     | 
    
         
            +
                rstr    = rb_funcall2(reader->io, oj_readpartial_id, 1, args);
         
     | 
| 
       164 
163 
     | 
    
         
             
                if (Qnil == rstr) {
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
      
 164 
     | 
    
         
            +
                    return Qfalse;
         
     | 
| 
       166 
165 
     | 
    
         
             
                }
         
     | 
| 
       167 
166 
     | 
    
         
             
                str = StringValuePtr(rstr);
         
     | 
| 
       168 
167 
     | 
    
         
             
                cnt = RSTRING_LEN(rstr);
         
     | 
| 
       169 
     | 
    
         
            -
                //printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
         
     | 
| 
      
 168 
     | 
    
         
            +
                // printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
         
     | 
| 
       170 
169 
     | 
    
         
             
                strcpy(reader->tail, str);
         
     | 
| 
       171 
170 
     | 
    
         
             
                reader->read_end = reader->tail + cnt;
         
     | 
| 
       172 
171 
     | 
    
         | 
| 
       173 
172 
     | 
    
         
             
                return Qtrue;
         
     | 
| 
       174 
173 
     | 
    
         
             
            }
         
     | 
| 
       175 
174 
     | 
    
         | 
| 
       176 
     | 
    
         
            -
            static VALUE
         
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
                 
     | 
| 
       179 
     | 
    
         
            -
                VALUE 
     | 
| 
       180 
     | 
    
         
            -
                 
     | 
| 
       181 
     | 
    
         
            -
                 
     | 
| 
       182 
     | 
    
         
            -
                size_t	cnt;
         
     | 
| 
      
 175 
     | 
    
         
            +
            static VALUE io_cb(VALUE rbuf) {
         
     | 
| 
      
 176 
     | 
    
         
            +
                Reader reader = (Reader)rbuf;
         
     | 
| 
      
 177 
     | 
    
         
            +
                VALUE  args[1];
         
     | 
| 
      
 178 
     | 
    
         
            +
                VALUE  rstr;
         
     | 
| 
      
 179 
     | 
    
         
            +
                char * str;
         
     | 
| 
      
 180 
     | 
    
         
            +
                size_t cnt;
         
     | 
| 
       183 
181 
     | 
    
         | 
| 
       184 
182 
     | 
    
         
             
                args[0] = ULONG2NUM(reader->end - reader->tail);
         
     | 
| 
       185 
     | 
    
         
            -
                rstr 
     | 
| 
      
 183 
     | 
    
         
            +
                rstr    = rb_funcall2(reader->io, oj_read_id, 1, args);
         
     | 
| 
       186 
184 
     | 
    
         
             
                if (Qnil == rstr) {
         
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
      
 185 
     | 
    
         
            +
                    return Qfalse;
         
     | 
| 
       188 
186 
     | 
    
         
             
                }
         
     | 
| 
       189 
187 
     | 
    
         
             
                str = StringValuePtr(rstr);
         
     | 
| 
       190 
188 
     | 
    
         
             
                cnt = RSTRING_LEN(rstr);
         
     | 
| 
       191 
     | 
    
         
            -
                //printf("*** read %lu bytes, str: '%s'\n", cnt, str);
         
     | 
| 
      
 189 
     | 
    
         
            +
                // printf("*** read %lu bytes, str: '%s'\n", cnt, str);
         
     | 
| 
       192 
190 
     | 
    
         
             
                strcpy(reader->tail, str);
         
     | 
| 
       193 
191 
     | 
    
         
             
                reader->read_end = reader->tail + cnt;
         
     | 
| 
       194 
192 
     | 
    
         | 
| 
       195 
193 
     | 
    
         
             
                return Qtrue;
         
     | 
| 
       196 
194 
     | 
    
         
             
            }
         
     | 
| 
       197 
195 
     | 
    
         | 
| 
       198 
     | 
    
         
            -
            static int
         
     | 
| 
       199 
     | 
    
         
            -
            read_from_io_partial(Reader reader) {
         
     | 
| 
      
 196 
     | 
    
         
            +
            static int read_from_io_partial(Reader reader) {
         
     | 
| 
       200 
197 
     | 
    
         
             
                return (Qfalse == rb_rescue(partial_io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
         
     | 
| 
       201 
198 
     | 
    
         
             
            }
         
     | 
| 
       202 
199 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
            static int
         
     | 
| 
       204 
     | 
    
         
            -
            read_from_io(Reader reader) {
         
     | 
| 
      
 200 
     | 
    
         
            +
            static int read_from_io(Reader reader) {
         
     | 
| 
       205 
201 
     | 
    
         
             
                return (Qfalse == rb_rescue(io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
         
     | 
| 
       206 
202 
     | 
    
         
             
            }
         
     | 
| 
       207 
203 
     | 
    
         | 
| 
       208 
     | 
    
         
            -
            static int
         
     | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
                 
     | 
| 
       211 
     | 
    
         
            -
                size_t	max = reader->end - reader->tail;
         
     | 
| 
      
 204 
     | 
    
         
            +
            static int read_from_fd(Reader reader) {
         
     | 
| 
      
 205 
     | 
    
         
            +
                ssize_t cnt;
         
     | 
| 
      
 206 
     | 
    
         
            +
                size_t  max = reader->end - reader->tail;
         
     | 
| 
       212 
207 
     | 
    
         | 
| 
       213 
208 
     | 
    
         
             
                cnt = read(reader->fd, reader->tail, max);
         
     | 
| 
       214 
209 
     | 
    
         
             
                if (cnt <= 0) {
         
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
      
 210 
     | 
    
         
            +
                    return -1;
         
     | 
| 
       216 
211 
     | 
    
         
             
                } else if (0 != cnt) {
         
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
      
 212 
     | 
    
         
            +
                    reader->read_end = reader->tail + cnt;
         
     | 
| 
       218 
213 
     | 
    
         
             
                }
         
     | 
| 
       219 
214 
     | 
    
         
             
                return 0;
         
     | 
| 
       220 
215 
     | 
    
         
             
            }
         
     | 
    
        data/ext/oj/reader.h
    CHANGED
    
    | 
         @@ -1,42 +1,43 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            // Copyright (c) 2011 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 
     | 
    
         
             
            #ifndef OJ_READER_H
         
     | 
| 
       4 
5 
     | 
    
         
             
            #define OJ_READER_H
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            typedef struct _reader {
         
     | 
| 
       7 
     | 
    
         
            -
                char 
     | 
| 
       8 
     | 
    
         
            -
                char 
     | 
| 
       9 
     | 
    
         
            -
                char 
     | 
| 
       10 
     | 
    
         
            -
                char 
     | 
| 
       11 
     | 
    
         
            -
                char 
     | 
| 
       12 
     | 
    
         
            -
                char 
     | 
| 
       13 
     | 
    
         
            -
                char 
     | 
| 
       14 
     | 
    
         
            -
                long 
     | 
| 
       15 
     | 
    
         
            -
                int 
     | 
| 
       16 
     | 
    
         
            -
                int 
     | 
| 
       17 
     | 
    
         
            -
                int 
     | 
| 
       18 
     | 
    
         
            -
                int 
     | 
| 
      
 8 
     | 
    
         
            +
                char  base[0x00001000];
         
     | 
| 
      
 9 
     | 
    
         
            +
                char *head;
         
     | 
| 
      
 10 
     | 
    
         
            +
                char *end;
         
     | 
| 
      
 11 
     | 
    
         
            +
                char *tail;
         
     | 
| 
      
 12 
     | 
    
         
            +
                char *read_end; /* one past last character read */
         
     | 
| 
      
 13 
     | 
    
         
            +
                char *pro;      /* protection start, buffer can not slide past this point */
         
     | 
| 
      
 14 
     | 
    
         
            +
                char *str;      /* start of current string being read */
         
     | 
| 
      
 15 
     | 
    
         
            +
                long  pos;
         
     | 
| 
      
 16 
     | 
    
         
            +
                int   line;
         
     | 
| 
      
 17 
     | 
    
         
            +
                int   col;
         
     | 
| 
      
 18 
     | 
    
         
            +
                int   free_head;
         
     | 
| 
      
 19 
     | 
    
         
            +
                int (*read_func)(struct _reader *reader);
         
     | 
| 
       19 
20 
     | 
    
         
             
                union {
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 21 
     | 
    
         
            +
                    int         fd;
         
     | 
| 
      
 22 
     | 
    
         
            +
                    VALUE       io;
         
     | 
| 
      
 23 
     | 
    
         
            +
                    const char *in_str;
         
     | 
| 
       23 
24 
     | 
    
         
             
                };
         
     | 
| 
       24 
     | 
    
         
            -
            } *Reader;
         
     | 
| 
      
 25 
     | 
    
         
            +
            } * Reader;
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
            extern void 
     | 
| 
       27 
     | 
    
         
            -
            extern int 
     | 
| 
      
 27 
     | 
    
         
            +
            extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
         
     | 
| 
      
 28 
     | 
    
         
            +
            extern int  oj_reader_read(Reader reader);
         
     | 
| 
       28 
29 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
            static inline char
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                // 
     | 
| 
      
 30 
     | 
    
         
            +
            static inline char reader_get(Reader reader) {
         
     | 
| 
      
 31 
     | 
    
         
            +
                // printf("*** drive get from '%s'  from start: %ld	buf: %p	 from read_end: %ld\n",
         
     | 
| 
      
 32 
     | 
    
         
            +
                // reader->tail, reader->tail - reader->head, reader->head, reader->read_end - reader->tail);
         
     | 
| 
       32 
33 
     | 
    
         
             
                if (reader->read_end <= reader->tail) {
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
                    if (0 != oj_reader_read(reader)) {
         
     | 
| 
      
 35 
     | 
    
         
            +
                        return '\0';
         
     | 
| 
      
 36 
     | 
    
         
            +
                    }
         
     | 
| 
       36 
37 
     | 
    
         
             
                }
         
     | 
| 
       37 
38 
     | 
    
         
             
                if ('\n' == *reader->tail) {
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
                    reader->line++;
         
     | 
| 
      
 40 
     | 
    
         
            +
                    reader->col = 0;
         
     | 
| 
       40 
41 
     | 
    
         
             
                }
         
     | 
| 
       41 
42 
     | 
    
         
             
                reader->col++;
         
     | 
| 
       42 
43 
     | 
    
         
             
                reader->pos++;
         
     | 
| 
         @@ -44,46 +45,40 @@ reader_get(Reader reader) { 
     | 
|
| 
       44 
45 
     | 
    
         
             
                return *reader->tail++;
         
     | 
| 
       45 
46 
     | 
    
         
             
            }
         
     | 
| 
       46 
47 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
            static inline void
         
     | 
| 
       48 
     | 
    
         
            -
            reader_backup(Reader reader) {
         
     | 
| 
      
 48 
     | 
    
         
            +
            static inline void reader_backup(Reader reader) {
         
     | 
| 
       49 
49 
     | 
    
         
             
                reader->tail--;
         
     | 
| 
       50 
50 
     | 
    
         
             
                reader->col--;
         
     | 
| 
       51 
51 
     | 
    
         
             
                reader->pos--;
         
     | 
| 
       52 
52 
     | 
    
         
             
                if (0 >= reader->col) {
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                    reader->line--;
         
     | 
| 
      
 54 
     | 
    
         
            +
                    // allow col to be negative since we never backup twice in a row
         
     | 
| 
       55 
55 
     | 
    
         
             
                }
         
     | 
| 
       56 
56 
     | 
    
         
             
            }
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
            static inline void
         
     | 
| 
       59 
     | 
    
         
            -
            reader_protect(Reader reader) {
         
     | 
| 
      
 58 
     | 
    
         
            +
            static inline void reader_protect(Reader reader) {
         
     | 
| 
       60 
59 
     | 
    
         
             
                reader->pro = reader->tail;
         
     | 
| 
       61 
     | 
    
         
            -
                reader->str = reader->tail; 
     | 
| 
      
 60 
     | 
    
         
            +
                reader->str = reader->tail;  // can't have str before pro
         
     | 
| 
       62 
61 
     | 
    
         
             
            }
         
     | 
| 
       63 
62 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
            static inline void
         
     | 
| 
       65 
     | 
    
         
            -
            reader_release(Reader reader) {
         
     | 
| 
      
 63 
     | 
    
         
            +
            static inline void reader_release(Reader reader) {
         
     | 
| 
       66 
64 
     | 
    
         
             
                reader->pro = 0;
         
     | 
| 
       67 
65 
     | 
    
         
             
            }
         
     | 
| 
       68 
66 
     | 
    
         | 
| 
       69 
67 
     | 
    
         
             
            /* Starts by reading a character so it is safe to use with an empty or
         
     | 
| 
       70 
68 
     | 
    
         
             
             * compacted buffer.
         
     | 
| 
       71 
69 
     | 
    
         
             
             */
         
     | 
| 
       72 
     | 
    
         
            -
            static inline char
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                char	c;
         
     | 
| 
      
 70 
     | 
    
         
            +
            static inline char reader_next_non_white(Reader reader) {
         
     | 
| 
      
 71 
     | 
    
         
            +
                char c;
         
     | 
| 
       75 
72 
     | 
    
         | 
| 
       76 
73 
     | 
    
         
             
                while ('\0' != (c = reader_get(reader))) {
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
            	    return c;
         
     | 
| 
       86 
     | 
    
         
            -
            	}
         
     | 
| 
      
 74 
     | 
    
         
            +
                    switch (c) {
         
     | 
| 
      
 75 
     | 
    
         
            +
                    case ' ':
         
     | 
| 
      
 76 
     | 
    
         
            +
                    case '\t':
         
     | 
| 
      
 77 
     | 
    
         
            +
                    case '\f':
         
     | 
| 
      
 78 
     | 
    
         
            +
                    case '\n':
         
     | 
| 
      
 79 
     | 
    
         
            +
                    case '\r': break;
         
     | 
| 
      
 80 
     | 
    
         
            +
                    default: return c;
         
     | 
| 
      
 81 
     | 
    
         
            +
                    }
         
     | 
| 
       87 
82 
     | 
    
         
             
                }
         
     | 
| 
       88 
83 
     | 
    
         
             
                return '\0';
         
     | 
| 
       89 
84 
     | 
    
         
             
            }
         
     | 
| 
         @@ -91,56 +86,48 @@ reader_next_non_white(Reader reader) { 
     | 
|
| 
       91 
86 
     | 
    
         
             
            /* Starts by reading a character so it is safe to use with an empty or
         
     | 
| 
       92 
87 
     | 
    
         
             
             * compacted buffer.
         
     | 
| 
       93 
88 
     | 
    
         
             
             */
         
     | 
| 
       94 
     | 
    
         
            -
            static inline char
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                char	c;
         
     | 
| 
      
 89 
     | 
    
         
            +
            static inline char reader_next_white(Reader reader) {
         
     | 
| 
      
 90 
     | 
    
         
            +
                char c;
         
     | 
| 
       97 
91 
     | 
    
         | 
| 
       98 
92 
     | 
    
         
             
                while ('\0' != (c = reader_get(reader))) {
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
            	    break;
         
     | 
| 
       109 
     | 
    
         
            -
            	}
         
     | 
| 
      
 93 
     | 
    
         
            +
                    switch (c) {
         
     | 
| 
      
 94 
     | 
    
         
            +
                    case ' ':
         
     | 
| 
      
 95 
     | 
    
         
            +
                    case '\t':
         
     | 
| 
      
 96 
     | 
    
         
            +
                    case '\f':
         
     | 
| 
      
 97 
     | 
    
         
            +
                    case '\n':
         
     | 
| 
      
 98 
     | 
    
         
            +
                    case '\r':
         
     | 
| 
      
 99 
     | 
    
         
            +
                    case '\0': return c;
         
     | 
| 
      
 100 
     | 
    
         
            +
                    default: break;
         
     | 
| 
      
 101 
     | 
    
         
            +
                    }
         
     | 
| 
       110 
102 
     | 
    
         
             
                }
         
     | 
| 
       111 
103 
     | 
    
         
             
                return '\0';
         
     | 
| 
       112 
104 
     | 
    
         
             
            }
         
     | 
| 
       113 
105 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
            static inline int
         
     | 
| 
       115 
     | 
    
         
            -
            reader_expect(Reader reader, const char *s) {
         
     | 
| 
      
 106 
     | 
    
         
            +
            static inline int reader_expect(Reader reader, const char *s) {
         
     | 
| 
       116 
107 
     | 
    
         
             
                for (; '\0' != *s; s++) {
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 108 
     | 
    
         
            +
                    if (reader_get(reader) != *s) {
         
     | 
| 
      
 109 
     | 
    
         
            +
                        return -1;
         
     | 
| 
      
 110 
     | 
    
         
            +
                    }
         
     | 
| 
       120 
111 
     | 
    
         
             
                }
         
     | 
| 
       121 
112 
     | 
    
         
             
                return 0;
         
     | 
| 
       122 
113 
     | 
    
         
             
            }
         
     | 
| 
       123 
114 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
            static inline void
         
     | 
| 
       125 
     | 
    
         
            -
            reader_cleanup(Reader reader) {
         
     | 
| 
      
 115 
     | 
    
         
            +
            static inline void reader_cleanup(Reader reader) {
         
     | 
| 
       126 
116 
     | 
    
         
             
                if (reader->free_head && 0 != reader->head) {
         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
      
 117 
     | 
    
         
            +
                    xfree((char *)reader->head);
         
     | 
| 
      
 118 
     | 
    
         
            +
                    reader->head      = 0;
         
     | 
| 
      
 119 
     | 
    
         
            +
                    reader->free_head = 0;
         
     | 
| 
       130 
120 
     | 
    
         
             
                }
         
     | 
| 
       131 
121 
     | 
    
         
             
            }
         
     | 
| 
       132 
122 
     | 
    
         | 
| 
       133 
     | 
    
         
            -
            static inline int
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
                switch(c) {
         
     | 
| 
      
 123 
     | 
    
         
            +
            static inline int is_white(char c) {
         
     | 
| 
      
 124 
     | 
    
         
            +
                switch (c) {
         
     | 
| 
       136 
125 
     | 
    
         
             
                case ' ':
         
     | 
| 
       137 
126 
     | 
    
         
             
                case '\t':
         
     | 
| 
       138 
127 
     | 
    
         
             
                case '\f':
         
     | 
| 
       139 
128 
     | 
    
         
             
                case '\n':
         
     | 
| 
       140 
     | 
    
         
            -
                case '\r':
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                default:
         
     | 
| 
       143 
     | 
    
         
            -
            	break;
         
     | 
| 
      
 129 
     | 
    
         
            +
                case '\r': return 1;
         
     | 
| 
      
 130 
     | 
    
         
            +
                default: break;
         
     | 
| 
       144 
131 
     | 
    
         
             
                }
         
     | 
| 
       145 
132 
     | 
    
         
             
                return 0;
         
     | 
| 
       146 
133 
     | 
    
         
             
            }
         
     |