Skip to content

Commit 50ae06e

Browse files
CharReader: Add ErrorInfo and parse() overload
1 parent 94cda30 commit 50ae06e

File tree

3 files changed

+66
-13
lines changed

3 files changed

+66
-13
lines changed

Diff for: include/json/reader.h

+25
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,13 @@ class JSONCPP_DEPRECATED(
244244
*/
245245
class JSON_API CharReader {
246246
public:
247+
class JSON_API ErrorInfo {
248+
public:
249+
ptrdiff_t offset_start;
250+
ptrdiff_t offset_limit;
251+
String message;
252+
};
253+
247254
virtual ~CharReader() = default;
248255
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
249256
* document. The document must be a UTF-8 encoded string containing the
@@ -264,6 +271,24 @@ class JSON_API CharReader {
264271
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
265272
String* errs) = 0;
266273

274+
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
275+
* document. The document must be a UTF-8 encoded string containing the
276+
* document to read.
277+
*
278+
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string
279+
* of the document to read.
280+
* \param endDoc Pointer on the end of the UTF-8 encoded string of the
281+
* document to read. Must be >= beginDoc.
282+
* \param[out] root Contains the root value of the document if it was
283+
* successfully parsed.
284+
* \param[out] errs Structured error messages a list of items that list
285+
* errors in the parsed document.
286+
* \return \c true if the document was successfully parsed, \c false if an
287+
* error occurred.
288+
*/
289+
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
290+
std::vector<ErrorInfo>& errs) = 0;
291+
267292
class JSON_API Factory {
268293
public:
269294
virtual ~Factory() = default;

Diff for: src/lib_json/json_reader.cpp

+15-13
Original file line numberDiff line numberDiff line change
@@ -884,17 +884,12 @@ class OurReader {
884884
public:
885885
using Char = char;
886886
using Location = const Char*;
887-
struct StructuredError {
888-
ptrdiff_t offset_start;
889-
ptrdiff_t offset_limit;
890-
String message;
891-
};
892887

893888
explicit OurReader(OurFeatures const& features);
894889
bool parse(const char* beginDoc, const char* endDoc, Value& root,
895890
bool collectComments = true);
896891
String getFormattedErrorMessages() const;
897-
std::vector<StructuredError> getStructuredErrors() const;
892+
std::vector<CharReader::ErrorInfo> getErrorInfo() const;
898893

899894
private:
900895
OurReader(OurReader const&); // no impl
@@ -1849,14 +1844,14 @@ String OurReader::getFormattedErrorMessages() const {
18491844
return formattedMessage;
18501845
}
18511846

1852-
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
1853-
std::vector<OurReader::StructuredError> allErrors;
1847+
std::vector<CharReader::ErrorInfo> OurReader::getErrorInfo() const {
1848+
std::vector<CharReader::ErrorInfo> allErrors;
18541849
for (const auto& error : errors_) {
1855-
OurReader::StructuredError structured;
1856-
structured.offset_start = error.token_.start_ - begin_;
1857-
structured.offset_limit = error.token_.end_ - begin_;
1858-
structured.message = error.message_;
1859-
allErrors.push_back(structured);
1850+
CharReader::ErrorInfo errorInfo;
1851+
errorInfo.offset_start = error.token_.start_ - begin_;
1852+
errorInfo.offset_limit = error.token_.end_ - begin_;
1853+
errorInfo.message = error.message_;
1854+
allErrors.push_back(errorInfo);
18601855
}
18611856
return allErrors;
18621857
}
@@ -1876,6 +1871,13 @@ class OurCharReader : public CharReader {
18761871
}
18771872
return ok;
18781873
}
1874+
1875+
bool parse(char const* beginDoc, char const* endDoc, Value* root,
1876+
std::vector<ErrorInfo>& errs) override {
1877+
bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
1878+
errs = reader_.getErrorInfo();
1879+
return ok;
1880+
}
18791881
};
18801882

18811883
CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }

Diff for: src/test_lib_json/main.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -3903,6 +3903,32 @@ JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) {
39033903
example.size()));
39043904
}
39053905

3906+
struct ParseWithErrorInfoTest : JsonTest::TestCase {};
3907+
3908+
JSONTEST_FIXTURE_LOCAL(ParseWithErrorInfoTest, success) {
3909+
Json::CharReaderBuilder b;
3910+
CharReaderPtr reader(b.newCharReader());
3911+
char const doc[] = "{}";
3912+
Json::Value root;
3913+
std::vector<Json::CharReader::ErrorInfo> errs;
3914+
JSONTEST_ASSERT(reader->parse(doc, doc + std::strlen(doc), &root, errs));
3915+
JSONTEST_ASSERT_EQUAL(0, errs.size());
3916+
}
3917+
3918+
JSONTEST_FIXTURE_LOCAL(ParseWithErrorInfoTest, singleError) {
3919+
Json::CharReaderBuilder b;
3920+
CharReaderPtr reader(b.newCharReader());
3921+
char const doc[] = R"({ 1: 2 })";
3922+
Json::Value root;
3923+
std::vector<Json::CharReader::ErrorInfo> errs;
3924+
JSONTEST_ASSERT(!reader->parse(doc, doc + std::strlen(doc), &root, errs));
3925+
JSONTEST_ASSERT_EQUAL(1, errs.size());
3926+
JSONTEST_ASSERT_EQUAL(std::string("Missing '}' or object member name"),
3927+
errs[0].message);
3928+
JSONTEST_ASSERT_EQUAL(2, errs[0].offset_start);
3929+
JSONTEST_ASSERT_EQUAL(3, errs[0].offset_limit);
3930+
}
3931+
39063932
int main(int argc, const char* argv[]) {
39073933
JsonTest::Runner runner;
39083934

0 commit comments

Comments
 (0)