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>
120 template<
typename ValueType>
121 inline void Read(ValueType *out_value);
125 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 127 std::ostringstream os;
128 os <<
" Line " << std::max(line_count_r_, line_count_n_);
129 is_->getline(temp, 64);
130 os <<
", around ^`" << temp <<
"`";
133 std::string info =
" Line ";
134 info += std::to_string(std::max(line_count_r_, line_count_n_));
137 size_t end_pos = is_->find(
'\n');
138 end_pos = std::min((
size_t)64,
139 end_pos == std::string::npos ? is_->size() : end_pos);
140 std::string line = is_->substr(0, end_pos);
141 is_->erase(0, line.size() + 1);
143 info +=
", around ^`" + line +
"`";
149 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 157 size_t line_count_r_;
159 size_t line_count_n_;
164 std::vector<size_t> scope_counter_;
169 inline int NextNonSpace();
174 inline int PeekNextNonSpace();
179 inline int NextChar();
184 inline int PeekNextChar();
196 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 206 inline void WriteNoEscape(
const std::string &s);
211 inline void WriteString(
const std::string &s);
217 template<
typename ValueType>
218 inline void WriteNumber(
const ValueType &v);
230 inline void BeginArray(
bool multi_line =
true);
232 inline void EndArray();
246 inline void EndObject();
253 template<
typename ValueType>
254 inline void WriteObjectKeyValue(
const std::string &key,
255 const ValueType &value);
260 inline void WriteArraySeperator();
266 template<
typename ValueType>
267 inline void WriteArrayItem(
const ValueType &value);
273 template<
typename ValueType>
274 inline void Write(
const ValueType &value);
277 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 287 std::vector<size_t> scope_counter_;
289 std::vector<bool> scope_multi_line_;
293 inline void WriteSeperator();
322 DeclareFieldInternal(key, addr,
false);
332 DeclareFieldInternal(key, addr,
true);
338 inline void ReadAllFields(
JSONReader *reader);
349 inline void DeclareFieldInternal(
const std::string &key, T *addr,
bool optional);
356 inline static void ReaderFunction(
JSONReader *reader,
void *addr);
358 typedef void (*ReadFunction)(
JSONReader *reader,
void *addr);
369 std::map<std::string, Entry> map_;
372 #define DMLC_JSON_ENABLE_ANY_VAR_DEF(KeyName) \ 373 static DMLC_ATTRIBUTE_UNUSED ::dmlc::json::AnyJSONManager& \ 374 __make_AnyJSONType ## _ ## KeyName ## __ 384 #define DMLC_JSON_ENABLE_ANY(Type, KeyName) \ 385 DMLC_STR_CONCAT(DMLC_JSON_ENABLE_ANY_VAR_DEF(KeyName), __COUNTER__) = \ 386 ::dmlc::json::AnyJSONManager::Global()->EnableType<Type>(#KeyName) \ 398 template<
typename ValueType>
399 struct NumericHandler {
400 inline static void Write(JSONWriter *writer,
const ValueType &value) {
401 writer->WriteNumber<ValueType>(value);
404 reader->ReadNumber<ValueType>(value);
408 template<
typename ContainerType>
409 struct ArrayHandler {
410 inline static void Write(JSONWriter *writer,
const ContainerType &array) {
411 typedef typename ContainerType::value_type ElemType;
413 for (
typename ContainerType::const_iterator it = array.begin();
414 it != array.end(); ++it) {
415 writer->WriteArrayItem(*it);
419 inline static void Read(
JSONReader *reader, ContainerType *array) {
420 typedef typename ContainerType::value_type ElemType;
422 reader->BeginArray();
423 while (reader->NextArrayItem()) {
425 Handler<ElemType>::Read(reader, &value);
426 array->insert(array->end(), value);
431 template<
typename ContainerType>
433 inline static void Write(JSONWriter *writer,
const ContainerType &map) {
434 writer->BeginObject(map.size() > 1);
435 for (
typename ContainerType::const_iterator it = map.begin(); it != map.end(); ++it) {
436 writer->WriteObjectKeyValue(it->first, it->second);
441 typedef typename ContainerType::mapped_type ElemType;
443 reader->BeginObject();
445 while (reader->NextObjectItem(&key)) {
447 reader->Read(&value);
454 struct CommonJSONSerializer {
455 inline static void Write(JSONWriter *writer,
const T &value) {
464 struct Handler<std::string> {
465 inline static void Write(JSONWriter *writer,
const std::string &value) {
466 writer->WriteString(value);
469 reader->ReadString(str);
474 struct Handler<std::vector<T> > :
public ArrayHandler<std::vector<T> > {
477 template<
typename K,
typename V>
478 struct Handler<std::pair<K, V> > {
479 inline static void Write(JSONWriter *writer,
const std::pair<K, V> &kv) {
480 writer->BeginArray();
481 writer->WriteArrayItem(kv.first);
482 writer->WriteArrayItem(kv.second);
485 inline static void Read(
JSONReader *reader, std::pair<K, V> *kv) {
486 reader->BeginArray();
487 CHECK(reader->NextArrayItem())
488 <<
"Expect array of length 2";
489 Handler<K>::Read(reader, &(kv->first));
490 CHECK(reader->NextArrayItem())
491 <<
"Expect array of length 2";
492 Handler<V>::Read(reader, &(kv->second));
493 CHECK(!reader->NextArrayItem())
494 <<
"Expect array of length 2";
499 struct Handler<std::list<T> > :
public ArrayHandler<std::list<T> > {
503 struct Handler<std::map<std::string, V> > :
public MapHandler<std::map<std::string, V> > {
508 struct Handler<std::unordered_map<std::string, V> >
509 :
public MapHandler<std::unordered_map<std::string, V> > {
511 #endif // DMLC_USE_CXX11 515 inline static void Write(JSONWriter *writer,
const T &data) {
518 CommonJSONSerializer<T> >::Type THandler;
519 THandler::Write(writer, data);
524 CommonJSONSerializer<T> >::Type THandler;
525 THandler::Read(reader, data);
529 #if DMLC_STRICT_CXX11 532 class AnyJSONManager {
535 inline AnyJSONManager& EnableType(
const std::string&
type_name) {
536 std::type_index tp = std::type_index(
typeid(T));
537 if (type_name_.count(tp) != 0) {
539 <<
"Type has already been registered as another typename " << type_name_.at(tp);
542 CHECK(type_map_.count(type_name) == 0)
543 <<
"Type name " << type_name <<
" already registered in registry";
546 e.write = WriteAny<T>;
552 inline static AnyJSONManager* Global() {
553 static AnyJSONManager inst;
561 inline static void WriteAny(JSONWriter *writer,
const any &data) {
562 writer->Write(dmlc::unsafe_get<T>(data));
565 inline static void ReadAny(
JSONReader *reader, any* data) {
568 *data = std::move(temp);
573 void (*write)(JSONWriter* reader,
const any& data);
577 friend struct Handler;
579 std::unordered_map<std::type_index, std::string> type_name_;
580 std::unordered_map<std::string, Entry> type_map_;
584 struct Handler<any> {
585 inline static void Write(JSONWriter *writer,
const any &data) {
586 std::unordered_map<std::type_index, std::string>&
587 nmap = AnyJSONManager::Global()->type_name_;
588 std::type_index
id = std::type_index(data.type());
589 auto it = nmap.find(
id);
590 CHECK(it != nmap.end() && it->first == id)
591 <<
"Type " <<
id.name() <<
" has not been registered via DMLC_JSON_ENABLE_ANY";
593 AnyJSONManager::Entry e = AnyJSONManager::Global()->type_map_.at(type_name);
594 writer->BeginArray(
false);
595 writer->WriteArrayItem(type_name);
596 writer->WriteArraySeperator();
597 e.write(writer, data);
602 reader->BeginArray();
603 CHECK(reader->NextArrayItem()) <<
"invalid any json format";
604 Handler<std::string>::Read(reader, &type_name);
605 std::unordered_map<std::string, AnyJSONManager::Entry>&
606 tmap = AnyJSONManager::Global()->type_map_;
607 auto it = tmap.find(type_name);
608 CHECK(it != tmap.end() && it->first ==
type_name)
609 <<
"Typename " << type_name <<
" has not been registered via DMLC_JSON_ENABLE_ANY";
610 AnyJSONManager::Entry e = it->second;
611 CHECK(reader->NextArrayItem()) <<
"invalid any json format";
612 e.read(reader, data);
613 CHECK(!reader->NextArrayItem()) <<
"invalid any json format";
616 #endif // DMLC_ENABLE_RTTI 617 #endif // DMLC_STRICT_CXX11 622 inline int JSONReader::NextChar() {
623 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 632 inline int JSONReader::PeekNextChar() {
633 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 640 inline int JSONReader::NextNonSpace() {
644 if (ch ==
'\n') ++line_count_n_;
645 if (ch ==
'\r') ++line_count_r_;
650 inline int JSONReader::PeekNextNonSpace() {
654 if (ch ==
'\n') ++line_count_n_;
655 if (ch ==
'\r') ++line_count_r_;
664 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 665 void Extend(std::ostream *os, T item) {
669 void Extend(std::string *ostr, T item) {
676 int ch = NextNonSpace();
679 <<
", Expect \'\"\' but get \'" <<
static_cast<char>(ch) <<
'\'';
680 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 681 std::ostringstream output;
683 std::string output =
"";
688 char sch =
static_cast<char>(NextChar());
690 case 'r': Extend(&output,
"\r");
break;
691 case 'n': Extend(&output,
"\n");
break;
692 case '\\': Extend(&output,
"\\");
break;
693 case 't': Extend(&output,
"\t");
break;
694 case '\"': Extend(&output,
"\"");
break;
695 default: LOG(FATAL) <<
"unknown string escape \\" << sch;
698 if (ch ==
'\"')
break;
699 Extend(&output, static_cast<char>(ch));
701 if (ch == EOF || ch ==
'\r' || ch ==
'\n') {
704 <<
", Expect \'\"\' but reach end of line ";
707 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 708 *out_str = output.str();
714 template<
typename ValueType>
716 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 720 <<
", Expect number";
723 const char* icstr = is_->c_str();
724 unsigned number = strtol(icstr, &endptr, 10);
725 is_->erase(0, endptr - icstr);
726 *out_value =
static_cast<ValueType
>(number);
731 int ch = NextNonSpace();
734 <<
", Expect \'{\' but get \'" <<
static_cast<char>(ch) <<
'\'';
735 scope_counter_.push_back(0);
739 int ch = NextNonSpace();
742 <<
", Expect \'[\' but get \'" <<
static_cast<char>(ch) <<
'\'';
743 scope_counter_.push_back(0);
748 if (scope_counter_.back() != 0) {
749 int ch = NextNonSpace();
752 }
else if (ch ==
'}') {
757 <<
", JSON object expect \'}\' or \',\' \'" <<
static_cast<char>(ch) <<
'\'';
760 int ch = PeekNextNonSpace();
767 scope_counter_.pop_back();
770 scope_counter_.back() += 1;
772 int ch = NextNonSpace();
775 <<
", Expect \':\' but get \'" <<
static_cast<char>(ch) <<
'\'';
782 if (scope_counter_.back() != 0) {
783 int ch = NextNonSpace();
786 }
else if (ch ==
']') {
791 <<
", JSON array expect \']\' or \',\'. Get \'" <<
static_cast<char>(ch) <<
"\' instead";
794 int ch = PeekNextNonSpace();
801 scope_counter_.pop_back();
804 scope_counter_.back() += 1;
809 template<
typename ValueType>
811 json::Handler<ValueType>::Read(
this, out_value);
822 for (
size_t i = 0; i < s.length(); ++i) {
825 case '\r': Extend(os_,
"\\r");
break;
826 case '\n': Extend(os_,
"\\n");
break;
827 case '\\': Extend(os_,
"\\\\");
break;
828 case '\t': Extend(os_,
"\\t");
break;
829 case '\"': Extend(os_,
"\\\"");
break;
830 default: Extend(os_, ch);
836 template<
typename ValueType>
838 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 841 Extend(os_, std::to_string(v));
847 scope_multi_line_.push_back(multi_line);
848 scope_counter_.push_back(0);
852 CHECK_NE(scope_multi_line_.size(), 0U);
853 CHECK_NE(scope_counter_.size(), 0U);
854 bool newline = scope_multi_line_.back();
855 size_t nelem = scope_counter_.back();
856 scope_multi_line_.pop_back();
857 scope_counter_.pop_back();
858 if (newline && nelem != 0) WriteSeperator();
864 scope_multi_line_.push_back(multi_line);
865 scope_counter_.push_back(0);
869 CHECK_NE(scope_multi_line_.size(), 0U);
870 CHECK_NE(scope_counter_.size(), 0U);
871 bool newline = scope_multi_line_.back();
872 size_t nelem = scope_counter_.back();
873 scope_multi_line_.pop_back();
874 scope_counter_.pop_back();
875 if (newline && nelem != 0) WriteSeperator();
879 template<
typename ValueType>
881 const ValueType &value) {
882 if (scope_counter_.back() > 0) {
889 scope_counter_.back() += 1;
890 json::Handler<ValueType>::Write(
this, value);
894 if (scope_counter_.back() != 0) {
897 scope_counter_.back() += 1;
901 template<
typename ValueType>
903 this->WriteArraySeperator();
904 json::Handler<ValueType>::Write(
this, value);
907 template<
typename ValueType>
909 size_t nscope = scope_multi_line_.size();
910 json::Handler<ValueType>::Write(
this, value);
911 CHECK_EQ(nscope, scope_multi_line_.size())
912 <<
"Uneven scope, did you call EndArray/EndObject after each BeginObject/Array?";
915 inline void JSONWriter::WriteSeperator() {
916 if (scope_multi_line_.size() == 0 || scope_multi_line_.back()) {
918 Extend(os_, std::string(scope_multi_line_.size() * 2,
' '));
923 reader->BeginObject();
924 std::map<std::string, int> visited;
926 while (reader->NextObjectItem(&key)) {
927 if (map_.count(key) != 0) {
929 (*e.func)(reader, e.addr);
932 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 933 std::ostringstream err;
937 Extend(&err,
"JSONReader: Unknown field ");
939 Extend(&err,
", candidates are: \n");
940 for (std::map<std::string, Entry>::iterator
941 it = map_.begin(); it != map_.end(); ++it) {
943 Extend(&err, it->first);
944 Extend(&err,
"\"\n");
946 #ifndef _LIBCPP_SGX_NO_IOSTREAMS 947 LOG(FATAL) << err.str();
953 if (visited.size() != map_.size()) {
954 for (std::map<std::string, Entry>::iterator
955 it = map_.begin(); it != map_.end(); ++it) {
956 if (it->second.optional)
continue;
957 CHECK_NE(visited.count(it->first), 0U)
958 <<
"JSONReader: Missing field \"" << it->first <<
"\"\n At " 959 << reader->line_info();
965 inline void JSONObjectReadHelper::ReaderFunction(
JSONReader *reader,
void *addr) {
966 json::Handler<T>::Read(reader, static_cast<T*>(addr));
970 inline void JSONObjectReadHelper::
971 DeclareFieldInternal(
const std::string &key, T *addr,
bool optional) {
972 CHECK_EQ(map_.count(key), 0U)
973 <<
"Adding duplicate field " << key;
975 e.func = ReaderFunction<T>;
976 e.addr =
static_cast<void*
>(addr);
977 e.optional = optional;
983 #endif // DMLC_JSON_H_ JSONWriter(std::ostream *os)
Constructor.
Definition: json.h:197
void BeginObject(bool multi_line=true)
Start beginning of array.
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
std::string line_info() const
Definition: json.h:124
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:321
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:312
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:331
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:190
std::string type_name()
the string representation of type name
Definition: type_traits.h:101