# dcop Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 == "float" || result == "double")
    00224             str << " = 0.0";
    00225             else if ( result == "bool" )
    00226             str << " = false";
    00227
    00228             str << ";" << endl;
    00229         }
    00230
    00231         str << "    if ( !dcopClient()  ) {"<< endl;
    00232         str << "\tsetStatus( CallFailed );" << endl;
    00233         if ( result != "void" )
    00234             str << "\treturn result;" << endl;
    00235         else
    00236             str << "\treturn;" << endl;
    00237         str << "    }" << endl;
    00238
    00239         str << "    QByteArray data, replyData;" << endl;
    00240         str << "    QCString replyType;" << endl;
    00241
    00242         if ( !args.isEmpty() ) {
    00243             str << "    QDataStream arg( data, IO_WriteOnly );" << endl;
    00244             for( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
    00245             str << "    arg << " << *args_count << ";" << endl;
    00246             }
    00247         }
    00248         str << "    if ( dcopClient()->call( app(), obj(), \"" << funcName << "\",";
    00249         str << " data, replyType, replyData ) ) {" << endl;
    00250         if ( result != "void" ) {
    00251             str << "\tif ( replyType == \"" << result << "\" ) {" << endl;
    00252             str << "\t    QDataStream _reply_stream( replyData, IO_ReadOnly );"  << endl;
    00253             str << "\t    _reply_stream >> result;" << endl;
    00254             str << "\t    setStatus( CallSucceeded );" << endl;
    00255             str << "\t} else {" << endl;
    00256             str << "\t    callFailed();" << endl;
    00257             str << "\t}" << endl;
    00258         } else {
    00259             str << "\tsetStatus( CallSucceeded );" << endl;
    00260         }
    00261         str << "    } else { " << endl;
    00262         str << "\tcallFailed();" << endl;
    00263         str << "    }" << endl;
    00264         if ( result != "void" )
    00265             str << "    return result;" << endl;
    00266         }
    00267         str << "}" << endl << endl;
    00268     }
    00269
    00270     for(; namespace_count > 0; --namespace_count )
    00271         str << "} // namespace" << endl;
    00272     str << endl;
    00273     }
    00274     impl.close();
    00275 }
    00276
    00277 // :set expandtab!<RETURN>:set ts=8<RETURN>:set sts=4<RETURN>:set sw=4<RETURN>

This file is part of the documentation for dcop Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:16:55 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003