picojson_ruby 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b93d3bf2ca6e4e3a54b13e32b8e39fd44b9f8e4e
4
- data.tar.gz: e9f69410ee2d219160da2511d8acb34168110b21
3
+ metadata.gz: 137d421ec982c80068225b39ea31706d95098a51
4
+ data.tar.gz: 86986ee4df601fef4bd285e69dc2070912963880
5
5
  SHA512:
6
- metadata.gz: c1549d708b02c250e542af3b94943ac29c1b8c7a0a46a2c120d41b2037a133f961b82e1938345e5838a0623eeb72fec2cb1b6fc0b6d1509c36b9f555ab342486
7
- data.tar.gz: f920dd505c7c7004bfb362d97afecf58370d7f17720edc174a9eacb9debeeb62edae174de814a9976377aae74008bdd35963b3b92ea3bea56f9ec7ba0916107b
6
+ metadata.gz: f340245f8205f688e265fa8973e7ad48f4a1ba5d087e7debb954483957f63661cef078a4b0ba273ec17f2ad2e71ac5ff39b223a59edf81ab3b6768492c84bc4c
7
+ data.tar.gz: 32d3658da12a13a56eebbad841542c537fd243126d1527d96c3345641faa509ed0bd8e30aae7c830642c7cf8b110ddf73a97ba7b11c119d67b1a09b8b7d26298
@@ -1,3 +1,3 @@
1
1
  class PicojsonRuby
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,1010 @@
1
+ /*
2
+ * Copyright 2009-2010 Cybozu Labs, Inc.
3
+ * Copyright 2011-2014 Kazuho Oku
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ * POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+ #ifndef picojson_h
29
+ #define picojson_h
30
+
31
+ #include <algorithm>
32
+ #include <cstdio>
33
+ #include <cstdlib>
34
+ #include <cstring>
35
+ #include <iostream>
36
+ #include <iterator>
37
+ #include <limits>
38
+ #include <map>
39
+ #include <stdexcept>
40
+ #include <string>
41
+ #include <vector>
42
+
43
+ // for isnan/isinf
44
+ #if __cplusplus>=201103L
45
+ # include <cmath>
46
+ #else
47
+ extern "C" {
48
+ # ifdef _MSC_VER
49
+ # include <float.h>
50
+ # elif defined(__INTEL_COMPILER)
51
+ # include <mathimf.h>
52
+ # else
53
+ # include <math.h>
54
+ # endif
55
+ }
56
+ #endif
57
+
58
+ // experimental support for int64_t (see README.mkdn for detail)
59
+ #ifdef PICOJSON_USE_INT64
60
+ # define __STDC_FORMAT_MACROS
61
+ # include <errno.h>
62
+ # include <inttypes.h>
63
+ #endif
64
+
65
+ // to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
66
+ #ifndef PICOJSON_USE_LOCALE
67
+ # define PICOJSON_USE_LOCALE 1
68
+ #endif
69
+ #if PICOJSON_USE_LOCALE
70
+ extern "C" {
71
+ # include <locale.h>
72
+ }
73
+ #endif
74
+
75
+ #ifndef PICOJSON_ASSERT
76
+ # define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0)
77
+ #endif
78
+
79
+ #ifdef _MSC_VER
80
+ #define SNPRINTF _snprintf_s
81
+ #pragma warning(push)
82
+ #pragma warning(disable : 4244) // conversion from int to char
83
+ #pragma warning(disable : 4127) // conditional expression is constant
84
+ #pragma warning(disable : 4702) // unreachable code
85
+ #else
86
+ #define SNPRINTF snprintf
87
+ #endif
88
+
89
+ namespace picojson {
90
+
91
+ enum {
92
+ null_type,
93
+ boolean_type,
94
+ number_type,
95
+ string_type,
96
+ array_type,
97
+ object_type
98
+ #ifdef PICOJSON_USE_INT64
99
+ , int64_type
100
+ #endif
101
+ };
102
+
103
+ enum {
104
+ INDENT_WIDTH = 2
105
+ };
106
+
107
+ struct null {};
108
+
109
+ class value {
110
+ public:
111
+ typedef std::vector<value> array;
112
+ typedef std::map<std::string, value> object;
113
+ union _storage {
114
+ bool boolean_;
115
+ double number_;
116
+ #ifdef PICOJSON_USE_INT64
117
+ int64_t int64_;
118
+ #endif
119
+ std::string* string_;
120
+ array* array_;
121
+ object* object_;
122
+ };
123
+ protected:
124
+ int type_;
125
+ _storage u_;
126
+ public:
127
+ value();
128
+ value(int type, bool);
129
+ explicit value(bool b);
130
+ #ifdef PICOJSON_USE_INT64
131
+ explicit value(int64_t i);
132
+ #endif
133
+ explicit value(double n);
134
+ explicit value(const std::string& s);
135
+ explicit value(const array& a);
136
+ explicit value(const object& o);
137
+ explicit value(const char* s);
138
+ value(const char* s, size_t len);
139
+ ~value();
140
+ value(const value& x);
141
+ value& operator=(const value& x);
142
+ void swap(value& x);
143
+ template <typename T> bool is() const;
144
+ template <typename T> const T& get() const;
145
+ template <typename T> T& get();
146
+ bool evaluate_as_boolean() const;
147
+ const value& get(size_t idx) const;
148
+ const value& get(const std::string& key) const;
149
+ value& get(size_t idx);
150
+ value& get(const std::string& key);
151
+
152
+ bool contains(size_t idx) const;
153
+ bool contains(const std::string& key) const;
154
+ std::string to_str() const;
155
+ template <typename Iter> void serialize(Iter os, bool prettify = false) const;
156
+ std::string serialize(bool prettify = false) const;
157
+ private:
158
+ template <typename T> value(const T*); // intentionally defined to block implicit conversion of pointer to bool
159
+ template <typename Iter> static void _indent(Iter os, int indent);
160
+ template <typename Iter> void _serialize(Iter os, int indent) const;
161
+ std::string _serialize(int indent) const;
162
+ };
163
+
164
+ typedef value::array array;
165
+ typedef value::object object;
166
+
167
+ inline value::value() : type_(null_type) {}
168
+
169
+ inline value::value(int type, bool) : type_(type) {
170
+ switch (type) {
171
+ #define INIT(p, v) case p##type: u_.p = v; break
172
+ INIT(boolean_, false);
173
+ INIT(number_, 0.0);
174
+ #ifdef PICOJSON_USE_INT64
175
+ INIT(int64_, 0);
176
+ #endif
177
+ INIT(string_, new std::string());
178
+ INIT(array_, new array());
179
+ INIT(object_, new object());
180
+ #undef INIT
181
+ default: break;
182
+ }
183
+ }
184
+
185
+ inline value::value(bool b) : type_(boolean_type) {
186
+ u_.boolean_ = b;
187
+ }
188
+
189
+ #ifdef PICOJSON_USE_INT64
190
+ inline value::value(int64_t i) : type_(int64_type) {
191
+ u_.int64_ = i;
192
+ }
193
+ #endif
194
+
195
+ inline value::value(double n) : type_(number_type) {
196
+ if (
197
+ #ifdef _MSC_VER
198
+ ! _finite(n)
199
+ #elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf))
200
+ std::isnan(n) || std::isinf(n)
201
+ #else
202
+ isnan(n) || isinf(n)
203
+ #endif
204
+ ) {
205
+ throw std::overflow_error("");
206
+ }
207
+ u_.number_ = n;
208
+ }
209
+
210
+ inline value::value(const std::string& s) : type_(string_type) {
211
+ u_.string_ = new std::string(s);
212
+ }
213
+
214
+ inline value::value(const array& a) : type_(array_type) {
215
+ u_.array_ = new array(a);
216
+ }
217
+
218
+ inline value::value(const object& o) : type_(object_type) {
219
+ u_.object_ = new object(o);
220
+ }
221
+
222
+ inline value::value(const char* s) : type_(string_type) {
223
+ u_.string_ = new std::string(s);
224
+ }
225
+
226
+ inline value::value(const char* s, size_t len) : type_(string_type) {
227
+ u_.string_ = new std::string(s, len);
228
+ }
229
+
230
+ inline value::~value() {
231
+ switch (type_) {
232
+ #define DEINIT(p) case p##type: delete u_.p; break
233
+ DEINIT(string_);
234
+ DEINIT(array_);
235
+ DEINIT(object_);
236
+ #undef DEINIT
237
+ default: break;
238
+ }
239
+ }
240
+
241
+ inline value::value(const value& x) : type_(x.type_) {
242
+ switch (type_) {
243
+ #define INIT(p, v) case p##type: u_.p = v; break
244
+ INIT(string_, new std::string(*x.u_.string_));
245
+ INIT(array_, new array(*x.u_.array_));
246
+ INIT(object_, new object(*x.u_.object_));
247
+ #undef INIT
248
+ default:
249
+ u_ = x.u_;
250
+ break;
251
+ }
252
+ }
253
+
254
+ inline value& value::operator=(const value& x) {
255
+ if (this != &x) {
256
+ value t(x);
257
+ swap(t);
258
+ }
259
+ return *this;
260
+ }
261
+
262
+ inline void value::swap(value& x) {
263
+ std::swap(type_, x.type_);
264
+ std::swap(u_, x.u_);
265
+ }
266
+
267
+ #define IS(ctype, jtype) \
268
+ template <> inline bool value::is<ctype>() const { \
269
+ return type_ == jtype##_type; \
270
+ }
271
+ IS(null, null)
272
+ IS(bool, boolean)
273
+ #ifdef PICOJSON_USE_INT64
274
+ IS(int64_t, int64)
275
+ #endif
276
+ IS(std::string, string)
277
+ IS(array, array)
278
+ IS(object, object)
279
+ #undef IS
280
+ template <> inline bool value::is<double>() const {
281
+ return type_ == number_type
282
+ #ifdef PICOJSON_USE_INT64
283
+ || type_ == int64_type
284
+ #endif
285
+ ;
286
+ }
287
+
288
+ #define GET(ctype, var) \
289
+ template <> inline const ctype& value::get<ctype>() const { \
290
+ PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \
291
+ && is<ctype>()); \
292
+ return var; \
293
+ } \
294
+ template <> inline ctype& value::get<ctype>() { \
295
+ PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \
296
+ && is<ctype>()); \
297
+ return var; \
298
+ }
299
+ GET(bool, u_.boolean_)
300
+ GET(std::string, *u_.string_)
301
+ GET(array, *u_.array_)
302
+ GET(object, *u_.object_)
303
+ #ifdef PICOJSON_USE_INT64
304
+ GET(double, (type_ == int64_type && (const_cast<value*>(this)->type_ = number_type, const_cast<value*>(this)->u_.number_ = u_.int64_), u_.number_))
305
+ GET(int64_t, u_.int64_)
306
+ #else
307
+ GET(double, u_.number_)
308
+ #endif
309
+ #undef GET
310
+
311
+ inline bool value::evaluate_as_boolean() const {
312
+ switch (type_) {
313
+ case null_type:
314
+ return false;
315
+ case boolean_type:
316
+ return u_.boolean_;
317
+ case number_type:
318
+ return u_.number_ != 0;
319
+ case string_type:
320
+ return ! u_.string_->empty();
321
+ default:
322
+ return true;
323
+ }
324
+ }
325
+
326
+ inline const value& value::get(size_t idx) const {
327
+ static value s_null;
328
+ PICOJSON_ASSERT(is<array>());
329
+ return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
330
+ }
331
+
332
+ inline value& value::get(size_t idx) {
333
+ static value s_null;
334
+ PICOJSON_ASSERT(is<array>());
335
+ return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
336
+ }
337
+
338
+ inline const value& value::get(const std::string& key) const {
339
+ static value s_null;
340
+ PICOJSON_ASSERT(is<object>());
341
+ object::const_iterator i = u_.object_->find(key);
342
+ return i != u_.object_->end() ? i->second : s_null;
343
+ }
344
+
345
+ inline value& value::get(const std::string& key) {
346
+ static value s_null;
347
+ PICOJSON_ASSERT(is<object>());
348
+ object::iterator i = u_.object_->find(key);
349
+ return i != u_.object_->end() ? i->second : s_null;
350
+ }
351
+
352
+ inline bool value::contains(size_t idx) const {
353
+ PICOJSON_ASSERT(is<array>());
354
+ return idx < u_.array_->size();
355
+ }
356
+
357
+ inline bool value::contains(const std::string& key) const {
358
+ PICOJSON_ASSERT(is<object>());
359
+ object::const_iterator i = u_.object_->find(key);
360
+ return i != u_.object_->end();
361
+ }
362
+
363
+ inline std::string value::to_str() const {
364
+ switch (type_) {
365
+ case null_type: return "null";
366
+ case boolean_type: return u_.boolean_ ? "true" : "false";
367
+ #ifdef PICOJSON_USE_INT64
368
+ case int64_type: {
369
+ char buf[sizeof("-9223372036854775808")];
370
+ SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
371
+ return buf;
372
+ }
373
+ #endif
374
+ case number_type: {
375
+ char buf[256];
376
+ double tmp;
377
+ SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_);
378
+ #if PICOJSON_USE_LOCALE
379
+ char *decimal_point = localeconv()->decimal_point;
380
+ if (strcmp(decimal_point, ".") != 0) {
381
+ size_t decimal_point_len = strlen(decimal_point);
382
+ for (char *p = buf; *p != '\0'; ++p) {
383
+ if (strncmp(p, decimal_point, decimal_point_len) == 0) {
384
+ return std::string(buf, p) + "." + (p + decimal_point_len);
385
+ }
386
+ }
387
+ }
388
+ #endif
389
+ return buf;
390
+ }
391
+ case string_type: return *u_.string_;
392
+ case array_type: return "array";
393
+ case object_type: return "object";
394
+ default: PICOJSON_ASSERT(0);
395
+ #ifdef _MSC_VER
396
+ __assume(0);
397
+ #endif
398
+ }
399
+ return std::string();
400
+ }
401
+
402
+ template <typename Iter> void copy(const std::string& s, Iter oi) {
403
+ std::copy(s.begin(), s.end(), oi);
404
+ }
405
+
406
+ template <typename Iter> void serialize_str(const std::string& s, Iter oi) {
407
+ *oi++ = '"';
408
+ for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
409
+ switch (*i) {
410
+ #define MAP(val, sym) case val: copy(sym, oi); break
411
+ MAP('"', "\\\"");
412
+ MAP('\\', "\\\\");
413
+ MAP('/', "\\/");
414
+ MAP('\b', "\\b");
415
+ MAP('\f', "\\f");
416
+ MAP('\n', "\\n");
417
+ MAP('\r', "\\r");
418
+ MAP('\t', "\\t");
419
+ #undef MAP
420
+ default:
421
+ if (static_cast<unsigned char>(*i) < 0x20 || *i == 0x7f) {
422
+ char buf[7];
423
+ SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff);
424
+ copy(buf, buf + 6, oi);
425
+ } else {
426
+ *oi++ = *i;
427
+ }
428
+ break;
429
+ }
430
+ }
431
+ *oi++ = '"';
432
+ }
433
+
434
+ template <typename Iter> void value::serialize(Iter oi, bool prettify) const {
435
+ return _serialize(oi, prettify ? 0 : -1);
436
+ }
437
+
438
+ inline std::string value::serialize(bool prettify) const {
439
+ return _serialize(prettify ? 0 : -1);
440
+ }
441
+
442
+ template <typename Iter> void value::_indent(Iter oi, int indent) {
443
+ *oi++ = '\n';
444
+ for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
445
+ *oi++ = ' ';
446
+ }
447
+ }
448
+
449
+ template <typename Iter> void value::_serialize(Iter oi, int indent) const {
450
+ switch (type_) {
451
+ case string_type:
452
+ serialize_str(*u_.string_, oi);
453
+ break;
454
+ case array_type: {
455
+ *oi++ = '[';
456
+ if (indent != -1) {
457
+ ++indent;
458
+ }
459
+ for (array::const_iterator i = u_.array_->begin();
460
+ i != u_.array_->end();
461
+ ++i) {
462
+ if (i != u_.array_->begin()) {
463
+ *oi++ = ',';
464
+ }
465
+ if (indent != -1) {
466
+ _indent(oi, indent);
467
+ }
468
+ i->_serialize(oi, indent);
469
+ }
470
+ if (indent != -1) {
471
+ --indent;
472
+ if (! u_.array_->empty()) {
473
+ _indent(oi, indent);
474
+ }
475
+ }
476
+ *oi++ = ']';
477
+ break;
478
+ }
479
+ case object_type: {
480
+ *oi++ = '{';
481
+ if (indent != -1) {
482
+ ++indent;
483
+ }
484
+ for (object::const_iterator i = u_.object_->begin();
485
+ i != u_.object_->end();
486
+ ++i) {
487
+ if (i != u_.object_->begin()) {
488
+ *oi++ = ',';
489
+ }
490
+ if (indent != -1) {
491
+ _indent(oi, indent);
492
+ }
493
+ serialize_str(i->first, oi);
494
+ *oi++ = ':';
495
+ if (indent != -1) {
496
+ *oi++ = ' ';
497
+ }
498
+ i->second._serialize(oi, indent);
499
+ }
500
+ if (indent != -1) {
501
+ --indent;
502
+ if (! u_.object_->empty()) {
503
+ _indent(oi, indent);
504
+ }
505
+ }
506
+ *oi++ = '}';
507
+ break;
508
+ }
509
+ default:
510
+ copy(to_str(), oi);
511
+ break;
512
+ }
513
+ if (indent == 0) {
514
+ *oi++ = '\n';
515
+ }
516
+ }
517
+
518
+ inline std::string value::_serialize(int indent) const {
519
+ std::string s;
520
+ _serialize(std::back_inserter(s), indent);
521
+ return s;
522
+ }
523
+
524
+ template <typename Iter> class input {
525
+ protected:
526
+ Iter cur_, end_;
527
+ int last_ch_;
528
+ bool ungot_;
529
+ int line_;
530
+ public:
531
+ input(const Iter& first, const Iter& last) : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {}
532
+ int getc() {
533
+ if (ungot_) {
534
+ ungot_ = false;
535
+ return last_ch_;
536
+ }
537
+ if (cur_ == end_) {
538
+ last_ch_ = -1;
539
+ return -1;
540
+ }
541
+ if (last_ch_ == '\n') {
542
+ line_++;
543
+ }
544
+ last_ch_ = *cur_ & 0xff;
545
+ ++cur_;
546
+ return last_ch_;
547
+ }
548
+ void ungetc() {
549
+ if (last_ch_ != -1) {
550
+ PICOJSON_ASSERT(! ungot_);
551
+ ungot_ = true;
552
+ }
553
+ }
554
+ Iter cur() const { return cur_; }
555
+ int line() const { return line_; }
556
+ void skip_ws() {
557
+ while (1) {
558
+ int ch = getc();
559
+ if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
560
+ ungetc();
561
+ break;
562
+ }
563
+ }
564
+ }
565
+ bool expect(int expect) {
566
+ skip_ws();
567
+ if (getc() != expect) {
568
+ ungetc();
569
+ return false;
570
+ }
571
+ return true;
572
+ }
573
+ bool match(const std::string& pattern) {
574
+ for (std::string::const_iterator pi(pattern.begin());
575
+ pi != pattern.end();
576
+ ++pi) {
577
+ if (getc() != *pi) {
578
+ ungetc();
579
+ return false;
580
+ }
581
+ }
582
+ return true;
583
+ }
584
+ };
585
+
586
+ template<typename Iter> inline int _parse_quadhex(input<Iter> &in) {
587
+ int uni_ch = 0, hex;
588
+ for (int i = 0; i < 4; i++) {
589
+ if ((hex = in.getc()) == -1) {
590
+ return -1;
591
+ }
592
+ if ('0' <= hex && hex <= '9') {
593
+ hex -= '0';
594
+ } else if ('A' <= hex && hex <= 'F') {
595
+ hex -= 'A' - 0xa;
596
+ } else if ('a' <= hex && hex <= 'f') {
597
+ hex -= 'a' - 0xa;
598
+ } else {
599
+ in.ungetc();
600
+ return -1;
601
+ }
602
+ uni_ch = uni_ch * 16 + hex;
603
+ }
604
+ return uni_ch;
605
+ }
606
+
607
+ template<typename String, typename Iter> inline bool _parse_codepoint(String& out, input<Iter>& in) {
608
+ int uni_ch;
609
+ if ((uni_ch = _parse_quadhex(in)) == -1) {
610
+ return false;
611
+ }
612
+ if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
613
+ if (0xdc00 <= uni_ch) {
614
+ // a second 16-bit of a surrogate pair appeared
615
+ return false;
616
+ }
617
+ // first 16-bit of surrogate pair, get the next one
618
+ if (in.getc() != '\\' || in.getc() != 'u') {
619
+ in.ungetc();
620
+ return false;
621
+ }
622
+ int second = _parse_quadhex(in);
623
+ if (! (0xdc00 <= second && second <= 0xdfff)) {
624
+ return false;
625
+ }
626
+ uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
627
+ uni_ch += 0x10000;
628
+ }
629
+ if (uni_ch < 0x80) {
630
+ out.push_back(uni_ch);
631
+ } else {
632
+ if (uni_ch < 0x800) {
633
+ out.push_back(0xc0 | (uni_ch >> 6));
634
+ } else {
635
+ if (uni_ch < 0x10000) {
636
+ out.push_back(0xe0 | (uni_ch >> 12));
637
+ } else {
638
+ out.push_back(0xf0 | (uni_ch >> 18));
639
+ out.push_back(0x80 | ((uni_ch >> 12) & 0x3f));
640
+ }
641
+ out.push_back(0x80 | ((uni_ch >> 6) & 0x3f));
642
+ }
643
+ out.push_back(0x80 | (uni_ch & 0x3f));
644
+ }
645
+ return true;
646
+ }
647
+
648
+ template<typename String, typename Iter> inline bool _parse_string(String& out, input<Iter>& in) {
649
+ while (1) {
650
+ int ch = in.getc();
651
+ if (ch < ' ') {
652
+ in.ungetc();
653
+ return false;
654
+ } else if (ch == '"') {
655
+ return true;
656
+ } else if (ch == '\\') {
657
+ if ((ch = in.getc()) == -1) {
658
+ return false;
659
+ }
660
+ switch (ch) {
661
+ #define MAP(sym, val) case sym: out.push_back(val); break
662
+ MAP('"', '\"');
663
+ MAP('\\', '\\');
664
+ MAP('/', '/');
665
+ MAP('b', '\b');
666
+ MAP('f', '\f');
667
+ MAP('n', '\n');
668
+ MAP('r', '\r');
669
+ MAP('t', '\t');
670
+ #undef MAP
671
+ case 'u':
672
+ if (! _parse_codepoint(out, in)) {
673
+ return false;
674
+ }
675
+ break;
676
+ default:
677
+ return false;
678
+ }
679
+ } else {
680
+ out.push_back(ch);
681
+ }
682
+ }
683
+ return false;
684
+ }
685
+
686
+ template <typename Context, typename Iter> inline bool _parse_array(Context& ctx, input<Iter>& in) {
687
+ if (! ctx.parse_array_start()) {
688
+ return false;
689
+ }
690
+ size_t idx = 0;
691
+ if (in.expect(']')) {
692
+ return ctx.parse_array_stop(idx);
693
+ }
694
+ do {
695
+ if (! ctx.parse_array_item(in, idx)) {
696
+ return false;
697
+ }
698
+ idx++;
699
+ } while (in.expect(','));
700
+ return in.expect(']') && ctx.parse_array_stop(idx);
701
+ }
702
+
703
+ template <typename Context, typename Iter> inline bool _parse_object(Context& ctx, input<Iter>& in) {
704
+ if (! ctx.parse_object_start()) {
705
+ return false;
706
+ }
707
+ if (in.expect('}')) {
708
+ return true;
709
+ }
710
+ do {
711
+ std::string key;
712
+ if (! in.expect('"')
713
+ || ! _parse_string(key, in)
714
+ || ! in.expect(':')) {
715
+ return false;
716
+ }
717
+ if (! ctx.parse_object_item(in, key)) {
718
+ return false;
719
+ }
720
+ } while (in.expect(','));
721
+ return in.expect('}');
722
+ }
723
+
724
+ template <typename Iter> inline std::string _parse_number(input<Iter>& in) {
725
+ std::string num_str;
726
+ while (1) {
727
+ int ch = in.getc();
728
+ if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-'
729
+ || ch == 'e' || ch == 'E') {
730
+ num_str.push_back(ch);
731
+ } else if (ch == '.') {
732
+ #if PICOJSON_USE_LOCALE
733
+ num_str += localeconv()->decimal_point;
734
+ #else
735
+ num_str.push_back('.');
736
+ #endif
737
+ } else {
738
+ in.ungetc();
739
+ break;
740
+ }
741
+ }
742
+ return num_str;
743
+ }
744
+
745
+ template <typename Context, typename Iter> inline bool _parse(Context& ctx, input<Iter>& in) {
746
+ in.skip_ws();
747
+ int ch = in.getc();
748
+ switch (ch) {
749
+ #define IS(ch, text, op) case ch: \
750
+ if (in.match(text) && op) { \
751
+ return true; \
752
+ } else { \
753
+ return false; \
754
+ }
755
+ IS('n', "ull", ctx.set_null());
756
+ IS('f', "alse", ctx.set_bool(false));
757
+ IS('t', "rue", ctx.set_bool(true));
758
+ #undef IS
759
+ case '"':
760
+ return ctx.parse_string(in);
761
+ case '[':
762
+ return _parse_array(ctx, in);
763
+ case '{':
764
+ return _parse_object(ctx, in);
765
+ default:
766
+ if (('0' <= ch && ch <= '9') || ch == '-') {
767
+ double f;
768
+ char *endp;
769
+ in.ungetc();
770
+ std::string num_str = _parse_number(in);
771
+ if (num_str.empty()) {
772
+ return false;
773
+ }
774
+ #ifdef PICOJSON_USE_INT64
775
+ {
776
+ errno = 0;
777
+ intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
778
+ if (errno == 0
779
+ && std::numeric_limits<int64_t>::min() <= ival
780
+ && ival <= std::numeric_limits<int64_t>::max()
781
+ && endp == num_str.c_str() + num_str.size()) {
782
+ ctx.set_int64(ival);
783
+ return true;
784
+ }
785
+ }
786
+ #endif
787
+ f = strtod(num_str.c_str(), &endp);
788
+ if (endp == num_str.c_str() + num_str.size()) {
789
+ ctx.set_number(f);
790
+ return true;
791
+ }
792
+ return false;
793
+ }
794
+ break;
795
+ }
796
+ in.ungetc();
797
+ return false;
798
+ }
799
+
800
+ class deny_parse_context {
801
+ public:
802
+ bool set_null() { return false; }
803
+ bool set_bool(bool) { return false; }
804
+ #ifdef PICOJSON_USE_INT64
805
+ bool set_int64(int64_t) { return false; }
806
+ #endif
807
+ bool set_number(double) { return false; }
808
+ template <typename Iter> bool parse_string(input<Iter>&) { return false; }
809
+ bool parse_array_start() { return false; }
810
+ template <typename Iter> bool parse_array_item(input<Iter>&, size_t) {
811
+ return false;
812
+ }
813
+ bool parse_array_stop(size_t) { return false; }
814
+ bool parse_object_start() { return false; }
815
+ template <typename Iter> bool parse_object_item(input<Iter>&, const std::string&) {
816
+ return false;
817
+ }
818
+ };
819
+
820
+ class default_parse_context {
821
+ protected:
822
+ value* out_;
823
+ public:
824
+ default_parse_context(value* out) : out_(out) {}
825
+ bool set_null() {
826
+ *out_ = value();
827
+ return true;
828
+ }
829
+ bool set_bool(bool b) {
830
+ *out_ = value(b);
831
+ return true;
832
+ }
833
+ #ifdef PICOJSON_USE_INT64
834
+ bool set_int64(int64_t i) {
835
+ *out_ = value(i);
836
+ return true;
837
+ }
838
+ #endif
839
+ bool set_number(double f) {
840
+ *out_ = value(f);
841
+ return true;
842
+ }
843
+ template<typename Iter> bool parse_string(input<Iter>& in) {
844
+ *out_ = value(string_type, false);
845
+ return _parse_string(out_->get<std::string>(), in);
846
+ }
847
+ bool parse_array_start() {
848
+ *out_ = value(array_type, false);
849
+ return true;
850
+ }
851
+ template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
852
+ array& a = out_->get<array>();
853
+ a.push_back(value());
854
+ default_parse_context ctx(&a.back());
855
+ return _parse(ctx, in);
856
+ }
857
+ bool parse_array_stop(size_t) { return true; }
858
+ bool parse_object_start() {
859
+ *out_ = value(object_type, false);
860
+ return true;
861
+ }
862
+ template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string& key) {
863
+ object& o = out_->get<object>();
864
+ default_parse_context ctx(&o[key]);
865
+ return _parse(ctx, in);
866
+ }
867
+ private:
868
+ default_parse_context(const default_parse_context&);
869
+ default_parse_context& operator=(const default_parse_context&);
870
+ };
871
+
872
+ class null_parse_context {
873
+ public:
874
+ struct dummy_str {
875
+ void push_back(int) {}
876
+ };
877
+ public:
878
+ null_parse_context() {}
879
+ bool set_null() { return true; }
880
+ bool set_bool(bool) { return true; }
881
+ #ifdef PICOJSON_USE_INT64
882
+ bool set_int64(int64_t) { return true; }
883
+ #endif
884
+ bool set_number(double) { return true; }
885
+ template <typename Iter> bool parse_string(input<Iter>& in) {
886
+ dummy_str s;
887
+ return _parse_string(s, in);
888
+ }
889
+ bool parse_array_start() { return true; }
890
+ template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
891
+ return _parse(*this, in);
892
+ }
893
+ bool parse_array_stop(size_t) { return true; }
894
+ bool parse_object_start() { return true; }
895
+ template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string&) {
896
+ return _parse(*this, in);
897
+ }
898
+ private:
899
+ null_parse_context(const null_parse_context&);
900
+ null_parse_context& operator=(const null_parse_context&);
901
+ };
902
+
903
+ // obsolete, use the version below
904
+ template <typename Iter> inline std::string parse(value& out, Iter& pos, const Iter& last) {
905
+ std::string err;
906
+ pos = parse(out, pos, last, &err);
907
+ return err;
908
+ }
909
+
910
+ template <typename Context, typename Iter> inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) {
911
+ input<Iter> in(first, last);
912
+ if (! _parse(ctx, in) && err != NULL) {
913
+ char buf[64];
914
+ SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
915
+ *err = buf;
916
+ while (1) {
917
+ int ch = in.getc();
918
+ if (ch == -1 || ch == '\n') {
919
+ break;
920
+ } else if (ch >= ' ') {
921
+ err->push_back(ch);
922
+ }
923
+ }
924
+ }
925
+ return in.cur();
926
+ }
927
+
928
+ template <typename Iter> inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) {
929
+ default_parse_context ctx(&out);
930
+ return _parse(ctx, first, last, err);
931
+ }
932
+
933
+ inline std::string parse(value& out, const std::string& s) {
934
+ std::string err;
935
+ parse(out, s.begin(), s.end(), &err);
936
+ return err;
937
+ }
938
+
939
+ inline std::string parse(value& out, std::istream& is) {
940
+ std::string err;
941
+ parse(out, std::istreambuf_iterator<char>(is.rdbuf()),
942
+ std::istreambuf_iterator<char>(), &err);
943
+ return err;
944
+ }
945
+
946
+ template <typename T> struct last_error_t {
947
+ static std::string s;
948
+ };
949
+ template <typename T> std::string last_error_t<T>::s;
950
+
951
+ inline void set_last_error(const std::string& s) {
952
+ last_error_t<bool>::s = s;
953
+ }
954
+
955
+ inline const std::string& get_last_error() {
956
+ return last_error_t<bool>::s;
957
+ }
958
+
959
+ inline bool operator==(const value& x, const value& y) {
960
+ if (x.is<null>())
961
+ return y.is<null>();
962
+ #define PICOJSON_CMP(type) \
963
+ if (x.is<type>()) \
964
+ return y.is<type>() && x.get<type>() == y.get<type>()
965
+ PICOJSON_CMP(bool);
966
+ PICOJSON_CMP(double);
967
+ PICOJSON_CMP(std::string);
968
+ PICOJSON_CMP(array);
969
+ PICOJSON_CMP(object);
970
+ #undef PICOJSON_CMP
971
+ PICOJSON_ASSERT(0);
972
+ #ifdef _MSC_VER
973
+ __assume(0);
974
+ #endif
975
+ return false;
976
+ }
977
+
978
+ inline bool operator!=(const value& x, const value& y) {
979
+ return ! (x == y);
980
+ }
981
+ }
982
+
983
+ namespace std {
984
+ template<> inline void swap(picojson::value& x, picojson::value& y)
985
+ {
986
+ x.swap(y);
987
+ }
988
+ }
989
+
990
+ inline std::istream& operator>>(std::istream& is, picojson::value& x)
991
+ {
992
+ picojson::set_last_error(std::string());
993
+ std::string err = picojson::parse(x, is);
994
+ if (! err.empty()) {
995
+ picojson::set_last_error(err);
996
+ is.setstate(std::ios::failbit);
997
+ }
998
+ return is;
999
+ }
1000
+
1001
+ inline std::ostream& operator<<(std::ostream& os, const picojson::value& x)
1002
+ {
1003
+ x.serialize(std::ostream_iterator<char>(os));
1004
+ return os;
1005
+ }
1006
+ #ifdef _MSC_VER
1007
+ #pragma warning(pop)
1008
+ #endif
1009
+
1010
+ #endif
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.license = "MIT"
19
19
 
20
20
  spec.files = `git ls-files -z`.split("\x0")
21
+ spec.files += ["modules/picojson/picojson.h"]
21
22
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
23
  spec.test_files = spec.files.grep(%r{^(test|spec|features|examples)/})
23
24
  spec.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picojson_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - SpringMT
@@ -71,6 +71,7 @@ files:
71
71
  - ext/picojson_ruby/picojson_ruby.h
72
72
  - lib/picojson_ruby.rb
73
73
  - lib/picojson_ruby/version.rb
74
+ - modules/picojson/picojson.h
74
75
  - picojson_ruby.gemspec
75
76
  - spec/picojson_ruby_spec.rb
76
77
  - spec/spec_helper.rb