1313#include < QtConcurrent>
1414#include < QUrl>
1515
16+ #include < simdjson.h>
17+
1618#include " apputils.h"
1719#include " qcompress.h"
1820#include " value-editor/largetextmodel.h"
@@ -23,7 +25,8 @@ bool QmlUtils::isBinaryString(const QVariant &value) {
2325 if (!value.canConvert (QVariant::ByteArray)) {
2426 return false ;
2527 }
26- QByteArray val = value.toByteArray ();
28+ QByteArray val = value.toByteArray ();
29+
2730 return isBinary (val);
2831}
2932
@@ -44,6 +47,132 @@ QVariant QmlUtils::b64toByteArray(const QVariant &value)
4447 return QVariant (QByteArray::fromBase64 (value.toString ().toUtf8 ()));
4548}
4649
50+ QByteArray QmlUtils::minifyJSON (const QVariant &value)
51+ {
52+ if (!value.canConvert (QVariant::ByteArray)) {
53+ return QByteArray ();
54+ }
55+
56+ QByteArray val = value.toByteArray ();
57+
58+ QByteArray minified;
59+ minified.resize (val.size ());
60+
61+ size_t new_length{};
62+ auto error = simdjson::minify (val.data (), val.size (), minified.data (), new_length);
63+
64+ if (error != 0 ) {
65+ qDebug () << " Failed to minify JSON with simdjson:" << error;
66+ return QByteArray ();
67+ }
68+
69+ minified.resize (new_length);
70+
71+ return minified;
72+ }
73+
74+ QByteArray QmlUtils::prettyPrintJSON (const QVariant &value)
75+ {
76+ if (!value.canConvert (QVariant::ByteArray)) {
77+ return QByteArray ();
78+ }
79+
80+ QByteArray val = value.toByteArray ();
81+ QByteArray result;
82+ result.reserve (val.size () * 32 );
83+
84+ const QByteArray whitespace (" " );
85+ long level = 0 ;
86+ bool ignore_next = false ;
87+ bool in_string = false ;
88+
89+ // Based on https://github.com/alula/json-beautifier/blob/master/src/beautify.cpp
90+ for (auto c : qAsConst (val)) {
91+ switch (c) {
92+ case ' [' :
93+ case ' {' :
94+ if (in_string) {
95+ result.append (c);
96+ break ;
97+ }
98+ level++;
99+ result.append (c);
100+ result.append (" \n " );
101+ for (long i = 0 ; i < level; i++) result.append (whitespace);
102+ break ;
103+ case ' ]' :
104+ case ' }' :
105+ if (in_string) {
106+ result.append (c);
107+ break ;
108+ }
109+ if (level != 0 ) level--;
110+ result.append (" \n " );
111+ for (long i = 0 ; i < level; i++) result.append (whitespace);
112+ result.append (c);
113+ break ;
114+ case ' ,' :
115+ if (in_string) {
116+ result.append (' ,' );
117+ break ;
118+ }
119+ result.append (' ,' );
120+ result.append (" \n " );
121+ for (long i = 0 ; i < level; i++) result.append (whitespace);
122+ break ;
123+ case ' \\ ' :
124+ if (ignore_next)
125+ ignore_next = false ;
126+ else
127+ ignore_next = true ;
128+ result.append (" \\ " );
129+ break ;
130+ case ' "' :
131+ if (!ignore_next) in_string = !in_string;
132+ result.append (" \" " );
133+ break ;
134+ case ' ' :
135+ if (in_string) result.append (" " );
136+ break ;
137+ case ' :' :
138+ result.append (" :" );
139+ if (!in_string) result.append (" " );
140+ break ;
141+ case ' \r ' :
142+ case ' \n ' :
143+ break ;
144+ default :
145+ if (ignore_next) ignore_next = false ;
146+ result.append (c);
147+ break ;
148+ }
149+ }
150+
151+ return result;
152+ }
153+
154+ bool QmlUtils::isJSON (const QVariant &value)
155+ {
156+ if (!value.canConvert (QVariant::ByteArray)) {
157+ return false ;
158+ }
159+
160+ QByteArray val = value.toByteArray ();
161+ int originalSize = val.size ();
162+ val.resize (val.size () + simdjson::SIMDJSON_PADDING);
163+
164+ simdjson::dom::parser parser;
165+ simdjson::dom::element data;
166+ auto error = parser.parse (val.data (), originalSize, false ).get (data);
167+
168+ if (error != simdjson::SUCCESS && error != simdjson::NUMBER_ERROR) {
169+ qDebug () << " JSON is not valid:" << simdjson::error_message (error);
170+ return false ;
171+ }
172+
173+ return true ;
174+ }
175+
47176QVariant QmlUtils::decompress (const QVariant &value) {
48177 if (!value.canConvert (QVariant::ByteArray)) {
49178 return 0 ;
0 commit comments