oj 3.11.0 → 3.11.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/ext/oj/buf.h +34 -38
  4. data/ext/oj/cache8.c +59 -62
  5. data/ext/oj/cache8.h +8 -7
  6. data/ext/oj/circarray.c +33 -35
  7. data/ext/oj/circarray.h +11 -9
  8. data/ext/oj/code.c +170 -174
  9. data/ext/oj/code.h +21 -20
  10. data/ext/oj/compat.c +159 -166
  11. data/ext/oj/custom.c +802 -851
  12. data/ext/oj/dump.c +766 -778
  13. data/ext/oj/dump.h +49 -51
  14. data/ext/oj/dump_compat.c +1 -0
  15. data/ext/oj/dump_leaf.c +116 -157
  16. data/ext/oj/dump_object.c +609 -628
  17. data/ext/oj/dump_strict.c +318 -327
  18. data/ext/oj/encode.h +3 -4
  19. data/ext/oj/err.c +39 -25
  20. data/ext/oj/err.h +24 -15
  21. data/ext/oj/extconf.rb +2 -1
  22. data/ext/oj/fast.c +1008 -1038
  23. data/ext/oj/hash.c +62 -66
  24. data/ext/oj/hash.h +7 -6
  25. data/ext/oj/hash_test.c +450 -443
  26. data/ext/oj/mimic_json.c +413 -402
  27. data/ext/oj/object.c +559 -528
  28. data/ext/oj/odd.c +123 -128
  29. data/ext/oj/odd.h +27 -25
  30. data/ext/oj/oj.c +1131 -924
  31. data/ext/oj/oj.h +286 -298
  32. data/ext/oj/parse.c +938 -930
  33. data/ext/oj/parse.h +70 -69
  34. data/ext/oj/rails.c +836 -839
  35. data/ext/oj/rails.h +7 -7
  36. data/ext/oj/reader.c +135 -140
  37. data/ext/oj/reader.h +66 -79
  38. data/ext/oj/resolve.c +43 -43
  39. data/ext/oj/resolve.h +3 -2
  40. data/ext/oj/rxclass.c +67 -68
  41. data/ext/oj/rxclass.h +12 -10
  42. data/ext/oj/saj.c +451 -479
  43. data/ext/oj/scp.c +93 -103
  44. data/ext/oj/sparse.c +770 -730
  45. data/ext/oj/stream_writer.c +120 -149
  46. data/ext/oj/strict.c +71 -86
  47. data/ext/oj/string_writer.c +198 -243
  48. data/ext/oj/trace.c +29 -33
  49. data/ext/oj/trace.h +14 -11
  50. data/ext/oj/util.c +103 -103
  51. data/ext/oj/util.h +3 -2
  52. data/ext/oj/val_stack.c +47 -47
  53. data/ext/oj/val_stack.h +79 -86
  54. data/ext/oj/wab.c +291 -309
  55. data/lib/oj/bag.rb +1 -0
  56. data/lib/oj/easy_hash.rb +5 -4
  57. data/lib/oj/mimic.rb +0 -12
  58. data/lib/oj/version.rb +1 -1
  59. data/test/activerecord/result_test.rb +7 -2
  60. data/test/foo.rb +35 -32
  61. data/test/helper.rb +10 -0
  62. data/test/json_gem/json_generator_test.rb +15 -3
  63. data/test/json_gem/test_helper.rb +8 -0
  64. data/test/test_compat.rb +2 -2
  65. data/test/test_generate.rb +21 -0
  66. data/test/test_hash.rb +10 -0
  67. data/test/test_scp.rb +1 -1
  68. metadata +4 -2
data/ext/oj/resolve.c CHANGED
@@ -1,76 +1,76 @@
1
1
  // Copyright (c) 2012 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
2
3
 
3
- #include <stdlib.h>
4
4
  #include <stdio.h>
5
+ #include <stdlib.h>
5
6
  #include <string.h>
6
7
  #ifdef HAVE_PTHREAD_MUTEX_INIT
7
8
  #include <pthread.h>
8
9
  #endif
9
10
 
10
- #include "oj.h"
11
11
  #include "err.h"
12
- #include "parse.h"
13
12
  #include "hash.h"
13
+ #include "oj.h"
14
+ #include "parse.h"
14
15
 
15
- inline static VALUE
16
- resolve_classname(VALUE mod, const char *classname, int auto_define) {
17
- VALUE clas;
18
- ID ci = rb_intern(classname);
16
+ inline static VALUE resolve_classname(VALUE mod, const char *classname, int auto_define) {
17
+ VALUE clas;
18
+ ID ci = rb_intern(classname);
19
19
 
20
20
  if (rb_const_defined_at(mod, ci)) {
21
- clas = rb_const_get_at(mod, ci);
21
+ clas = rb_const_get_at(mod, ci);
22
22
  } else if (auto_define) {
23
- clas = rb_define_class_under(mod, classname, oj_bag_class);
23
+ clas = rb_define_class_under(mod, classname, oj_bag_class);
24
24
  } else {
25
- clas = Qundef;
25
+ clas = Qundef;
26
26
  }
27
27
  return clas;
28
28
  }
29
29
 
30
30
  static VALUE
31
31
  resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
32
- char class_name[1024];
33
- VALUE clas;
34
- char *end = class_name + sizeof(class_name) - 1;
35
- char *s;
36
- const char *n = name;
32
+ char class_name[1024];
33
+ VALUE clas;
34
+ char * end = class_name + sizeof(class_name) - 1;
35
+ char * s;
36
+ const char *n = name;
37
37
 
38
38
  clas = rb_cObject;
39
39
  for (s = class_name; 0 < len; n++, len--) {
40
- if (':' == *n) {
41
- *s = '\0';
42
- n++;
43
- len--;
44
- if (':' != *n) {
45
- return Qundef;
46
- }
47
- if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
48
- return Qundef;
49
- }
50
- s = class_name;
51
- } else if (end <= s) {
52
- return Qundef;
53
- } else {
54
- *s++ = *n;
55
- }
40
+ if (':' == *n) {
41
+ *s = '\0';
42
+ n++;
43
+ len--;
44
+ if (':' != *n) {
45
+ return Qundef;
46
+ }
47
+ if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
48
+ return Qundef;
49
+ }
50
+ s = class_name;
51
+ } else if (end <= s) {
52
+ return Qundef;
53
+ } else {
54
+ *s++ = *n;
55
+ }
56
56
  }
57
57
  *s = '\0';
58
58
  if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
59
- oj_set_error_at(pi, error_class, __FILE__, __LINE__, "class %s is not defined", name);
60
- if (Qnil != error_class) {
61
- pi->err_class = error_class;
62
- }
59
+ oj_set_error_at(pi, error_class, __FILE__, __LINE__, "class %s is not defined", name);
60
+ if (Qnil != error_class) {
61
+ pi->err_class = error_class;
62
+ }
63
63
  }
64
64
  return clas;
65
65
  }
66
66
 
67
67
  VALUE
68
68
  oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
69
- VALUE clas;
70
- VALUE *slot;
69
+ VALUE clas;
70
+ VALUE *slot;
71
71
 
72
72
  if (No == pi->options.class_cache) {
73
- return resolve_classpath(pi, name, len, auto_define, error_class);
73
+ return resolve_classpath(pi, name, len, auto_define, error_class);
74
74
  }
75
75
  #ifdef HAVE_PTHREAD_MUTEX_INIT
76
76
  pthread_mutex_lock(&oj_cache_mutex);
@@ -78,9 +78,9 @@ oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE
78
78
  rb_mutex_lock(oj_cache_mutex);
79
79
  #endif
80
80
  if (Qnil == (clas = oj_class_hash_get(name, len, &slot))) {
81
- if (Qundef != (clas = resolve_classpath(pi, name, len, auto_define, error_class))) {
82
- *slot = clas;
83
- }
81
+ if (Qundef != (clas = resolve_classpath(pi, name, len, auto_define, error_class))) {
82
+ *slot = clas;
83
+ }
84
84
  }
