Consolix
Loading...
Searching...
No Matches
json_utils.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _CONSOLIX_JSON_UTILS_HPP_INCLUDED
3#define _CONSOLIX_JSON_UTILS_HPP_INCLUDED
4
7
8#include <string>
9#include <algorithm>
10
11namespace consolix {
12
17 inline bool check_escaped(const std::string &json_string, size_t quote_position) {
18 int backslash_count = 0;
19 for (ptrdiff_t i = quote_position - 1; i >= 0 && json_string[i] == '\\'; --i) {
20 ++backslash_count;
21 }
22 return (backslash_count % 2) != 0;
23 };
24
40 const std::string &json_string,
41 bool with_whitespace = false,
42 bool preserve_newlines = true) {
43 enum CommentType { NO_COMMENT, SINGLE_COMMENT, MULTI_COMMENT };
44 CommentType inside_comment = CommentType::NO_COMMENT;
45 bool inside_string = false;
46
47 size_t offset = 0;
48 const size_t json_string_size = json_string.size();
49 const size_t json_max_index = json_string_size - 1;
50 std::string result;
51 result.reserve(json_string_size);
52
53 for (size_t i = 0; i < json_string_size; ++i) {
54 const char current_character = json_string[i];
55 const char next_character = i < json_max_index ? json_string[i + 1] : 0;
56
57 if (inside_comment == CommentType::NO_COMMENT && current_character == '"') {
58 if (!check_escaped(json_string, i)) inside_string = !inside_string;
59 }
60
61 if (inside_string) continue;
62
63 switch (inside_comment) {
64 case CommentType::NO_COMMENT:
65 if (current_character == '#' || (current_character == '/' && next_character == '/')) {
66 inside_comment = SINGLE_COMMENT;
67 result.append(json_string, offset, i - offset);
68 offset = i;
69 i += (next_character == '/') ? 2 : 1;
70 continue;
71 } else
72 if (current_character == '/' && next_character == '*') {
73 inside_comment = MULTI_COMMENT;
74 result.append(json_string, offset, i - offset);
75 offset = i;
76 ++i;
77 continue;
78 }
79 break;
80 case CommentType::SINGLE_COMMENT:
81 if ((current_character == '\r' && next_character == '\n') || current_character == '\n') {
82 inside_comment = NO_COMMENT;
83 if (with_whitespace) {
84 result.append(std::string(i - offset, ' '));
85 if (current_character == '\r') {
86 result += "\r\n";
87 i += 2;
88 } else {
89 result += '\n';
90 ++i;
91 }
92 } else {
93 i += (current_character == '\r') ? 2 : 1;
94 }
95 offset = i;
96 continue;
97 }
98 break;
99 case CommentType::MULTI_COMMENT:
100 if (current_character == '*' && next_character == '/') {
101 inside_comment = CommentType::NO_COMMENT;
102 ++i;
103 if (with_whitespace) {
104 if (preserve_newlines) {
105 std::string temp = json_string.substr(offset, i - offset + 1);
106 std::replace_if(temp.begin(), temp.end(), [](char ch){
107 return ch != '\n' && ch != '\r';
108 }, ' ');
109 result += temp;
110 } else {
111 result.append(std::string(i - offset + 1, ' '));
112 }
113 }
114 offset = i + 1;
115 continue;
116 }
117 break;
118 default:
119 break;
120 };
121 }
122
123 switch (inside_comment) {
124 case CommentType::NO_COMMENT:
125 result += json_string.substr(offset);
126 break;
127 case CommentType::SINGLE_COMMENT:
128 if (with_whitespace) {
129 result.append(std::string(json_max_index - offset, ' '));
130 }
131 break;
132 case CommentType::MULTI_COMMENT:
133 if (with_whitespace) {
134 if (preserve_newlines) {
135 std::string temp = json_string.substr(offset, json_max_index - offset);
136 std::replace_if(temp.begin(), temp.end(), [](char ch){
137 return ch != '\n' && ch != '\r';
138 }, ' ');
139 result += temp;
140 } else {
141 result.append(std::string(json_max_index - offset, ' '));
142 }
143 }
144 break;
145 default:
146 break;
147 };
148 return result;
149 };
150} // namespace consolix
151
152#endif // _CONSOLIX_JSON_UTILS_HPP_INCLUDED
< Utility modules and helpers.
*The resulting JSON string may optionally retain whitespace or newlines *where the comments were removed **param json_string The JSON string to process *param with_whitespace If comments are replaced with equivalent whitespace *If comments are removed without leaving whitespace *param preserve_newlines If true and with_whitespace is newline characters *in comments are preserved all characters in the *comments are replaced with whitespace *return A JSON string with comments removed *std::string strip_json_comments(const std::string &json_string, bool with_whitespace=false, bool preserve_newlines=true)
bool check_escaped(const std::string &json_string, size_t quote_position)
Checks if a character in a JSON string is escaped.