marshall.cpp

00001 /*****************************************************************
00002 Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00017 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00018 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00019 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00020 
00021 ******************************************************************/
00022 
00023 #define KDE_QT_ONLY
00024 #include "../../kdecore/kurl.cpp"
00025 
00026 bool mkBool( const QString& s )
00027 {
00028     if ( s.lower()  == "true" )
00029     return true;
00030     if ( s.lower()  == "yes" )
00031     return true;
00032     if ( s.lower()  == "on" )
00033     return true;
00034     if ( s.toInt() != 0 )
00035     return true;
00036 
00037     return false;
00038 }
00039 
00040 QPoint mkPoint( const QString &str )
00041 {
00042     const char *s = str.latin1();
00043     char *end;
00044     while(*s && !isdigit(*s) && *s != '-') s++;
00045     int x = strtol(s, &end, 10);
00046     s = (const char *)end;
00047     while(*s && !isdigit(*s) && *s != '-') s++;
00048     int y = strtol(s, &end, 10);
00049     return QPoint( x, y );
00050 }
00051 
00052 QSize mkSize( const QString &str )
00053 {
00054     const char *s = str.latin1();
00055     char *end;
00056     while(*s && !isdigit(*s) && *s != '-') s++;
00057     int w = strtol(s, &end, 10);
00058     s = (const char *)end;
00059     while(*s && !isdigit(*s) && *s != '-') s++;
00060     int h = strtol(s, &end, 10);
00061     return QSize( w, h );
00062 }
00063 
00064 QRect mkRect( const QString &str )
00065 {
00066     const char *s = str.latin1();
00067     char *end;
00068     while(*s && !isdigit(*s) && *s != '-') s++;
00069     int p1 = strtol(s, &end, 10);
00070     s = (const char *)end;
00071     bool legacy = (*s == 'x');
00072     while(*s && !isdigit(*s) && *s != '-') s++;
00073     int p2 = strtol(s, &end, 10);
00074     s = (const char *)end;
00075     while(*s && !isdigit(*s) && *s != '-') s++;
00076     int p3 = strtol(s, &end, 10);
00077     s = (const char *)end;
00078     while(*s && !isdigit(*s) && *s != '-') s++;
00079     int p4 = strtol(s, &end, 10);
00080     if (legacy)
00081     {
00082        return QRect( p3, p4, p1, p2 );
00083     }
00084     return QRect( p1, p2, p3, p4 );
00085 }
00086 
00087 QColor mkColor( const QString& s )
00088 {
00089     QColor c;
00090     c.setNamedColor(s);
00091     return c;
00092 }
00093 
00094 const char *qStringToC(const QCString &s)
00095 {
00096    if (s.isEmpty())
00097       return "";
00098    return s.data();
00099 }
00100 
00101 QCString demarshal( QDataStream &stream, const QString &type )
00102 {
00103     QCString result;
00104 
00105     if ( type == "int" || type == "Q_INT32" )
00106     {
00107         int i;
00108         stream >> i;
00109         result.setNum( i );
00110     } else if ( type == "uint" || type == "Q_UINT32" || type == "unsigned int" )
00111     {
00112         uint i;
00113         stream >> i;
00114         result.setNum( i );
00115     } else if ( type == "long" || type == "long int" )
00116     {
00117         long l;
00118         stream >> l;
00119         result.setNum( l );
00120     } else if ( type == "unsigned long" || type == "unsigned long int" )
00121     {
00122         unsigned long l;
00123         stream >> l;
00124         result.setNum( l );
00125     } else if ( type == "float" )
00126     {
00127         float f;
00128         stream >> f;
00129         result.setNum( f, 'f' );
00130     } else if ( type == "double" )
00131     {
00132         double d;
00133         stream >> d;
00134         result.setNum( d, 'f' );
00135     } else if ( type == "Q_INT64" ) {
00136         Q_INT64 i;
00137         stream >> i;
00138         result.sprintf( "%lld", i );
00139     } else if ( type == "Q_UINT64" ) {
00140         Q_UINT64 i;
00141         stream >> i;
00142         result.sprintf( "%llu", i );
00143     } else if ( type == "bool" )
00144     {
00145         bool b;
00146         stream >> b;
00147         result = b ? "true" : "false";
00148     } else if ( type == "QString" )
00149     {
00150         QString s;
00151         stream >> s;
00152         result = s.local8Bit();
00153     } else if ( type == "QCString" )
00154     {
00155         stream >> result;
00156     } else if ( type == "QCStringList" )
00157     {
00158         return demarshal( stream, "QValueList<QCString>" );
00159     } else if ( type == "QStringList" )
00160     {
00161         return demarshal( stream, "QValueList<QString>" );
00162     } else if ( type == "QColor" )
00163     {
00164         QColor c;
00165         stream >> c;
00166         result = c.name().local8Bit();
00167     } else if ( type == "QSize" )
00168     {
00169         QSize s;
00170         stream >> s;
00171         result.sprintf( "%dx%d", s.width(), s.height() );
00172     } else if ( type == "QPixmap" || type == "QImage" ) 
00173     {
00174         QImage i;
00175         stream >> i;
00176         QByteArray ba;
00177         QBuffer buf( ba );
00178         buf.open( IO_WriteOnly );
00179         i.save( &buf, "XPM" );
00180         result = ba;
00181     } else if ( type == "QPoint" )
00182     {
00183         QPoint p;
00184         stream >> p;
00185         result.sprintf( "+%d+%d", p.x(), p.y() );
00186     } else if ( type == "QRect" )
00187     {
00188         QRect r;
00189         stream >> r;
00190         result.sprintf( "%dx%d+%d+%d", r.width(), r.height(), r.x(), r.y() );
00191     } else if ( type == "QVariant" )
00192     {
00193         Q_INT32 type;
00194         stream >> type;
00195         return demarshal( stream, QVariant::typeToName( (QVariant::Type)type ) );
00196     } else if ( type == "DCOPRef" )
00197     {
00198         DCOPRef r;
00199         stream >> r;
00200         result.sprintf( "DCOPRef(%s,%s)", qStringToC(r.app()), qStringToC(r.object()) );
00201     } else if ( type == "KURL" )
00202     {
00203         KURL r;
00204         stream >> r;
00205         result = r.url().local8Bit();
00206     } else if ( type.left( 11 ) == "QValueList<" )
00207     {
00208         if ( (uint)type.find( '>', 11 ) != type.length() - 1 )
00209             return result;
00210 
00211         QString nestedType = type.mid( 11, type.length() - 12 );
00212 
00213         if ( nestedType.isEmpty() )
00214             return result;
00215 
00216         Q_UINT32 count;
00217         stream >> count;
00218 
00219         Q_UINT32 i = 0;
00220         for (; i < count; ++i )
00221         {
00222             QCString arg = demarshal( stream, nestedType );
00223             result += arg;
00224 
00225             if ( i < count - 1 )
00226                 result += '\n';
00227         }
00228     } else if ( type.left( 5 ) == "QMap<" )
00229     {
00230         int commaPos = type.find( ',', 5 );
00231 
00232         if ( commaPos == -1 )
00233             return result;
00234 
00235         if ( (uint)type.find( '>', commaPos ) != type.length() - 1 )
00236             return result;
00237 
00238         QString keyType = type.mid( 5, commaPos - 5 );
00239         QString valueType = type.mid( commaPos + 1, type.length() - commaPos - 2 );
00240 
00241         Q_UINT32 count;
00242         stream >> count;
00243 
00244         Q_UINT32 i = 0;
00245         for (; i < count; ++i )
00246         {
00247             QCString key = demarshal( stream, keyType );
00248 
00249             if ( key.isEmpty() )
00250                 continue;
00251 
00252             QCString value = demarshal( stream, valueType );
00253 
00254             if ( value.isEmpty() )
00255                 continue;
00256 
00257             result += key + "->" + value;
00258 
00259             if ( i < count - 1 )
00260                 result += '\n';
00261         }
00262     }
00263     else
00264     {
00265        result.sprintf( "<%s>", type.latin1());
00266     }
00267 
00268     return result;
00269 
00270 }
00271 
00272 void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
00273 {
00274     if (type == "QStringList")
00275        type = "QValueList<QString>";
00276     if (type == "QCStringList")
00277        type = "QValueList<QCString>";
00278     if( i >= args.count() )
00279     {
00280     qWarning("Not enough arguments.");
00281     exit(1);
00282     }
00283     QString s = QString::fromLocal8Bit( args[ i ] );
00284 
00285     if ( type == "int" )
00286     arg << s.toInt();
00287     else if ( type == "uint" )
00288     arg << s.toUInt();
00289     else if ( type == "unsigned" )
00290     arg << s.toUInt();
00291     else if ( type == "unsigned int" )
00292     arg << s.toUInt();
00293     else if ( type == "Q_INT32" )
00294     arg << s.toInt();
00295     else if ( type == "Q_INT64" ) {
00296     QVariant qv = QVariant( s );
00297     arg << qv.toLongLong();
00298     }
00299     else if ( type == "Q_UINT32" )
00300     arg << s.toUInt();
00301     else if ( type == "Q_UINT64" ) {
00302     QVariant qv = QVariant( s );
00303     arg << qv.toULongLong();
00304     }
00305     else if ( type == "long" )
00306     arg << s.toLong();
00307     else if ( type == "long int" )
00308     arg << s.toLong();
00309     else if ( type == "unsigned long" )
00310     arg << s.toULong();
00311     else if ( type == "unsigned long int" )
00312     arg << s.toULong();
00313     else if ( type == "float" )
00314     arg << s.toFloat();
00315     else if ( type == "double" )
00316     arg << s.toDouble();
00317     else if ( type == "bool" )
00318     arg << mkBool( s );
00319     else if ( type == "QString" )
00320     arg << s;
00321     else if ( type == "QCString" )
00322     arg << QCString( args[ i ] );
00323     else if ( type == "QColor" )
00324     arg << mkColor( s );
00325     else if ( type == "QPoint" )
00326     arg << mkPoint( s );
00327     else if ( type == "QSize" )
00328     arg << mkSize( s );
00329     else if ( type == "QRect" )
00330     arg << mkRect( s );
00331     else if ( type == "KURL" )
00332     arg << KURL( s );
00333     else if ( type == "QVariant" ) {
00334     if ( s == "true" || s == "false" )
00335         arg << QVariant( mkBool( s ), 42 );
00336     else if ( s.left( 4 ) == "int(" )
00337         arg << QVariant( s.mid(4, s.length()-5).toInt() );
00338     else if ( s.left( 7 ) == "QPoint(" )
00339         arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
00340     else if ( s.left( 6 ) == "QSize(" )
00341         arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
00342     else if ( s.left( 6 ) == "QRect(" )
00343         arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
00344     else if ( s.left( 7 ) == "QColor(" )
00345         arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
00346     else
00347         arg << QVariant( s );
00348     } else if ( type.startsWith("QValueList<") ||
00349             type == "KURL::List" ) {
00350     if ( type == "KURL::List" )
00351             type = "KURL";
00352         else
00353         type = type.mid(11, type.length() - 12);
00354     QStringList list;
00355     QString delim = s;
00356     if (delim == "[")
00357        delim = "]";
00358     if (delim == "(")
00359        delim = ")";
00360     i++;
00361     QByteArray dummy_data;
00362     QDataStream dummy_arg(dummy_data, IO_WriteOnly);
00363 
00364     uint j = i;
00365     uint count = 0;
00366     // Parse list to get the count
00367     while (true) {
00368         if( j > args.count() )
00369         {
00370         qWarning("List end-delimiter '%s' not found.", delim.latin1());
00371         exit(1);
00372         }
00373         if( QString::fromLocal8Bit( args[ j ] ) == delim )
00374         break;
00375         marshall( dummy_arg, args, j, type );
00376         count++;
00377     }
00378     arg << (Q_UINT32) count;
00379     // Parse the list for real
00380     while (true) {
00381         if( i > args.count() )
00382         {
00383         qWarning("List end-delimiter '%s' not found.", delim.latin1());
00384         exit(1);
00385         }
00386         if( QString::fromLocal8Bit( args[ i ] ) == delim )
00387         break;
00388         marshall( arg, args, i, type );
00389     }
00390     } else {
00391     qWarning( "cannot handle datatype '%s'", type.latin1() );
00392     exit(1);
00393     }
00394     i++;
00395 }
00396 
00397 // vim: set noet ts=8 sts=4 sw=4:
00398 
KDE Home | KDE Accessibility Home | Description of Access Keys