1 /* Copyright 2014, Uwe L. Korn <uwelk@xhochy.com> 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in all 11 * copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 * SOFTWARE. 20 */ 21 22 #include "Json.h" 23 24 // Qt version specific includes 25 #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) 26 #include <QJsonDocument> 27 #include <QMetaProperty> 28 #include <QVariantHash> 29 #else 30 #include <qjson/parser.h> 31 #include <qjson/qobjecthelper.h> 32 #include <qjson/serializer.h> 33 #endif 34 35 namespace QJsonWrapper 36 { 37 38 QVariantMap qobject2qvariant(const QObject * object)39 qobject2qvariant( const QObject *object ) 40 { 41 #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) 42 QVariantMap map; 43 if ( !object ) 44 { 45 return map; 46 } 47 48 const QMetaObject *metaObject = object->metaObject(); 49 for ( int i = 0; i < metaObject->propertyCount(); ++i ) 50 { 51 QMetaProperty metaproperty = metaObject->property( i ); 52 if ( metaproperty.isReadable() ) 53 { 54 map[ QLatin1String( metaproperty.name() ) ] = object->property( metaproperty.name() ); 55 } 56 } 57 return map; 58 #else 59 return QJson::QObjectHelper::qobject2qvariant( object ); 60 #endif 61 } 62 63 64 void qvariant2qobject(const QVariantMap & variant,QObject * object)65 qvariant2qobject( const QVariantMap &variant, QObject *object ) 66 { 67 #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) 68 for ( QVariantMap::const_iterator iter = variant.begin(); iter != variant.end(); ++iter ) 69 { 70 QVariant property = object->property( iter.key().toLatin1() ); 71 Q_ASSERT( property.isValid() ); 72 if ( property.isValid() ) 73 { 74 QVariant value = iter.value(); 75 if ( value.canConvert( property.type() ) ) 76 { 77 value.convert( property.type() ); 78 object->setProperty( iter.key().toLatin1(), value ); 79 } 80 else if ( QString( QLatin1String( "QVariant" ) ).compare( QLatin1String( property.typeName() ) ) == 0 ) 81 { 82 object->setProperty( iter.key().toLatin1(), value ); 83 } 84 } 85 } 86 #else 87 QJson::QObjectHelper::qvariant2qobject( variant, object ); 88 #endif 89 } 90 91 92 QVariant parseJson(const QByteArray & jsonData,bool * ok,QByteArray * errorString)93 parseJson( const QByteArray &jsonData, bool *ok, QByteArray *errorString ) 94 { 95 #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) 96 QJsonParseError error; 97 QJsonDocument doc = QJsonDocument::fromJson( jsonData, &error ); 98 if ( ok ) 99 { 100 *ok = ( error.error == QJsonParseError::NoError ); 101 } 102 if ( errorString && !ok ) 103 { 104 *errorString = error.errorString().toUtf8(); 105 } 106 return doc.toVariant(); 107 #else 108 QJson::Parser p; 109 QVariant variant = p.parse( jsonData, ok ); 110 if ( errorString && !ok ) 111 { 112 *errorString = p.errorString().toUtf8(); 113 } 114 return variant; 115 #endif 116 } 117 118 119 QByteArray toJson(const QVariant & variant,bool * ok,QByteArray * errorString,bool indented)120 toJson( const QVariant &variant, bool *ok, QByteArray *errorString, bool indented ) 121 { 122 #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) 123 QVariant _variant = variant; 124 if ( variant.type() == QVariant::Hash ) 125 { 126 // QJsonDocument cannot deal with QVariantHash, so convert. 127 const QVariantHash hash = variant.toHash(); 128 QVariantMap map; 129 QHashIterator<QString, QVariant> it( hash ); 130 while ( it.hasNext() ) 131 { 132 it.next(); 133 map.insert( it.key(), it.value() ); 134 } 135 _variant = map; 136 } 137 138 QJsonDocument doc = QJsonDocument::fromVariant( _variant ); 139 if ( ok ) 140 { 141 *ok = !doc.isNull(); 142 } 143 if ( errorString && !ok ) 144 { 145 *errorString = QByteArray( "Failed to convert from variant" ); 146 } 147 return doc.toJson( indented ? QJsonDocument::Indented : QJsonDocument::Compact ); 148 #else 149 QJson::Serializer serializer; 150 serializer.setIndentMode( indented ? QJson::IndentFull : QJson::IndentCompact ); 151 QByteArray jsondata = serializer.serialize( variant, ok ); 152 if ( errorString && !ok ) 153 { 154 *errorString = serializer.errorMessage().toUtf8(); 155 } 156 return jsondata; 157 #endif 158 } 159 160 } 161