85
85
  #ifdef HAVE_PTHREAD_MUTEX_INIT
86
86
  pthread_mutex_unlock(&oj_cache_mutex);
@@ -92,8 +92,8 @@ oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE
92
92
 
93
93
  VALUE
94
94
  oj_name2struct(ParseInfo pi, VALUE nameVal, VALUE error_class) {
95
- size_t len = RSTRING_LEN(nameVal);
96
- const char *str = StringValuePtr(nameVal);
95
+ size_t len = RSTRING_LEN(nameVal);
96
+ const char *str = StringValuePtr(nameVal);
97
97
 
98
98
  return resolve_classpath(pi, str, len, 0, error_class);
99
99
  }
data/ext/oj/resolve.h CHANGED
@@ -1,11 +1,12 @@
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_RESOLVE_H
4
5
  #define OJ_RESOLVE_H
5
6
 
6
7
  #include "ruby.h"
7
8
 
8
- extern VALUE oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class);
9
- extern VALUE oj_name2struct(ParseInfo pi, VALUE nameVal, VALUE error_class);
9
+ extern VALUE oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class);
10
+ extern VALUE oj_name2struct(ParseInfo pi, VALUE nameVal, VALUE error_class);
10
11
 
11
12
  #endif /* OJ_RESOLVE_H */
data/ext/oj/rxclass.c CHANGED
@@ -1,10 +1,11 @@
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
- #include <sys/types.h>
4
- #include <stdlib.h>
5
4
  #include <errno.h>
6
- #include <string.h>
7
5
  #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <sys/types.h>
8
9
  #if !IS_WINDOWS
9
10
  #include <regex.h>
10
11
  #endif
@@ -12,65 +13,64 @@
12
13
  #include "rxclass.h"
13
14
 
14
15
  typedef struct _rxC {
15
- struct _rxC *next;
16
- VALUE rrx;
16
+ struct _rxC *next;
17
+ VALUE rrx;
17
18
  #if !IS_WINDOWS
18
- regex_t rx;
19
+ regex_t rx;
19
20
  #endif
20
- VALUE clas;
21
- char src[256];
22
- } *RxC;
21
+ VALUE clas;
22
+ char src[256];
23
+ } * RxC;
23
24
 
24
- void
25
- oj_rxclass_init(RxClass rc) {
25
+ void oj_rxclass_init(RxClass rc) {
26
26
  *rc->err = '\0';
27
27
  rc->head = NULL;
28
28
  rc->tail = NULL;
29
29
  }
30
30
 
31
- void
32
- oj_rxclass_cleanup(RxClass rc) {
33
- RxC rxc;
31
+ void oj_rxclass_cleanup(RxClass rc) {
32
+ RxC rxc;
34
33
 
35
34
  while (NULL != (rxc = rc->head)) {
36
- rc->head = rc->head->next;
35
+ rc->head = rc->head->next;
37
36
  #if !IS_WINDOWS
38
- if (Qnil == rxc->rrx) {
39
- regfree(&rxc->rx);
40
- }
41
- xfree(rxc);
37
+ if (Qnil == rxc->rrx) {
38
+ regfree(&rxc->rx);
39
+ }
40
+ xfree(rxc);
42
41
  #endif
43
42
  }
44
43
  }
45
44
 
46
- void
47
- oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
48
- RxC rxc = ALLOC_N(struct _rxC, 1);
45
+ void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
46
+ RxC rxc = ALLOC_N(struct _rxC, 1);
49
47
 
50
48
  memset(rxc, 0, sizeof(struct _rxC));
51
- rxc->rrx = rx;
49
+ rxc->rrx = rx;
52
50
  rxc->clas = clas;
53
51
  if (NULL == rc->tail) {
54
- rc->head = rxc;
52
+ rc->head = rxc;
55
53
  } else {
56
- rc->tail->next = rxc;
54
+ rc->tail->next = rxc;
57
55
  }
58
56
  rc->tail = rxc;
59
57
  }
60
58
 
61
59
  // Attempt to compile the expression. If it fails populate the error code..
62
- int
63
- oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
64
- RxC rxc;
60
+ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
61
+ RxC rxc;
65
62
  #if !IS_WINDOWS
66
- int err;
67
- int flags = 0;
63
+ int err;
64
+ int flags = 0;
68
65
  #endif
69
66
  if (sizeof(rxc->src) <= strlen(expr)) {
70
- snprintf(rc->err, sizeof(rc->err), "expressions must be less than %lu characters", (unsigned long)sizeof(rxc->src));
71
- return EINVAL;
67
+ snprintf(rc->err,
68
+ sizeof(rc->err),
69
+ "expressions must be less than %lu characters",
70
+ (unsigned long)sizeof(rxc->src));
71
+ return EINVAL;
72
72
  }
73
- rxc = ALLOC_N(struct _rxC, 1);
73
+ rxc = ALLOC_N(struct _rxC, 1);
74
74
  rxc->next = 0;
75
75
  rxc->clas = clas;
76
76
 
@@ -79,15 +79,15 @@ oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
79
79
  #else
80
80
  rxc->rrx = Qnil;
81
81
  if (0 != (err = regcomp(&rxc->rx, expr, flags))) {
82
- regerror(err, &rxc->rx, rc->err, sizeof(rc->err));
83
- free(rxc);
84
- return err;
82
+ regerror(err, &rxc->rx, rc->err, sizeof(rc->err));
83
+ free(rxc);
84
+ return err;
85
85
  }
86
86
  #endif
87
87
  if (NULL == rc->tail) {
88
- rc->head = rxc;
88
+ rc->head = rxc;
89
89
  } else {
90
- rc->tail->next = rxc;
90
+ rc->tail->next = rxc;
91
91
  }
92
92
  rc->tail = rxc;
93
93
 
@@ -96,49 +96,48 @@ oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
96
96
 
97
97
  VALUE
98
98
  oj_rxclass_match(RxClass rc, const char *str, int len) {
99
- RxC rxc;
100
- char buf[4096];
99
+ RxC rxc;
100
+ char buf[4096];
101
101
 
102
102
  for (rxc = rc->head; NULL != rxc; rxc = rxc->next) {
103
- if (Qnil != rxc->rrx) {
104
- // Must use a valiabel for this to work.
105
- volatile VALUE rstr = rb_str_new(str, len);
106
-
107
- //if (Qtrue == rb_funcall(rxc->rrx, rb_intern("match?"), 1, rstr)) {
108
- if (Qnil != rb_funcall(rxc->rrx, rb_intern("match"), 1, rstr)) {
109
- return rxc->clas;
110
- }
111
- } else if (len < (int)sizeof(buf)) {
103
+ if (Qnil != rxc->rrx) {
104
+ // Must use a valiabel for this to work.
105
+ volatile VALUE rstr = rb_str_new(str, len);
106
+
107
+ // if (Qtrue == rb_funcall(rxc->rrx, rb_intern("match?"), 1, rstr)) {
108
+ if (Qnil != rb_funcall(rxc->rrx, rb_intern("match"), 1, rstr)) {
109
+ return rxc->clas;
110
+ }
111
+ } else if (len < (int)sizeof(buf)) {
112
112
  #if !IS_WINDOWS
113
- // string is not \0 terminated so copy and atempt a match
114
- memcpy(buf, str, len);
115
- buf[len] = '\0';
116
- if (0 == regexec(&rxc->rx, buf, 0, NULL, 0)) { // match
117
- return rxc->clas;
118
- }
113
+ // string is not \0 terminated so copy and atempt a match
114
+ memcpy(buf, str, len);
115
+ buf[len] = '\0';
116
+ if (0 == regexec(&rxc->rx, buf, 0, NULL, 0)) { // match
117
+ return rxc->clas;
118
+ }
119
119
  #endif
120
- } else {
121
- // TBD allocate a larger buffer and attempt
122
- }
120
+ } else {
121
+ // TBD allocate a larger buffer and attempt
122
+ }
123
123
  }
124
124
  return Qnil;
125
125
  }
126
126
 
127
- void
128
- oj_rxclass_copy(RxClass src, RxClass dest) {
127
+ void oj_rxclass_copy(RxClass src, RxClass dest) {
129
128
  dest->head = NULL;
130
129
  dest->tail = NULL;
131
130
  if (NULL != src->head) {
132
- RxC rxc;
131
+ RxC rxc;
133
132
 
134
- for (rxc = src->head; NULL != rxc; rxc = rxc->next) {
135
- if (Qnil != rxc->rrx) {
136
- oj_rxclass_rappend(dest, rxc->rrx, rxc->clas);
137
- } else {
133
+ for (rxc = src->head; NULL != rxc; rxc = rxc->next) {
134
+ if (Qnil != rxc->rrx) {
135
+ oj_rxclass_rappend(dest, rxc->rrx, rxc->clas);
136
+ } else {
138
137
  #if !IS_WINDOWS
139
- oj_rxclass_append(dest, rxc->src, rxc->clas);
138
+ oj_rxclass_append(dest, rxc->src, rxc->clas);
140
139
  #endif
141
- }
142
- }
140
+ }
141
+ }
143
142
  }
144
143
  }
data/ext/oj/rxclass.h CHANGED
@@ -1,24 +1,26 @@
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_RXCLASS_H
4
5
  #define OJ_RXCLASS_H
5
6
 
6
7
  #include <stdbool.h>
8
+
7
9
  #include "ruby.h"
8
10
 
9
11
  struct _rxC;
10
12
 
11
13
  typedef struct _rxClass {
12
- struct _rxC *head;
13
- struct _rxC *tail;
14
- char err[128];
15
- } *RxClass;
14
+ struct _rxC *head;
15
+ struct _rxC *tail;
16
+ char err[128];
17
+ } * RxClass;
16
18
 
17
- extern void oj_rxclass_init(RxClass rc);
18
- extern void oj_rxclass_cleanup(RxClass rc);
19
- extern int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas);
20
- extern VALUE oj_rxclass_match(RxClass rc, const char *str, int len);
21
- extern void oj_rxclass_copy(RxClass src, RxClass dest);
22
- extern void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas);
19
+ extern void oj_rxclass_init(RxClass rc);
20
+ extern void oj_rxclass_cleanup(RxClass rc);
21
+ extern int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas);
22
+ extern VALUE oj_rxclass_match(RxClass rc, const char *str, int len);
23
+ extern void oj_rxclass_copy(RxClass src, RxClass dest);
24
+ extern void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas);
23
25
 
