@@ -96,6 +96,14 @@ class QX_CORE_EXPORT File
9696 QString string () const ;
9797};
9898
99+ class QX_CORE_EXPORT Data
100+ {
101+ public:
102+ Data ();
103+
104+ QString string () const ;
105+ };
106+
99107class QX_CORE_EXPORT Document
100108{
101109private:
@@ -145,7 +153,7 @@ class QX_CORE_EXPORT ArrayElement
145153 QString string () const ;
146154};
147155
148- using ContextNode = std::variant<File, Document, Object, ObjectKey, Array, ArrayElement>;
156+ using ContextNode = std::variant<File, Data, Document, Object, ObjectKey, Array, ArrayElement>;
149157
150158} // namespace QxJson
151159
@@ -163,6 +171,7 @@ class QX_CORE_EXPORT JsonError final : public AbstractError<"Qx::JsonError", 5>
163171 TypeMismatch,
164172 EmptyDoc,
165173 InvalidValue,
174+ InvalidData,
166175 MissingFile,
167176 InaccessibleFile,
168177 FileReadError,
@@ -177,6 +186,7 @@ class QX_CORE_EXPORT JsonError final : public AbstractError<"Qx::JsonError", 5>
177186 {TypeMismatch, u" Value type mismatch." _s},
178187 {EmptyDoc, u" The document is empty." _s},
179188 {InvalidValue, u" Invalid value for type." _s},
189+ {InvalidData, u" Data parse error." _s},
180190 {MissingFile, u" File does not exist." _s},
181191 {InaccessibleFile, u" Cannot open the file." _s},
182192 {FileReadError, u" File read error." _s},
@@ -289,6 +299,7 @@ static inline const QString ERR_CONV_TYPE = u"JSON Error: Converting value to %1
289299static inline const QString ERR_NO_KEY = u" JSON Error: Could not retrieve key '%1'." _s;
290300static inline const QString ERR_PARSE_DOC = u" JSON Error: Could not parse JSON document." _s;
291301static inline const QString ERR_READ_FILE = u" JSON Error: Could not read JSON file." _s;
302+ static inline const QString ERR_READ_DATA = u" JSON Error: Could not read JSON data." _s;
292303static inline const QString ERR_WRITE_FILE = u" JSON Error: Could not write JSON file." _s;
293304
294305// -Structs---------------------------------------------------------------
@@ -788,10 +799,45 @@ void serializeJson(QJsonDocument& serialized, const T& root)
788799 serialized = QJsonDocument (QxJson::Converter<T>::toJson (root));
789800}
790801
802+ template <typename T>
803+ requires json_root<T>
804+ JsonError parseJson (T& parsed, const QByteArray& data)
805+ {
806+ // Check for no data
807+ if (data.isEmpty ())
808+ return JsonError (QxJsonPrivate::ERR_READ_DATA, JsonError::EmptyDoc).withContext (QxJson::Data ());
809+
810+ // Basic parse
811+ QJsonParseError jpe;
812+ QJsonDocument jd = QJsonDocument::fromJson (data, &jpe);
813+
814+ if (jpe.error != jpe.NoError )
815+ return JsonError (QxJsonPrivate::ERR_READ_DATA, JsonError::InvalidData).withContext (QxJson::Data ());
816+
817+ // True parse
818+ return parseJson (parsed, jd).withContext (QxJson::Data ());
819+ }
820+
821+ template <typename T>
822+ requires json_root<T>
823+ void serializeJson (QByteArray& serialized, const T& root, QJsonDocument::JsonFormat fmt = QJsonDocument::Indented)
824+ {
825+ // Ensure buffer is clear
826+ serialized.clear ();
827+
828+ // Create document
829+ QJsonDocument jd;
830+ serializeJson (jd, root);
831+
832+ // Write data
833+ serialized = jd.toJson (fmt);
834+ }
835+
791836template <typename T>
792837 requires json_root<T>
793838JsonError parseJson (T& parsed, QFile& file)
794839{
840+ // NOTE: Don't utilize the QByteArray "data" overload here as we would lose the better error info
795841 if (!file.exists ())
796842 return JsonError (QxJsonPrivate::ERR_READ_FILE, JsonError::MissingFile).withContext (QxJson::File (file.fileName ()));
797843
@@ -828,7 +874,7 @@ JsonError parseJson(T& parsed, QFile& file)
828874
829875template <typename T>
830876 requires json_root<T>
831- JsonError serializeJson (QFile& serialized, const T& root)
877+ JsonError serializeJson (QFile& serialized, const T& root, QJsonDocument::JsonFormat fmt = QJsonDocument::Indented )
832878{
833879 // Close and re-open file, if open, to ensure correct mode and start of file
834880 if (serialized.isOpen ())
@@ -840,15 +886,9 @@ JsonError serializeJson(QFile& serialized, const T& root)
840886 // Close file when finished
841887 QScopeGuard fileGuard ([&serialized]{ serialized.close (); });
842888
843- // Create document
844- QJsonDocument jd;
845- serializeJson (jd, root);
846-
847- // Write data
848- QByteArray jsonData = jd.toJson ();
849- if (jsonData.isEmpty ())
850- return JsonError (); // No-op
851-
889+ // Serialize
890+ QByteArray jsonData;
891+ serializeJson (jsonData, root, fmt);
852892 if (serialized.write (jsonData) != jsonData.size ())
853893 return JsonError (QxJsonPrivate::ERR_WRITE_FILE, JsonError::FileWriteError).withContext (QxJson::File (serialized.fileName (), serialized.errorString ()));
854894
@@ -866,11 +906,11 @@ JsonError parseJson(T& parsed, const QString& filePath)
866906
867907template <typename T>
868908 requires json_root<T>
869- JsonError serializeJson (const QString& serializedPath, const T& root)
909+ JsonError serializeJson (const QString& serializedPath, const T& root, QJsonDocument::JsonFormat fmt = QJsonDocument::Indented )
870910{
871911 QFile file (serializedPath);
872912
873- return serializeJson (file, root);
913+ return serializeJson (file, root, fmt );
874914}
875915
876916QX_CORE_EXPORT QList<QJsonValue> findAllValues (const QJsonValue& rootValue, QStringView key);
0 commit comments