/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/serialisation/JSON_IO.h Copyright (C) 2015 Author: Guido Cossu This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef GRID_SERIALISATION_JSON_IO_H #define GRID_SERIALISATION_JSON_IO_H #include #include #include #include #include #include #include #include // for convenience using json = nlohmann::json; namespace Grid { class JSONWriter: public Writer { public: JSONWriter(const std::string &fileName); virtual ~JSONWriter(void); void push(const std::string &s); void pop(void); template void writeDefault(const std::string &s, const U &x); template void writeDefault(const std::string &s, const std::complex &x); template void writeDefault(const std::string &s, const std::vector &x); template void writeDefault(const std::string &s, const std::pair &x); template void writeDefault(const std::string &s, const char(&x)[N]); void writeDefault(const std::string &s, const std::string &x); private: void delete_comma(); std::string fileName_; std::ostringstream ss_; }; class JSONReader: public Reader { public: JSONReader(const std::string &fileName); virtual ~JSONReader(void) = default; bool push(const std::string &s); void pop(void); bool nextElement(const std::string &s); template void readDefault(const std::string &s, U &output); template void readDefault(const std::string &s, std::complex &output); template void readDefault(const std::string &s, std::vector &output); template void readDefault(const std::string &s, std::pair &output); private: json jobject_; // main object json jcur_; // current json object std::vector jold_; // previous json object std::string fileName_; std::vector do_pop; json::iterator it_; json::iterator it_end_; }; template <> struct isReader< JSONReader > { static const bool value = true; }; template <> struct isWriter< JSONWriter > { static const bool value = true; }; // Writer template implementation //////////////////////////////////////////// template void JSONWriter::writeDefault(const std::string &s, const U &x) { //std::cout << "JSONWriter::writeDefault(U) : " << s << " " << x < void JSONWriter::writeDefault(const std::string &s, const std::complex &x) { //std::cout << "JSONWriter::writeDefault(complex) : " << s << " " << x << std::endl; std::ostringstream os; os << "["<< std::boolalpha << x.real() << ", " << x.imag() << "]"; if (s.size()) ss_ << "\""<< s << "\" : " << os.str() << " ," ; else ss_ << os.str() << " ," ; } template void JSONWriter::writeDefault(const std::string &s, const std::pair &x) { //std::cout << "JSONWriter::writeDefault(pair) : " << s << " " << x << std::endl; std::ostringstream os; os << "["<< std::boolalpha << "\""<< x.first << "\" , \"" << x.second << "\" ]"; if (s.size()) ss_ << "\""<< s << "\" : " << os.str() << " ," ; else ss_ << os.str() << " ," ; } template void JSONWriter::writeDefault(const std::string &s, const std::vector &x) { //std::cout << "JSONWriter::writeDefault(vec U) : " << s << std::endl; if (s.size()) ss_ << " \""< void JSONWriter::writeDefault(const std::string &s, const char(&x)[N]){ //std::cout << "JSONWriter::writeDefault(char U) : " << s << " " << x << std::endl; if (s.size()) ss_ << "\""<< s << "\" : \"" << x << "\" ," ; else ss_ << "\"" << x << "\" ," ; } // Reader template implementation //////////////////////////////////////////// template void JSONReader::readDefault(const std::string &s, U &output) { //std::cout << "JSONReader::readDefault(U) : " << s << " : "<< jcur_ << std::endl; if (s.size()){ //std::cout << "String: "<< jcur_[s] << std::endl; output = jcur_[s]; } else { //std::cout << "String: "<< jcur_ << std::endl; output = jcur_; } } // Reader template implementation //////////////////////////////////////////// template void JSONReader::readDefault(const std::string &s, std::pair &output) { U first; P second; json j; if (s.size()){ //std::cout << "JSONReader::readDefault(pair) : " << s << " | "<< jcur_[s] << std::endl; j = jcur_[s]; } else { j = jcur_; } json::iterator it = j.begin(); jcur_ = *it; read("", first); it++; jcur_ = *it; read("", second); output = std::pair(first,second); } template void JSONReader::readDefault(const std::string &s, std::complex &output) { U tmp1, tmp2; //std::cout << "JSONReader::readDefault(complex U) : " << s << " : "<< jcur_ << std::endl; json j = jcur_; json::iterator it = j.begin(); jcur_ = *it; read("", tmp1); it++; jcur_ = *it; read("", tmp2); output = std::complex(tmp1,tmp2); } template <> void JSONReader::readDefault(const std::string &s, std::string &output); template void JSONReader::readDefault(const std::string &s, std::vector &output) { std::string buf; unsigned int i = 0; //std::cout << "JSONReader::readDefault(vec) : " << jcur_ << std::endl; if (s.size()) push(s); json j = jcur_; for (json::iterator it = j.begin(); it != j.end(); ++it) { jcur_ = *it; //std::cout << "Value: " << it.value() << "\n"; output.resize(i + 1); read("", output[i++]); } jcur_ = j; if (s.size()) pop(); } } #endif