24
26
  #endif /* OJ_RXCLASS_H */
data/ext/oj/saj.c CHANGED
@@ -1,45 +1,46 @@
1
1
  // Copyright (c) 2012 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
2
3
 
3
4
  #if !IS_WINDOWS
4
- #include <sys/resource.h> /* for getrlimit() on linux */
5
+ #include <sys/resource.h> /* for getrlimit() on linux */
5
6
  #endif
6
- #include <stdlib.h>
7
+ #include <math.h>
7
8
  #include <stdio.h>
9
+ #include <stdlib.h>
8
10
  #include <string.h>
9
- #include <math.h>
10
11
  #include <sys/types.h>
11
12
  #include <unistd.h>
12
13
 
13
14
  // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
14
- #define OJ_INFINITY (1.0/0.0)
15
+ #define OJ_INFINITY (1.0 / 0.0)
15
16
 
16
- #include "oj.h"
17
17
  #include "encode.h"
18
+ #include "oj.h"
18
19
 
19
20
  typedef struct _parseInfo {
20
- char *str; /* buffer being read from */
21
- char *s; /* current position in buffer */
22
- void *stack_min;
23
- VALUE handler;
24
- int has_hash_start;
25
- int has_hash_end;
26
- int has_array_start;
27
- int has_array_end;
28
- int has_add_value;
29
- int has_error;
30
- } *ParseInfo;
31
-
32
- static void read_next(ParseInfo pi, const char *key);
33
- static void read_hash(ParseInfo pi, const char *key);
34
- static void read_array(ParseInfo pi, const char *key);
35
- static void read_str(ParseInfo pi, const char *key);
36
- static void read_num(ParseInfo pi, const char *key);
37
- static void read_true(ParseInfo pi, const char *key);
38
- static void read_false(ParseInfo pi, const char *key);
39
- static void read_nil(ParseInfo pi, const char *key);
40
- static void next_non_white(ParseInfo pi);
41
- static char* read_quoted_value(ParseInfo pi);
42
- static void skip_comment(ParseInfo pi);
21
+ char *str; /* buffer being read from */
22
+ char *s; /* current position in buffer */
23
+ void *stack_min;
24
+ VALUE handler;
25
+ int has_hash_start;
26
+ int has_hash_end;
27
+ int has_array_start;
28
+ int has_array_end;
29
+ int has_add_value;
30
+ int has_error;
31
+ } * ParseInfo;
32
+
33
+ static void read_next(ParseInfo pi, const char *key);
34
+ static void read_hash(ParseInfo pi, const char *key);
35
+ static void read_array(ParseInfo pi, const char *key);
36
+ static void read_str(ParseInfo pi, const char *key);
37
+ static void read_num(ParseInfo pi, const char *key);
38
+ static void read_true(ParseInfo pi, const char *key);
39
+ static void read_false(ParseInfo pi, const char *key);
40
+ static void read_nil(ParseInfo pi, const char *key);
41
+ static void next_non_white(ParseInfo pi);
42
+ static char *read_quoted_value(ParseInfo pi);
43
+ static void skip_comment(ParseInfo pi);
43
44
 
44
45
  /* This JSON parser is a single pass, destructive, callback parser. It is a
45
46
  * single pass parse since it only make one pass over the characters in the
@@ -54,126 +55,108 @@ static void skip_comment(ParseInfo pi);
54
55
  * all cases to parse the string.
55
56
  */
56
57
 
