00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "serializer.h"
00023
00024 #include <QtCore/QDataStream>
00025 #include <QtCore/QStringList>
00026 #include <QtCore/QVariant>
00027
00028 using namespace QJson;
00029
00030 class Serializer::SerializerPrivate {
00031 };
00032
00033 Serializer::Serializer() : d( new SerializerPrivate ) {
00034 }
00035
00036 Serializer::~Serializer() {
00037 delete d;
00038 }
00039
00040 void Serializer::serialize( const QVariant& v, QIODevice* io, bool* ok )
00041 {
00042 Q_ASSERT( io );
00043 if (!io->isOpen()) {
00044 if (!io->open(QIODevice::WriteOnly)) {
00045 if ( ok != 0 )
00046 *ok = false;
00047 qCritical ("Error opening device");
00048 return;
00049 }
00050 }
00051
00052 if (!io->isWritable()) {
00053 if (ok != 0)
00054 *ok = false;
00055 qCritical ("Device is not readable");
00056 io->close();
00057 return;
00058 }
00059
00060 const QByteArray str = serialize( v );
00061 if ( !str.isNull() ) {
00062 QDataStream stream( io );
00063 stream << str;
00064 } else {
00065 if ( ok )
00066 *ok = false;
00067 }
00068 }
00069
00070 static QString sanitizeString( QString str )
00071 {
00072 str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) );
00073 str.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
00074 str.replace( QLatin1String( "\b" ), QLatin1String( "\\b" ) );
00075 str.replace( QLatin1String( "\f" ), QLatin1String( "\\f" ) );
00076 str.replace( QLatin1String( "\n" ), QLatin1String( "\\n" ) );
00077 str.replace( QLatin1String( "\r" ), QLatin1String( "\\r" ) );
00078 str.replace( QLatin1String( "\t" ), QLatin1String( "\\t" ) );
00079 return QString( QLatin1String( "\"%1\"" ) ).arg( str );
00080 }
00081
00082 static QByteArray join( const QList<QByteArray>& list, const QByteArray& sep ) {
00083 QByteArray res;
00084 Q_FOREACH( const QByteArray& i, list ) {
00085 if ( !res.isEmpty() )
00086 res += sep;
00087 res += i;
00088 }
00089 return res;
00090 }
00091
00092 QByteArray Serializer::serialize( const QVariant &v )
00093 {
00094 QByteArray str;
00095 bool error = false;
00096
00097 if ( ! v.isValid() ) {
00098 str = "null";
00099 } else if ( v.type() == QVariant::List ) {
00100 const QVariantList list = v.toList();
00101 QList<QByteArray> values;
00102 Q_FOREACH( const QVariant& v, list )
00103 {
00104 QByteArray serializedValue = serialize( v );
00105 if ( serializedValue.isNull() ) {
00106 error = true;
00107 break;
00108 }
00109 values << serializedValue;
00110 }
00111 str = "[ " + join( values, ", " ) + " ]";
00112 } else if ( v.type() == QVariant::Map ) {
00113 const QVariantMap vmap = v.toMap();
00114 QMapIterator<QString, QVariant> it( vmap );
00115 str = "{ ";
00116 QList<QByteArray> pairs;
00117 while ( it.hasNext() ) {
00118 it.next();
00119 QByteArray serializedValue = serialize( it.value() );
00120 if ( serializedValue.isNull() ) {
00121 error = true;
00122 break;
00123 }
00124 pairs << sanitizeString( it.key() ).toUtf8() + " : " + serializedValue;
00125 }
00126 str += join( pairs, ", " );
00127 str += " }";
00128 } else if (( v.type() == QVariant::String ) || ( v.type() == QVariant::ByteArray )) {
00129 str = sanitizeString( v.toString() ).toUtf8();
00130 } else if ( v.type() == QVariant::Double ) {
00131 str = QByteArray::number( v.toDouble() );
00132 if( ! str.contains( "." ) && ! str.contains( "e" ) ) {
00133 str += ".0";
00134 }
00135 } else if ( v.type() == QVariant::Bool ) {
00136 str = ( v.toBool() ? "true" : "false" );
00137 } else if ( v.type() == QVariant::ULongLong ) {
00138 str = QByteArray::number( v.value<qulonglong>() );
00139 } else if ( v.canConvert<qlonglong>() ) {
00140 str = QByteArray::number( v.value<qlonglong>() );
00141 } else if ( v.canConvert<QString>() ){
00142
00143 str = sanitizeString( v.toString() ).toUtf8();
00144
00145 } else {
00146 error = true;
00147 }
00148 if ( !error )
00149 return str;
00150 else
00151 return QByteArray();
00152 }