bool parse_file(rapidjson::Document & doc, std::string const& file_name) { file_string file_data(file_name); if(file_data.is_valid() == false) { log_error(log_scope::ENGINE, "Unable to open json file \"{}\".", file_name); return false; } doc.Parse<0>(file_data.get_str().c_str()); if(doc.HasParseError()) { // rapidjson does not provide line/column, only character offset // hacking it here until (if) rapidjson implements it std::string const& file_data_str = file_data.get_str(); size_t const error_char_offset = doc.GetErrorOffset(); std::string::const_iterator error_it = file_data_str.cbegin() + error_char_offset; // Compute line number, using 1 as base line size_t const error_line_num = 1 + std::count_if( file_data_str.cbegin(), error_it, std::bind2nd(std::equal_to<char>(), '\n')); // Compute column (char offset into line), using 1 as base column std::string::const_reverse_iterator reverse_error_it{error_it}; auto error_line_begin_it = std::find( reverse_error_it, file_data_str.crend(), '\n'); // If this is the first line we can size_t const error_column_num = error_line_begin_it != file_data_str.crend() ? std::distance(reverse_error_it, error_line_begin_it) + 1 : error_char_offset + 1; // Log error log_error(log_scope::ENGINE, "Error parsing json file {}", file_name); log_error_no_prefix(log_line_seperator); log_error_no_prefix("== JSON ERRORS =========="); log_error_no_prefix("Line {}, Column {} - {}", error_line_num, error_column_num, doc.GetParseError()); log_error_no_prefix(log_line_seperator); return false; } return true; }
bool parseJson(const char* json,rapidjson::Document& doc){ doc.Parse<0>(json); if(doc.HasParseError()){ rapidjson::ParseErrorCode e = doc.GetParseError(); size_t o = doc.GetErrorOffset(); std::cerr << "Error: " << rapidjson::GetParseError_En(e) << std::endl;; std::string slice = (strlen(json)>o+10)?std::string(json).substr(o,10):std::string(json); std::cerr << " at offset " << o << " near '" << slice << "...'" << std::endl; return false; } return true; }
inline bool loadDocument(const std::string &path, rapidjson::Document &document) { // Load schema JSON from file std::string file; if (!loadFile(path, file)) { std::cerr << "Failed to load json from file '" << path << "'." << std::endl; return false; } // Parse schema document.Parse<0>(file.c_str()); if (document.HasParseError()) { std::cerr << "RapidJson failed to parse the document:" << std::endl; std::cerr << "Parse error: " << document.GetParseError() << std::endl; std::cerr << "Near: " << file.substr(std::max(size_t(0), document.GetErrorOffset() - 20), 40) << std::endl; return false; } return true; }
int SettingRegistry::loadJSON(std::string filename, rapidjson::Document& json_document) { FILE* f = fopen(filename.c_str(), "rb"); if (!f) { cura::logError("Couldn't open JSON file.\n"); return 1; } char read_buffer[4096]; rapidjson::FileReadStream reader_stream(f, read_buffer, sizeof(read_buffer)); json_document.ParseStream(reader_stream); fclose(f); if (json_document.HasParseError()) { cura::logError("Error parsing JSON(offset %u): %s\n", (unsigned)json_document.GetErrorOffset(), GetParseError_En(json_document.GetParseError())); return 2; } return 0; }
JSON_API void read_json(std::string const &fname, rapidjson::Document &d) { FILE* fp = fopen(fname.c_str(), "rb"); // non-Windows use "r" if(!fp) { std::stringstream str; str << "ERROR [read_json]: file " << fname << " not found!"; throw std::runtime_error(str.str()); } fseek(fp, 0, SEEK_END); size_t length = static_cast<size_t>(ftell(fp)); //std::cout << "file size = " << length << std::endl; fseek(fp, 0, SEEK_SET); char* readBuffer = static_cast<char*>(malloc(length + 1)); size_t readLength = fread(readBuffer, 1, length, fp); readBuffer[readLength] = '\0'; fclose(fp); d.Parse<rapidjson::kParseCommentsFlag>(readBuffer); if(d.HasParseError()) { std::stringstream str; str << "ERROR [read_json]: json document cannot be parsed!" << std::endl; str << "\t Parse Error " << d.GetParseError() << " (" << GetParseError_En(d.GetParseError()) << ")" << std::endl; str << "\t Error offset = " << d.GetErrorOffset() << '\n'; throw std::runtime_error(str.str()); } if(!d.IsObject()) { std::stringstream str; str << "ERROR [read_json]: json document is not an object!"; throw std::runtime_error(str.str()); } }