| // Copyright 2018 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SRC_LIB_JSON_PARSER_JSON_PARSER_H_ | |
| #define SRC_LIB_JSON_PARSER_JSON_PARSER_H_ | |
| #include <stdlib.h> | |
| #include <string> | |
| #include <vector> | |
| #include <rapidjson/document.h> | |
| #include "lib/fit/function.h" | |
| #include "src/lib/fxl/macros.h" | |
| namespace json_parser { | |
| // A JSON parser utility class. | |
| // | |
| // This class provides general facilities to parse a JSON file, and report | |
| // errors. If parsing succeeds, ReadFrom() returns a rapidjson::Document | |
| // representing the file. The class is agnostic to the actual structure of | |
| // the document -- client code is responsible for interpreting the | |
| // rapidjson::Document, which could contain any valid JSON. | |
| class JSONParser { | |
| public: | |
| JSONParser() = default; | |
| JSONParser(JSONParser&&) = default; | |
| JSONParser& operator=(JSONParser&&) = default; | |
| // Parses a JSON file. If reading or parsing the file fails, reports errors in | |
| // error_str(). May be called multiple times, for example on multiple files, | |
| // in which case any previous errors will be retained. | |
| rapidjson::Document ParseFromFile(const std::string& file); | |
| // Like |ParseFromFile|, but relative to a directory. | |
| rapidjson::Document ParseFromFileAt(int dirfd, const std::string& file); | |
| // Initialize the document from a JSON string |data|. If parsing fails, | |
| // reports errors in error_str(). |file| is not read, but it is used as the | |
| // prefix for lines in error_str(). May be called multiple times, for example | |
| // on multiple files, in which case any previous errors will be retained. | |
| rapidjson::Document ParseFromString(const std::string& data, const std::string& file); | |
| // Initialize multiple documents from files in a directory. |cb| is | |
| // called for each file that parses. The traversal is not recursive, and all | |
| // files in the directory are expected to be JSON files. If the directory does | |
| // not exist, no error is reported, and no callbacks are called. Callers | |
| // wishing to identify such a state should stat the path themselves. | |
| // | |
| // It is up to the caller to decide how to merge multiple documents. | |
| void ParseFromDirectory(const std::string& path, fit::function<void(rapidjson::Document)> cb); | |
| // Like |ParseFromDirectory|, but relative to a directory. | |
| void ParseFromDirectoryAt(int dirfd, const std::string& path, | |
| fit::function<void(rapidjson::Document)> cb); | |
| // Copies the string values from a |name|d |value| to the |out| vector. | |
| // Clears |out| and calls ReportError() if |value| does not refer to an array, | |
| // or if the array contains non-string values. | |
| void CopyStringArray(const std::string& name, const rapidjson::Value& value, | |
| std::vector<std::string>* out); | |
| // Returns true if there was an error initializing the document. | |
| bool HasError() const; | |
| // If HasError() is true, returns a human-readable string describing the | |
| // error(s) initializing the document. | |
| std::string error_str() const; | |
| // Records an error initializing the object. Multiple errors may be recorded. | |
| void ReportError(const std::string& error); | |
| private: | |
| // Internal version of |ReportError| that includes an offset. | |
| void ReportErrorInternal(size_t offset, const std::string& error); | |
| std::vector<std::string> errors_; | |
| // Stores the filename, for reporting debug information. | |
| std::string file_; | |
| // Stores the file content, for reporting debug information. | |
| std::string data_; | |
| FXL_DISALLOW_COPY_AND_ASSIGN(JSONParser); | |
| }; | |
| } // namespace json_parser | |
| namespace json { | |
| // The JSONParser should be used from the json_parser namespace to be consistent with the rest of | |
| // this library but currently many callsites expect this to live in the json namespace. This alias | |
| // allows both names to work. | |
| // TODO(fxbug.dev/36759): Update callers to new name and remove this alias. | |
| using JSONParser = ::json_parser::JSONParser; | |
| } // namespace json | |
| #endif // SRC_LIB_JSON_PARSER_JSON_PARSER_H_ |