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.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:14:34 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001