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 ";
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
217 template<
typename ValueType>
230 inline void BeginArray(
bool multi_line =
true);
253 template<
typename ValueType>
255 const ValueType &value);
266 template<
typename ValueType>
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);
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);
403 inline static void Read(JSONReader *reader, 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);
440 inline static void Read(JSONReader *reader, ContainerType *map) {
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) {
458 inline static void Read(JSONReader *reader, T *value) {
464 struct Handler<
std::string> {
465 inline static void Write(JSONWriter *writer,
const std::string &value) {
466 writer->WriteString(value);
468 inline static void Read(JSONReader *reader, std::string *str) {
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);
521 inline static void Read(JSONReader *reader, T *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);
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);
572 void (*read)(JSONReader* reader, any *data);
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);
596 writer->WriteArraySeperator();
597 e.write(writer, data);
600 inline static void Read(JSONReader *reader, any *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_;
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
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>
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_