Crow  0.3
A C++ microframework for the web
json.h
1#pragma once
2
3//#define CROW_JSON_NO_ERROR_CHECK
4//#define CROW_JSON_USE_MAP
5
6#include <string>
7#ifdef CROW_JSON_USE_MAP
8#include <map>
9#else
10#include <unordered_map>
11#endif
12#include <iostream>
13#include <algorithm>
14#include <memory>
15#include <boost/lexical_cast.hpp>
16#include <boost/algorithm/string/predicate.hpp>
17#include <boost/operators.hpp>
18#include <vector>
19
20#include "crow/settings.h"
21#include "crow/returnable.h"
22
23#if defined(__GNUG__) || defined(__clang__)
24#define crow_json_likely(x) __builtin_expect(x, 1)
25#define crow_json_unlikely(x) __builtin_expect(x, 0)
26#else
27#define crow_json_likely(x) x
28#define crow_json_unlikely(x) x
29#endif
30
31
32namespace crow
33{
34 namespace mustache
35 {
36 class template_t;
37 }
38
39 namespace json
40 {
41 inline void escape(const std::string& str, std::string& ret)
42 {
43 ret.reserve(ret.size() + str.size()+str.size()/4);
44 for(auto c:str)
45 {
46 switch(c)
47 {
48 case '"': ret += "\\\""; break;
49 case '\\': ret += "\\\\"; break;
50 case '\n': ret += "\\n"; break;
51 case '\b': ret += "\\b"; break;
52 case '\f': ret += "\\f"; break;
53 case '\r': ret += "\\r"; break;
54 case '\t': ret += "\\t"; break;
55 default:
56 if (c >= 0 && c < 0x20)
57 {
58 ret += "\\u00";
59 auto to_hex = [](char c)
60 {
61 c = c&0xf;
62 if (c < 10)
63 return '0' + c;
64 return 'a'+c-10;
65 };
66 ret += to_hex(c/16);
67 ret += to_hex(c%16);
68 }
69 else
70 ret += c;
71 break;
72 }
73 }
74 }
75 inline std::string escape(const std::string& str)
76 {
77 std::string ret;
78 escape(str, ret);
79 return ret;
80 }
81
82 enum class type : char
83 {
84 Null,
85 False,
86 True,
87 Number,
88 String,
89 List,
90 Object,
91 };
92
93 inline const char* get_type_str(type t) {
94 switch(t){
95 case type::Number: return "Number";
96 case type::False: return "False";
97 case type::True: return "True";
98 case type::List: return "List";
99 case type::String: return "String";
100 case type::Object: return "Object";
101 default: return "Unknown";
102 }
103 }
104
105 enum class num_type : char {
106 Signed_integer,
107 Unsigned_integer,
108 Floating_point,
109 Null
110 };
111
112 class rvalue;
113 rvalue load(const char* data, size_t size);
114
115 namespace detail
116 {
117 /// A read string implementation with comparison functionality.
118 struct r_string
119 : boost::less_than_comparable<r_string>,
120 boost::less_than_comparable<r_string, std::string>,
121 boost::equality_comparable<r_string>,
122 boost::equality_comparable<r_string, std::string>
123 {
124 r_string() {};
125 r_string(char* s, char* e)
126 : s_(s), e_(e)
127 {};
128 ~r_string()
129 {
130 if (owned_)
131 delete[] s_;
132 }
133
134 r_string(const r_string& r)
135 {
136 *this = r;
137 }
138
139 r_string(r_string&& r)
140 {
141 *this = r;
142 }
143
144 r_string& operator = (r_string&& r)
145 {
146 s_ = r.s_;
147 e_ = r.e_;
148 owned_ = r.owned_;
149 if (r.owned_)
150 r.owned_ = 0;
151 return *this;
152 }
153
154 r_string& operator = (const r_string& r)
155 {
156 s_ = r.s_;
157 e_ = r.e_;
158 owned_ = 0;
159 return *this;
160 }
161
162 operator std::string () const
163 {
164 return std::string(s_, e_);
165 }
166
167
168 const char* begin() const { return s_; }
169 const char* end() const { return e_; }
170 size_t size() const { return end() - begin(); }
171
172 using iterator = const char*;
173 using const_iterator = const char*;
174
175 char* s_; ///< Start.
176 mutable char* e_; ///< End.
177 uint8_t owned_{0};
178 friend std::ostream& operator << (std::ostream& os, const r_string& s)
179 {
180 os << static_cast<std::string>(s);
181 return os;
182 }
183 private:
184 void force(char* s, uint32_t length)
185 {
186 s_ = s;
187 e_ = s_ + length;
188 owned_ = 1;
189 }
190 friend rvalue crow::json::load(const char* data, size_t size);
191 };
192
193 inline bool operator < (const r_string& l, const r_string& r)
194 {
195 return boost::lexicographical_compare(l,r);
196 }
197
198 inline bool operator < (const r_string& l, const std::string& r)
199 {
200 return boost::lexicographical_compare(l,r);
201 }
202
203 inline bool operator > (const r_string& l, const std::string& r)
204 {
205 return boost::lexicographical_compare(r,l);
206 }
207
208 inline bool operator == (const r_string& l, const r_string& r)
209 {
210 return boost::equals(l,r);
211 }
212
213 inline bool operator == (const r_string& l, const std::string& r)
214 {
215 return boost::equals(l,r);
216 }
217 }
218
219 /// JSON read value.
220
221 ///
222 /// Value can mean any json value, including a JSON object.
223 /// Read means this class is used to primarily read strings into a JSON value.
224 class rvalue
225 {
226 static const int cached_bit = 2;
227 static const int error_bit = 4;
228 public:
229 rvalue() noexcept : option_{error_bit}
230 {}
231 rvalue(type t) noexcept
232 : lsize_{}, lremain_{}, t_{t}
233 {}
234 rvalue(type t, char* s, char* e) noexcept
235 : start_{s},
236 end_{e},
237 t_{t}
238 {
239 determine_num_type();
240 }
241
242 rvalue(const rvalue& r)
243 : start_(r.start_),
244 end_(r.end_),
245 key_(r.key_),
246 t_(r.t_),
247 nt_(r.nt_),
248 option_(r.option_)
249 {
250 copy_l(r);
251 }
252
253 rvalue(rvalue&& r) noexcept
254 {
255 *this = std::move(r);
256 }
257
258 rvalue& operator = (const rvalue& r)
259 {
260 start_ = r.start_;
261 end_ = r.end_;
262 key_ = r.key_;
263 t_ = r.t_;
264 nt_ = r.nt_;
265 option_ = r.option_;
266 copy_l(r);
267 return *this;
268 }
269 rvalue& operator = (rvalue&& r) noexcept
270 {
271 start_ = r.start_;
272 end_ = r.end_;
273 key_ = std::move(r.key_);
274 l_ = std::move(r.l_);
275 lsize_ = r.lsize_;
276 lremain_ = r.lremain_;
277 t_ = r.t_;
278 nt_ = r.nt_;
279 option_ = r.option_;
280 return *this;
281 }
282
283 explicit operator bool() const noexcept
284 {
285 return (option_ & error_bit) == 0;
286 }
287
288 explicit operator int64_t() const
289 {
290 return i();
291 }
292
293 explicit operator uint64_t() const
294 {
295 return u();
296 }
297
298 explicit operator int() const
299 {
300 return static_cast<int>(i());
301 }
302
303 ///Return any json value (not object or list) as a string.
304 explicit operator std::string() const
305 {
306#ifndef CROW_JSON_NO_ERROR_CHECK
307 if (t() == type::Object || t() == type::List)
308 throw std::runtime_error("json type container");
309#endif
310 switch (t())
311 {
312 case type::String:
313 return std::string(s());
314 case type::Null:
315 return std::string("null");
316 case type::True:
317 return std::string("true");
318 case type::False:
319 return std::string("false");
320 default:
321 return std::string(start_, end_-start_);
322 }
323 }
324
325 /// The type of the JSON value.
326 type t() const
327 {
328#ifndef CROW_JSON_NO_ERROR_CHECK
329 if (option_ & error_bit)
330 {
331 throw std::runtime_error("invalid json object");
332 }
333#endif
334 return t_;
335 }
336
337 /// The number type of the JSON value.
338 num_type nt() const
339 {
340#ifndef CROW_JSON_NO_ERROR_CHECK
341 if (option_ & error_bit)
342 {
343 throw std::runtime_error("invalid json object");
344 }
345#endif
346 return nt_;
347 }
348
349 /// The integer value.
350 int64_t i() const
351 {
352#ifndef CROW_JSON_NO_ERROR_CHECK
353 switch (t()) {
354 case type::Number:
355 case type::String:
356 return boost::lexical_cast<int64_t>(start_, end_-start_);
357 default:
358 const std::string msg = "expected number, got: "
359 + std::string(get_type_str(t()));
360 throw std::runtime_error(msg);
361 }
362#endif
363 return boost::lexical_cast<int64_t>(start_, end_-start_);
364 }
365
366 /// The unsigned integer value.
367 uint64_t u() const
368 {
369#ifndef CROW_JSON_NO_ERROR_CHECK
370 switch (t()) {
371 case type::Number:
372 case type::String:
373 return boost::lexical_cast<uint64_t>(start_, end_-start_);
374 default:
375 throw std::runtime_error(std::string("expected number, got: ") + get_type_str(t()));
376 }
377#endif
378 return boost::lexical_cast<uint64_t>(start_, end_-start_);
379 }
380
381 /// The double precision floating-point number value.
382 double d() const
383 {
384#ifndef CROW_JSON_NO_ERROR_CHECK
385 if (t() != type::Number)
386 throw std::runtime_error("value is not number");
387#endif
388 return boost::lexical_cast<double>(start_, end_-start_);
389 }
390
391 /// The boolean value.
392 bool b() const
393 {
394#ifndef CROW_JSON_NO_ERROR_CHECK
395 if (t() != type::True && t() != type::False)
396 throw std::runtime_error("value is not boolean");
397#endif
398 return t() == type::True;
399 }
400
401 /// The string value.
403 {
404#ifndef CROW_JSON_NO_ERROR_CHECK
405 if (t() != type::String)
406 throw std::runtime_error("value is not string");
407#endif
408 unescape();
409 return detail::r_string{start_, end_};
410 }
411
412 ///The list or object value
413 std::vector<rvalue> lo()
414 {
415#ifndef CROW_JSON_NO_ERROR_CHECK
416 if (t() != type::Object && t() != type::List)
417 throw std::runtime_error("value is not a container");
418#endif
419 std::vector<rvalue> ret;
420 ret.reserve(lsize_);
421 for (uint32_t i = 0; i<lsize_; i++)
422 {
423 ret.emplace_back(l_[i]);
424 }
425 return ret;
426 }
427
428 /// Convert escaped string character to their original form ("\\n" -> '\n').
429 void unescape() const
430 {
431 if (*(start_-1))
432 {
433 char* head = start_;
434 char* tail = start_;
435 while(head != end_)
436 {
437 if (*head == '\\')
438 {
439 switch(*++head)
440 {
441 case '"': *tail++ = '"'; break;
442 case '\\': *tail++ = '\\'; break;
443 case '/': *tail++ = '/'; break;
444 case 'b': *tail++ = '\b'; break;
445 case 'f': *tail++ = '\f'; break;
446 case 'n': *tail++ = '\n'; break;
447 case 'r': *tail++ = '\r'; break;
448 case 't': *tail++ = '\t'; break;
449 case 'u':
450 {
451 auto from_hex = [](char c)
452 {
453 if (c >= 'a')
454 return c - 'a' + 10;
455 if (c >= 'A')
456 return c - 'A' + 10;
457 return c - '0';
458 };
459 unsigned int code =
460 (from_hex(head[1])<<12) +
461 (from_hex(head[2])<< 8) +
462 (from_hex(head[3])<< 4) +
463 from_hex(head[4]);
464 if (code >= 0x800)
465 {
466 *tail++ = 0xE0 | (code >> 12);
467 *tail++ = 0x80 | ((code >> 6) & 0x3F);
468 *tail++ = 0x80 | (code & 0x3F);
469 }
470 else if (code >= 0x80)
471 {
472 *tail++ = 0xC0 | (code >> 6);
473 *tail++ = 0x80 | (code & 0x3F);
474 }
475 else
476 {
477 *tail++ = code;
478 }
479 head += 4;
480 }
481 break;
482 }
483 }
484 else
485 *tail++ = *head;
486 head++;
487 }
488 end_ = tail;
489 *end_ = 0;
490 *(start_-1) = 0;
491 }
492 }
493
494 ///Check if the json object has the passed string as a key.
495 bool has(const char* str) const
496 {
497 return has(std::string(str));
498 }
499
500 bool has(const std::string& str) const
501 {
502 struct Pred
503 {
504 bool operator()(const rvalue& l, const rvalue& r) const
505 {
506 return l.key_ < r.key_;
507 };
508 bool operator()(const rvalue& l, const std::string& r) const
509 {
510 return l.key_ < r;
511 };
512 bool operator()(const std::string& l, const rvalue& r) const
513 {
514 return l < r.key_;
515 };
516 };
517 if (!is_cached())
518 {
519 std::sort(begin(), end(), Pred());
520 set_cached();
521 }
522 auto it = lower_bound(begin(), end(), str, Pred());
523 return it != end() && it->key_ == str;
524 }
525
526 int count(const std::string& str)
527 {
528 return has(str) ? 1 : 0;
529 }
530
531 rvalue* begin() const
532 {
533#ifndef CROW_JSON_NO_ERROR_CHECK
534 if (t() != type::Object && t() != type::List)
535 throw std::runtime_error("value is not a container");
536#endif
537 return l_.get();
538 }
539 rvalue* end() const
540 {
541#ifndef CROW_JSON_NO_ERROR_CHECK
542 if (t() != type::Object && t() != type::List)
543 throw std::runtime_error("value is not a container");
544#endif
545 return l_.get()+lsize_;
546 }
547
548 const detail::r_string& key() const
549 {
550 return key_;
551 }
552
553 size_t size() const
554 {
555 if (t() == type::String)
556 return s().size();
557#ifndef CROW_JSON_NO_ERROR_CHECK
558 if (t() != type::Object && t() != type::List)
559 throw std::runtime_error("value is not a container");
560#endif
561 return lsize_;
562 }
563
564 const rvalue& operator[](int index) const
565 {
566#ifndef CROW_JSON_NO_ERROR_CHECK
567 if (t() != type::List)
568 throw std::runtime_error("value is not a list");
569 if (index >= static_cast<int>(lsize_) || index < 0)
570 throw std::runtime_error("list out of bound");
571#endif
572 return l_[index];
573 }
574
575 const rvalue& operator[](size_t index) const
576 {
577#ifndef CROW_JSON_NO_ERROR_CHECK
578 if (t() != type::List)
579 throw std::runtime_error("value is not a list");
580 if (index >= lsize_)
581 throw std::runtime_error("list out of bound");
582#endif
583 return l_[index];
584 }
585
586 const rvalue& operator[](const char* str) const
587 {
588 return this->operator[](std::string(str));
589 }
590
591 const rvalue& operator[](const std::string& str) const
592 {
593#ifndef CROW_JSON_NO_ERROR_CHECK
594 if (t() != type::Object)
595 throw std::runtime_error("value is not an object");
596#endif
597 struct Pred
598 {
599 bool operator()(const rvalue& l, const rvalue& r) const
600 {
601 return l.key_ < r.key_;
602 };
603 bool operator()(const rvalue& l, const std::string& r) const
604 {
605 return l.key_ < r;
606 };
607 bool operator()(const std::string& l, const rvalue& r) const
608 {
609 return l < r.key_;
610 };
611 };
612 if (!is_cached())
613 {
614 std::sort(begin(), end(), Pred());
615 set_cached();
616 }
617 auto it = lower_bound(begin(), end(), str, Pred());
618 if (it != end() && it->key_ == str)
619 return *it;
620#ifndef CROW_JSON_NO_ERROR_CHECK
621 throw std::runtime_error("cannot find key");
622#else
623 static rvalue nullValue;
624 return nullValue;
625#endif
626 }
627
628 void set_error()
629 {
630 option_|=error_bit;
631 }
632
633 bool error() const
634 {
635 return (option_&error_bit)!=0;
636 }
637
638 std::vector<std::string> keys()
639 {
640#ifndef CROW_JSON_NO_ERROR_CHECK
641 if (t() != type::Object)
642 throw std::runtime_error("value is not an object");
643#endif
644 std::vector<std::string> ret;
645 ret.reserve(lsize_);
646 for (uint32_t i = 0; i<lsize_; i++)
647 {
648 ret.emplace_back(std::string(l_[i].key()));
649 }
650 return ret;
651 }
652 private:
653 bool is_cached() const
654 {
655 return (option_&cached_bit)!=0;
656 }
657 void set_cached() const
658 {
659 option_ |= cached_bit;
660 }
661 void copy_l(const rvalue& r)
662 {
663 if (r.t() != type::Object && r.t() != type::List)
664 return;
665 lsize_ = r.lsize_;
666 lremain_ = 0;
667 l_.reset(new rvalue[lsize_]);
668 std::copy(r.begin(), r.end(), begin());
669 }
670
671 void emplace_back(rvalue&& v)
672 {
673 if (!lremain_)
674 {
675 int new_size = lsize_ + lsize_;
676 if (new_size - lsize_ > 60000)
677 new_size = lsize_ + 60000;
678 if (new_size < 4)
679 new_size = 4;
680 rvalue* p = new rvalue[new_size];
681 rvalue* p2 = p;
682 for(auto& x : *this)
683 *p2++ = std::move(x);
684 l_.reset(p);
685 lremain_ = new_size - lsize_;
686 }
687 l_[lsize_++] = std::move(v);
688 lremain_ --;
689 }
690
691 /// determines num_type from the string.
692 void determine_num_type()
693 {
694 if (t_ != type::Number)
695 {
696 nt_ = num_type::Null;
697 return;
698 }
699
700 const std::size_t len = end_ - start_;
701 const bool has_minus = std::memchr(start_, '-', len) != nullptr;
702 const bool has_e = std::memchr(start_, 'e', len) != nullptr
703 || std::memchr(start_, 'E', len) != nullptr;
704 const bool has_dec_sep = std::memchr(start_, '.', len) != nullptr;
705 if (has_dec_sep || has_e)
706 nt_ = num_type::Floating_point;
707 else if (has_minus)
708 nt_ = num_type::Signed_integer;
709 else
710 nt_ = num_type::Unsigned_integer;
711 }
712
713 mutable char* start_;
714 mutable char* end_;
715 detail::r_string key_;
716 std::unique_ptr<rvalue[]> l_;
717 uint32_t lsize_;
718 uint16_t lremain_;
719 type t_;
720 num_type nt_{num_type::Null};
721 mutable uint8_t option_{0};
722
723 friend rvalue load_nocopy_internal(char* data, size_t size);
724 friend rvalue load(const char* data, size_t size);
725 friend std::ostream& operator <<(std::ostream& os, const rvalue& r)
726 {
727 switch(r.t_)
728 {
729
730 case type::Null: os << "null"; break;
731 case type::False: os << "false"; break;
732 case type::True: os << "true"; break;
733 case type::Number:
734 {
735 switch (r.nt())
736 {
737 case num_type::Floating_point: os << r.d(); break;
738 case num_type::Signed_integer: os << r.i(); break;
739 case num_type::Unsigned_integer: os << r.u(); break;
740 case num_type::Null: throw std::runtime_error("Number with num_type Null");
741 }
742 }
743 break;
744 case type::String: os << '"' << r.s() << '"'; break;
745 case type::List:
746 {
747 os << '[';
748 bool first = true;
749 for(auto& x : r)
750 {
751 if (!first)
752 os << ',';
753 first = false;
754 os << x;
755 }
756 os << ']';
757 }
758 break;
759 case type::Object:
760 {
761 os << '{';
762 bool first = true;
763 for(auto& x : r)
764 {
765 if (!first)
766 os << ',';
767 os << '"' << escape(x.key_) << "\":";
768 first = false;
769 os << x;
770 }
771 os << '}';
772 }
773 break;
774 }
775 return os;
776 }
777 };
778 namespace detail {
779 }
780
781 inline bool operator == (const rvalue& l, const std::string& r)
782 {
783 return l.s() == r;
784 }
785
786 inline bool operator == (const std::string& l, const rvalue& r)
787 {
788 return l == r.s();
789 }
790
791 inline bool operator != (const rvalue& l, const std::string& r)
792 {
793 return l.s() != r;
794 }
795
796 inline bool operator != (const std::string& l, const rvalue& r)
797 {
798 return l != r.s();
799 }
800
801 inline bool operator == (const rvalue& l, double r)
802 {
803 return l.d() == r;
804 }
805
806 inline bool operator == (double l, const rvalue& r)
807 {
808 return l == r.d();
809 }
810
811 inline bool operator != (const rvalue& l, double r)
812 {
813 return l.d() != r;
814 }
815
816 inline bool operator != (double l, const rvalue& r)
817 {
818 return l != r.d();
819 }
820
821
822 inline rvalue load_nocopy_internal(char* data, size_t size)
823 {
824 //static const char* escaped = "\"\\/\b\f\n\r\t";
825 struct Parser
826 {
827 Parser(char* data, size_t /*size*/)
828 : data(data)
829 {
830 }
831
832 bool consume(char c)
833 {
834 if (crow_json_unlikely(*data != c))
835 return false;
836 data++;
837 return true;
838 }
839
840 void ws_skip()
841 {
842 while(*data == ' ' || *data == '\t' || *data == '\r' || *data == '\n') ++data;
843 };
844
845 rvalue decode_string()
846 {
847 if (crow_json_unlikely(!consume('"')))
848 return {};
849 char* start = data;
850 uint8_t has_escaping = 0;
851 while(1)
852 {
853 if (crow_json_likely(*data != '"' && *data != '\\' && *data != '\0'))
854 {
855 data ++;
856 }
857 else if (*data == '"')
858 {
859 *data = 0;
860 *(start-1) = has_escaping;
861 data++;
862 return {type::String, start, data-1};
863 }
864 else if (*data == '\\')
865 {
866 has_escaping = 1;
867 data++;
868 switch(*data)
869 {
870 case 'u':
871 {
872 auto check = [](char c)
873 {
874 return
875 ('0' <= c && c <= '9') ||
876 ('a' <= c && c <= 'f') ||
877 ('A' <= c && c <= 'F');
878 };
879 if (!(check(*(data+1)) &&
880 check(*(data+2)) &&
881 check(*(data+3)) &&
882 check(*(data+4))))
883 return {};
884 }
885 data += 5;
886 break;
887 case '"':
888 case '\\':
889 case '/':
890 case 'b':
891 case 'f':
892 case 'n':
893 case 'r':
894 case 't':
895 data ++;
896 break;
897 default:
898 return {};
899 }
900 }
901 else
902 return {};
903 }
904 return {};
905 }
906
907 rvalue decode_list()
908 {
909 rvalue ret(type::List);
910 if (crow_json_unlikely(!consume('[')))
911 {
912 ret.set_error();
913 return ret;
914 }
915 ws_skip();
916 if (crow_json_unlikely(*data == ']'))
917 {
918 data++;
919 return ret;
920 }
921
922 while(1)
923 {
924 auto v = decode_value();
925 if (crow_json_unlikely(!v))
926 {
927 ret.set_error();
928 break;
929 }
930 ws_skip();
931 ret.emplace_back(std::move(v));
932 if (*data == ']')
933 {
934 data++;
935 break;
936 }
937 if (crow_json_unlikely(!consume(',')))
938 {
939 ret.set_error();
940 break;
941 }
942 ws_skip();
943 }
944 return ret;
945 }
946
947 rvalue decode_number()
948 {
949 char* start = data;
950
951 enum NumberParsingState
952 {
953 Minus,
954 AfterMinus,
955 ZeroFirst,
956 Digits,
957 DigitsAfterPoints,
958 E,
959 DigitsAfterE,
960 Invalid,
961 } state{Minus};
962 while(crow_json_likely(state != Invalid))
963 {
964 switch(*data)
965 {
966 case '0':
967 state = static_cast<NumberParsingState>("\2\2\7\3\4\6\6"[state]);
968 /*if (state == NumberParsingState::Minus || state == NumberParsingState::AfterMinus)
969 {
970 state = NumberParsingState::ZeroFirst;
971 }
972 else if (state == NumberParsingState::Digits ||
973 state == NumberParsingState::DigitsAfterE ||
974 state == NumberParsingState::DigitsAfterPoints)
975 {
976 // ok; pass
977 }
978 else if (state == NumberParsingState::E)
979 {
980 state = NumberParsingState::DigitsAfterE;
981 }
982 else
983 return {};*/
984 break;
985 case '1': case '2': case '3':
986 case '4': case '5': case '6':
987 case '7': case '8': case '9':
988 state = static_cast<NumberParsingState>("\3\3\7\3\4\6\6"[state]);
989 while(*(data+1) >= '0' && *(data+1) <= '9') data++;
990 /*if (state == NumberParsingState::Minus || state == NumberParsingState::AfterMinus)
991 {
992 state = NumberParsingState::Digits;
993 }
994 else if (state == NumberParsingState::Digits ||
995 state == NumberParsingState::DigitsAfterE ||
996 state == NumberParsingState::DigitsAfterPoints)
997 {
998 // ok; pass
999 }
1000 else if (state == NumberParsingState::E)
1001 {
1002 state = NumberParsingState::DigitsAfterE;
1003 }
1004 else
1005 return {};*/
1006 break;
1007 case '.':
1008 state = static_cast<NumberParsingState>("\7\7\4\4\7\7\7"[state]);
1009 /*
1010 if (state == NumberParsingState::Digits || state == NumberParsingState::ZeroFirst)
1011 {
1012 state = NumberParsingState::DigitsAfterPoints;
1013 }
1014 else
1015 return {};
1016 */
1017 break;
1018 case '-':
1019 state = static_cast<NumberParsingState>("\1\7\7\7\7\6\7"[state]);
1020 /*if (state == NumberParsingState::Minus)
1021 {
1022 state = NumberParsingState::AfterMinus;
1023 }
1024 else if (state == NumberParsingState::E)
1025 {
1026 state = NumberParsingState::DigitsAfterE;
1027 }
1028 else
1029 return {};*/
1030 break;
1031 case '+':
1032 state = static_cast<NumberParsingState>("\7\7\7\7\7\6\7"[state]);
1033 /*if (state == NumberParsingState::E)
1034 {
1035 state = NumberParsingState::DigitsAfterE;
1036 }
1037 else
1038 return {};*/
1039 break;
1040 case 'e': case 'E':
1041 state = static_cast<NumberParsingState>("\7\7\7\5\5\7\7"[state]);
1042 /*if (state == NumberParsingState::Digits ||
1043 state == NumberParsingState::DigitsAfterPoints)
1044 {
1045 state = NumberParsingState::E;
1046 }
1047 else
1048 return {};*/
1049 break;
1050 default:
1051 if (crow_json_likely(state == NumberParsingState::ZeroFirst ||
1052 state == NumberParsingState::Digits ||
1053 state == NumberParsingState::DigitsAfterPoints ||
1054 state == NumberParsingState::DigitsAfterE))
1055 return {type::Number, start, data};
1056 else
1057 return {};
1058 }
1059 data++;
1060 }
1061
1062 return {};
1063 }
1064
1065 rvalue decode_value()
1066 {
1067 switch(*data)
1068 {
1069 case '[':
1070 return decode_list();
1071 case '{':
1072 return decode_object();
1073 case '"':
1074 return decode_string();
1075 case 't':
1076 if (//e-data >= 4 &&
1077 data[1] == 'r' &&
1078 data[2] == 'u' &&
1079 data[3] == 'e')
1080 {
1081 data += 4;
1082 return {type::True};
1083 }
1084 else
1085 return {};
1086 case 'f':
1087 if (//e-data >= 5 &&
1088 data[1] == 'a' &&
1089 data[2] == 'l' &&
1090 data[3] == 's' &&
1091 data[4] == 'e')
1092 {
1093 data += 5;
1094 return {type::False};
1095 }
1096 else
1097 return {};
1098 case 'n':
1099 if (//e-data >= 4 &&
1100 data[1] == 'u' &&
1101 data[2] == 'l' &&
1102 data[3] == 'l')
1103 {
1104 data += 4;
1105 return {type::Null};
1106 }
1107 else
1108 return {};
1109 //case '1': case '2': case '3':
1110 //case '4': case '5': case '6':
1111 //case '7': case '8': case '9':
1112 //case '0': case '-':
1113 default:
1114 return decode_number();
1115 }
1116 return {};
1117 }
1118
1119 rvalue decode_object()
1120 {
1121 rvalue ret(type::Object);
1122 if (crow_json_unlikely(!consume('{')))
1123 {
1124 ret.set_error();
1125 return ret;
1126 }
1127
1128 ws_skip();
1129
1130 if (crow_json_unlikely(*data == '}'))
1131 {
1132 data++;
1133 return ret;
1134 }
1135
1136 while(1)
1137 {
1138 auto t = decode_string();
1139 if (crow_json_unlikely(!t))
1140 {
1141 ret.set_error();
1142 break;
1143 }
1144
1145 ws_skip();
1146 if (crow_json_unlikely(!consume(':')))
1147 {
1148 ret.set_error();
1149 break;
1150 }
1151
1152 // TODO caching key to speed up (flyweight?)
1153 // I have no idea how flyweight could apply here, but maybe some speedup can happen if we stopped checking type since decode_string returns a string anyway
1154 auto key = t.s();
1155
1156 ws_skip();
1157 auto v = decode_value();
1158 if (crow_json_unlikely(!v))
1159 {
1160 ret.set_error();
1161 break;
1162 }
1163 ws_skip();
1164
1165 v.key_ = std::move(key);
1166 ret.emplace_back(std::move(v));
1167 if (crow_json_unlikely(*data == '}'))
1168 {
1169 data++;
1170 break;
1171 }
1172 if (crow_json_unlikely(!consume(',')))
1173 {
1174 ret.set_error();
1175 break;
1176 }
1177 ws_skip();
1178 }
1179 return ret;
1180 }
1181
1182 rvalue parse()
1183 {
1184 ws_skip();
1185 auto ret = decode_value(); // or decode object?
1186 ws_skip();
1187 if (ret && *data != '\0')
1188 ret.set_error();
1189 return ret;
1190 }
1191
1192 char* data;
1193 };
1194 return Parser(data, size).parse();
1195 }
1196 inline rvalue load(const char* data, size_t size)
1197 {
1198 char* s = new char[size+1];
1199 memcpy(s, data, size);
1200 s[size] = 0;
1201 auto ret = load_nocopy_internal(s, size);
1202 if (ret)
1203 ret.key_.force(s, size);
1204 else
1205 delete[] s;
1206 return ret;
1207 }
1208
1209 inline rvalue load(const char* data)
1210 {
1211 return load(data, strlen(data));
1212 }
1213
1214 inline rvalue load(const std::string& str)
1215 {
1216 return load(str.data(), str.size());
1217 }
1218
1219 /// JSON write value.
1220
1221 ///
1222 /// Value can mean any json value, including a JSON object.
1223 /// Write means this class is used to primarily assemble JSON objects using keys and values and export those into a string.
1224 class wvalue : public returnable
1225 {
1226 friend class crow::mustache::template_t;
1227 public:
1228 type t() const { return t_; }
1229 private:
1230 type t_{type::Null}; ///< The type of the value.
1231 num_type nt{num_type::Null}; ///< The specific type of the number if \ref t_ is a number.
1232 union {
1233 double d;
1234 int64_t si;
1235 uint64_t ui {};
1236 } num; ///< Value if type is a number.
1237 std::string s; ///< Value if type is a string.
1238 std::unique_ptr<std::vector<wvalue>> l; ///< Value if type is a list.
1239#ifdef CROW_JSON_USE_MAP
1240 std::unique_ptr<std::map<std::string, wvalue>> o;
1241#else
1242 std::unique_ptr<std::unordered_map<std::string, wvalue>> o; ///< Value if type is a JSON object.
1243#endif
1244
1245 public:
1246
1247 wvalue() : returnable("application/json") {}
1248
1249 wvalue(std::vector<wvalue>& r) : returnable("application/json")
1250 {
1251 t_ = type::List;
1252 l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
1253 l->reserve(r.size());
1254 for(auto it = r.begin(); it != r.end(); ++it)
1255 l->emplace_back(*it);
1256 }
1257
1258 /// Create a write value from a read value (useful for editing JSON strings).
1259 wvalue(const rvalue& r) : returnable("application/json")
1260 {
1261 t_ = r.t();
1262 switch(r.t())
1263 {
1264 case type::Null:
1265 case type::False:
1266 case type::True:
1267 return;
1268 case type::Number:
1269 nt = r.nt();
1270 if (nt == num_type::Floating_point)
1271 num.d = r.d();
1272 else if (nt == num_type::Signed_integer)
1273 num.si = r.i();
1274 else
1275 num.ui = r.u();
1276 return;
1277 case type::String:
1278 s = r.s();
1279 return;
1280 case type::List:
1281 l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
1282 l->reserve(r.size());
1283 for(auto it = r.begin(); it != r.end(); ++it)
1284 l->emplace_back(*it);
1285 return;
1286 case type::Object:
1287#ifdef CROW_JSON_USE_MAP
1288 o = std::unique_ptr<std::map<std::string, wvalue>>(new std::map<std::string, wvalue>{});
1289#else
1290 o = std::unique_ptr<std::unordered_map<std::string, wvalue>>(new std::unordered_map<std::string, wvalue>{});
1291#endif
1292 for(auto it = r.begin(); it != r.end(); ++it)
1293 o->emplace(it->key(), *it);
1294 return;
1295 }
1296 }
1297
1298 wvalue(const wvalue& r) : returnable("application/json")
1299 {
1300 t_ = r.t();
1301 switch(r.t())
1302 {
1303 case type::Null:
1304 case type::False:
1305 case type::True:
1306 return;
1307 case type::Number:
1308 nt = r.nt;
1309 if (nt == num_type::Floating_point)
1310 num.d = r.num.d;
1311 else if (nt == num_type::Signed_integer)
1312 num.si = r.num.si;
1313 else
1314 num.ui = r.num.ui;
1315 return;
1316 case type::String:
1317 s = r.s;
1318 return;
1319 case type::List:
1320 l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
1321 l->reserve(r.size());
1322 for(auto it = r.l->begin(); it != r.l->end(); ++it)
1323 l->emplace_back(*it);
1324 return;
1325 case type::Object:
1326#ifdef CROW_JSON_USE_MAP
1327 o = std::unique_ptr<std::map<std::string, wvalue>>(new std::map<std::string, wvalue>{});
1328#else
1329 o = std::unique_ptr<std::unordered_map<std::string, wvalue>>(new std::unordered_map<std::string, wvalue>{});
1330#endif
1331 o->insert(r.o->begin(), r.o->end());
1332 return;
1333 }
1334 }
1335
1336 wvalue(wvalue&& r) : returnable("application/json")
1337 {
1338 *this = std::move(r);
1339 }
1340
1341 wvalue& operator = (wvalue&& r)
1342 {
1343 t_ = r.t_;
1344 num = r.num;
1345 s = std::move(r.s);
1346 l = std::move(r.l);
1347 o = std::move(r.o);
1348 return *this;
1349 }
1350
1351 /// Used for compatibility, same as \ref reset()
1352 void clear()
1353 {
1354 reset();
1355 }
1356
1357 void reset()
1358 {
1359 t_ = type::Null;
1360 l.reset();
1361 o.reset();
1362 }
1363
1364 wvalue& operator = (std::nullptr_t)
1365 {
1366 reset();
1367 return *this;
1368 }
1369 wvalue& operator = (bool value)
1370 {
1371 reset();
1372 if (value)
1373 t_ = type::True;
1374 else
1375 t_ = type::False;
1376 return *this;
1377 }
1378
1379 wvalue& operator = (double value)
1380 {
1381 reset();
1382 t_ = type::Number;
1383 num.d = value;
1384 nt = num_type::Floating_point;
1385 return *this;
1386 }
1387
1388 wvalue& operator = (unsigned short value)
1389 {
1390 reset();
1391 t_ = type::Number;
1392 num.ui = value;
1393 nt = num_type::Unsigned_integer;
1394 return *this;
1395 }
1396
1397 wvalue& operator = (short value)
1398 {
1399 reset();
1400 t_ = type::Number;
1401 num.si = value;
1402 nt = num_type::Signed_integer;
1403 return *this;
1404 }
1405
1406 wvalue& operator = (long long value)
1407 {
1408 reset();
1409 t_ = type::Number;
1410 num.si = value;
1411 nt = num_type::Signed_integer;
1412 return *this;
1413 }
1414
1415 wvalue& operator = (long value)
1416 {
1417 reset();
1418 t_ = type::Number;
1419 num.si = value;
1420 nt = num_type::Signed_integer;
1421 return *this;
1422 }
1423
1424 wvalue& operator = (int value)
1425 {
1426 reset();
1427 t_ = type::Number;
1428 num.si = value;
1429 nt = num_type::Signed_integer;
1430 return *this;
1431 }
1432
1433 wvalue& operator = (unsigned long long value)
1434 {
1435 reset();
1436 t_ = type::Number;
1437 num.ui = value;
1438 nt = num_type::Unsigned_integer;
1439 return *this;
1440 }
1441
1442 wvalue& operator = (unsigned long value)
1443 {
1444 reset();
1445 t_ = type::Number;
1446 num.ui = value;
1447 nt = num_type::Unsigned_integer;
1448 return *this;
1449 }
1450
1451 wvalue& operator = (unsigned int value)
1452 {
1453 reset();
1454 t_ = type::Number;
1455 num.ui = value;
1456 nt = num_type::Unsigned_integer;
1457 return *this;
1458 }
1459
1460 wvalue& operator=(const char* str)
1461 {
1462 reset();
1463 t_ = type::String;
1464 s = str;
1465 return *this;
1466 }
1467
1468 wvalue& operator=(const std::string& str)
1469 {
1470 reset();
1471 t_ = type::String;
1472 s = str;
1473 return *this;
1474 }
1475
1476 wvalue& operator=(std::vector<wvalue>&& v)
1477 {
1478 if (t_ != type::List)
1479 reset();
1480 t_ = type::List;
1481 if (!l)
1482 l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
1483 l->clear();
1484 l->resize(v.size());
1485 size_t idx = 0;
1486 for(auto& x:v)
1487 {
1488 (*l)[idx++] = std::move(x);
1489 }
1490 return *this;
1491 }
1492
1493 template <typename T>
1494 wvalue& operator=(const std::vector<T>& v)
1495 {
1496 if (t_ != type::List)
1497 reset();
1498 t_ = type::List;
1499 if (!l)
1500 l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
1501 l->clear();
1502 l->resize(v.size());
1503 size_t idx = 0;
1504 for(auto& x:v)
1505 {
1506 (*l)[idx++] = x;
1507 }
1508 return *this;
1509 }
1510
1511 wvalue& operator[](unsigned index)
1512 {
1513 if (t_ != type::List)
1514 reset();
1515 t_ = type::List;
1516 if (!l)
1517 l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
1518 if (l->size() < index+1)
1519 l->resize(index+1);
1520 return (*l)[index];
1521 }
1522
1523 int count(const std::string& str)
1524 {
1525 if (t_ != type::Object)
1526 return 0;
1527 if (!o)
1528 return 0;
1529 return o->count(str);
1530 }
1531
1532 wvalue& operator[](const std::string& str)
1533 {
1534 if (t_ != type::Object)
1535 reset();
1536 t_ = type::Object;
1537 if (!o)
1538#ifdef CROW_JSON_USE_MAP
1539 o = std::unique_ptr<std::map<std::string, wvalue>>(new std::map<std::string, wvalue>{});
1540#else
1541 o = std::unique_ptr<std::unordered_map<std::string, wvalue>>(new std::unordered_map<std::string, wvalue>{});
1542#endif
1543 return (*o)[str];
1544 }
1545
1546 std::vector<std::string> keys() const
1547 {
1548 if (t_ != type::Object)
1549 return {};
1550 std::vector<std::string> result;
1551 for (auto& kv:*o)
1552 {
1553 result.push_back(kv.first);
1554 }
1555 return result;
1556 }
1557
1558 /// If the wvalue is a list, it returns the length of the list, otherwise it returns 1.
1559 std::size_t size() const
1560 {
1561 if (t_ != type::List)
1562 return 1;
1563 return l->size();
1564 }
1565
1566 /// Returns an estimated size of the value in bytes.
1567 size_t estimate_length() const
1568 {
1569 switch(t_)
1570 {
1571 case type::Null: return 4;
1572 case type::False: return 5;
1573 case type::True: return 4;
1574 case type::Number: return 30;
1575 case type::String: return 2+s.size()+s.size()/2;
1576 case type::List:
1577 {
1578 size_t sum{};
1579 if (l)
1580 {
1581 for(auto& x:*l)
1582 {
1583 sum += 1;
1584 sum += x.estimate_length();
1585 }
1586 }
1587 return sum+2;
1588 }
1589 case type::Object:
1590 {
1591 size_t sum{};
1592 if (o)
1593 {
1594 for(auto& kv:*o)
1595 {
1596 sum += 2;
1597 sum += 2+kv.first.size()+kv.first.size()/2;
1598 sum += kv.second.estimate_length();
1599 }
1600 }
1601 return sum+2;
1602 }
1603 }
1604 return 1;
1605 }
1606
1607 private:
1608
1609 inline void dump_string(const std::string& str, std::string& out) const
1610 {
1611 out.push_back('"');
1612 escape(str, out);
1613 out.push_back('"');
1614 }
1615
1616 inline void dump_internal(const wvalue& v, std::string& out) const
1617 {
1618 switch(v.t_)
1619 {
1620 case type::Null: out += "null"; break;
1621 case type::False: out += "false"; break;
1622 case type::True: out += "true"; break;
1623 case type::Number:
1624 {
1625 if (v.nt == num_type::Floating_point)
1626 {
1627 #ifdef _MSC_VER
1628 #define MSC_COMPATIBLE_SPRINTF(BUFFER_PTR, FORMAT_PTR, VALUE) sprintf_s((BUFFER_PTR), 128, (FORMAT_PTR), (VALUE))
1629 #else
1630 #define MSC_COMPATIBLE_SPRINTF(BUFFER_PTR, FORMAT_PTR, VALUE) sprintf((BUFFER_PTR), (FORMAT_PTR), (VALUE))
1631 #endif
1632 char outbuf[128];
1633 MSC_COMPATIBLE_SPRINTF(outbuf, "%g", v.num.d);
1634 out += outbuf;
1635 #undef MSC_COMPATIBLE_SPRINTF
1636 }
1637 else if (v.nt == num_type::Signed_integer)
1638 {
1639 out += std::to_string(v.num.si);
1640 }
1641 else
1642 {
1643 out += std::to_string(v.num.ui);
1644 }
1645 }
1646 break;
1647 case type::String: dump_string(v.s, out); break;
1648 case type::List:
1649 {
1650 out.push_back('[');
1651 if (v.l)
1652 {
1653 bool first = true;
1654 for(auto& x:*v.l)
1655 {
1656 if (!first)
1657 {
1658 out.push_back(',');
1659 }
1660 first = false;
1661 dump_internal(x, out);
1662 }
1663 }
1664 out.push_back(']');
1665 }
1666 break;
1667 case type::Object:
1668 {
1669 out.push_back('{');
1670 if (v.o)
1671 {
1672 bool first = true;
1673 for(auto& kv:*v.o)
1674 {
1675 if (!first)
1676 {
1677 out.push_back(',');
1678 }
1679 first = false;
1680 dump_string(kv.first, out);
1681 out.push_back(':');
1682 dump_internal(kv.second, out);
1683 }
1684 }
1685 out.push_back('}');
1686 }
1687 break;
1688 }
1689 }
1690
1691 public:
1692 std::string dump() const
1693 {
1694 std::string ret;
1695 ret.reserve(estimate_length());
1696 dump_internal(*this, ret);
1697 return ret;
1698 }
1699
1700 };
1701
1702
1703
1704 //std::vector<boost::asio::const_buffer> dump_ref(wvalue& v)
1705 //{
1706 //}
1707 }
1708}
1709
1710#undef crow_json_likely
1711#undef crow_json_unlikely
JSON read value.
Definition: json.h:225
int64_t i() const
The integer value.
Definition: json.h:350
bool has(const char *str) const
Check if the json object has the passed string as a key.
Definition: json.h:495
double d() const
The double precision floating-point number value.
Definition: json.h:382
bool b() const
The boolean value.
Definition: json.h:392
uint64_t u() const
The unsigned integer value.
Definition: json.h:367
void unescape() const
Convert escaped string character to their original form ("\\n" -> ' ').
Definition: json.h:429
num_type nt() const
The number type of the JSON value.
Definition: json.h:338
type t() const
The type of the JSON value.
Definition: json.h:326
detail::r_string s() const
The string value.
Definition: json.h:402
std::vector< rvalue > lo()
The list or object value.
Definition: json.h:413
JSON write value.
Definition: json.h:1225
wvalue(const rvalue &r)
Create a write value from a read value (useful for editing JSON strings).
Definition: json.h:1259
std::size_t size() const
If the wvalue is a list, it returns the length of the list, otherwise it returns 1.
Definition: json.h:1559
size_t estimate_length() const
Returns an estimated size of the value in bytes.
Definition: json.h:1567
void clear()
Used for compatibility, same as reset()
Definition: json.h:1352
A mustache template object.
Definition: mustache.h:57
A read string implementation with comparison functionality.
Definition: json.h:123
char * s_
Start.
Definition: json.h:175
char * e_
End.
Definition: json.h:176
An abstract class that allows any other class to be returned by a handler.
Definition: returnable.h:9