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