12 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 24 #include "./logging.h" 30 #include <unordered_map> 34 #endif // DMLC_ENABLE_RTTI 35 #endif // DMLC_STRICT_CXX11 36 #endif // DMLC_USE_CXX11 50 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 70 template<
typename ValueType>
119 template<
typename ValueType>
120 inline void Read(ValueType *out_value);
124 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 126 std::ostringstream os;
127 os <<
" Line " << std::max(line_count_r_, line_count_n_);
128 is_->getline(temp, 64);
129 os <<
", around ^`" << temp <<
"`";
132 std::string info =
" Line ";
133 info += std::to_string(std::max(line_count_r_, line_count_n_));
136 size_t end_pos = is_->find(
'\n');
137 end_pos = std::min((
size_t)64,
138 end_pos == std::string::npos ? is_->size() : end_pos);
139 std::string line = is_->substr(0, end_pos);
140 is_->erase(0, line.size() + 1);
142 info +=
", around ^`" + line +
"`";
148 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 156 size_t line_count_r_;
158 size_t line_count_n_;
163 std::vector<size_t> scope_counter_;
168 inline int NextNonSpace();
173 inline int PeekNextNonSpace();
178 inline int NextChar();
183 inline int PeekNextChar();
195 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 205 inline void WriteNoEscape(
const std::string &s);
210 inline void WriteString(
const std::string &s);
216 template<
typename ValueType>
217 inline void WriteNumber(
const ValueType &v);
229 inline void BeginArray(
bool multi_line =
true);
231 inline void EndArray();
245 inline void EndObject();
252 template<
typename ValueType>
253 inline void WriteObjectKeyValue(
const std::string &key,
254 const ValueType &value);
259 inline void WriteArraySeperator();
265 template<
typename ValueType>
266 inline void WriteArrayItem(
const ValueType &value);
272 template<
typename ValueType>
273 inline void Write(
const ValueType &value);
276 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 286 std::vector<size_t> scope_counter_;
288 std::vector<bool> scope_multi_line_;
292 inline void WriteSeperator();
321 DeclareFieldInternal(key, addr,
false);
331 DeclareFieldInternal(key, addr,
true);
337 inline void ReadAllFields(
JSONReader *reader);
348 inline void DeclareFieldInternal(
const std::string &key, T *addr,
bool optional);
355 inline static void ReaderFunction(
JSONReader *reader,
void *addr);
357 typedef void (*ReadFunction)(
JSONReader *reader,
void *addr);
368 std::map<std::string, Entry> map_;
371 #define DMLC_JSON_ENABLE_ANY_VAR_DEF(KeyName) \ 372 static DMLC_ATTRIBUTE_UNUSED ::dmlc::json::AnyJSONManager& \ 373 __make_AnyJSONType ## _ ## KeyName ## __ 383 #define DMLC_JSON_ENABLE_ANY(Type, KeyName) \ 384 DMLC_STR_CONCAT(DMLC_JSON_ENABLE_ANY_VAR_DEF(KeyName), __COUNTER__) = \ 385 ::dmlc::json::AnyJSONManager::Global()->EnableType<Type>(#KeyName) \ 397 template<
typename ValueType>
398 struct NumericHandler {
399 inline static void Write(JSONWriter *writer,
const ValueType &value) {
400 writer->WriteNumber<ValueType>(value);
403 reader->ReadNumber<ValueType>(value);
407 template<
typename ContainerType>
408 struct ArrayHandler {
409 inline static void Write(JSONWriter *writer,
const ContainerType &array) {
410 typedef typename ContainerType::value_type ElemType;
412 for (
typename ContainerType::const_iterator it = array.begin();
413 it != array.end(); ++it) {
414 writer->WriteArrayItem(*it);
418 inline static void Read(
JSONReader *reader, ContainerType *array) {
419 typedef typename ContainerType::value_type ElemType;
421 reader->BeginArray();
422 while (reader->NextArrayItem()) {
424 Handler<ElemType>::Read(reader, &value);
425 array->insert(array->end(), value);
430 template<
typename ContainerType>
432 inline static void Write(JSONWriter *writer,
const ContainerType &map) {
433 writer->BeginObject(map.size() > 1);
434 for (
typename ContainerType::const_iterator it = map.begin(); it != map.end(); ++it) {
435 writer->WriteObjectKeyValue(it->first, it->second);
440 typedef typename ContainerType::mapped_type ElemType;
442 reader->BeginObject();
444 while (reader->NextObjectItem(&key)) {
446 reader->Read(&value);
453 struct CommonJSONSerializer {
454 inline static void Write(JSONWriter *writer,
const T &value) {
463 struct Handler<std::string> {
464 inline static void Write(JSONWriter *writer,
const std::string &value) {
465 writer->WriteString(value);
468 reader->ReadString(str);
473 struct Handler<std::vector<T> > :
public ArrayHandler<std::vector<T> > {
476 template<
typename K,
typename V>
477 struct Handler<std::pair<K, V> > {
478 inline static void Write(JSONWriter *writer,
const std::pair<K, V> &kv) {
479 writer->BeginArray();
480 writer->WriteArrayItem(kv.first);
481 writer->WriteArrayItem(kv.second);
484 inline static void Read(
JSONReader *reader, std::pair<K, V> *kv) {
485 reader->BeginArray();
486 CHECK(reader->NextArrayItem())
487 <<
"Expect array of length 2";
488 Handler<K>::Read(reader, &(kv->first));
489 CHECK(reader->NextArrayItem())
490 <<
"Expect array of length 2";
491 Handler<V>::Read(reader, &(kv->second));
492 CHECK(!reader->NextArrayItem())
493 <<
"Expect array of length 2";
498 struct Handler<std::list<T> > :
public ArrayHandler<std::list<T> > {
502 struct Handler<std::map<std::string, V> > :
public MapHandler<std::map<std::string, V> > {
507 struct Handler<std::unordered_map<std::string, V> >
508 :
public MapHandler<std::unordered_map<std::string, V> > {
510 #endif // DMLC_USE_CXX11 514 inline static void Write(JSONWriter *writer,
const T &data) {
517 CommonJSONSerializer<T> >::Type THandler;
518 THandler::Write(writer, data);
523 CommonJSONSerializer<T> >::Type THandler;
524 THandler::Read(reader, data);
528 #if DMLC_STRICT_CXX11 531 class AnyJSONManager {
534 inline AnyJSONManager& EnableType(
const std::string&
type_name) {
535 std::type_index tp = std::type_index(
typeid(T));
536 if (type_name_.count(tp) != 0) {
538 <<
"Type has already been registered as another typename " << type_name_.at(tp);
541 CHECK(type_map_.count(type_name) == 0)
542 <<
"Type name " << type_name <<
" already registered in registry";
545 e.write = WriteAny<T>;
551 inline static AnyJSONManager* Global() {
552 static AnyJSONManager inst;
560 inline static void WriteAny(JSONWriter *writer,
const any &data) {
561 writer->Write(dmlc::unsafe_get<T>(data));
564 inline static void ReadAny(
JSONReader *reader, any* data) {
567 *data = std::move(temp);
572 void (*write)(JSONWriter* reader,
const any& data);
576 friend struct Handler;
578 std::unordered_map<std::type_index, std::string> type_name_;
579 std::unordered_map<std::string, Entry> type_map_;
583 struct Handler<any> {
584 inline static void Write(JSONWriter *writer,
const any &data) {
585 std::unordered_map<std::type_index, std::string>&
586 nmap = AnyJSONManager::Global()->type_name_;
587 std::type_index
id = std::type_index(data.type());
588 auto it = nmap.find(
id);
589 CHECK(it != nmap.end() && it->first == id)
590 <<
"Type " <<
id.name() <<
" has not been registered via DMLC_JSON_ENABLE_ANY";
592 AnyJSONManager::Entry e = AnyJSONManager::Global()->type_map_.at(type_name);
593 writer->BeginArray(
false);
594 writer->WriteArrayItem(type_name);
595 writer->WriteArraySeperator();
596 e.write(writer, data);
601 reader->BeginArray();
602 CHECK(reader->NextArrayItem()) <<
"invalid any json format";
603 Handler<std::string>::Read(reader, &type_name);
604 std::unordered_map<std::string, AnyJSONManager::Entry>&
605 tmap = AnyJSONManager::Global()->type_map_;
606 auto it = tmap.find(type_name);
607 CHECK(it != tmap.end() && it->first ==
type_name)
608 <<
"Typename " << type_name <<
" has not been registered via DMLC_JSON_ENABLE_ANY";
609 AnyJSONManager::Entry e = it->second;
610 CHECK(reader->NextArrayItem()) <<
"invalid any json format";
611 e.read(reader, data);
612 CHECK(!reader->NextArrayItem()) <<
"invalid any json format";
615 #endif // DMLC_ENABLE_RTTI 616 #endif // DMLC_STRICT_CXX11 621 inline int JSONReader::NextChar() {
622 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 631 inline int JSONReader::PeekNextChar() {
632 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 639 inline int JSONReader::NextNonSpace() {
643 if (ch ==
'\n') ++line_count_n_;
644 if (ch ==
'\r') ++line_count_r_;
649 inline int JSONReader::PeekNextNonSpace() {
653 if (ch ==
'\n') ++line_count_n_;
654 if (ch ==
'\r') ++line_count_r_;
663 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 664 void Extend(std::ostream *os, T item) {
668 void Extend(std::string *ostr, T item) {
675 int ch = NextNonSpace();
678 <<
", Expect \'\"\' but get \'" <<
static_cast<char>(ch) <<
'\'';
679 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 680 std::ostringstream output;
682 std::string output =
"";
687 char sch =
static_cast<char>(NextChar());
689 case 'r': Extend(&output,
"\r");
break;
690 case 'n': Extend(&output,
"\n");
break;
691 case '\\': Extend(&output,
"\\");
break;
692 case 't': Extend(&output,
"\t");
break;
693 case '\"': Extend(&output,
"\"");
break;
694 default: LOG(FATAL) <<
"unknown string escape \\" << sch;
697 if (ch ==
'\"')
break;
698 Extend(&output, static_cast<char>(ch));
700 if (ch == EOF || ch ==
'\r' || ch ==
'\n') {
703 <<
", Expect \'\"\' but reach end of line ";
706 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 707 *out_str = output.str();
713 template<
typename ValueType>
715 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 719 <<
", Expect number";
722 const char* icstr = is_->c_str();
723 unsigned number = strtol(icstr, &endptr, 10);
724 is_->erase(0, endptr - icstr);
725 *out_value =
static_cast<ValueType
>(number);
730 int ch = NextNonSpace();
733 <<
", Expect \'{\' but get \'" <<
static_cast<char>(ch) <<
'\'';
734 scope_counter_.push_back(0);
738 int ch = NextNonSpace();
741 <<
", Expect \'{\' but get \'" <<
static_cast<char>(ch) <<
'\'';
742 scope_counter_.push_back(0);
747 if (scope_counter_.back() != 0) {
748 int ch = NextNonSpace();
751 }
else if (ch ==
'}') {
756 <<
", JSON object expect \'}\' or \',\' \'" <<
static_cast<char>(ch) <<
'\'';
759 int ch = PeekNextNonSpace();
766 scope_counter_.pop_back();
769 scope_counter_.back() += 1;
771 int ch = NextNonSpace();
774 <<
", Expect \':\' but get \'" <<
static_cast<char>(ch) <<
'\'';
781 if (scope_counter_.back() != 0) {
782 int ch = NextNonSpace();
785 }
else if (ch ==
']') {
790 <<
", JSON array expect \']\' or \',\'. Get \'" <<
static_cast<char>(ch) <<
"\' instead";
793 int ch = PeekNextNonSpace();
800 scope_counter_.pop_back();
803 scope_counter_.back() += 1;
808 template<
typename ValueType>
810 json::Handler<ValueType>::Read(
this, out_value);
821 for (
size_t i = 0; i < s.length(); ++i) {
824 case '\r': Extend(os_,
"\\r");
break;
825 case '\n': Extend(os_,
"\\n");
break;
826 case '\\': Extend(os_,
"\\\\");
break;
827 case '\t': Extend(os_,
"\\t");
break;
828 case '\"': Extend(os_,
"\\\"");
break;
829 default: Extend(os_, ch);
835 template<
typename ValueType>
837 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 840 Extend(os_, std::to_string(v));
846 scope_multi_line_.push_back(multi_line);
847 scope_counter_.push_back(0);
851 CHECK_NE(scope_multi_line_.size(), 0U);
852 CHECK_NE(scope_counter_.size(), 0U);
853 bool newline = scope_multi_line_.back();
854 size_t nelem = scope_counter_.back();
855 scope_multi_line_.pop_back();
856 scope_counter_.pop_back();
857 if (newline && nelem != 0) WriteSeperator();
863 scope_multi_line_.push_back(multi_line);
864 scope_counter_.push_back(0);
868 CHECK_NE(scope_multi_line_.size(), 0U);
869 CHECK_NE(scope_counter_.size(), 0U);
870 bool newline = scope_multi_line_.back();
871 size_t nelem = scope_counter_.back();
872 scope_multi_line_.pop_back();
873 scope_counter_.pop_back();
874 if (newline && nelem != 0) WriteSeperator();
878 template<
typename ValueType>
880 const ValueType &value) {
881 if (scope_counter_.back() > 0) {
888 scope_counter_.back() += 1;
889 json::Handler<ValueType>::Write(
this, value);
893 if (scope_counter_.back() != 0) {
896 scope_counter_.back() += 1;
900 template<
typename ValueType>
902 this->WriteArraySeperator();
903 json::Handler<ValueType>::Write(
this, value);
906 template<
typename ValueType>
908 size_t nscope = scope_multi_line_.size();
909 json::Handler<ValueType>::Write(
this, value);
910 CHECK_EQ(nscope, scope_multi_line_.size())
911 <<
"Uneven scope, did you call EndArray/EndObject after each BeginObject/Array?";
914 inline void JSONWriter::WriteSeperator() {
915 if (scope_multi_line_.size() == 0 || scope_multi_line_.back()) {
917 Extend(os_, std::string(scope_multi_line_.size() * 2,
' '));
922 reader->BeginObject();
923 std::map<std::string, int> visited;
925 while (reader->NextObjectItem(&key)) {
926 if (map_.count(key) != 0) {
928 (*e.func)(reader, e.addr);
931 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 932 std::ostringstream err;
936 Extend(&err,
"JSONReader: Unknown field ");
938 Extend(&err,
", candidates are: \n");
939 for (std::map<std::string, Entry>::iterator
940 it = map_.begin(); it != map_.end(); ++it) {
942 Extend(&err, it->first);
943 Extend(&err,
"\"\n");
945 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 946 LOG(FATAL) << err.str();
952 if (visited.size() != map_.size()) {
953 for (std::map<std::string, Entry>::iterator
954 it = map_.begin(); it != map_.end(); ++it) {
955 if (it->second.optional)
continue;
956 CHECK_NE(visited.count(it->first), 0U)
957 <<
"JSONReader: Missing field \"" << it->first <<
"\"\n At " 958 << reader->line_info();
964 inline void JSONObjectReadHelper::ReaderFunction(
JSONReader *reader,
void *addr) {
965 json::Handler<T>::Read(reader, static_cast<T*>(addr));
969 inline void JSONObjectReadHelper::
970 DeclareFieldInternal(
const std::string &key, T *addr,
bool optional) {
971 CHECK_EQ(map_.count(key), 0U)
972 <<
"Adding duplicate field " << key;
974 e.func = ReaderFunction<T>;
975 e.addr =
static_cast<void*
>(addr);
976 e.optional = optional;
982 #endif // DMLC_JSON_H_ JSONWriter(std::ostream *os)
Constructor.
Definition: json.h:196
void BeginObject(bool multi_line=true)
Start beginning of array.
std::string line_info() const
Definition: json.h:123
whether a type is pod type
Definition: type_traits.h:21
void WriteArraySeperator()
Write seperator of array, before writing next element. User can proceed to call writer->Write to writ...
c++17 compatible optional class.
Definition: optional.h:43
void WriteString(const std::string &s)
Write a string that can contain escape characters.
void WriteNoEscape(const std::string &s)
Write a string that do not contain escape characters.
void WriteObjectKeyValue(const std::string &key, const ValueType &value)
Write key value pair in the object.
void BeginObject()
Begin parsing an object.
void DeclareField(const std::string &key, T *addr)
Declare field of type T.
Definition: json.h:320
void ReadNumber(ValueType *out_value)
Read Number.
void ReadAllFields(JSONReader *reader)
Read in all the declared fields.
void EndArray()
Finish writing an array.
void BeginArray()
Begin parsing an array.
Helper class to read JSON into a class or struct object.
Definition: json.h:311
Lightweight JSON Reader to read any STL compositions and structs. The user need to know the schema of...
Definition: json.h:44
bool isspace(char c)
Inline implementation of isspace(). Tests whether the given character is a whitespace letter...
Definition: strtonum.h:26
Container to hold any data type.
void EndObject()
Finish writing object.
namespace for dmlc
Definition: array_view.h:12
void Write(const ValueType &value)
Write value to json.
void WriteNumber(const ValueType &v)
Write a string that can contain escape characters.
template to select type based on condition For example, IfThenElseType<true, int, float>::Type will g...
Definition: type_traits.h:123
void DeclareOptionalField(const std::string &key, T *addr)
Declare optional field of type T.
Definition: json.h:330
JSONReader(std::istream *is)
Constructor.
Definition: json.h:51
void WriteArrayItem(const ValueType &value)
Write value into array.
void Read(ValueType *out_value)
Read next ValueType.
void BeginArray(bool multi_line=true)
Start beginning of array.
bool NextArrayItem()
Try to read the next element in the array. If this call is successful, user can proceed to call reade...
void ReadString(std::string *out_str)
Parse next JSON string.
bool NextObjectItem(std::string *out_key)
Try to move to next object item. If this call is successful, user can proceed to call reader->Read to...
type traits information header
Lightweight json to write any STL compositions.
Definition: json.h:189
std::string type_name()
the string representation of type name
Definition: type_traits.h:101