dcop Library API Documentation

stubimpl.cpp

00001 /***************************************************************** 00002 Copyright (c) 1999 Torben Weis <weis@kde.org> 00003 Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org> 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00019 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00020 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00021 00022 ******************************************************************/ 00023 #include <qdom.h> 00024 #include <qfile.h> 00025 #include <qtextstream.h> 00026 #include <qstring.h> 00027 #include <qstringlist.h> 00028 00029 #include <string.h> 00030 #include <stdlib.h> 00031 #include <stdio.h> 00032 #include <unistd.h> 00033 #include "main.h" 00034 #include "type.h" 00035 00036 static bool isIntType( const QString& t ) 00037 { 00038 return ((t == "int") 00039 || (t == "signed int") 00040 || (t == "unsigned int") 00041 || (t == "uint") 00042 || (t == "unsigned") 00043 || (t == "signed short int") 00044 || (t == "signed short") 00045 || (t == "short int") 00046 || (t == "short") 00047 || (t == "unsigned short int") 00048 || (t == "unsigned short") 00049 || (t == "ushort") 00050 || (t == "long int") 00051 || (t == "signed long int") 00052 || (t == "long") 00053 || (t == "signed long") 00054 || (t == "unsigned long int") 00055 || (t == "unsigned long") 00056 || (t == "ulong") 00057 || (t == "char") 00058 || (t == "signed char") 00059 || (t == "unsigned char")); 00060 } 00061 00062 /* 00063 * Writes the stub implementation 00064 */ 00065 void generateStubImpl( const QString& idl, const QString& header, const QString& /*headerBase*/, const QString& filename, QDomElement de ) 00066 { 00067 QFile impl( filename ); 00068 if ( !impl.open( IO_WriteOnly ) ) 00069 qFatal("Could not write to %s", filename.latin1() ); 00070 00071 QTextStream str( &impl ); 00072 00073 str << "/****************************************************************************" << endl; 00074 str << "**" << endl; 00075 str << "** DCOP Stub Implementation created by dcopidl2cpp from " << idl << endl; 00076 str << "**" << endl; 00077 str << "** WARNING! All changes made in this file will be lost!" << endl; 00078 str << "**" << endl; 00079 str << "*****************************************************************************/" << endl; 00080 str << endl; 00081 00082 str << "#include \"" << header << "\"" << endl; 00083 str << "#include <dcopclient.h>" << endl << endl; 00084 str << "#include <kdatastream.h>" << endl; 00085 00086 QDomElement e = de.firstChild().toElement(); 00087 for( ; !e.isNull(); e = e.nextSibling().toElement() ) { 00088 if ( e.tagName() != "CLASS" ) 00089 continue; 00090 QDomElement n = e.firstChild().toElement(); 00091 Q_ASSERT( n.tagName() == "NAME" ); 00092 QString classNameBase = n.firstChild().toText().data(); 00093 QString className_stub = classNameBase + "_stub"; 00094 00095 QString classNameFull = className_stub; // class name with possible namespaces prepended 00096 // namespaces will be removed from className now 00097 int namespace_count = 0; 00098 QString namespace_tmp = className_stub; 00099 str << endl; 00100 for(;;) { 00101 int pos = namespace_tmp.find( "::" ); 00102 if( pos < 0 ) { 00103 className_stub = namespace_tmp; 00104 break; 00105 } 00106 str << "namespace " << namespace_tmp.left( pos ) << " {" << endl; 00107 ++namespace_count; 00108 namespace_tmp = namespace_tmp.mid( pos + 2 ); 00109 } 00110 00111 str << endl; 00112 00113 // Write constructors 00114 str << className_stub << "::" << className_stub << "( const QCString& app, const QCString& obj )" << endl; 00115 str << " : "; 00116 00117 // Always explicitly call DCOPStub constructor, because it's virtual base class. 00118 // Calling other ones doesn't matter, as they don't do anything important. 00119 str << "DCOPStub( app, obj )" << endl; 00120 00121 str << "{" << endl; 00122 str << "}" << endl << endl; 00123 00124 str << className_stub << "::" << className_stub << "( DCOPClient* client, const QCString& app, const QCString& obj )" << endl; 00125 str << " : "; 00126 00127 str << "DCOPStub( client, app, obj )" << endl; 00128 00129 str << "{" << endl; 00130 str << "}" << endl << endl; 00131 00132 str << className_stub << "::" << className_stub << "( const DCOPRef& ref )" << endl; 00133 str << " : "; 00134 00135 str << "DCOPStub( ref )" << endl; 00136 00137 str << "{" << endl; 00138 str << "}" << endl << endl; 00139 00140 // Write marshalling code 00141 QDomElement s = e.firstChild().toElement(); 00142 for( ; !s.isNull(); s = s.nextSibling().toElement() ) { 00143 if (s.tagName() != "FUNC") 00144 continue; 00145 QDomElement r = s.firstChild().toElement(); 00146 Q_ASSERT( r.tagName() == "TYPE" ); 00147 QString result = r.firstChild().toText().data(); 00148 bool async = result == "ASYNC"; 00149 if ( async) { 00150 result = "void"; 00151 str << result << " "; 00152 } else 00153 result = writeType( str, r ); 00154 00155 r = r.nextSibling().toElement(); 00156 Q_ASSERT ( r.tagName() == "NAME" ); 00157 QString funcName = r.firstChild().toText().data(); 00158 str << className_stub << "::" << funcName << "("; 00159 00160 QStringList args; 00161 QStringList argtypes; 00162 bool first = true; 00163 r = r.nextSibling().toElement(); 00164 for( ; !r.isNull(); r = r.nextSibling().toElement() ) { 00165 if ( !first ) 00166 str << ", "; 00167 else 00168 str << " "; 00169 first = false; 00170 Q_ASSERT( r.tagName() == "ARG" ); 00171 QDomElement a = r.firstChild().toElement(); 00172 QString type = writeType( str, a ); 00173 argtypes.append( type ); 00174 args.append( QString("arg" ) + QString::number( args.count() ) ) ; 00175 str << args.last(); 00176 } 00177 if ( !first ) 00178 str << " "; 00179 str << ")"; 00180 00181 //const methods in a stub can't compile, they need to call setStatus() 00182 //if ( s.hasAttribute("qual") ) 00183 // str << " " << s.attribute("qual"); 00184 str << endl; 00185 00186 str << "{" << endl ; 00187 00188 00189 funcName += "("; 00190 first = true; 00191 for( QStringList::Iterator it = argtypes.begin(); it != argtypes.end(); ++it ){ 00192 if ( !first ) 00193 funcName += ","; 00194 first = false; 00195 funcName += *it; 00196 } 00197 funcName += ")"; 00198 00199 if ( async ) { 00200 00201 str << " if ( !dcopClient() ) {"<< endl; 00202 str << "\tsetStatus( CallFailed );" << endl; 00203 str << "\treturn;" << endl; 00204 str << " }" << endl; 00205 00206 str << " QByteArray data;" << endl; 00207 if ( !args.isEmpty() ) { 00208 str << " QDataStream arg( data, IO_WriteOnly );" << endl; 00209 for( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){ 00210 str << " arg << " << *args_count << ";" << endl; 00211 } 00212 } 00213 00214 str << " dcopClient()->send( app(), obj(), \"" << funcName << "\", data );" << endl; 00215 str << " setStatus( CallSucceeded );" << endl; 00216 00217 } else { 00218 00219 if ( result != "void" ) { 00220 str << " " << result << " result"; 00221 if (isIntType( result )) 00222 str << " = 0"; 00223 else if ( result == "bool" ) 00224 str << " = false"; 00225 00226 str << ";" << endl; 00227 } 00228 00229 str << " if ( !dcopClient() ) {"<< endl; 00230 str << "\tsetStatus( CallFailed );" << endl; 00231 if ( result != "void" ) 00232 str << "\treturn result;" << endl; 00233 else 00234 str << "\treturn;" << endl; 00235 str << " }" << endl; 00236 00237 str << " QByteArray data, replyData;" << endl; 00238 str << " QCString replyType;" << endl; 00239 00240 if ( !args.isEmpty() ) { 00241 str << " QDataStream arg( data, IO_WriteOnly );" << endl; 00242 for( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){ 00243 str << " arg << " << *args_count << ";" << endl; 00244 } 00245 } 00246 str << " if ( dcopClient()->call( app(), obj(), \"" << funcName << "\","; 00247 str << " data, replyType, replyData ) ) {" << endl; 00248 if ( result != "void" ) { 00249 str << "\tif ( replyType == \"" << result << "\" ) {" << endl; 00250 str << "\t QDataStream _reply_stream( replyData, IO_ReadOnly );" << endl; 00251 str << "\t _reply_stream >> result;" << endl; 00252 str << "\t setStatus( CallSucceeded );" << endl; 00253 str << "\t} else {" << endl; 00254 str << "\t callFailed();" << endl; 00255 str << "\t}" << endl; 00256 } else { 00257 str << "\tsetStatus( CallSucceeded );" << endl; 00258 } 00259 str << " } else { " << endl; 00260 str << "\tcallFailed();" << endl; 00261 str << " }" << endl; 00262 if ( result != "void" ) 00263 str << " return result;" << endl; 00264 } 00265 str << "}" << endl << endl; 00266 } 00267 00268 for(; namespace_count > 0; --namespace_count ) 00269 str << "} // namespace" << endl; 00270 str << endl; 00271 } 00272 impl.close(); 00273 } 00274 00275 // :set expandtab!<RETURN>:set ts=8<RETURN>:set sts=4<RETURN>:set sw=4<RETURN>
KDE Logo
This file is part of the documentation for dcop Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 16 17:21:26 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003