57
- inline static void
58
- call_error(const char *msg, ParseInfo pi, const char* file, int line) {
59
- char buf[128];
60
- const char *s = pi->s;
61
- int jline = 1;
62
- int col = 1;
58
+ inline static void call_error(const char *msg, ParseInfo pi, const char *file, int line) {
59
+ char buf[128];
60
+ const char *s = pi->s;
61
+ int jline = 1;
62
+ int col = 1;
63
63
 
64
64
  for (; pi->str < s && '\n' != *s; s--) {
65
- col++;
65
+ col++;
66
66
  }
67
67
  for (; pi->str < s; s--) {
68
- if ('\n' == *s) {
69
- jline++;
70
- }
68
+ if ('\n' == *s) {
69
+ jline++;
70
+ }
71
71
  }
72
72
  sprintf(buf, "%s at line %d, column %d [%s:%d]", msg, jline, col, file, line);
73
73
  rb_funcall(pi->handler, oj_error_id, 3, rb_str_new2(buf), LONG2NUM(jline), LONG2NUM(col));
74
74
  }
75
75
 
76
- inline static void
77
- next_non_white(ParseInfo pi) {
76
+ inline static void next_non_white(ParseInfo pi) {
78
77
  for (; 1; pi->s++) {
79
- switch(*pi->s) {
80
- case ' ':
81
- case '\t':
82
- case '\f':
83
- case '\n':
84
- case '\r':
85
- break;
86
- case '/':
87
- skip_comment(pi);
88
- break;
89
- default:
90
- return;
91
- }
78
+ switch (*pi->s) {
79
+ case ' ':
80
+ case '\t':
81
+ case '\f':
82
+ case '\n':
83
+ case '\r': break;
84
+ case '/': skip_comment(pi); break;
85
+ default: return;
86
+ }
92
87
  }
93
88
  }
94
89
 
95
- inline static void
96
- call_add_value(VALUE handler, VALUE value, const char *key) {
97
- volatile VALUE k;
90
+ inline static void call_add_value(VALUE handler, VALUE value, const char *key) {
91
+ volatile VALUE k;
98
92
 
99
93
  if (0 == key) {
100
- k = Qnil;
94
+ k = Qnil;
101
95
  } else {
102
- k = rb_str_new2(key);
103
- k = oj_encode(k);
96
+ k = rb_str_new2(key);
97
+ k = oj_encode(k);
104
98
  }
105
99
  rb_funcall(handler, oj_add_value_id, 2, value, k);
106
100
  }
107
101
 
108
- inline static void
109
- call_no_value(VALUE handler, ID method, const char *key) {
110
- volatile VALUE k;
102
+ inline static void call_no_value(VALUE handler, ID method, const char *key) {
103
+ volatile VALUE k;
111
104
 
112
105
  if (0 == key) {
113
- k = Qnil;
106
+ k = Qnil;
114
107
  } else {
115
- k = rb_str_new2(key);
116
- k = oj_encode(k);
108
+ k = rb_str_new2(key);
109
+ k = oj_encode(k);
117
110
  }
118
111
  rb_funcall(handler, method, 1, k);
119
112
  }
120
113
 
121
- static void
122
- skip_comment(ParseInfo pi) {
114
+ static void skip_comment(ParseInfo pi) {
123
115
  pi->s++; /* skip first / */
124
116
  if ('*' == *pi->s) {
125
- pi->s++;
126
- for (; '\0' != *pi->s; pi->s++) {
127
- if ('*' == *pi->s && '/' == *(pi->s + 1)) {
128
- pi->s++;
129
- return;
130
- } else if ('\0' == *pi->s) {
131
- if (pi->has_error) {
132
- call_error("comment not terminated", pi, __FILE__, __LINE__);
133
- } else {
134
- raise_error("comment not terminated", pi->str, pi->s);
135
- }
136
- }
137
- }
117
+ pi->s++;
118
+ for (; '\0' != *pi->s; pi->s++) {
119
+ if ('*' == *pi->s && '/' == *(pi->s + 1)) {
120
+ pi->s++;
121
+ return;
122
+ } else if ('\0' == *pi->s) {
123
+ if (pi->has_error) {
124
+ call_error("comment not terminated", pi, __FILE__, __LINE__);
125
+ } else {
126
+ raise_error("comment not terminated", pi->str, pi->s);
127
+ }
128
+ }
129
+ }
138
130
  } else if ('/' == *pi->s) {
139
- for (; 1; pi->s++) {
140
- switch (*pi->s) {
141
- case '\n':
142
- case '\r':
143
- case '\f':
144
- case '\0':
145
- return;
146
- default:
147
- break;
148
- }
149
- }
131
+ for (; 1; pi->s++) {
132
+ switch (*pi->s) {
133
+ case '\n':
134
+ case '\r':
135
+ case '\f':
136
+ case '\0': return;
137
+ default: break;
138
+ }
139
+ }
150
140
  } else {
151
- if (pi->has_error) {
152
- call_error("invalid comment", pi, __FILE__, __LINE__);
153
- } else {
154
- raise_error("invalid comment", pi->str, pi->s);
155
- }
141
+ if (pi->has_error) {
142
+ call_error("invalid comment", pi, __FILE__, __LINE__);
143
+ } else {
144
+ raise_error("invalid comment", pi->str, pi->s);
145
+ }
156
146
  }
157
147
  }
158
148
 
159
- static void
160
- read_next(ParseInfo pi, const char *key) {
161
- VALUE obj;
149
+ static void read_next(ParseInfo pi, const char *key) {
150
+ VALUE obj;
162
151
 
163
- if ((void*)&obj < pi->stack_min) {
164
- rb_raise(rb_eSysStackError, "JSON is too deeply nested");
152
+ if ((void *)&obj < pi->stack_min) {
153
+ rb_raise(rb_eSysStackError, "JSON is too deeply nested");
165
154
  }
166
- next_non_white(pi); /* skip white space */
155
+ next_non_white(pi); /* skip white space */
167
156
  switch (*pi->s) {
168
- case '{':
169
- read_hash(pi, key);
170
- break;
171
- case '[':
172
- read_array(pi, key);
173
- break;
174
- case '"':
175
- read_str(pi, key);
176
- break;
157
+ case '{': read_hash(pi, key); break;
158
+ case '[': read_array(pi, key); break;
159
+ case '"': read_str(pi, key); break;
177
160
  case '+':
178
161
  case '-':
179
162
  case '0':
@@ -185,113 +168,104 @@ read_next(ParseInfo pi, const char *key) {
185
168
  case '6':
186
169
  case '7':
187
170
  case '8':
188
- case '9':
189
- read_num(pi, key);
190
- break;
191
- case 'I':
192
- read_num(pi, key);
193
- break;
194
- case 't':
195
- read_true(pi, key);
196
- break;
197
- case 'f':
198
- read_false(pi, key);
199
- break;
200
- case 'n':
201
- read_nil(pi, key);
202
- break;
203
- case '\0':
204
- return;
205
- default:
206
- return;
171
+ case '9': read_num(pi, key); break;
172
+ case 'I': read_num(pi, key); break;
173
+ case 't': read_true(pi, key); break;
174
+ case 'f': read_false(pi, key); break;
175
+ case 'n': read_nil(pi, key); break;
176
+ case '\0': return;
177
+ default: return;
207
178
  }
208
179
  }
209
180
 
210
- static void
211
- read_hash(ParseInfo pi, const char *key) {
212
- const char *ks;
181
+ static void read_hash(ParseInfo pi, const char *key) {
182
+ const char *ks;
213
183
 
214
184
  if (pi->has_hash_start) {
215
- call_no_value(pi->handler, oj_hash_start_id, key);
185
+ call_no_value(pi->handler, oj_hash_start_id, key);
216
186
  }
217
187
  pi->s++;
218
188
  next_non_white(pi);
219
189
  if ('}' == *pi->s) {
220
- pi->s++;
190
+ pi->s++;
221
191
  } else {
222
- while (1) {
223
- next_non_white(pi);
224
- ks = read_quoted_value(pi);
225
- next_non_white(pi);
226
- if (':' == *pi->s) {
227
- pi->s++;
228
- } else {
229
- if (pi->has_error) {
230
- call_error("invalid format, expected :", pi, __FILE__, __LINE__);
231
- }
232
- raise_error("invalid format, expected :", pi->str, pi->s);
233
- }
234
- read_next(pi, ks);
235
- next_non_white(pi);
236
- if ('}' == *pi->s) {
237
- pi->s++;
238
- break;
239
- } else if (',' == *pi->s) {
240
- pi->s++;
241
- } else {
242
- if (pi->has_error) {
243
- call_error("invalid format, expected , or } while in an object", pi, __FILE__, __LINE__);
244
- }
245
- raise_error("invalid format, expected , or } while in an object", pi->str, pi->s);
246
- }
247
- }
192
+ while (1) {
193
+ next_non_white(pi);
194
+ ks = read_quoted_value(pi);
195
+ next_non_white(pi);
196
+ if (':' == *pi->s) {
197
+ pi->s++;
198
+ } else {
199
+ if (pi->has_error) {
200
+ call_error("invalid format, expected :", pi, __FILE__, __LINE__);
201
+ }
202
+ raise_error("invalid format, expected :", pi->str, pi->s);
203
+ }
204
+ read_next(pi, ks);
205
+ next_non_white(pi);
206
+ if ('}' == *pi->s) {
207
+ pi->s++;
208
+ break;
209
+ } else if (',' == *pi->s) {
210
+ pi->s++;
211
+ } else {
212
+ if (pi->has_error) {
213
+ call_error("invalid format, expected , or } while in an object",
214
+ pi,
215
+ __FILE__,
216
+ __LINE__);
217
+ }
218
+ raise_error("invalid format, expected , or } while in an object", pi->str, pi->s);
219
+ }
220
+ }
248
221
  }
249
222
  if (pi->has_hash_end) {
250
- call_no_value(pi->handler, oj_hash_end_id, key);
223
+ call_no_value(pi->handler, oj_hash_end_id, key);
251
224
  }
252
225
  }
253
226
 
254
- static void
255
- read_array(ParseInfo pi, const char *key) {
227
+ static void read_array(ParseInfo pi, const char *key) {
256
228
  if (pi->has_array_start) {
257
- call_no_value(pi->handler, oj_array_start_id, key);
229
+ call_no_value(pi->handler, oj_array_start_id, key);
258
230
  }
259
231
  pi->s++;
260
232
  next_non_white(pi);
261
233
  if (']' == *pi->s) {
262
- pi->s++;
234
+ pi->s++;
263
235
  } else {
264
- while (1) {
265
- read_next(pi, 0);
266
- next_non_white(pi);
267
- if (',' == *pi->s) {
268
- pi->s++;
269
- } else if (']' == *pi->s) {
270
- pi->s++;
271
- break;
272
- } else {
273
- if (pi->has_error) {
274
- call_error("invalid format, expected , or ] while in an array", pi, __FILE__, __LINE__);
275
- }
276
- raise_error("invalid format, expected , or ] while in an array", pi->str, pi->s);
277
- }
278
- }
236
+ while (1) {
237
+ read_next(pi, 0);
238
+ next_non_white(pi);
239
+ if (',' == *pi->s) {
240
+ pi->s++;
241
+ } else if (']' == *pi->s) {
242
+ pi->s++;
243
+ break;
244
+ } else {
245
+ if (pi->has_error) {
246
+ call_error("invalid format, expected , or ] while in an array",
247
+ pi,
248
+ __FILE__,
249
+ __LINE__);
250
+ }
251
+ raise_error("invalid format, expected , or ] while in an array", pi->str, pi->s);
252
+ }
253
+ }
279
254
  }
280
255
  if (pi->has_array_end) {
281
- call_no_value(pi->handler, oj_array_end_id, key);
256
+ call_no_value(pi->handler, oj_array_end_id, key);
282
257
  }
283
258
  }
284
259
 
285
- static void
286
- read_str(ParseInfo pi, const char *key) {
287
- char *text;
260
+ static void read_str(ParseInfo pi, const char *key) {
261
+ char *text;
288
262
 
289
263
  text = read_quoted_value(pi);
290
264
  if (pi->has_add_value) {
291
- VALUE s = rb_str_new2(text);
265
+ VALUE s = rb_str_new2(text);
292
266
 
293
- s = oj_encode(s);
294
- call_add_value(pi->handler, s, key);
267
+ s = oj_encode(s);
268
+ call_add_value(pi->handler, s, key);
295
269
  }
296
270
  }
297
271
 
@@ -301,230 +275,228 @@ read_str(ParseInfo pi, const char *key) {
301
275
  #define NUM_MAX (FIXNUM_MAX >> 8)
302
276
  #endif
303
277
 
304
- static void
305
- read_num(ParseInfo pi, const char *key) {
306
- char *start = pi->s;
307
- int64_t n = 0;
308
- long a = 0;
309
- long div = 1;
310
- long e = 0;
311
- int neg = 0;
312
- int eneg = 0;
313
- int big = 0;
278
+ static void read_num(ParseInfo pi, const char *key) {
279
+ char * start = pi->s;
280
+ int64_t n = 0;
281
+ long a = 0;
282
+ long div = 1;
283
+ long e = 0;
284
+ int neg = 0;
285
+ int eneg = 0;
286
+ int big = 0;
314
287
 
315
288
  if ('-' == *pi->s) {
316
- pi->s++;
317
- neg = 1;
289
+ pi->s++;
290
+ neg = 1;
318
291
  } else if ('+' == *pi->s) {
319
- pi->s++;
292
+ pi->s++;
320
293
  }
321
294
  if ('I' == *pi->s) {
322
- if (0 != strncmp("Infinity", pi->s, 8)) {
323
- if (pi->has_error) {
324
- call_error("number or other value", pi, __FILE__, __LINE__);
325
- }
326
- raise_error("number or other value", pi->str, pi->s);
327
- }
328
- pi->s += 8;
329
- if (neg) {
330
- if (pi->has_add_value) {
331
- call_add_value(pi->handler, rb_float_new(-OJ_INFINITY), key);
332
- }
333
- } else {
334
- if (pi->has_add_value) {
335
- call_add_value(pi->handler, rb_float_new(OJ_INFINITY), key);
336
- }
337
- }
338
- return;
295
+ if (0 != strncmp("Infinity", pi->s, 8)) {
296
+ if (pi->has_error) {
297
+ call_error("number or other value", pi, __FILE__, __LINE__);
298
+ }
299
+ raise_error("number or other value", pi->str, pi->s);
300
+ }
301
+ pi->s += 8;
302
+ if (neg) {
303
+ if (pi->has_add_value) {
304
+ call_add_value(pi->handler, rb_float_new(-OJ_INFINITY), key);
305
+ }
306
+ } else {
307
+ if (pi->has_add_value) {
308
+ call_add_value(pi->handler, rb_float_new(OJ_INFINITY), key);
309
+ }
310
+ }
311
+ return;
339
312
  }
340
313
  for (; '0' <= *pi->s && *pi->s <= '9'; pi->s++) {
341
- if (big) {
342
- big++;
343
- } else {
344
- n = n * 10 + (*pi->s - '0');
345
- if (NUM_MAX <= n) {
346
- big = 1;
347
- }
348
- }
314
+ if (big) {
315
+ big++;
316
+ } else {
317
+ n = n * 10 + (*pi->s - '0');
318
+ if (NUM_MAX <= n) {
319
+ big = 1;
320
+ }
321
+ }
349
322
  }
350
323
  if ('.' == *pi->s) {
351
- pi->s++;
352
- for (; '0' <= *pi->s && *pi->s <= '9'; pi->s++) {
353
- a = a * 10 + (*pi->s - '0');
354
- div *= 10;
355
- if (NUM_MAX <= div) {
356
- big = 1;
357
- }
358
- }
324
+ pi->s++;
325
+ for (; '0' <= *pi->s && *pi->s <= '9'; pi->s++) {
326
+ a = a * 10 + (*pi->s - '0');
327
+ div *= 10;
328
+ if (NUM_MAX <= div) {
329
+ big = 1;
330
+ }
331
+ }
359
332
  }
360
333
  if ('e' == *pi->s || 'E' == *pi->s) {
361
- pi->s++;
362
- if ('-' == *pi->s) {
363
- pi->s++;
364
- eneg = 1;
365
- } else if ('+' == *pi->s) {
366
- pi->s++;
367
- }
368
- for (; '0' <= *pi->s && *pi->s <= '9'; pi->s++) {
369
- e = e * 10 + (*pi->s - '0');
370
- if (NUM_MAX <= e) {
371
- big = 1;
372
- }
373
- }
334
+ pi->s++;
335
+ if ('-' == *pi->s) {
336
+ pi->s++;
337
+ eneg = 1;
338
+ } else if ('+' == *pi->s) {
339
+ pi->s++;
340
+ }
341
+ for (; '0' <= *pi->s && *pi->s <= '9'; pi->s++) {
342
+ e = e * 10 + (*pi->s - '0');
343
+ if (NUM_MAX <= e) {
344
+ big = 1;
345
+ }
346
+ }
374
347
  }
375
348
  if (0 == e && 0 == a && 1 == div) {
376
- if (big) {
377
- char c = *pi->s;
378
-
379
- *pi->s = '\0';
380
- if (pi->has_add_value) {
381
- call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
382
- }
383
- *pi->s = c;
384
- } else {
385
- if (neg) {
386
- n = -n;
387
- }
388
- if (pi->has_add_value) {
389
- call_add_value(pi->handler, LONG2NUM(n), key);
390
- }
391
- }
392
- return;
349
+ if (big) {
350
+ char c = *pi->s;
351
+
352
+ *pi->s = '\0';
353
+ if (pi->has_add_value) {
354
+ call_add_value(pi->handler,
355
+ rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
356
+ key);
357
+ }
358
+ *pi->s = c;
359
+ } else {
360
+ if (neg) {
361
+ n = -n;
362
+ }
363
+ if (pi->has_add_value) {
364
+ call_add_value(pi->handler, LONG2NUM(n), key);
365
+ }
366
+ }
367
+ return;
393
368
  } else { /* decimal */
394
- if (big) {
395
- char c = *pi->s;
396
-
397
- *pi->s = '\0';
398
- if (pi->has_add_value) {
399
- call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
400
- }
401
- *pi->s = c;
402
- } else {
403
- double d = (double)n + (double)a / (double)div;
404
-
405
- if (neg) {
406
- d = -d;
407
- }
408
- if (1 < big) {
409
- e += big - 1;
410
- }
411
- if (0 != e) {
412
- if (eneg) {
413
- e = -e;
414
- }
415
- d *= pow(10.0, e);
416
- }
417
- if (pi->has_add_value) {
418
- call_add_value(pi->handler, rb_float_new(d), key);
419
- }
420
- }
369
+ if (big) {
370
+ char c = *pi->s;
371
+
372
+ *pi->s = '\0';
373
+ if (pi->has_add_value) {
374
+ call_add_value(pi->handler,
375
+ rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
376
+ key);
377
+ }
378
+ *pi->s = c;
379
+ } else {
380
+ double d = (double)n + (double)a / (double)div;
381
+
382
+ if (neg) {
383
+ d = -d;
384
+ }
385
+ if (1 < big) {
386
+ e += big - 1;
387
+ }
388
+ if (0 != e) {
389
+ if (eneg) {
390
+ e = -e;
391
+ }
392
+ d *= pow(10.0, e);
393
+ }
394
+ if (pi->has_add_value) {
395
+ call_add_value(pi->handler, rb_float_new(d), key);
396
+ }
397
+ }
421
398
  }
422
399
  }
423
400
 
424
- static void
425
- read_true(ParseInfo pi, const char *key) {
401
+ static void read_true(ParseInfo pi, const char *key) {
426
402
  pi->s++;
427
403
  if ('r' != *pi->s || 'u' != *(pi->s + 1) || 'e' != *(pi->s + 2)) {
428
- if (pi->has_error) {
429
- call_error("invalid format, expected 'true'", pi, __FILE__, __LINE__);
430
- }
431
- raise_error("invalid format, expected 'true'", pi->str, pi->s);
404
+ if (pi->has_error) {
405
+ call_error("invalid format, expected 'true'", pi, __FILE__, __LINE__);
406
+ }
407
+ raise_error("invalid format, expected 'true'", pi->str, pi->s);
432
408
  }
433
409
  pi->s += 3;
434
410
  if (pi->has_add_value) {
435
- call_add_value(pi->handler, Qtrue, key);
411
+ call_add_value(pi->handler, Qtrue, key);
436
412
  }
437
413
  }
438
414
 
439
- static void
440
- read_false(ParseInfo pi, const char *key) {
415
+ static void read_false(ParseInfo pi, const char *key) {
441
416
  pi->s++;
442
417
  if ('a' != *pi->s || 'l' != *(pi->s + 1) || 's' != *(pi->s + 2) || 'e' != *(pi->s + 3)) {
443
- if (pi->has_error) {
444
- call_error("invalid format, expected 'false'", pi, __FILE__, __LINE__);
445
- }
446
- raise_error("invalid format, expected 'false'", pi->str, pi->s);
418
+ if (pi->has_error) {
419
+ call_error("invalid format, expected 'false'", pi, __FILE__, __LINE__);
420
+ }
421
+ raise_error("invalid format, expected 'false'", pi->str, pi->s);
447
422
  }
448
423
  pi->s += 4;
449
424
  if (pi->has_add_value) {
450
- call_add_value(pi->handler, Qfalse, key);
425
+ call_add_value(pi->handler, Qfalse, key);
451
426
  }
452
427
  }
453
428
 
454
- static void
455
- read_nil(ParseInfo pi, const char *key) {
429
+ static void read_nil(ParseInfo pi, const char *key) {
456
430
  pi->s++;
457
431
  if ('u' != *pi->s || 'l' != *(pi->s + 1) || 'l' != *(pi->s + 2)) {
458
- if (pi->has_error) {
459
- call_error("invalid format, expected 'null'", pi, __FILE__, __LINE__);
460
- }
461
- raise_error("invalid format, expected 'null'", pi->str, pi->s);
432
+ if (pi->has_error) {
433
+ call_error("invalid format, expected 'null'", pi, __FILE__, __LINE__);
434
+ }
435
+ raise_error("invalid format, expected 'null'", pi->str, pi->s);
462
436
  }
463
437
  pi->s += 3;
464
438
  if (pi->has_add_value) {
465
- call_add_value(pi->handler, Qnil, key);
439
+ call_add_value(pi->handler, Qnil, key);
466
440
  }
467
441
  }
468
442
 
469
- static uint32_t
470
- read_hex(ParseInfo pi, char *h) {
471
- uint32_t b = 0;
472
- int i;
443
+ static uint32_t read_hex(ParseInfo pi, char *h) {
444
+ uint32_t b = 0;
445
+ int i;
473
446
 
474
447
  /* TBD this can be made faster with a table */
475
448
  for (i = 0; i < 4; i++, h++) {
476
- b = b << 4;
477
- if ('0' <= *h && *h <= '9') {
478
- b += *h - '0';
479
- } else if ('A' <= *h && *h <= 'F') {
480
- b += *h - 'A' + 10;
481
- } else if ('a' <= *h && *h <= 'f') {
482
- b += *h - 'a' + 10;
483
- } else {
484
- pi->s = h;
485
- if (pi->has_error) {
486
- call_error("invalid hex character", pi, __FILE__, __LINE__);
487
- }
488
- raise_error("invalid hex character", pi->str, pi->s);
489
- }
449
+ b = b << 4;
450
+ if ('0' <= *h && *h <= '9') {
451
+ b += *h - '0';
452
+ } else if ('A' <= *h && *h <= 'F') {
453
+ b += *h - 'A' + 10;
454
+ } else if ('a' <= *h && *h <= 'f') {
455
+ b += *h - 'a' + 10;
456
+ } else {
457
+ pi->s = h;
458
+ if (pi->has_error) {
459
+ call_error("invalid hex character", pi, __FILE__, __LINE__);
460
+ }
461
+ raise_error("invalid hex character", pi->str, pi->s);
462
+ }
490
463
  }
491
464
  return b;
492
465
  }
493
466
 
494
- static char*
495
- unicode_to_chars(ParseInfo pi, char *t, uint32_t code) {
467
+ static char *unicode_to_chars(ParseInfo pi, char *t, uint32_t code) {
496
468
  if (0x0000007F >= code) {
497
- *t = (char)code;
469
+ *t = (char)code;
498
470
  } else if (0x000007FF >= code) {
499
- *t++ = 0xC0 | (code >> 6);
500
- *t = 0x80 | (0x3F & code);
471
+ *t++ = 0xC0 | (code >> 6);
472
+ *t = 0x80 | (0x3F & code);
501
473
  } else if (0x0000FFFF >= code) {
502
- *t++ = 0xE0 | (code >> 12);
503
- *t++ = 0x80 | ((code >> 6) & 0x3F);
504
- *t = 0x80 | (0x3F & code);
474
+ *t++ = 0xE0 | (code >> 12);
475
+ *t++ = 0x80 | ((code >> 6) & 0x3F);
476
+ *t = 0x80 | (0x3F & code);
505
477
  } else if (0x001FFFFF >= code) {
506
- *t++ = 0xF0 | (code >> 18);
507
- *t++ = 0x80 | ((code >> 12) & 0x3F);
508
- *t++ = 0x80 | ((code >> 6) & 0x3F);
509
- *t = 0x80 | (0x3F & code);
478
+ *t++ = 0xF0 | (code >> 18);
479
+ *t++ = 0x80 | ((code >> 12) & 0x3F);
480
+ *t++ = 0x80 | ((code >> 6) & 0x3F);
481
+ *t = 0x80 | (0x3F & code);
510
482
  } else if (0x03FFFFFF >= code) {
511
- *t++ = 0xF8 | (code >> 24);
512
- *t++ = 0x80 | ((code >> 18) & 0x3F);
513
- *t++ = 0x80 | ((code >> 12) & 0x3F);
514
- *t++ = 0x80 | ((code >> 6) & 0x3F);
515
- *t = 0x80 | (0x3F & code);
483
+ *t++ = 0xF8 | (code >> 24);
484
+ *t++ = 0x80 | ((code >> 18) & 0x3F);
485
+ *t++ = 0x80 | ((code >> 12) & 0x3F);
486
+ *t++ = 0x80 | ((code >> 6) & 0x3F);
487
+ *t = 0x80 | (0x3F & code);
516
488
  } else if (0x7FFFFFFF >= code) {
517
- *t++ = 0xFC | (code >> 30);
518
- *t++ = 0x80 | ((code >> 24) & 0x3F);
519
- *t++ = 0x80 | ((code >> 18) & 0x3F);
520
- *t++ = 0x80 | ((code >> 12) & 0x3F);
521
- *t++ = 0x80 | ((code >> 6) & 0x3F);
522
- *t = 0x80 | (0x3F & code);
489
+ *t++ = 0xFC | (code >> 30);
490
+ *t++ = 0x80 | ((code >> 24) & 0x3F);
491
+ *t++ = 0x80 | ((code >> 18) & 0x3F);
492
+ *t++ = 0x80 | ((code >> 12) & 0x3F);
493
+ *t++ = 0x80 | ((code >> 6) & 0x3F);
494
+ *t = 0x80 | (0x3F & code);
523
495
  } else {
524
- if (pi->has_error) {
525
- call_error("invalid Unicode", pi, __FILE__, __LINE__);
526
- }
527
- raise_error("invalid Unicode", pi->str, pi->s);
496
+ if (pi->has_error) {
497
+ call_error("invalid Unicode", pi, __FILE__, __LINE__);
498
+ }
499
+ raise_error("invalid Unicode", pi->str, pi->s);
528
500
  }
529
501
  return t;
530
502
  }
@@ -532,119 +504,119 @@ unicode_to_chars(ParseInfo pi, char *t, uint32_t code) {
532
504
  /* Assume the value starts immediately and goes until the quote character is
533
505
  * reached again. Do not read the character after the terminating quote.
534
506
  */
535
- static char*
536
- read_quoted_value(ParseInfo pi) {
537
- char *value = 0;
538
- char *h = pi->s; /* head */
539
- char *t = h; /* tail */
540
- uint32_t code;
541
-
542
- h++; /* skip quote character */
507
+ static char *read_quoted_value(ParseInfo pi) {
508
+ char * value = 0;
509
+ char * h = pi->s; /* head */
510
+ char * t = h; /* tail */
511
+ uint32_t code;
512
+
513
+ h++; /* skip quote character */
543
514
  t++;
544
515
  value = h;
545
516
  for (; '"' != *h; h++, t++) {
546
- if ('\0' == *h) {
547
- pi->s = h;
548
- raise_error("quoted string not terminated", pi->str, pi->s);
549
- } else if ('\\' == *h) {
550
- h++;
551
- switch (*h) {
552
- case 'n': *t = '\n'; break;
553
- case 'r': *t = '\r'; break;
554
- case 't': *t = '\t'; break;
555
- case 'f': *t = '\f'; break;
556
- case 'b': *t = '\b'; break;
557
- case '"': *t = '"'; break;
558
- case '/': *t = '/'; break;
559
- case '\\': *t = '\\'; break;
560
- case 'u':
561
- h++;
562
- code = read_hex(pi, h);
563
- h += 3;
564
- if (0x0000D800 <= code && code <= 0x0000DFFF) {
565
- uint32_t c1 = (code - 0x0000D800) & 0x000003FF;
566
- uint32_t c2;
567
-
568
- h++;
569
- if ('\\' != *h || 'u' != *(h + 1)) {
570
- pi->s = h;
571
- if (pi->has_error) {
572
- call_error("invalid escaped character", pi, __FILE__, __LINE__);
573
- }
574
- raise_error("invalid escaped character", pi->str, pi->s);
575
- }
576
- h += 2;
577
- c2 = read_hex(pi, h);
578
- h += 3;
579
- c2 = (c2 - 0x0000DC00) & 0x000003FF;
580
- code = ((c1 << 10) | c2) + 0x00010000;
581
- }
582
- t = unicode_to_chars(pi, t, code);
583
- break;
584
- default:
585
- pi->s = h;
586
- if (pi->has_error) {
587
- call_error("invalid escaped character", pi, __FILE__, __LINE__);
588
- }
589
- raise_error("invalid escaped character", pi->str, pi->s);
590
- break;
591
- }
592
- } else if (t != h) {
593
- *t = *h;
594
- }
595
- }
596
- *t = '\0'; /* terminate value */
517
+ if ('\0' == *h) {
518
+ pi->s = h;
519
+ raise_error("quoted string not terminated", pi->str, pi->s);
520
+ } else if ('\\' == *h) {
521
+ h++;
522
+ switch (*h) {
523
+ case 'n': *t = '\n'; break;
524
+ case 'r': *t = '\r'; break;
525
+ case 't': *t = '\t'; break;
526
+ case 'f': *t = '\f'; break;
527
+ case 'b': *t = '\b'; break;
528
+ case '"': *t = '"'; break;
529
+ case '/': *t = '/'; break;
530
+ case '\\': *t = '\\'; break;
531
+ case 'u':
532
+ h++;
533
+ code = read_hex(pi, h);
534
+ h += 3;
535
+ if (0x0000D800 <= code && code <= 0x0000DFFF) {
536
+ uint32_t c1 = (code - 0x0000D800) & 0x000003FF;
537
+ uint32_t c2;
538
+
539
+ h++;
540
+ if ('\\' != *h || 'u' != *(h + 1)) {
541
+ pi->s = h;
542
+ if (pi->has_error) {
543
+ call_error("invalid escaped character", pi, __FILE__, __LINE__);
544
+ }
545
+ raise_error("invalid escaped character", pi->str, pi->s);
546
+ }
547
+ h += 2;
548
+ c2 = read_hex(pi, h);
549
+ h += 3;
550
+ c2 = (c2 - 0x0000DC00) & 0x000003FF;
551
+ code = ((c1 << 10) | c2) + 0x00010000;
552
+ }
553
+ t = unicode_to_chars(pi, t, code);
554
+ break;
555
+ default:
556
+ pi->s = h;
557
+ if (pi->has_error) {
558
+ call_error("invalid escaped character", pi, __FILE__, __LINE__);
559
+ }
560
+ raise_error("invalid escaped character", pi->str, pi->s);
561
+ break;
562
+ }
563
+ } else if (t != h) {
564
+ *t = *h;
565
+ }
566
+ }
567
+ *t = '\0'; /* terminate value */
597
568
  pi->s = h + 1;
598
569
 
599
570
  return value;
600
571
  }
601
572
 
602
- static void
603
- saj_parse(VALUE handler, char *json) {
604
- volatile VALUE obj = Qnil;
605
- struct _parseInfo pi;
573
+ static void saj_parse(VALUE handler, char *json) {
574
+ volatile VALUE obj = Qnil;
575
+ struct _parseInfo pi;
606
576
 
607
577
  if (0 == json) {
608
- if (pi.has_error) {
609
- call_error("Invalid arg, xml string can not be null", &pi, __FILE__, __LINE__);
610
- }
611
- raise_error("Invalid arg, xml string can not be null", json, 0);
578
+ if (pi.has_error) {
579
+ call_error("Invalid arg, xml string can not be null", &pi, __FILE__, __LINE__);
580
+ }
581
+ raise_error("Invalid arg, xml string can not be null", json, 0);
612
582
  }
613
583
  /* skip UTF-8 BOM if present */
614
584
  if (0xEF == (uint8_t)*json && 0xBB == (uint8_t)json[1] && 0xBF == (uint8_t)json[2]) {
615
- json += 3;
585
+ json += 3;
616
586
  }
617
587
  /* initialize parse info */
618
588
  pi.str = json;
619
- pi.s = json;
589
+ pi.s = json;
620
590
  #if IS_WINDOWS
621
- pi.stack_min = (void*)((char*)&obj - (512 * 1024)); /* assume a 1M stack and give half to ruby */
591
+ pi.stack_min = (void *)((char *)&obj -
592
+ (512 * 1024)); /* assume a 1M stack and give half to ruby */
622
593
  #else
623
594
  {
624
- struct rlimit lim;
595
+ struct rlimit lim;
625
596
 
626
- if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
627
- pi.stack_min = (void*)((char*)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
628
- } else {
629
- pi.stack_min = 0; /* indicates not to check stack limit */
630
- }
597
+ if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
598
+ pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 *
599
+ 3)); /* let 3/4ths of the stack be used only */
600
+ } else {
601
+ pi.stack_min = 0; /* indicates not to check stack limit */
602
+ }
631
603
  }
632
604
  #endif
633
- pi.handler = handler;
634
- pi.has_hash_start = rb_respond_to(handler, oj_hash_start_id);
635
- pi.has_hash_end = rb_respond_to(handler, oj_hash_end_id);
605
+ pi.handler = handler;
606
+ pi.has_hash_start = rb_respond_to(handler, oj_hash_start_id);
607
+ pi.has_hash_end = rb_respond_to(handler, oj_hash_end_id);
636
608
  pi.has_array_start = rb_respond_to(handler, oj_array_start_id);
637
- pi.has_array_end = rb_respond_to(handler, oj_array_end_id);
638
- pi.has_add_value = rb_respond_to(handler, oj_add_value_id);
639
- pi.has_error = rb_respond_to(handler, oj_error_id);
609
+ pi.has_array_end = rb_respond_to(handler, oj_array_end_id);
610
+ pi.has_add_value = rb_respond_to(handler, oj_add_value_id);
611
+ pi.has_error = rb_respond_to(handler, oj_error_id);
640
612
  read_next(&pi, 0);
641
613
  next_non_white(&pi);
642
614
  if ('\0' != *pi.s) {
643
- if (pi.has_error) {
644
- call_error("invalid format, extra characters", &pi, __FILE__, __LINE__);
645
- } else {
646
- raise_error("invalid format, extra characters", pi.str, pi.s);
647
- }
615
+ if (pi.has_error) {
616
+ call_error("invalid format, extra characters", &pi, __FILE__, __LINE__);
617
+ } else {
618
+ raise_error("invalid format, extra characters", pi.str, pi.s);
619
+ }
648
620
  }
649
621
  }
650
622
 
@@ -661,48 +633,48 @@ saj_parse(VALUE handler, char *json) {
661
633
  */
662
634
  VALUE
663
635
  oj_saj_parse(int argc, VALUE *argv, VALUE self) {
664
- char *json = 0;
665
- size_t len = 0;
666
- VALUE input = argv[1];
636
+ char * json = 0;
637
+ size_t len = 0;
638
+ VALUE input = argv[1];
667
639
 
668
640
  if (argc < 2) {
669
- rb_raise(rb_eArgError, "Wrong number of arguments to saj_parse.\n");
641
+ rb_raise(rb_eArgError, "Wrong number of arguments to saj_parse.\n");
670
642
  }
671
643
  if (rb_type(input) == T_STRING) {
672
- // the json string gets modified so make a copy of it
673
- len = RSTRING_LEN(input) + 1;
674
- json = ALLOC_N(char, len);
675
- strcpy(json, StringValuePtr(input));
644
+ // the json string gets modified so make a copy of it
645
+ len = RSTRING_LEN(input) + 1;
646
+ json = ALLOC_N(char, len);
647
+ strcpy(json, StringValuePtr(input));
676
648
  } else {
677
- VALUE clas = rb_obj_class(input);
678
- volatile VALUE s;
679
-
680
- if (oj_stringio_class == clas) {
681
- s = rb_funcall2(input, oj_string_id, 0, 0);
682
- len = RSTRING_LEN(s) + 1;
683
- json = ALLOC_N(char, len);
684
- strcpy(json, rb_string_value_cstr((VALUE*)&s));
649
+ VALUE clas = rb_obj_class(input);
650
+ volatile VALUE s;
651
+
652
+ if (oj_stringio_class == clas) {
653
+ s = rb_funcall2(input, oj_string_id, 0, 0);
654
+ len = RSTRING_LEN(s) + 1;
655
+ json = ALLOC_N(char, len);
656
+ strcpy(json, rb_string_value_cstr((VALUE *)&s));
685
657
  #if !IS_WINDOWS
686
- } else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
687
- int fd = FIX2INT(rb_funcall(input, oj_fileno_id, 0));
688
- ssize_t cnt;
689
-
690
- len = lseek(fd, 0, SEEK_END);
691
- lseek(fd, 0, SEEK_SET);
692
- json = ALLOC_N(char, len + 1);
693
- if (0 >= (cnt = read(fd, json, len)) || cnt != (ssize_t)len) {
694
- rb_raise(rb_eIOError, "failed to read from IO Object.");
695
- }
696
- json[len] = '\0';
658
+ } else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
659
+ int fd = FIX2INT(rb_funcall(input, oj_fileno_id, 0));
660
+ ssize_t cnt;
661
+
662
+ len = lseek(fd, 0, SEEK_END);
663
+ lseek(fd, 0, SEEK_SET);
664
+ json = ALLOC_N(char, len + 1);
665
+ if (0 >= (cnt = read(fd, json, len)) || cnt != (ssize_t)len) {
666
+ rb_raise(rb_eIOError, "failed to read from IO Object.");
667
+ }
668
+ json[len] = '\0';
697
669
  #endif
698
- } else if (rb_respond_to(input, oj_read_id)) {
699
- s = rb_funcall2(input, oj_read_id, 0, 0);
700
- len = RSTRING_LEN(s) + 1;
701
- json = ALLOC_N(char, len);
702
- strcpy(json, rb_string_value_cstr((VALUE*)&s));
703
- } else {
704
- rb_raise(rb_eArgError, "saj_parse() expected a String or IO Object.");
705
- }
670
+ } else if (rb_respond_to(input, oj_read_id)) {
671
+ s = rb_funcall2(input, oj_read_id, 0, 0);
672
+ len = RSTRING_LEN(s) + 1;
673
+ json = ALLOC_N(char, len);
674
+ strcpy(json, rb_string_value_cstr((VALUE *)&s));
675
+ } else {
676
+ rb_raise(rb_eArgError, "saj_parse() expected a String or IO Object.");
677
+ }
706
678
  }
707
679
  saj_parse(*argv, json);
708
680
  xfree(json);