Skip to content

Commit cf55e8f

Browse files
committed
1. Code improvement
2. Make "ignore trailling comma and comment" configurable #fixes #101 #closes #101
1 parent ebc1d76 commit cf55e8f

File tree

3 files changed

+117
-104
lines changed

3 files changed

+117
-104
lines changed
+18-72
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,33 @@
11
#include "JsonHandler.h"
22

3-
#include "rapidjson/reader.h"
4-
#include "rapidjson/stringbuffer.h"
5-
#include "rapidjson/document.h"
6-
#include "rapidjson/error/en.h"
7-
8-
JsonHandler::JsonHandler(const ParseOptions& options)
9-
: m_parseOptions(options)
10-
{
11-
}
12-
13-
auto JsonHandler::GetCompressedJson(const std::string& jsonText)-> const Result
3+
JsonHandler::JsonHandler(const ParseOptions &options)
4+
: m_parseOptions(options)
145
{
15-
return ParseJson(jsonText);
166
}
177

18-
auto JsonHandler::FormatJson(const std::string& jsonText, LE le, LF lf, char indentChar, unsigned indentLen)-> const Result
8+
auto JsonHandler::GetCompressedJson(const std::string &jsonText) -> const Result
199
{
20-
Result retVal{};
21-
22-
rapidjson::StringBuffer sb;
23-
rapidjson::PrettyWriter<rapidjson::StringBuffer> pw(sb);
24-
rapidjson::StringStream ss(jsonText.c_str());
25-
rapidjson::Reader reader;
26-
27-
pw.SetLineEnding(le);
28-
pw.SetFormatOptions(lf);
29-
pw.SetIndent(indentChar, indentLen);
10+
rapidjson::StringBuffer sb;
11+
rapidjson::Writer<rapidjson::StringBuffer> handler(sb);
3012

31-
if (reader.Parse<rapidjson::kParseFullPrecisionFlag | rapidjson::kParseCommentsFlag |
32-
rapidjson::kParseEscapedApostropheFlag | rapidjson::kParseNanAndInfFlag | rapidjson::kParseTrailingCommasFlag>(ss, pw)
33-
&& sb.GetString())
34-
{
35-
retVal.success = true;
36-
retVal.response = sb.GetString();
37-
retVal.error_str.clear();
38-
retVal.error_code = retVal.error_pos = -1;
39-
}
40-
else
41-
{
42-
retVal.success = false;
43-
retVal.response.clear();
44-
retVal.error_str = rapidjson::GetParseError_En(reader.GetParseErrorCode());
45-
retVal.error_pos = static_cast<int>(reader.GetErrorOffset());
46-
retVal.error_code = reader.GetParseErrorCode();
47-
}
48-
49-
return retVal;
13+
return ParseJson(jsonText, sb, handler);
5014
}
5115

52-
53-
auto JsonHandler::ValidateJson(const std::string& jsonText)-> const Result
16+
auto JsonHandler::FormatJson(const std::string &jsonText, LE le, LF lf, char indentChar, unsigned indentLen) -> const Result
5417
{
55-
return ParseJson(jsonText);
18+
rapidjson::StringBuffer sb;
19+
rapidjson::PrettyWriter<rapidjson::StringBuffer> handler(sb);
20+
handler.SetLineEnding(le);
21+
handler.SetFormatOptions(lf);
22+
handler.SetIndent(indentChar, indentLen);
23+
24+
return ParseJson(jsonText, sb, handler);
5625
}
5726

58-
auto JsonHandler::ParseJson(const std::string& jsonText) -> const Result
27+
auto JsonHandler::ValidateJson(const std::string &jsonText) -> const Result
5928
{
60-
Result retVal{};
29+
rapidjson::StringBuffer sb;
30+
rapidjson::Writer<rapidjson::StringBuffer> handler(sb);
6131

62-
rapidjson::StringBuffer sb;
63-
rapidjson::Writer<rapidjson::StringBuffer> pw(sb);
64-
rapidjson::StringStream ss(jsonText.c_str());
65-
rapidjson::Reader reader;
66-
67-
if (reader.Parse<rapidjson::kParseFullPrecisionFlag | rapidjson::kParseCommentsFlag |
68-
rapidjson::kParseEscapedApostropheFlag | rapidjson::kParseNanAndInfFlag | rapidjson::kParseTrailingCommasFlag>(ss, pw)
69-
&& sb.GetString())
70-
{
71-
retVal.success = true;
72-
retVal.response = sb.GetString();
73-
retVal.error_str.clear();
74-
retVal.error_code = retVal.error_pos = -1;
75-
}
76-
else
77-
{
78-
retVal.success = false;
79-
retVal.response.clear();
80-
retVal.error_str = rapidjson::GetParseError_En(reader.GetParseErrorCode());
81-
retVal.error_pos = static_cast<int>(reader.GetErrorOffset());
82-
retVal.error_code = reader.GetParseErrorCode();
83-
}
84-
85-
return retVal;
32+
return ParseJson(jsonText, sb, handler);
8633
}
87-
+73-14
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,92 @@
11
#pragma once
22

