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( i >= args.count() ) 00275 { 00276 qWarning("Not enough arguments (expected %d, got %d).", i, args.count()); 00277 exit(1); 00278 } 00279 QString s = QString::fromLocal8Bit( args[ i ] ); 00280 00281 if (type == "QStringList") 00282 type = "QValueList<QString>"; 00283 if (type == "QCStringList") 00284 type = "QValueList<QCString>"; 00285 00286 if ( type == "int" ) 00287 arg << s.toInt(); 00288 else if ( type == "uint" ) 00289 arg << s.toUInt(); 00290 else if ( type == "unsigned" ) 00291 arg << s.toUInt(); 00292 else if ( type == "unsigned int" ) 00293 arg << s.toUInt(); 00294 else if ( type == "Q_INT32" ) 00295 arg << s.toInt(); 00296 else if ( type == "Q_INT64" ) { 00297 QVariant qv = QVariant( s ); 00298 arg << qv.toLongLong(); 00299 } 00300 else if ( type == "Q_UINT32" ) 00301 arg << s.toUInt(); 00302 else if ( type == "Q_UINT64" ) { 00303 QVariant qv = QVariant( s ); 00304 arg << qv.toULongLong(); 00305 } 00306 else if ( type == "long" ) 00307 arg << s.toLong(); 00308 else if ( type == "long int" ) 00309 arg << s.toLong(); 00310 else if ( type == "unsigned long" ) 00311 arg << s.toULong(); 00312 else if ( type == "unsigned long int" ) 00313 arg << s.toULong(); 00314 else if ( type == "float" ) 00315 arg << s.toFloat(); 00316 else if ( type == "double" ) 00317 arg << s.toDouble(); 00318 else if ( type == "bool" ) 00319 arg << mkBool( s ); 00320 else if ( type == "QString" ) 00321 arg << s; 00322 else if ( type == "QCString" ) 00323 arg << QCString( args[ i ] ); 00324 else if ( type == "QColor" ) 00325 arg << mkColor( s ); 00326 else if ( type == "QPoint" ) 00327 arg << mkPoint( s ); 00328 else if ( type == "QSize" ) 00329 arg << mkSize( s ); 00330 else if ( type == "QRect" ) 00331 arg << mkRect( s ); 00332 else if ( type == "KURL" ) 00333 arg << KURL( s ); 00334 else if ( type == "QVariant" ) { 00335 if ( s == "true" || s == "false" ) 00336 arg << QVariant( mkBool( s ), 42 ); 00337 else if ( s.left( 4 ) == "int(" ) 00338 arg << QVariant( s.mid(4, s.length()-5).toInt() ); 00339 else if ( s.left( 7 ) == "QPoint(" ) 00340 arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) ); 00341 else if ( s.left( 6 ) == "QSize(" ) 00342 arg << QVariant( mkSize( s.mid(6, s.length()-7) ) ); 00343 else if ( s.left( 6 ) == "QRect(" ) 00344 arg << QVariant( mkRect( s.mid(6, s.length()-7) ) ); 00345 else if ( s.left( 7 ) == "QColor(" ) 00346 arg << QVariant( mkColor( s.mid(7, s.length()-8) ) ); 00347 else 00348 arg << QVariant( s ); 00349 } else if ( type.startsWith("QValueList<") || 00350 type == "KURL::List" ) { 00351 if ( type == "KURL::List" ) 00352 type = "KURL"; 00353 else 00354 type = type.mid(11, type.length() - 12); 00355 QStringList list; 00356 QString delim = s; 00357 if (delim == "[") 00358 delim = "]"; 00359 if (delim == "(") 00360 delim = ")"; 00361 i++; 00362 QByteArray dummy_data; 00363 QDataStream dummy_arg(dummy_data, IO_WriteOnly); 00364 00365 uint j = i; 00366 uint count = 0; 00367 // Parse list to get the count 00368 while (true) { 00369 if( j > args.count() ) 00370 { 00371 qWarning("List end-delimiter '%s' not found.", delim.latin1()); 00372 exit(1); 00373 } 00374 if( QString::fromLocal8Bit( args[ j ] ) == delim ) 00375 break; 00376 marshall( dummy_arg, args, j, type ); 00377 count++; 00378 } 00379 arg << (Q_UINT32) count; 00380 // Parse the list for real 00381 while (true) { 00382 if( i > args.count() ) 00383 { 00384 qWarning("List end-delimiter '%s' not found.", delim.latin1()); 00385 exit(1); 00386 } 00387 if( QString::fromLocal8Bit( args[ i ] ) == delim ) 00388 break; 00389 marshall( arg, args, i, type ); 00390 } 00391 } else { 00392 qWarning( "cannot handle datatype '%s'", type.latin1() ); 00393 exit(1); 00394 } 00395 i++; 00396 } 00397 00398 // vim: set noet ts=8 sts=4 sw=4: 00399