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