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 
32 namespace 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(unsigned char 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 < 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
crow::json::detail::r_string::e_
char * e_
End.
Definition: json.h:176
crow::json::rvalue::has
bool has(const char *str) const
Check if the json object has the passed string as a key.
Definition: json.h:495
crow::json::rvalue::unescape
void unescape() const
Convert escaped string character to their original form ("\\n" -> ' ').
Definition: json.h:429
crow::json::rvalue::d
double d() const
The double precision floating-point number value.
Definition: json.h:382
crow::json::wvalue::clear
void clear()
Used for compatibility, same as reset()
Definition: json.h:1352
crow::json::rvalue::s
detail::r_string s() const
The string value.
Definition: json.h:402
crow::json::rvalue::i
int64_t i() const
The integer value.
Definition: json.h:350
crow::json::rvalue::lo
std::vector< rvalue > lo()
The list or object value.
Definition: json.h:413
crow::json::wvalue
JSON write value.
Definition: json.h:1224
crow::json::wvalue::estimate_length
size_t estimate_length() const
Returns an estimated size of the value in bytes.
Definition: json.h:1567
crow::json::detail::r_string::s_
char * s_
Start.
Definition: json.h:175
crow::mustache::template_t
A mustache template object.
Definition: mustache.h:54
crow::returnable
An abstract class that allows any other class to be returned by a handler.
Definition: returnable.h:8
crow::json::rvalue::b
bool b() const
The boolean value.
Definition: json.h:392
crow::json::rvalue::t
type t() const
The type of the JSON value.
Definition: json.h:326
crow::json::wvalue::size
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
crow::json::rvalue::u
uint64_t u() const
The unsigned integer value.
Definition: json.h:367
crow::json::rvalue::nt
num_type nt() const
The number type of the JSON value.
Definition: json.h:338
crow::json::detail::r_string
A read string implementation with comparison functionality.
Definition: json.h:118
crow::json::wvalue::wvalue
wvalue(const rvalue &r)
Create a write value from a read value (useful for editing JSON strings).
Definition: json.h:1259
crow::json::rvalue
JSON read value.
Definition: json.h:224