oj 3.11.1 → 3.11.6

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -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 +1042 -1041
  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 +412 -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 +1123 -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/test_fast.rb +32 -2
  62. data/test/test_generate.rb +21 -0
  63. data/test/test_hash.rb +10 -0
  64. data/test/test_scp.rb +1 -1
  65. 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);