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 "../../tdecore/kurl.cpp" 00025 00026 bool mkBool( const TQString& 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 TQPoint mkPoint( const TQString &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 TQPoint( x, y ); 00050 } 00051 00052 TQSize mkSize( const TQString &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 TQSize( w, h ); 00062 } 00063 00064 TQRect mkRect( const TQString &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 TQRect( p3, p4, p1, p2 ); 00083 } 00084 return TQRect( p1, p2, p3, p4 ); 00085 } 00086 00087 TQColor mkColor( const TQString& s ) 00088 { 00089 TQColor c; 00090 c.setNamedColor(s); 00091 return c; 00092 } 00093 00094 const char *qStringToC(const TQCString &s) 00095 { 00096 if (s.isEmpty()) 00097 return ""; 00098 return s.data(); 00099 } 00100 00101 TQCString demarshal( TQDataStream &stream, const TQString &type ) 00102 { 00103 TQCString result; 00104 00105 if ( type == "int" || type == "TQ_INT32" ) 00106 { 00107 int i; 00108 stream >> i; 00109 result.setNum( i ); 00110 } else if ( type == "uint" || type == "TQ_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 == "TQ_INT64" ) { 00136 TQ_INT64 i; 00137 stream >> i; 00138 result.sprintf( "%lld", i ); 00139 } else if ( type == "TQ_UINT64" ) { 00140 TQ_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 == TQSTRING_OBJECT_NAME_STRING ) 00149 { 00150 TQString s; 00151 stream >> s; 00152 result = s.local8Bit(); 00153 } else if ( type == TQCSTRING_OBJECT_NAME_STRING ) 00154 { 00155 stream >> result; 00156 } else if ( type == "QCStringList" ) 00157 { 00158 return demarshal( stream, TQVALUELIST_OBJECT_NAME_STRING "<" TQCSTRING_OBJECT_NAME_STRING ">" ); 00159 } else if ( type == TQSTRINGLIST_OBJECT_NAME_STRING ) 00160 { 00161 return demarshal( stream, TQVALUELIST_OBJECT_NAME_STRING "<" TQCSTRING_OBJECT_NAME_STRING ">" ); 00162 } else if ( type == TQCOLOR_OBJECT_NAME_STRING ) 00163 { 00164 TQColor c; 00165 stream >> c; 00166 result = TQString(c.name()).local8Bit(); 00167 } else if ( type == TQSIZE_OBJECT_NAME_STRING ) 00168 { 00169 TQSize s; 00170 stream >> s; 00171 result.sprintf( "%dx%d", s.width(), s.height() ); 00172 } else if ( type == TQPIXMAP_OBJECT_NAME_STRING || type == TQIMAGE_OBJECT_NAME_STRING ) 00173 { 00174 TQImage i; 00175 stream >> i; 00176 TQByteArray ba; 00177 TQBuffer buf( ba ); 00178 buf.open( IO_WriteOnly ); 00179 i.save( &buf, "XPM" ); 00180 result = buf.buffer(); 00181 } else if ( type == TQPOINT_OBJECT_NAME_STRING ) 00182 { 00183 TQPoint p; 00184 stream >> p; 00185 result.sprintf( "+%d+%d", p.x(), p.y() ); 00186 } else if ( type == TQRECT_OBJECT_NAME_STRING ) 00187 { 00188 TQRect r; 00189 stream >> r; 00190 result.sprintf( "%dx%d+%d+%d", r.width(), r.height(), r.x(), r.y() ); 00191 } else if ( type == TQVARIANT_OBJECT_NAME_STRING ) 00192 { 00193 TQ_INT32 type; 00194 stream >> type; 00195 return demarshal( stream, TQVariant::typeToName( (TQVariant::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 ) == TQVALUELIST_OBJECT_NAME_STRING "<" ) 00207 { 00208 if ( (uint)type.find( '>', 11 ) != type.length() - 1 ) 00209 return result; 00210 00211 TQString nestedType = type.mid( 11, type.length() - 12 ); 00212 00213 if ( nestedType.isEmpty() ) 00214 return result; 00215 00216 TQ_UINT32 count; 00217 stream >> count; 00218 00219 TQ_UINT32 i = 0; 00220 for (; i < count; ++i ) 00221 { 00222 TQCString arg = demarshal( stream, nestedType ); 00223 result += arg; 00224 00225 if ( i < count - 1 ) 00226 result += '\n'; 00227 } 00228 } else if ( type.left( 5 ) == TQMAP_OBJECT_NAME_STRING "<" ) 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 TQString keyType = type.mid( 5, commaPos - 5 ); 00239 TQString valueType = type.mid( commaPos + 1, type.length() - commaPos - 2 ); 00240 00241 TQ_UINT32 count; 00242 stream >> count; 00243 00244 TQ_UINT32 i = 0; 00245 for (; i < count; ++i ) 00246 { 00247 TQCString key = demarshal( stream, keyType ); 00248 00249 if ( key.isEmpty() ) 00250 continue; 00251 00252 TQCString 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( TQDataStream &arg, QCStringList args, uint &i, TQString type ) 00273 { 00274 if( i >= args.count() ) 00275 { 00276 tqWarning("Not enough arguments (expected %u, got %lu).", i, args.count()); 00277 exit(1); 00278 } 00279 TQString s = TQString::fromLocal8Bit( args[ i ] ); 00280 00281 if (type == TQSTRINGLIST_OBJECT_NAME_STRING) { 00282 type = TQVALUELIST_OBJECT_NAME_STRING "<" TQSTRING_OBJECT_NAME_STRING ">"; 00283 } 00284 if (type == "QCStringList") { 00285 type = TQVALUELIST_OBJECT_NAME_STRING "<" TQSTRING_OBJECT_NAME_STRING ">"; 00286 } 00287 00288 if ( type == "int" ) 00289 arg << s.toInt(); 00290 else if ( type == "uint" ) 00291 arg << s.toUInt(); 00292 else if ( type == "unsigned" ) 00293 arg << s.toUInt(); 00294 else if ( type == "unsigned int" ) 00295 arg << s.toUInt(); 00296 else if ( type == "TQ_INT32" ) 00297 arg << s.toInt(); 00298 else if ( type == "TQ_INT64" ) { 00299 TQVariant qv = TQVariant( s ); 00300 arg << qv.toLongLong(); 00301 } 00302 else if ( type == "TQ_UINT32" ) 00303 arg << s.toUInt(); 00304 else if ( type == "TQ_UINT64" ) { 00305 TQVariant qv = TQVariant( s ); 00306 arg << qv.toULongLong(); 00307 } 00308 else if ( type == "long" ) 00309 arg << s.toLong(); 00310 else if ( type == "long int" ) 00311 arg << s.toLong(); 00312 else if ( type == "unsigned long" ) 00313 arg << s.toULong(); 00314 else if ( type == "unsigned long int" ) 00315 arg << s.toULong(); 00316 else if ( type == "float" ) 00317 arg << s.toFloat(); 00318 else if ( type == "double" ) 00319 arg << s.toDouble(); 00320 else if ( type == "bool" ) 00321 arg << mkBool( s ); 00322 else if ( type == TQSTRING_OBJECT_NAME_STRING ) 00323 arg << s; 00324 else if ( type == TQCSTRING_OBJECT_NAME_STRING ) 00325 arg << TQCString( args[ i ] ); 00326 else if ( type == TQCOLOR_OBJECT_NAME_STRING ) 00327 arg << mkColor( s ); 00328 else if ( type == TQPOINT_OBJECT_NAME_STRING ) 00329 arg << mkPoint( s ); 00330 else if ( type == TQSIZE_OBJECT_NAME_STRING ) 00331 arg << mkSize( s ); 00332 else if ( type == TQRECT_OBJECT_NAME_STRING ) 00333 arg << mkRect( s ); 00334 else if ( type == "KURL" ) 00335 arg << KURL( s ); 00336 else if ( type == TQVARIANT_OBJECT_NAME_STRING ) { 00337 int tqPointKeywordLength = strlen(TQPOINT_OBJECT_NAME_STRING); 00338 int tqSizeKeywordLength = strlen(TQSIZE_OBJECT_NAME_STRING); 00339 int tqRectKeywordLength = strlen(TQRECT_OBJECT_NAME_STRING); 00340 int tqColorKeywordLength = strlen(TQCOLOR_OBJECT_NAME_STRING); 00341 if ( s == "true" || s == "false" ) { 00342 arg << TQVariant( mkBool( s ), 42 ); 00343 } 00344 else if ( s.left( 4 ) == "int(" ) { 00345 arg << TQVariant( s.mid(4, s.length()-5).toInt() ); 00346 } 00347 else if ( s.left( (tqPointKeywordLength+1) ) == TQPOINT_OBJECT_NAME_STRING "(" ) { 00348 arg << TQVariant( mkPoint( s.mid((tqPointKeywordLength+1), s.length()-(tqPointKeywordLength+2)) ) ); 00349 } 00350 else if ( s.left( (tqSizeKeywordLength+1) ) == TQSIZE_OBJECT_NAME_STRING "(" ) { 00351 arg << TQVariant( mkSize( s.mid((tqSizeKeywordLength+1), s.length()-(tqSizeKeywordLength+2)) ) ); 00352 } 00353 else if ( s.left( (tqRectKeywordLength+1) ) == TQRECT_OBJECT_NAME_STRING "(" ) { 00354 arg << TQVariant( mkRect( s.mid((tqRectKeywordLength+1), s.length()-(tqRectKeywordLength+2)) ) ); 00355 } 00356 else if ( s.left( (tqColorKeywordLength+1) ) == TQCOLOR_OBJECT_NAME_STRING "(" ) { 00357 arg << TQVariant( mkColor( s.mid((tqColorKeywordLength+1), s.length()-(tqColorKeywordLength+2)) ) ); 00358 } 00359 else { 00360 arg << TQVariant( s ); 00361 } 00362 } else if ( type.startsWith(TQVALUELIST_OBJECT_NAME_STRING "<") || type == "KURL::List" ) { 00363 if ( type == "KURL::List" ) { 00364 type = "KURL"; 00365 } 00366 else { 00367 int tqValueListKeywordLength = strlen(TQVALUELIST_OBJECT_NAME_STRING); 00368 type = type.mid((tqValueListKeywordLength+1), type.length() - (tqValueListKeywordLength+2)); 00369 } 00370 TQStringList list; 00371 TQString delim = s; 00372 if (delim == "[") 00373 delim = "]"; 00374 if (delim == "(") 00375 delim = ")"; 00376 i++; 00377 TQByteArray dummy_data; 00378 TQDataStream dummy_arg(dummy_data, IO_WriteOnly); 00379 00380 uint j = i; 00381 uint count = 0; 00382 // Parse list to get the count 00383 while (true) { 00384 if( j > args.count() ) 00385 { 00386 tqWarning("List end-delimiter '%s' not found.", delim.latin1()); 00387 exit(1); 00388 } 00389 if( TQString::fromLocal8Bit( args[ j ] ) == delim ) 00390 break; 00391 marshall( dummy_arg, args, j, type ); 00392 count++; 00393 } 00394 arg << (TQ_UINT32) count; 00395 // Parse the list for real 00396 while (true) { 00397 if( i > args.count() ) 00398 { 00399 tqWarning("List end-delimiter '%s' not found.", delim.latin1()); 00400 exit(1); 00401 } 00402 if( TQString::fromLocal8Bit( args[ i ] ) == delim ) 00403 break; 00404 marshall( arg, args, i, type ); 00405 } 00406 } else { 00407 tqWarning( "cannot handle datatype '%s'", type.latin1() ); 00408 exit(1); 00409 } 00410 i++; 00411 } 00412 00413 // vim: set noet ts=8 sts=4 sw=4: 00414