33
#include <string>
4-
#include "rapidjson/prettywriter.h"
4+
5+
#include <rapidjson/reader.h>
6+
#include <rapidjson/writer.h>
7+
#include <rapidjson/prettywriter.h>
8+
#include <rapidjson/stringbuffer.h>
9+
#include <rapidjson/error/en.h>
510
#include "Define.h"
611

712
struct Result
813
{
9-
bool success = false;
10-
int error_pos = -1;
11-
int error_code = -1;
12-
std::string error_str;
13-
std::string response;
14+
bool success = false;
15+
int error_pos = -1;
16+
int error_code = -1;
17+
std::string error_str;
18+
std::string response;
1419
};
1520

1621
using LE = rapidjson::LineEndingOption;
1722
using LF = rapidjson::PrettyFormatOptions;
1823

1924
class JsonHandler
2025
{
21-
ParseOptions m_parseOptions{};
26+
ParseOptions m_parseOptions {};
27+
2228
public:
23-
JsonHandler(const ParseOptions& options);
24-
~JsonHandler() = default;
29+
JsonHandler(const ParseOptions &options);
30+
~JsonHandler() = default;
2531

26-
auto GetCompressedJson(const std::string& jsonText)->const Result;
27-
auto FormatJson(const std::string& jsonText, LE le, LF lf, char indentChar, unsigned indentLen)->const Result;
28-
auto ValidateJson(const std::string& jsonText)->const Result;
32+
auto GetCompressedJson(const std::string &jsonText) -> const Result;
33+
auto FormatJson(const std::string &jsonText, LE le, LF lf, char indentChar, unsigned indentLen) -> const Result;
34+
auto ValidateJson(const std::string &jsonText) -> const Result;
2935

30-
private:
31-
auto ParseJson(const std::string& jsonText)->const Result;
36+
template <typename Handler>
37+
auto ParseJson(const std::string &jsonText, rapidjson::StringBuffer &sb, Handler &handler) -> const Result;
3238
};
3339

40+
template <typename Handler>
41+
inline auto JsonHandler::ParseJson(const std::string &jsonText, rapidjson::StringBuffer &sb, Handler &handler) -> const Result
42+
{
43+
Result retVal {};
44+
45+
bool success = false;
46+
rapidjson::Reader reader;
47+
rapidjson::StringStream ss(jsonText.c_str());
48+
49+
// TODO: Find some better way
50+
constexpr auto flgBase = rapidjson::kParseFullPrecisionFlag | rapidjson::kParseEscapedApostropheFlag | rapidjson::kParseNanAndInfFlag;
51+
constexpr auto flgBase_commemt = flgBase | rapidjson::kParseCommentsFlag;
52+
constexpr auto flgBase_comma = flgBase | rapidjson::kParseTrailingCommasFlag;
53+
constexpr auto flgBase_Both = flgBase_comma | flgBase_commemt;
54+
55+
if (m_parseOptions.bIgnoreComment && m_parseOptions.bIgnoreTraillingComma)
56+
{
57+
success = reader.Parse<flgBase_Both>(ss, handler) && sb.GetString();
58+
}
59+
60+
else if (!m_parseOptions.bIgnoreComment && m_parseOptions.bIgnoreTraillingComma)
61+
{
62+
success = reader.Parse<flgBase_comma>(ss, handler) && sb.GetString();
63+
}
64+
65+
else if (m_parseOptions.bIgnoreComment && !m_parseOptions.bIgnoreTraillingComma)
66+
{
67+
success = reader.Parse<flgBase_commemt>(ss, handler) && sb.GetString();
68+
}
69+
70+
else if (!m_parseOptions.bIgnoreComment && !m_parseOptions.bIgnoreTraillingComma)
71+
{
72+
success = reader.Parse<flgBase>(ss, handler) && sb.GetString();
73+
}
74+
75+
if (success)
76+
{
77+
retVal.success = true;
78+
retVal.response = sb.GetString();
79+
retVal.error_code = retVal.error_pos = -1;
80+
retVal.error_str.clear();
81+
}
82+
else
83+
{
84+
retVal.success = false;
85+
retVal.error_str = rapidjson::GetParseError_En(reader.GetParseErrorCode());
86+
retVal.error_pos = static_cast<int>(reader.GetErrorOffset());
87+
retVal.error_code = reader.GetParseErrorCode();
88+
retVal.response.clear();
89+
}
90+
91+
return retVal;
92+
}

