Crow  1.1
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 <vector>
16 #include <cmath>
17 #include <cfloat>
18 
19 #include "crow/utility.h"
20 #include "crow/settings.h"
21 #include "crow/returnable.h"
22 #include "crow/logging.h"
23 
24 using std::isinf;
25 using std::isnan;
26 
27 
28 namespace crow // NOTE: Already documented in "crow/app.h"
29 {
30  namespace mustache
31  {
32  class template_t;
33  }
34 
35  namespace json
36  {
37  static inline char to_hex(char c)
38  {
39  c = c & 0xf;
40  if (c < 10)
41  return '0' + c;
42  return 'a' + c - 10;
43  }
44 
45  inline void escape(const std::string& str, std::string& ret)
46  {
47  ret.reserve(ret.size() + str.size() + str.size() / 4);
48  for (auto c : str)
49  {
50  switch (c)
51  {
52  case '"': ret += "\\\""; break;
53  case '\\': ret += "\\\\"; break;
54  case '\n': ret += "\\n"; break;
55  case '\b': ret += "\\b"; break;
56  case '\f': ret += "\\f"; break;
57  case '\r': ret += "\\r"; break;
58  case '\t': ret += "\\t"; break;
59  default:
60  if (c >= 0 && c < 0x20)
61  {
62  ret += "\\u00";
63  ret += to_hex(c / 16);
64  ret += to_hex(c % 16);
65  }
66  else
67  ret += c;
68  break;
69  }
70  }
71  }
72  inline std::string escape(const std::string& str)
73  {
74  std::string ret;
75  escape(str, ret);
76  return ret;
77  }
78 
79  enum class type : char
80  {
81  Null,
82  False,
83  True,
84  Number,
85  String,
86  List,
87  Object,
88  Function
89  };
90 
91  inline const char* get_type_str(type t)
92  {
93  switch (t)
94  {
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  case type::Function: return "Function";
102  default: return "Unknown";
103  }
104  }
105 
106  enum class num_type : char
107  {
108  Signed_integer,
109  Unsigned_integer,
110  Floating_point,
111  Null,
112  Double_precision_floating_point
113  };
114 
115  class rvalue;
116  rvalue load(const char* data, size_t size);
117 
118  namespace detail
119  {
120  /// A read string implementation with comparison functionality.
121  struct r_string
122  {
123  r_string(){};
124  r_string(char* s, char* e):
125  s_(s), e_(e){};
126  ~r_string()
127  {
128  if (owned_)
129  delete[] s_;
130  }
131 
132  r_string(const r_string& r)
133  {
134  *this = r;
135  }
136 
137  r_string(r_string&& r)
138  {
139  *this = r;
140  }
141 
142  r_string& operator=(r_string&& r)
143  {
144  s_ = r.s_;
145  e_ = r.e_;
146  owned_ = r.owned_;
147  if (r.owned_)
148  r.owned_ = 0;
149  return *this;
150  }
151 
152  r_string& operator=(const r_string& r)
153  {
154  s_ = r.s_;
155  e_ = r.e_;
156  owned_ = 0;
157  return *this;
158  }
159 
160  operator std::string() const
161  {
162  return std::string(s_, e_);
163  }
164 
165 
166  const char* begin() const { return s_; }
167  const char* end() const { return e_; }
168  size_t size() const { return end() - begin(); }
169 
170  using iterator = const char*;
171  using const_iterator = const char*;
172 
173  char* s_; ///< Start.
174  mutable char* e_; ///< End.
175  uint8_t owned_{0};
176  friend std::ostream& operator<<(std::ostream& os, const r_string& s)
177  {
178  os << static_cast<std::string>(s);
179  return os;
180  }
181 
182  private:
183  void force(char* s, uint32_t length)
184  {
185  s_ = s;
186  e_ = s_ + length;
187  owned_ = 1;
188  }
189  friend rvalue crow::json::load(const char* data, size_t size);
190 
191  friend bool operator==(const r_string& l, const r_string& r);
192  friend bool operator==(const std::string& l, const r_string& r);
193  friend bool operator==(const r_string& l, const std::string& r);
194 
195  template<typename T, typename U>
196  inline static bool equals(const T& l, const U& r)
197  {
198  if (l.size() != r.size())
199  return false;
200 
201  for (size_t i = 0; i < l.size(); i++)
202  {
203  if (*(l.begin() + i) != *(r.begin() + i))
204  return false;
205  }
206 
207  return true;
208  }
209  };
210 
211  inline bool operator<(const r_string& l, const r_string& r)
212  {
213  return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
214  }
215 
216  inline bool operator<(const r_string& l, const std::string& r)
217  {
218  return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
219  }
220 
221  inline bool operator<(const std::string& l, const r_string& r)
222  {
223  return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
224  }
225 
226  inline bool operator>(const r_string& l, const r_string& r)
227  {
228  return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
229  }
230 
231  inline bool operator>(const r_string& l, const std::string& r)
232  {
233  return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
234  }
235 
236  inline bool operator>(const std::string& l, const r_string& r)
237  {
238  return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
239  }
240 
241  inline bool operator==(const r_string& l, const r_string& r)
242  {
243  return r_string::equals(l, r);
244  }
245 
246  inline bool operator==(const r_string& l, const std::string& r)
247  {
248  return r_string::equals(l, r);
249  }
250 
251  inline bool operator==(const std::string& l, const r_string& r)
252  {
253  return r_string::equals(l, r);
254  }
255 
256  inline bool operator!=(const r_string& l, const r_string& r)
257  {
258  return !(l == r);
259  }
260 
261  inline bool operator!=(const r_string& l, const std::string& r)
262  {
263  return !(l == r);
264  }
265 
266  inline bool operator!=(const std::string& l, const r_string& r)
267  {
268  return !(l == r);
269  }
270  } // namespace detail
271 
272  /// JSON read value.
273 
274  ///
275  /// Value can mean any json value, including a JSON object.
276  /// Read means this class is used to primarily read strings into a JSON value.
277  class rvalue
278  {
279  static const int cached_bit = 2;
280  static const int error_bit = 4;
281 
282  public:
283  rvalue() noexcept:
284  option_{error_bit}
285  {
286  }
287  rvalue(type t) noexcept:
288  lsize_{}, lremain_{}, t_{t}
289  {
290  }
291  rvalue(type t, char* s, char* e) noexcept:
292  start_{s}, end_{e}, t_{t}
293  {
294  determine_num_type();
295  }
296 
297  rvalue(const rvalue& r):
298  start_(r.start_), end_(r.end_), key_(r.key_), t_(r.t_), nt_(r.nt_), option_(r.option_)
299  {
300  copy_l(r);
301  }
302 
303  rvalue(rvalue&& r) noexcept
304  {
305  *this = std::move(r);
306  }
307 
308  rvalue& operator=(const rvalue& r)
309  {
310  start_ = r.start_;
311  end_ = r.end_;
312  key_ = r.key_;
313  t_ = r.t_;
314  nt_ = r.nt_;
315  option_ = r.option_;
316  copy_l(r);
317  return *this;
318  }
319  rvalue& operator=(rvalue&& r) noexcept
320  {
321  start_ = r.start_;
322  end_ = r.end_;
323  key_ = std::move(r.key_);
324  l_ = std::move(r.l_);
325  lsize_ = r.lsize_;
326  lremain_ = r.lremain_;
327  t_ = r.t_;
328  nt_ = r.nt_;
329  option_ = r.option_;
330  return *this;
331  }
332 
333  explicit operator bool() const noexcept
334  {
335  return (option_ & error_bit) == 0;
336  }
337 
338  explicit operator int64_t() const
339  {
340  return i();
341  }
342 
343  explicit operator uint64_t() const
344  {
345  return u();
346  }
347 
348  explicit operator int() const
349  {
350  return static_cast<int>(i());
351  }
352 
353  /// Return any json value (not object or list) as a string.
354  explicit operator std::string() const
355  {
356 #ifndef CROW_JSON_NO_ERROR_CHECK
357  if (t() == type::Object || t() == type::List)
358  throw std::runtime_error("json type container");
359 #endif
360  switch (t())
361  {
362  case type::String:
363  return std::string(s());
364  case type::Null:
365  return std::string("null");
366  case type::True:
367  return std::string("true");
368  case type::False:
369  return std::string("false");
370  default:
371  return std::string(start_, end_ - start_);
372  }
373  }
374 
375  /// The type of the JSON value.
376  type t() const
377  {
378 #ifndef CROW_JSON_NO_ERROR_CHECK
379  if (option_ & error_bit)
380  {
381  throw std::runtime_error("invalid json object");
382  }
383 #endif
384  return t_;
385  }
386 
387  /// The number type of the JSON value.
388  num_type nt() const
389  {
390 #ifndef CROW_JSON_NO_ERROR_CHECK
391  if (option_ & error_bit)
392  {
393  throw std::runtime_error("invalid json object");
394  }
395 #endif
396  return nt_;
397  }
398 
399  /// The integer value.
400  int64_t i() const
401  {
402 #ifndef CROW_JSON_NO_ERROR_CHECK
403  switch (t())
404  {
405  case type::Number:
406  case type::String:
407  return utility::lexical_cast<int64_t>(start_, end_ - start_);
408  default:
409  const std::string msg = "expected number, got: " + std::string(get_type_str(t()));
410  throw std::runtime_error(msg);
411  }
412 #endif
413  return utility::lexical_cast<int64_t>(start_, end_ - start_);
414  }
415 
416  /// The unsigned integer value.
417  uint64_t u() const
418  {
419 #ifndef CROW_JSON_NO_ERROR_CHECK
420  switch (t())
421  {
422  case type::Number:
423  case type::String:
424  return utility::lexical_cast<uint64_t>(start_, end_ - start_);
425  default:
426  throw std::runtime_error(std::string("expected number, got: ") + get_type_str(t()));
427  }
428 #endif
429  return utility::lexical_cast<uint64_t>(start_, end_ - start_);
430  }
431 
432  /// The double precision floating-point number value.
433  double d() const
434  {
435 #ifndef CROW_JSON_NO_ERROR_CHECK
436  if (t() != type::Number)
437  throw std::runtime_error("value is not number");
438 #endif
439  return utility::lexical_cast<double>(start_, end_ - start_);
440  }
441 
442  /// The boolean value.
443  bool b() const
444  {
445 #ifndef CROW_JSON_NO_ERROR_CHECK
446  if (t() != type::True && t() != type::False)
447  throw std::runtime_error("value is not boolean");
448 #endif
449  return t() == type::True;
450  }
451 
452  /// The string value.
454  {
455 #ifndef CROW_JSON_NO_ERROR_CHECK
456  if (t() != type::String)
457  throw std::runtime_error("value is not string");
458 #endif
459  unescape();
460  return detail::r_string{start_, end_};
461  }
462 
463  /// The list or object value
464  std::vector<rvalue> lo() const
465  {
466 #ifndef CROW_JSON_NO_ERROR_CHECK
467  if (t() != type::Object && t() != type::List)
468  throw std::runtime_error("value is not a container");
469 #endif
470  std::vector<rvalue> ret;
471  ret.reserve(lsize_);
472  for (uint32_t i = 0; i < lsize_; i++)
473  {
474  ret.emplace_back(l_[i]);
475  }
476  return ret;
477  }
478 
479  /// Convert escaped string character to their original form ("\\n" -> '\n').
480  void unescape() const
481  {
482  if (*(start_ - 1))
483  {
484  char* head = start_;
485  char* tail = start_;
486  while (head != end_)
487  {
488  if (*head == '\\')
489  {
490  switch (*++head)
491  {
492  case '"': *tail++ = '"'; break;
493  case '\\': *tail++ = '\\'; break;
494  case '/': *tail++ = '/'; break;
495  case 'b': *tail++ = '\b'; break;
496  case 'f': *tail++ = '\f'; break;
497  case 'n': *tail++ = '\n'; break;
498  case 'r': *tail++ = '\r'; break;
499  case 't': *tail++ = '\t'; break;
500  case 'u':
501  {
502  auto from_hex = [](char c) {
503  if (c >= 'a')
504  return c - 'a' + 10;
505  if (c >= 'A')
506  return c - 'A' + 10;
507  return c - '0';
508  };
509  unsigned int code =
510  (from_hex(head[1]) << 12) +
511  (from_hex(head[2]) << 8) +
512  (from_hex(head[3]) << 4) +
513  from_hex(head[4]);
514  if (code >= 0x800)
515  {
516  *tail++ = 0xE0 | (code >> 12);
517  *tail++ = 0x80 | ((code >> 6) & 0x3F);
518  *tail++ = 0x80 | (code & 0x3F);
519  }
520  else if (code >= 0x80)
521  {
522  *tail++ = 0xC0 | (code >> 6);
523  *tail++ = 0x80 | (code & 0x3F);
524  }
525  else
526  {
527  *tail++ = code;
528  }
529  head += 4;
530  }
531  break;
532  }
533  }
534  else
535  *tail++ = *head;
536  head++;
537  }
538  end_ = tail;
539  *end_ = 0;
540  *(start_ - 1) = 0;
541  }
542  }
543 
544  /// Check if the json object has the passed string as a key.
545  bool has(const char* str) const
546  {
547  return has(std::string(str));
548  }
549 
550  bool has(const std::string& str) const
551  {
552  struct Pred
553  {
554  bool operator()(const rvalue& l, const rvalue& r) const
555  {
556  return l.key_ < r.key_;
557  };
558  bool operator()(const rvalue& l, const std::string& r) const
559  {
560  return l.key_ < r;
561  };
562  bool operator()(const std::string& l, const rvalue& r) const
563  {
564  return l < r.key_;
565  };
566  };
567  if (!is_cached())
568  {
569  std::sort(begin(), end(), Pred());
570  set_cached();
571  }
572  auto it = lower_bound(begin(), end(), str, Pred());
573  return it != end() && it->key_ == str;
574  }
575 
576  int count(const std::string& str) const
577  {
578  return has(str) ? 1 : 0;
579  }
580 
581  rvalue* begin() const
582  {
583 #ifndef CROW_JSON_NO_ERROR_CHECK
584  if (t() != type::Object && t() != type::List)
585  throw std::runtime_error("value is not a container");
586 #endif
587  return l_.get();
588  }
589  rvalue* end() const
590  {
591 #ifndef CROW_JSON_NO_ERROR_CHECK
592  if (t() != type::Object && t() != type::List)
593  throw std::runtime_error("value is not a container");
594 #endif
595  return l_.get() + lsize_;
596  }
597 
598  const detail::r_string& key() const
599  {
600  return key_;
601  }
602 
603  size_t size() const
604  {
605  if (t() == type::String)
606  return s().size();
607 #ifndef CROW_JSON_NO_ERROR_CHECK
608  if (t() != type::Object && t() != type::List)
609  throw std::runtime_error("value is not a container");
610 #endif
611  return lsize_;
612  }
613 
614  const rvalue& operator[](int index) const
615  {
616 #ifndef CROW_JSON_NO_ERROR_CHECK
617  if (t() != type::List)
618  throw std::runtime_error("value is not a list");
619  if (index >= static_cast<int>(lsize_) || index < 0)
620  throw std::runtime_error("list out of bound");
621 #endif
622  return l_[index];
623  }
624 
625  const rvalue& operator[](size_t index) const
626  {
627 #ifndef CROW_JSON_NO_ERROR_CHECK
628  if (t() != type::List)
629  throw std::runtime_error("value is not a list");
630  if (index >= lsize_)
631  throw std::runtime_error("list out of bound");
632 #endif
633  return l_[index];
634  }
635 
636  const rvalue& operator[](const char* str) const
637  {
638  return this->operator[](std::string(str));
639  }
640 
641  const rvalue& operator[](const std::string& str) const
642  {
643 #ifndef CROW_JSON_NO_ERROR_CHECK
644  if (t() != type::Object)
645  throw std::runtime_error("value is not an object");
646 #endif
647  struct Pred
648  {
649  bool operator()(const rvalue& l, const rvalue& r) const
650  {
651  return l.key_ < r.key_;
652  };
653  bool operator()(const rvalue& l, const std::string& r) const
654  {
655  return l.key_ < r;
656  };
657  bool operator()(const std::string& l, const rvalue& r) const
658  {
659  return l < r.key_;
660  };
661  };
662  if (!is_cached())
663  {
664  std::sort(begin(), end(), Pred());
665  set_cached();
666  }
667  auto it = lower_bound(begin(), end(), str, Pred());
668  if (it != end() && it->key_ == str)
669  return *it;
670 #ifndef CROW_JSON_NO_ERROR_CHECK
671  throw std::runtime_error("cannot find key: " + str);
672 #else
673  static rvalue nullValue;
674  return nullValue;
675 #endif
676  }
677 
678  void set_error()
679  {
680  option_ |= error_bit;
681  }
682 
683  bool error() const
684  {
685  return (option_ & error_bit) != 0;
686  }
687 
688  std::vector<std::string> keys() const
689  {
690 #ifndef CROW_JSON_NO_ERROR_CHECK
691  if (t() != type::Object)
692  throw std::runtime_error("value is not an object");
693 #endif
694  std::vector<std::string> ret;
695  ret.reserve(lsize_);
696  for (uint32_t i = 0; i < lsize_; i++)
697  {
698  ret.emplace_back(std::string(l_[i].key()));
699  }
700  return ret;
701  }
702 
703  private:
704  bool is_cached() const
705  {
706  return (option_ & cached_bit) != 0;
707  }
708  void set_cached() const
709  {
710  option_ |= cached_bit;
711  }
712  void copy_l(const rvalue& r)
713  {
714  if (r.t() != type::Object && r.t() != type::List)
715  return;
716  lsize_ = r.lsize_;
717  lremain_ = 0;
718  l_.reset(new rvalue[lsize_]);
719  std::copy(r.begin(), r.end(), begin());
720  }
721 
722  void emplace_back(rvalue&& v)
723  {
724  if (!lremain_)
725  {
726  int new_size = lsize_ + lsize_;
727  if (new_size - lsize_ > 60000)
728  new_size = lsize_ + 60000;
729  if (new_size < 4)
730  new_size = 4;
731  rvalue* p = new rvalue[new_size];
732  rvalue* p2 = p;
733  for (auto& x : *this)
734  *p2++ = std::move(x);
735  l_.reset(p);
736  lremain_ = new_size - lsize_;
737  }
738  l_[lsize_++] = std::move(v);
739  lremain_--;
740  }
741 
742  /// Determines num_type from the string.
743  void determine_num_type()
744  {
745  if (t_ != type::Number)
746  {
747  nt_ = num_type::Null;
748  return;
749  }
750 
751  const std::size_t len = end_ - start_;
752  const bool has_minus = std::memchr(start_, '-', len) != nullptr;
753  const bool has_e = std::memchr(start_, 'e', len) != nullptr || std::memchr(start_, 'E', len) != nullptr;
754  const bool has_dec_sep = std::memchr(start_, '.', len) != nullptr;
755  if (has_dec_sep || has_e)
756  nt_ = num_type::Floating_point;
757  else if (has_minus)
758  nt_ = num_type::Signed_integer;
759  else
760  nt_ = num_type::Unsigned_integer;
761  }
762 
763  mutable char* start_;
764  mutable char* end_;
765  detail::r_string key_;
766  std::unique_ptr<rvalue[]> l_;
767  uint32_t lsize_;
768  uint16_t lremain_;
769  type t_;
770  num_type nt_{num_type::Null};
771  mutable uint8_t option_{0};
772 
773  friend rvalue load_nocopy_internal(char* data, size_t size);
774  friend rvalue load(const char* data, size_t size);
775  friend std::ostream& operator<<(std::ostream& os, const rvalue& r)
776  {
777  switch (r.t_)
778  {
779 
780  case type::Null: os << "null"; break;
781  case type::False: os << "false"; break;
782  case type::True: os << "true"; break;
783  case type::Number:
784  {
785  switch (r.nt())
786  {
787  case num_type::Floating_point: os << r.d(); break;
788  case num_type::Double_precision_floating_point: os << r.d(); break;
789  case num_type::Signed_integer: os << r.i(); break;
790  case num_type::Unsigned_integer: os << r.u(); break;
791  case num_type::Null: throw std::runtime_error("Number with num_type Null");
792  }
793  }
794  break;
795  case type::String: os << '"' << r.s() << '"'; break;
796  case type::List:
797  {
798  os << '[';
799  bool first = true;
800  for (auto& x : r)
801  {
802  if (!first)
803  os << ',';
804  first = false;
805  os << x;
806  }
807  os << ']';
808  }
809  break;
810  case type::Object:
811  {
812  os << '{';
813  bool first = true;
814  for (auto& x : r)
815  {
816  if (!first)
817  os << ',';
818  os << '"' << escape(x.key_) << "\":";
819  first = false;
820  os << x;
821  }
822  os << '}';
823  }
824  break;
825  case type::Function: os << "custom function"; break;
826  }
827  return os;
828  }
829  };
830  namespace detail
831  {
832  }
833 
834  inline bool operator==(const rvalue& l, const std::string& r)
835  {
836  return l.s() == r;
837  }
838 
839  inline bool operator==(const std::string& l, const rvalue& r)
840  {
841  return l == r.s();
842  }
843 
844  inline bool operator!=(const rvalue& l, const std::string& r)
845  {
846  return l.s() != r;
847  }
848 
849  inline bool operator!=(const std::string& l, const rvalue& r)
850  {
851  return l != r.s();
852  }
853 
854  inline bool operator==(const rvalue& l, double r)
855  {
856  return l.d() == r;
857  }
858 
859  inline bool operator==(double l, const rvalue& r)
860  {
861  return l == r.d();
862  }
863 
864  inline bool operator!=(const rvalue& l, double r)
865  {
866  return l.d() != r;
867  }
868 
869  inline bool operator!=(double l, const rvalue& r)
870  {
871  return l != r.d();
872  }
873 
874 
875  inline rvalue load_nocopy_internal(char* data, size_t size)
876  {
877  // Defend against excessive recursion
878  static constexpr unsigned max_depth = 10000;
879 
880  //static const char* escaped = "\"\\/\b\f\n\r\t";
881  struct Parser
882  {
883  Parser(char* data_, size_t /*size*/):
884  data(data_)
885  {
886  }
887 
888  bool consume(char c)
889  {
890  if (CROW_UNLIKELY(*data != c))
891  return false;
892  data++;
893  return true;
894  }
895 
896  void ws_skip()
897  {
898  while (*data == ' ' || *data == '\t' || *data == '\r' || *data == '\n')
899  ++data;
900  };
901 
902  rvalue decode_string()
903  {
904  if (CROW_UNLIKELY(!consume('"')))
905  return {};
906  char* start = data;
907  uint8_t has_escaping = 0;
908  while (1)
909  {
910  if (CROW_LIKELY(*data != '"' && *data != '\\' && *data != '\0'))
911  {
912  data++;
913  }
914  else if (*data == '"')
915  {
916  *data = 0;
917  *(start - 1) = has_escaping;
918  data++;
919  return {type::String, start, data - 1};
920  }
921  else if (*data == '\\')
922  {
923  has_escaping = 1;
924  data++;
925  switch (*data)
926  {
927  case 'u':
928  {
929  auto check = [](char c) {
930  return ('0' <= c && c <= '9') ||
931  ('a' <= c && c <= 'f') ||
932  ('A' <= c && c <= 'F');
933  };
934  if (!(check(*(data + 1)) &&
935  check(*(data + 2)) &&
936  check(*(data + 3)) &&
937  check(*(data + 4))))
938  return {};
939  }
940  data += 5;
941  break;
942  case '"':
943  case '\\':
944  case '/':
945  case 'b':
946  case 'f':
947  case 'n':
948  case 'r':
949  case 't':
950  data++;
951  break;
952  default:
953  return {};
954  }
955  }
956  else
957  return {};
958  }
959  return {};
960  }
961 
962  rvalue decode_list(unsigned depth)
963  {
964  rvalue ret(type::List);
965  if (CROW_UNLIKELY(!consume('[')) || CROW_UNLIKELY(depth > max_depth))
966  {
967  ret.set_error();
968  return ret;
969  }
970  ws_skip();
971  if (CROW_UNLIKELY(*data == ']'))
972  {
973  data++;
974  return ret;
975  }
976 
977  while (1)
978  {
979  auto v = decode_value(depth + 1);
980  if (CROW_UNLIKELY(!v))
981  {
982  ret.set_error();
983  break;
984  }
985  ws_skip();
986  ret.emplace_back(std::move(v));
987  if (*data == ']')
988  {
989  data++;
990  break;
991  }
992  if (CROW_UNLIKELY(!consume(',')))
993  {
994  ret.set_error();
995  break;
996  }
997  ws_skip();
998  }
999  return ret;
1000  }
1001 
1002  rvalue decode_number()
1003  {
1004  char* start = data;
1005 
1006  enum NumberParsingState
1007  {
1008  Minus,
1009  AfterMinus,
1010  ZeroFirst,
1011  Digits,
1012  DigitsAfterPoints,
1013  E,
1014  DigitsAfterE,
1015  Invalid,
1016  } state{Minus};
1017  while (CROW_LIKELY(state != Invalid))
1018  {
1019  switch (*data)
1020  {
1021  case '0':
1022  state = static_cast<NumberParsingState>("\2\2\7\3\4\6\6"[state]);
1023  /*if (state == NumberParsingState::Minus || state == NumberParsingState::AfterMinus)
1024  {
1025  state = NumberParsingState::ZeroFirst;
1026  }
1027  else if (state == NumberParsingState::Digits ||
1028  state == NumberParsingState::DigitsAfterE ||
1029  state == NumberParsingState::DigitsAfterPoints)
1030  {
1031  // ok; pass
1032  }
1033  else if (state == NumberParsingState::E)
1034  {
1035  state = NumberParsingState::DigitsAfterE;
1036  }
1037  else
1038  return {};*/
1039  break;
1040  case '1':
1041  case '2':
1042  case '3':
1043  case '4':
1044  case '5':
1045  case '6':
1046  case '7':
1047  case '8':
1048  case '9':
1049  state = static_cast<NumberParsingState>("\3\3\7\3\4\6\6"[state]);
1050  while (*(data + 1) >= '0' && *(data + 1) <= '9')
1051  data++;
1052  /*if (state == NumberParsingState::Minus || state == NumberParsingState::AfterMinus)
1053  {
1054  state = NumberParsingState::Digits;
1055  }
1056  else if (state == NumberParsingState::Digits ||
1057  state == NumberParsingState::DigitsAfterE ||
1058  state == NumberParsingState::DigitsAfterPoints)
1059  {
1060  // ok; pass
1061  }
1062  else if (state == NumberParsingState::E)
1063  {
1064  state = NumberParsingState::DigitsAfterE;
1065  }
1066  else
1067  return {};*/
1068  break;
1069  case '.':
1070  state = static_cast<NumberParsingState>("\7\7\4\4\7\7\7"[state]);
1071  /*
1072  if (state == NumberParsingState::Digits || state == NumberParsingState::ZeroFirst)
1073  {
1074  state = NumberParsingState::DigitsAfterPoints;
1075  }
1076  else
1077  return {};
1078  */
1079  break;
1080  case '-':
1081  state = static_cast<NumberParsingState>("\1\7\7\7\7\6\7"[state]);
1082  /*if (state == NumberParsingState::Minus)
1083  {
1084  state = NumberParsingState::AfterMinus;
1085  }
1086  else if (state == NumberParsingState::E)
1087  {
1088  state = NumberParsingState::DigitsAfterE;
1089  }
1090  else
1091  return {};*/
1092  break;
1093  case '+':
1094  state = static_cast<NumberParsingState>("\7\7\7\7\7\6\7"[state]);
1095  /*if (state == NumberParsingState::E)
1096  {
1097  state = NumberParsingState::DigitsAfterE;
1098  }
1099  else
1100  return {};*/
1101  break;
1102  case 'e':
1103  case 'E':
1104  state = static_cast<NumberParsingState>("\7\7\7\5\5\7\7"[state]);
1105  /*if (state == NumberParsingState::Digits ||
1106  state == NumberParsingState::DigitsAfterPoints)
1107  {
1108  state = NumberParsingState::E;
1109  }
1110  else
1111  return {};*/
1112  break;
1113  default:
1114  if (CROW_LIKELY(state == NumberParsingState::ZeroFirst ||
1115  state == NumberParsingState::Digits ||
1116  state == NumberParsingState::DigitsAfterPoints ||
1117  state == NumberParsingState::DigitsAfterE))
1118  return {type::Number, start, data};
1119  else
1120  return {};
1121  }
1122  data++;
1123  }
1124 
1125  return {};
1126  }
1127 
1128 
1129  rvalue decode_value(unsigned depth)
1130  {
1131  switch (*data)
1132  {
1133  case '[':
1134  return decode_list(depth + 1);
1135  case '{':
1136  return decode_object(depth + 1);
1137  case '"':
1138  return decode_string();
1139  case 't':
1140  if ( //e-data >= 4 &&
1141  data[1] == 'r' &&
1142  data[2] == 'u' &&
1143  data[3] == 'e')
1144  {
1145  data += 4;
1146  return {type::True};
1147  }
1148  else
1149  return {};
1150  case 'f':
1151  if ( //e-data >= 5 &&
1152  data[1] == 'a' &&
1153  data[2] == 'l' &&
1154  data[3] == 's' &&
1155  data[4] == 'e')
1156  {
1157  data += 5;
1158  return {type::False};
1159  }
1160  else
1161  return {};
1162  case 'n':
1163  if ( //e-data >= 4 &&
1164  data[1] == 'u' &&
1165  data[2] == 'l' &&
1166  data[3] == 'l')
1167  {
1168  data += 4;
1169  return {type::Null};
1170  }
1171  else
1172  return {};
1173  //case '1': case '2': case '3':
1174  //case '4': case '5': case '6':
1175  //case '7': case '8': case '9':
1176  //case '0': case '-':
1177  default:
1178  return decode_number();
1179  }
1180  return {};
1181  }
1182 
1183  rvalue decode_object(unsigned depth)
1184  {
1185  rvalue ret(type::Object);
1186  if (CROW_UNLIKELY(!consume('{')) || CROW_UNLIKELY(depth > max_depth))
1187  {
1188  ret.set_error();
1189  return ret;
1190  }
1191 
1192  ws_skip();
1193 
1194  if (CROW_UNLIKELY(*data == '}'))
1195  {
1196  data++;
1197  return ret;
1198  }
1199 
1200  while (1)
1201  {
1202  auto t = decode_string();
1203  if (CROW_UNLIKELY(!t))
1204  {
1205  ret.set_error();
1206  break;
1207  }
1208 
1209  ws_skip();
1210  if (CROW_UNLIKELY(!consume(':')))
1211  {
1212  ret.set_error();
1213  break;
1214  }
1215 
1216  // TODO(ipkn) caching key to speed up (flyweight?)
1217  // 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
1218  auto key = t.s();
1219 
1220  ws_skip();
1221  auto v = decode_value(depth + 1);
1222  if (CROW_UNLIKELY(!v))
1223  {
1224  ret.set_error();
1225  break;
1226  }
1227  ws_skip();
1228 
1229  v.key_ = std::move(key);
1230  ret.emplace_back(std::move(v));
1231  if (CROW_UNLIKELY(*data == '}'))
1232  {
1233  data++;
1234  break;
1235  }
1236  if (CROW_UNLIKELY(!consume(',')))
1237  {
1238  ret.set_error();
1239  break;
1240  }
1241  ws_skip();
1242  }
1243  return ret;
1244  }
1245 
1246  rvalue parse()
1247  {
1248  ws_skip();
1249  auto ret = decode_value(0); // or decode object?
1250  ws_skip();
1251  if (ret && *data != '\0')
1252  ret.set_error();
1253  return ret;
1254  }
1255 
1256  char* data;
1257  };
1258  return Parser(data, size).parse();
1259  }
1260  inline rvalue load(const char* data, size_t size)
1261  {
1262  char* s = new char[size + 1];
1263  memcpy(s, data, size);
1264  s[size] = 0;
1265  auto ret = load_nocopy_internal(s, size);
1266  if (ret)
1267  ret.key_.force(s, size);
1268  else
1269  delete[] s;
1270  return ret;
1271  }
1272 
1273  inline rvalue load(const char* data)
1274  {
1275  return load(data, strlen(data));
1276  }
1277 
1278  inline rvalue load(const std::string& str)
1279  {
1280  return load(str.data(), str.size());
1281  }
1282 
1283  struct wvalue_reader;
1284 
1285  /// JSON write value.
1286 
1287  ///
1288  /// Value can mean any json value, including a JSON object.<br>
1289  /// Write means this class is used to primarily assemble JSON objects using keys and values and export those into a string.
1290  class wvalue : public returnable
1291  {
1292  friend class crow::mustache::template_t;
1293  friend struct wvalue_reader;
1294 
1295  public:
1296  using object =
1297 #ifdef CROW_JSON_USE_MAP
1298  std::map<std::string, wvalue>;
1299 #else
1300  std::unordered_map<std::string, wvalue>;
1301 #endif
1302 
1303  using list = std::vector<wvalue>;
1304 
1305  type t() const { return t_; }
1306 
1307  /// Create an empty json value (outputs "{}" instead of a "null" string)
1308  static crow::json::wvalue empty_object() { return crow::json::wvalue::object(); }
1309 
1310  private:
1311  type t_{type::Null}; ///< The type of the value.
1312  num_type nt{num_type::Null}; ///< The specific type of the number if \ref t_ is a number.
1313  union number
1314  {
1315  double d;
1316  int64_t si;
1317  uint64_t ui;
1318 
1319  public:
1320  constexpr number() noexcept:
1321  ui() {} /* default constructor initializes unsigned integer. */
1322  constexpr number(std::uint64_t value) noexcept:
1323  ui(value) {}
1324  constexpr number(std::int64_t value) noexcept:
1325  si(value) {}
1326  explicit constexpr number(double value) noexcept:
1327  d(value) {}
1328  explicit constexpr number(float value) noexcept:
1329  d(value) {}
1330  } num; ///< Value if type is a number.
1331  std::string s; ///< Value if type is a string.
1332  std::unique_ptr<list> l; ///< Value if type is a list.
1333  std::unique_ptr<object> o; ///< Value if type is a JSON object.
1334  std::function<std::string(std::string&)> f; ///< Value if type is a function (C++ lambda)
1335 
1336  public:
1337  wvalue():
1338  returnable("application/json") {}
1339 
1340  wvalue(std::nullptr_t):
1341  returnable("application/json"), t_(type::Null) {}
1342 
1343  wvalue(bool value):
1344  returnable("application/json"), t_(value ? type::True : type::False) {}
1345 
1346  wvalue(std::uint8_t value):
1347  returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1348  wvalue(std::uint16_t value):
1349  returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1350  wvalue(std::uint32_t value):
1351  returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1352  wvalue(std::uint64_t value):
1353  returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1354 
1355  wvalue(std::int8_t value):
1356  returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1357  wvalue(std::int16_t value):
1358  returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1359  wvalue(std::int32_t value):
1360  returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1361  wvalue(std::int64_t value):
1362  returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1363 
1364  wvalue(float value):
1365  returnable("application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
1366  wvalue(double value):
1367  returnable("application/json"), t_(type::Number), nt(num_type::Double_precision_floating_point), num(static_cast<double>(value)) {}
1368 
1369  wvalue(char const* value):
1370  returnable("application/json"), t_(type::String), s(value) {}
1371 
1372  wvalue(std::string const& value):
1373  returnable("application/json"), t_(type::String), s(value) {}
1374  wvalue(std::string&& value):
1375  returnable("application/json"), t_(type::String), s(std::move(value)) {}
1376 
1377  wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list):
1378  returnable("application/json"), t_(type::Object), o(new object(initializer_list)) {}
1379 
1380  wvalue(object const& value):
1381  returnable("application/json"), t_(type::Object), o(new object(value)) {}
1382  wvalue(object&& value):
1383  returnable("application/json"), t_(type::Object), o(new object(std::move(value))) {}
1384 
1385  wvalue(const list& r):
1386  returnable("application/json")
1387  {
1388  t_ = type::List;
1389  l = std::unique_ptr<list>(new list{});
1390  l->reserve(r.size());
1391  for (auto it = r.begin(); it != r.end(); ++it)
1392  l->emplace_back(*it);
1393  }
1394  wvalue(list& r):
1395  returnable("application/json")
1396  {
1397  t_ = type::List;
1398  l = std::unique_ptr<list>(new list{});
1399  l->reserve(r.size());
1400  for (auto it = r.begin(); it != r.end(); ++it)
1401  l->emplace_back(*it);
1402  }
1403 
1404  /// Create a write value from a read value (useful for editing JSON strings).
1405  wvalue(const rvalue& r):
1406  returnable("application/json")
1407  {
1408  t_ = r.t();
1409  switch (r.t())
1410  {
1411  case type::Null:
1412  case type::False:
1413  case type::True:
1414  case type::Function:
1415  return;
1416  case type::Number:
1417  nt = r.nt();
1418  if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1419  num.d = r.d();
1420  else if (nt == num_type::Signed_integer)
1421  num.si = r.i();
1422  else
1423  num.ui = r.u();
1424  return;
1425  case type::String:
1426  s = r.s();
1427  return;
1428  case type::List:
1429  l = std::unique_ptr<list>(new list{});
1430  l->reserve(r.size());
1431  for (auto it = r.begin(); it != r.end(); ++it)
1432  l->emplace_back(*it);
1433  return;
1434  case type::Object:
1435  o = std::unique_ptr<object>(new object{});
1436  for (auto it = r.begin(); it != r.end(); ++it)
1437  o->emplace(it->key(), *it);
1438  return;
1439  }
1440  }
1441 
1442  wvalue(const wvalue& r):
1443  returnable("application/json")
1444  {
1445  t_ = r.t();
1446  switch (r.t())
1447  {
1448  case type::Null:
1449  case type::False:
1450  case type::True:
1451  return;
1452  case type::Number:
1453  nt = r.nt;
1454  if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1455  num.d = r.num.d;
1456  else if (nt == num_type::Signed_integer)
1457  num.si = r.num.si;
1458  else
1459  num.ui = r.num.ui;
1460  return;
1461  case type::String:
1462  s = r.s;
1463  return;
1464  case type::List:
1465  l = std::unique_ptr<list>(new list{});
1466  l->reserve(r.size());
1467  for (auto it = r.l->begin(); it != r.l->end(); ++it)
1468  l->emplace_back(*it);
1469  return;
1470  case type::Object:
1471  o = std::unique_ptr<object>(new object{});
1472  o->insert(r.o->begin(), r.o->end());
1473  return;
1474  case type::Function:
1475  f = r.f;
1476  }
1477  }
1478 
1479  wvalue(wvalue&& r):
1480  returnable("application/json")
1481  {
1482  *this = std::move(r);
1483  }
1484 
1485  wvalue& operator=(wvalue&& r)
1486  {
1487  t_ = r.t_;
1488  nt = r.nt;
1489  num = r.num;
1490  s = std::move(r.s);
1491  l = std::move(r.l);
1492  o = std::move(r.o);
1493  return *this;
1494  }
1495 
1496  /// Used for compatibility, same as \ref reset()
1497  void clear()
1498  {
1499  reset();
1500  }
1501 
1502  void reset()
1503  {
1504  t_ = type::Null;
1505  l.reset();
1506  o.reset();
1507  }
1508 
1509  wvalue& operator=(std::nullptr_t)
1510  {
1511  reset();
1512  return *this;
1513  }
1514  wvalue& operator=(bool value)
1515  {
1516  reset();
1517  if (value)
1518  t_ = type::True;
1519  else
1520  t_ = type::False;
1521  return *this;
1522  }
1523 
1524  wvalue& operator=(float value)
1525  {
1526  reset();
1527  t_ = type::Number;
1528  num.d = value;
1529  nt = num_type::Floating_point;
1530  return *this;
1531  }
1532 
1533  wvalue& operator=(double value)
1534  {
1535  reset();
1536  t_ = type::Number;
1537  num.d = value;
1538  nt = num_type::Double_precision_floating_point;
1539  return *this;
1540  }
1541 
1542  wvalue& operator=(unsigned short value)
1543  {
1544  reset();
1545  t_ = type::Number;
1546  num.ui = value;
1547  nt = num_type::Unsigned_integer;
1548  return *this;
1549  }
1550 
1551  wvalue& operator=(short value)
1552  {
1553  reset();
1554  t_ = type::Number;
1555  num.si = value;
1556  nt = num_type::Signed_integer;
1557  return *this;
1558  }
1559 
1560  wvalue& operator=(long long value)
1561  {
1562  reset();
1563  t_ = type::Number;
1564  num.si = value;
1565  nt = num_type::Signed_integer;
1566  return *this;
1567  }
1568 
1569  wvalue& operator=(long value)
1570  {
1571  reset();
1572  t_ = type::Number;
1573  num.si = value;
1574  nt = num_type::Signed_integer;
1575  return *this;
1576  }
1577 
1578  wvalue& operator=(int value)
1579  {
1580  reset();
1581  t_ = type::Number;
1582  num.si = value;
1583  nt = num_type::Signed_integer;
1584  return *this;
1585  }
1586 
1587  wvalue& operator=(unsigned long long value)
1588  {
1589  reset();
1590  t_ = type::Number;
1591  num.ui = value;
1592  nt = num_type::Unsigned_integer;
1593  return *this;
1594  }
1595 
1596  wvalue& operator=(unsigned long value)
1597  {
1598  reset();
1599  t_ = type::Number;
1600  num.ui = value;
1601  nt = num_type::Unsigned_integer;
1602  return *this;
1603  }
1604 
1605  wvalue& operator=(unsigned int value)
1606  {
1607  reset();
1608  t_ = type::Number;
1609  num.ui = value;
1610  nt = num_type::Unsigned_integer;
1611  return *this;
1612  }
1613 
1614  wvalue& operator=(const char* str)
1615  {
1616  reset();
1617  t_ = type::String;
1618  s = str;
1619  return *this;
1620  }
1621 
1622  wvalue& operator=(const std::string& str)
1623  {
1624  reset();
1625  t_ = type::String;
1626  s = str;
1627  return *this;
1628  }
1629 
1630  wvalue& operator=(list&& v)
1631  {
1632  if (t_ != type::List)
1633  reset();
1634  t_ = type::List;
1635  if (!l)
1636  l = std::unique_ptr<list>(new list{});
1637  l->clear();
1638  l->resize(v.size());
1639  size_t idx = 0;
1640  for (auto& x : v)
1641  {
1642  (*l)[idx++] = std::move(x);
1643  }
1644  return *this;
1645  }
1646 
1647  template<typename T>
1648  wvalue& operator=(const std::vector<T>& v)
1649  {
1650  if (t_ != type::List)
1651  reset();
1652  t_ = type::List;
1653  if (!l)
1654  l = std::unique_ptr<list>(new list{});
1655  l->clear();
1656  l->resize(v.size());
1657  size_t idx = 0;
1658  for (auto& x : v)
1659  {
1660  (*l)[idx++] = x;
1661  }
1662  return *this;
1663  }
1664 
1665  wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
1666  {
1667  if (t_ != type::Object)
1668  {
1669  reset();
1670  t_ = type::Object;
1671  o = std::unique_ptr<object>(new object(initializer_list));
1672  }
1673  else
1674  {
1675 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1676  o = std::unique_ptr<object>(new object(initializer_list));
1677 #else
1678  (*o) = initializer_list;
1679 #endif
1680  }
1681  return *this;
1682  }
1683 
1684  wvalue& operator=(object const& value)
1685  {
1686  if (t_ != type::Object)
1687  {
1688  reset();
1689  t_ = type::Object;
1690  o = std::unique_ptr<object>(new object(value));
1691  }
1692  else
1693  {
1694 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1695  o = std::unique_ptr<object>(new object(value));
1696 #else
1697  (*o) = value;
1698 #endif
1699  }
1700  return *this;
1701  }
1702 
1703  wvalue& operator=(object&& value)
1704  {
1705  if (t_ != type::Object)
1706  {
1707  reset();
1708  t_ = type::Object;
1709  o = std::unique_ptr<object>(new object(std::move(value)));
1710  }
1711  else
1712  {
1713  (*o) = std::move(value);
1714  }
1715  return *this;
1716  }
1717 
1718  wvalue& operator=(std::function<std::string(std::string&)>&& func)
1719  {
1720  reset();
1721  t_ = type::Function;
1722  f = std::move(func);
1723  return *this;
1724  }
1725 
1726  wvalue& operator[](unsigned index)
1727  {
1728  if (t_ != type::List)
1729  reset();
1730  t_ = type::List;
1731  if (!l)
1732  l = std::unique_ptr<list>(new list{});
1733  if (l->size() < index + 1)
1734  l->resize(index + 1);
1735  return (*l)[index];
1736  }
1737 
1738  const wvalue& operator[](unsigned index) const
1739  {
1740  return const_cast<wvalue*>(this)->operator[](index);
1741  }
1742 
1743  int count(const std::string& str) const
1744  {
1745  if (t_ != type::Object)
1746  return 0;
1747  if (!o)
1748  return 0;
1749  return o->count(str);
1750  }
1751 
1752  wvalue& operator[](const std::string& str)
1753  {
1754  if (t_ != type::Object)
1755  reset();
1756  t_ = type::Object;
1757  if (!o)
1758  o = std::unique_ptr<object>(new object{});
1759  return (*o)[str];
1760  }
1761 
1762  const wvalue& operator[](const std::string& str) const
1763  {
1764  return const_cast<wvalue*>(this)->operator[](str);
1765  }
1766 
1767  std::vector<std::string> keys() const
1768  {
1769  if (t_ != type::Object)
1770  return {};
1771  std::vector<std::string> result;
1772  for (auto& kv : *o)
1773  {
1774  result.push_back(kv.first);
1775  }
1776  return result;
1777  }
1778 
1779  std::string execute(std::string txt = "") const //Not using reference because it cannot be used with a default rvalue
1780  {
1781  if (t_ != type::Function)
1782  return "";
1783  return f(txt);
1784  }
1785 
1786  /// If the wvalue is a list, it returns the length of the list, otherwise it returns 1.
1787  std::size_t size() const
1788  {
1789  if (t_ != type::List)
1790  return 1;
1791  return l->size();
1792  }
1793 
1794  /// Returns an estimated size of the value in bytes.
1795  size_t estimate_length() const
1796  {
1797  switch (t_)
1798  {
1799  case type::Null: return 4;
1800  case type::False: return 5;
1801  case type::True: return 4;
1802  case type::Number: return 30;
1803  case type::String: return 2 + s.size() + s.size() / 2;
1804  case type::List:
1805  {
1806  size_t sum{};
1807  if (l)
1808  {
1809  for (auto& x : *l)
1810  {
1811  sum += 1;
1812  sum += x.estimate_length();
1813  }
1814  }
1815  return sum + 2;
1816  }
1817  case type::Object:
1818  {
1819  size_t sum{};
1820  if (o)
1821  {
1822  for (auto& kv : *o)
1823  {
1824  sum += 2;
1825  sum += 2 + kv.first.size() + kv.first.size() / 2;
1826  sum += kv.second.estimate_length();
1827  }
1828  }
1829  return sum + 2;
1830  }
1831  case type::Function:
1832  return 0;
1833  }
1834  return 1;
1835  }
1836 
1837  private:
1838  inline void dump_string(const std::string& str, std::string& out) const
1839  {
1840  out.push_back('"');
1841  escape(str, out);
1842  out.push_back('"');
1843  }
1844 
1845  inline void dump_indentation_part(std::string& out, const int indent, const char separator, const int indent_level) const
1846  {
1847  out.push_back('\n');
1848  out.append(indent_level * indent, separator);
1849  }
1850 
1851 
1852  inline void dump_internal(const wvalue& v, std::string& out, const int indent, const char separator, const int indent_level = 0) const
1853  {
1854  switch (v.t_)
1855  {
1856  case type::Null: out += "null"; break;
1857  case type::False: out += "false"; break;
1858  case type::True: out += "true"; break;
1859  case type::Number:
1860  {
1861  if (v.nt == num_type::Floating_point || v.nt == num_type::Double_precision_floating_point)
1862  {
1863  if (isnan(v.num.d) || isinf(v.num.d))
1864  {
1865  out += "null";
1866  CROW_LOG_WARNING << "Invalid JSON value detected (" << v.num.d << "), value set to null";
1867  break;
1868  }
1869  enum
1870  {
1871  start,
1872  decp, // Decimal point
1873  zero
1874  } f_state;
1875  char outbuf[128];
1876  if (v.nt == num_type::Double_precision_floating_point)
1877  {
1878 #ifdef _MSC_VER
1879  sprintf_s(outbuf, sizeof(outbuf), "%.*g", DECIMAL_DIG, v.num.d);
1880 #else
1881  snprintf(outbuf, sizeof(outbuf), "%.*g", DECIMAL_DIG, v.num.d);
1882 #endif
1883  }
1884  else
1885  {
1886 #ifdef _MSC_VER
1887  sprintf_s(outbuf, sizeof(outbuf), "%f", v.num.d);
1888 #else
1889  snprintf(outbuf, sizeof(outbuf), "%f", v.num.d);
1890 #endif
1891  }
1892  char* p = &outbuf[0];
1893  char* pos_first_trailing_0 = nullptr;
1894  f_state = start;
1895  while (*p != '\0')
1896  {
1897  //std::cout << *p << std::endl;
1898  char ch = *p;
1899  switch (f_state)
1900  {
1901  case start: // Loop and lookahead until a decimal point is found
1902  if (ch == '.')
1903  {
1904  char fch = *(p + 1);
1905  // if the first character is 0, leave it be (this is so that "1.00000" becomes "1.0" and not "1.")
1906  if (fch != '\0' && fch == '0') p++;
1907  f_state = decp;
1908  }
1909  p++;
1910  break;
1911  case decp: // Loop until a 0 is found, if found, record its position
1912  if (ch == '0')
1913  {
1914  f_state = zero;
1915  pos_first_trailing_0 = p;
1916  }
1917  p++;
1918  break;
1919  case zero: // if a non 0 is found (e.g. 1.00004) remove the earlier recorded 0 position and look for more trailing 0s
1920  if (ch != '0')
1921  {
1922  pos_first_trailing_0 = nullptr;
1923  f_state = decp;
1924  }
1925  p++;
1926  break;
1927  }
1928  }
1929  if (pos_first_trailing_0 != nullptr) // if any trailing 0s are found, terminate the string where they begin
1930  *pos_first_trailing_0 = '\0';
1931  out += outbuf;
1932  }
1933  else if (v.nt == num_type::Signed_integer)
1934  {
1935  out += std::to_string(v.num.si);
1936  }
1937  else
1938  {
1939  out += std::to_string(v.num.ui);
1940  }
1941  }
1942  break;
1943  case type::String: dump_string(v.s, out); break;
1944  case type::List:
1945  {
1946  out.push_back('[');
1947 
1948  if (indent >= 0)
1949  {
1950  dump_indentation_part(out, indent, separator, indent_level + 1);
1951  }
1952 
1953  if (v.l)
1954  {
1955  bool first = true;
1956  for (auto& x : *v.l)
1957  {
1958  if (!first)
1959  {
1960  out.push_back(',');
1961 
1962  if (indent >= 0)
1963  {
1964  dump_indentation_part(out, indent, separator, indent_level + 1);
1965  }
1966  }
1967  first = false;
1968  dump_internal(x, out, indent, separator, indent_level + 1);
1969  }
1970  }
1971 
1972  if (indent >= 0)
1973  {
1974  dump_indentation_part(out, indent, separator, indent_level);
1975  }
1976 
1977  out.push_back(']');
1978  }
1979  break;
1980  case type::Object:
1981  {
1982  out.push_back('{');
1983 
1984  if (indent >= 0)
1985  {
1986  dump_indentation_part(out, indent, separator, indent_level + 1);
1987  }
1988 
1989  if (v.o)
1990  {
1991  bool first = true;
1992  for (auto& kv : *v.o)
1993  {
1994  if (!first)
1995  {
1996  out.push_back(',');
1997  if (indent >= 0)
1998  {
1999  dump_indentation_part(out, indent, separator, indent_level + 1);
2000  }
2001  }
2002  first = false;
2003  dump_string(kv.first, out);
2004  out.push_back(':');
2005 
2006  if (indent >= 0)
2007  {
2008  out.push_back(' ');
2009  }
2010 
2011  dump_internal(kv.second, out, indent, separator, indent_level + 1);
2012  }
2013  }
2014 
2015  if (indent >= 0)
2016  {
2017  dump_indentation_part(out, indent, separator, indent_level);
2018  }
2019 
2020  out.push_back('}');
2021  }
2022  break;
2023 
2024  case type::Function:
2025  out += "custom function";
2026  break;
2027  }
2028  }
2029 
2030  public:
2031  std::string dump(const int indent, const char separator = ' ') const
2032  {
2033  std::string ret;
2034  ret.reserve(estimate_length());
2035  dump_internal(*this, ret, indent, separator);
2036  return ret;
2037  }
2038 
2039  std::string dump() const override
2040  {
2041  static constexpr int DontIndent = -1;
2042 
2043  return dump(DontIndent);
2044  }
2045  };
2046 
2047  // Used for accessing the internals of a wvalue
2049  {
2050  int64_t get(int64_t fallback)
2051  {
2052  if (ref.t() != type::Number || ref.nt == num_type::Floating_point ||
2053  ref.nt == num_type::Double_precision_floating_point)
2054  return fallback;
2055  return ref.num.si;
2056  }
2057 
2058  double get(double fallback)
2059  {
2060  if (ref.t() != type::Number || ref.nt != num_type::Floating_point ||
2061  ref.nt == num_type::Double_precision_floating_point)
2062  return fallback;
2063  return ref.num.d;
2064  }
2065 
2066  bool get(bool fallback)
2067  {
2068  if (ref.t() == type::True) return true;
2069  if (ref.t() == type::False) return false;
2070  return fallback;
2071  }
2072 
2073  std::string get(const std::string& fallback)
2074  {
2075  if (ref.t() != type::String) return fallback;
2076  return ref.s;
2077  }
2078 
2079  const wvalue& ref;
2080  };
2081 
2082  //std::vector<asio::const_buffer> dump_ref(wvalue& v)
2083  //{
2084  //}
2085  } // namespace json
2086 } // namespace crow
JSON read value.
Definition: json.h:278
int64_t i() const
The integer value.
Definition: json.h:400
bool has(const char *str) const
Check if the json object has the passed string as a key.
Definition: json.h:545
double d() const
The double precision floating-point number value.
Definition: json.h:433
bool b() const
The boolean value.
Definition: json.h:443
uint64_t u() const
The unsigned integer value.
Definition: json.h:417
std::vector< rvalue > lo() const
The list or object value.
Definition: json.h:464
void unescape() const
Convert escaped string character to their original form ("\\n" -> ' ').
Definition: json.h:480
num_type nt() const
The number type of the JSON value.
Definition: json.h:388
type t() const
The type of the JSON value.
Definition: json.h:376
detail::r_string s() const
The string value.
Definition: json.h:453
JSON write value.
Definition: json.h:1291
wvalue(const rvalue &r)
Create a write value from a read value (useful for editing JSON strings).
Definition: json.h:1405
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:1787
size_t estimate_length() const
Returns an estimated size of the value in bytes.
Definition: json.h:1795
static crow::json::wvalue empty_object()
Create an empty json value (outputs "{}" instead of a "null" string)
Definition: json.h:1308
void clear()
Used for compatibility, same as reset()
Definition: json.h:1497
Compiled mustache template object.
Definition: mustache.h:134
template_t load(const std::string &filename)
Open, read and renders a file using a mustache compiler. It also sanitize the input before compilatio...
Definition: mustache.h:812
The main namespace of the library. In this namespace is defined the most important classes and functi...
A read string implementation with comparison functionality.
Definition: json.h:122
char * s_
Start.
Definition: json.h:173
char * e_
End.
Definition: json.h:174
Definition: json.h:2049
An abstract class that allows any other class to be returned by a handler.
Definition: returnable.h:9