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 
00035 int isIntType( const QString& t)
00036 {
00037   if ((t == "int")
00038       || (t == "signed int")
00039       || (t == "unsigned int")
00040       || (t == "uint")
00041       || (t == "unsigned")
00042       || (t == "signed short int")
00043       || (t == "signed short")
00044       || (t == "short int")
00045       || (t == "short")
00046       || (t == "unsigned short int")
00047       || (t == "unsigned short")
00048       || (t == "ushort")
00049       || (t == "long int")
00050       || (t == "signed long int")
00051       || (t == "long")
00052       || (t == "signed long")
00053       || (t == "unsigned long int")
00054       || (t == "unsigned long")
00055       || (t == "ulong")
00056       || (t == "char")
00057       || (t == "signed char")
00058       || (t == "unsigned char"))
00059     return 1;
00060   return 0;
00061 }
00062 
00066 void generateStubImpl( const QString& idl, const QString& header, const QString& /*headerBase*/, const QString& filename, QDomElement de )
00067 {
00068     QFile impl( filename );
00069     if ( !impl.open( IO_WriteOnly ) )
00070         qFatal("Could not write to %s", filename.latin1() );
00071 
00072     QTextStream str( &impl );
00073 
00074     str << "/****************************************************************************" << endl;
00075     str << "**" << endl;
00076     str << "** DCOP Stub Implementation created by dcopidl2cpp from " << idl << endl;
00077     str << "**" << endl;
00078     str << "** WARNING! All changes made in this file will be lost!" << endl;
00079     str << "**" << endl;
00080     str << "*****************************************************************************/" << endl;
00081     str << endl;
00082 
00083     str << "#include \"" << header << "\"" << endl;
00084     str << "#include <dcopclient.h>" << endl << endl;
00085     str << "#include <kdatastream.h>" << endl;
00086 
00087     QDomElement e = de.firstChild().toElement();
00088     for( ; !e.isNull(); e = e.nextSibling().toElement() ) {
00089         if ( e.tagName() == "CLASS" ) {
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                     {
00104                     className_stub = namespace_tmp;
00105                     break;
00106                     }
00107                 str << "namespace " << namespace_tmp.left( pos ) << " {" << endl;
00108                 ++namespace_count;
00109                 namespace_tmp = namespace_tmp.mid( pos + 2 );
00110             }
00111 
00112             str << endl;
00113 
00114             // Write constructors
00115             str << className_stub << "::" << className_stub << "( const QCString& app, const QCString& obj )" << endl;
00116             str << "  : ";
00117 
00118             // Always explicitly call DCOPStub constructor, because it's virtual base class.           
00119             // Calling other ones doesn't matter, as they don't do anything important.
00120             str << "DCOPStub( app, obj )" << endl;
00121 
00122             str << "{" << endl;
00123             str << "}" << endl << endl;
00124 
00125             str << className_stub << "::" << className_stub << "( DCOPClient* client, const QCString& app, const QCString& obj )" << endl;
00126             str << "  : ";
00127         
00128             str << "DCOPStub( client, app, obj )" << endl;
00129 
00130             str << "{" << endl;
00131             str << "}" << endl << endl;
00132 
00133             // Write marshalling code
00134             QDomElement s = e.firstChild().toElement();
00135             for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
00136                 if (s.tagName() == "FUNC") {
00137                     QDomElement r = s.firstChild().toElement();
00138                     Q_ASSERT( r.tagName() == "TYPE" );
00139                     QString result = r.firstChild().toText().data();
00140                     bool async = result == "ASYNC";
00141                     if ( async)
00142                         result = "void";
00143                     if ( r.hasAttribute( "qleft" ) )
00144                         str << r.attribute("qleft") << " ";
00145                     str << result;
00146                     if ( r.hasAttribute( "qright" ) )
00147                         str << r.attribute("qright") << " ";
00148                     else
00149                         str << " ";
00150 
00151                     r = r.nextSibling().toElement();
00152                     Q_ASSERT ( r.tagName() == "NAME" );
00153                     QString funcName = r.firstChild().toText().data();
00154                     str << className_stub << "::" << funcName << "(";
00155 
00156                     QStringList args;
00157                     QStringList argtypes;
00158                     bool first = TRUE;
00159                     r = r.nextSibling().toElement();
00160                     for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
00161                         if ( !first )
00162                             str << ", ";
00163                         else
00164                             str << " ";
00165                         first = FALSE;
00166                         Q_ASSERT( r.tagName() == "ARG" );
00167                         QDomElement a = r.firstChild().toElement();
00168                         Q_ASSERT( a.tagName() == "TYPE" );
00169                         if ( a.hasAttribute( "qleft" ) )
00170                             str << a.attribute("qleft") << " ";
00171                         argtypes.append( a.firstChild().toText().data() );
00172                         str << argtypes.last();
00173                         if ( a.hasAttribute( "qright" ) )
00174                             str << a.attribute("qright") << " ";
00175                         else
00176                             str << " ";
00177                         args.append( QString("arg" ) + QString::number( args.count() ) ) ;
00178                         str << args.last();
00179                     }
00180                     if ( !first )
00181                         str << " ";
00182                     str << ")";
00183 
00184                     if ( s.hasAttribute("qual") )
00185                         str << " " << s.attribute("qual");
00186                     str << endl;
00187                 
00188                     str << "{" << endl ;
00189 
00190                 
00191                     funcName += "(";
00192                     first = TRUE;
00193                     for( QStringList::Iterator it = argtypes.begin(); it != argtypes.end(); ++it ){
00194                         if ( !first )
00195                             funcName += ",";
00196                         first = FALSE;
00197                         funcName += *it;
00198                     }
00199                     funcName += ")";
00200                 
00201                     if ( async ) {
00202 
00203                         str << "    if ( !dcopClient()  ) {"<< endl;
00204                         str << "\tsetStatus( CallFailed );" << endl;
00205                         str << "\treturn;" << endl;
00206                         str << "    }" << endl;
00207                 
00208                         str << "    QByteArray data;" << endl;
00209                         if ( !args.isEmpty() ) {
00210                             str << "    QDataStream arg( data, IO_WriteOnly );" << endl;
00211                             for( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
00212                                 str << "    arg << " << *args_count << ";" << endl;
00213                             }
00214                         }
00215 
00216                         str << "    dcopClient()->send( app(), obj(), \"" << funcName << "\", data );" << endl;
00217                         str << "    setStatus( CallSucceeded );" << endl;
00218 
00219                     } else {
00220 
00221                         if ( result != "void" ) {
00222                             str << "    " << result << " result";
00223                             if (isIntType( result ))
00224                                 str << " = 0";
00225                             str << ";" << endl;
00226                         }
00227 
00228                         str << "    if ( !dcopClient()  ) {"<< endl;
00229                         str << "\tsetStatus( CallFailed );" << endl;
00230                         if ( result != "void" )
00231                             str << "\treturn result;" << endl;
00232                         else
00233                             str << "\treturn;" << endl;
00234                         str << "    }" << endl;
00235 
00236                         str << "    QByteArray data, replyData;" << endl;
00237                         str << "    QCString replyType;" << endl;
00238                 
00239                         if ( !args.isEmpty() ) {
00240                             str << "    QDataStream arg( data, IO_WriteOnly );" << endl;
00241                             for( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
00242                                 str << "    arg << " << *args_count << ";" << endl;
00243                             }
00244                         }
00245                         str << "    if ( dcopClient()->call( app(), obj(), \"" << funcName << "\",";
00246                         str << " data, replyType, replyData ) ) {" << endl;
00247                         if ( result != "void" ) {
00248                             str << "\tif ( replyType == \"" << result << "\" ) {" << endl;
00249                             str << "\t    QDataStream _reply_stream( replyData, IO_ReadOnly );"  << endl;
00250                             str << "\t    _reply_stream >> result;" << endl;
00251                             str << "\t    setStatus( CallSucceeded );" << endl;
00252                             str << "\t} else {" << endl;
00253                             str << "\t    callFailed();" << endl;
00254                             str << "\t}" << endl;
00255                         } else {
00256                             str << "\tsetStatus( CallSucceeded );" << endl;
00257                         }
00258                       str << "    } else { " << endl;
00259                       str << "\tcallFailed();" << endl;
00260                       str << "    }" << endl;
00261                         if ( result != "void" )
00262                             str << "    return result;" << endl;
00263                     }
00264                     str << "}" << endl << endl;
00265                 }
00266             }
00267 
00268             for(;
00269                  namespace_count > 0;
00270                  --namespace_count )
00271                 str << "} // namespace" << endl;
00272             str << endl;
00273         }
00274     }
00275     impl.close();
00276 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:42:42 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001