NppJSONViewer/NppJsonViewer/JsonViewDlg.cpp

+26-18
Original file line numberDiff line numberDiff line change
@@ -298,24 +298,32 @@ void JsonViewDlg::DrawJsonTree()
298298
EnableControls(ctrls, true);
299299
}
300300

301-
void JsonViewDlg::PopulateTreeUsingSax(HTREEITEM tree_root, const std::string& jsonText)
301+
void JsonViewDlg::PopulateTreeUsingSax(HTREEITEM tree_root, const std::string &jsonText)
302302
{
303-
RapidJsonHandler handler(this, tree_root);
304-
rapidjson::Reader reader;
303+
RapidJsonHandler handler(this, tree_root);
304+
rapidjson::StringBuffer sb;
305305

306-
rapidjson::StringStream ss(jsonText.c_str());
307-
if (!reader.Parse< rapidjson::kParseNumbersAsStringsFlag | rapidjson::kParseCommentsFlag |
308-
rapidjson::kParseEscapedApostropheFlag | rapidjson::kParseNanAndInfFlag | rapidjson::kParseTrailingCommasFlag>(ss, handler))
309-
{
310-
// Mark the error position
311-
size_t start = m_Editor->GetSelectionStart();
312-
size_t errPosition = start + reader.GetErrorOffset();
313-
m_Editor->MakeSelection(errPosition, errPosition + 1);
306+
Result res = JsonHandler(m_pSetting->parseOptions).ParseJson(jsonText, sb, handler);
307+
if (!res.success)
308+
{
309+
// Mark the error position
310+
size_t start = m_Editor->GetSelectionStart();
311+
size_t errPosition = start + static_cast<size_t>(res.error_pos);
312+
m_Editor->MakeSelection(errPosition, errPosition + 1);
314313

315-
::MessageBox(m_NppData._nppHandle, JSON_ERR_PARSE, JSON_ERROR_TITLE, MB_OK | MB_ICONERROR);
316-
}
317-
318-
m_Editor->SetLangAsJson();
314+
// Intimate user
315+
if (jsonText.empty())
316+
{
317+
::MessageBox(m_NppData._nppHandle, JSON_ERR_PARSE, JSON_ERROR_TITLE, MB_OK | MB_ICONERROR);
318+
}
319+
else
320+
{
321+
std::string err = std::format("\n\nError: ({} : {})", res.error_code, res.error_str);
322+
::MessageBox(m_NppData._nppHandle, (JSON_ERR_VALIDATE + StringHelper::ToWstring(err)).c_str(), JSON_ERROR_TITLE, MB_OK | MB_ICONERROR);
323+
}
324+
}
325+
326+
m_Editor->SetLangAsJson();
319327
}
320328

321329
HTREEITEM JsonViewDlg::InsertToTree(HTREEITEM parent, const std::string& text)
@@ -408,16 +416,16 @@ void JsonViewDlg::ShowContextMenu(HTREEITEM htiNode, LPPOINT lppScreen)
408416
itemFlag = MF_STRING | (bEnableCopyValue ? MF_ENABLED : MF_DISABLED);
409417
AppendMenu(hMenuPopup, itemFlag, IDM_COPY_NODEVALUE, STR_COPYVALUE);
410418

411-
itemFlag = MF_STRING | (bEnableCopyPath ? MF_ENABLED : MF_DISABLED);;
419+
itemFlag = MF_STRING | (bEnableCopyPath ? MF_ENABLED : MF_DISABLED);
412420
AppendMenu(hMenuPopup, itemFlag, IDM_COPY_NODEPATH, STR_COPYPATH);
413421

414422
// separator
415423
AppendMenu(hMenuPopup, MF_SEPARATOR, 0, NULL);
416424

417-
itemFlag = MF_STRING | (bEnableExpand ? MF_ENABLED : MF_DISABLED);;
425+
itemFlag = MF_STRING | (bEnableExpand ? MF_ENABLED : MF_DISABLED);
418426
AppendMenu(hMenuPopup, itemFlag, IDM_EXPANDALL, STR_EXPANDALL);
419427

420-
itemFlag = MF_STRING | (bEnableCollapse ? MF_ENABLED : MF_DISABLED);;
428+
itemFlag = MF_STRING | (bEnableCollapse ? MF_ENABLED : MF_DISABLED);
421429
AppendMenu(hMenuPopup, itemFlag, IDM_COLLAPSEALL, STR_COLLAPSEALL);
422430

423431
// Open menu

0 commit comments

Comments
 (0)