void Converter::convertOutputMessage( const Port&, const Message &message, KODE::Class &newClass ) { Message::Part part = message.parts().first(); // signal QString messageName = message.name(); messageName[ 0 ] = messageName[ 0 ].lower(); KODE::Function respSignal( messageName, "void", KODE::Function::Signal ); /** If one output message is used by two input messages, don't define it twice. */ if ( newClass.hasFunction( respSignal.name() ) ) return; const Message::Part::List parts = message.parts(); Message::Part::List::ConstIterator it; for ( it = parts.begin(); it != parts.end(); ++it ) { QStringList headers = mTypeMapper.header( (*it).type() ); for ( uint i = 0; i < headers.count(); ++i ) if ( !headers[ i ].isEmpty() ) newClass.addHeaderInclude( headers[ i ] ); respSignal.addArgument( mTypeMapper.argument( "value", (*it).type() ) ); } newClass.addFunction( respSignal ); // slot KODE::Function respSlot( messageName + "Slot", "void", KODE::Function::Slot | KODE::Function::Private ); respSlot.addArgument( "const QString &xml" ); KODE::Code code; code += "QDomDocument doc;"; code += "QString errorMsg;"; code += "int column, row;"; code.newLine(); code += "qDebug( \"%s\", xml.latin1() );"; code.newLine(); code += "if ( !doc.setContent( xml, true, &errorMsg, &row, &column ) ) {"; code.indent(); code += "qDebug( \"Unable to parse xml: %s (%d:%d)\", errorMsg.latin1(), row, column );"; code += "return;"; code.unindent(); code += "}"; code.newLine(); code += mTypeMapper.type( part.type() ) + "* value = new " + mTypeMapper.type( part.type() ) + ";"; code += "QDomElement envelope = doc.documentElement();"; code += "QDomElement body = envelope.firstChild().toElement();"; code += "QDomElement method = body.firstChild().toElement();"; code += "Serializer::demarshal( method.firstChild().toElement(), value );"; code.newLine(); code += "emit " + respSignal.name() + "( value );"; respSlot.setBody( code ); newClass.addFunction( respSlot ); }
void Converter::convertInputMessage( const Port &port, const Message &message, KODE::Class &newClass ) { KODE::MemberVariable transport( message.name() + "Transport", "Transport*" ); newClass.addMemberVariable( transport ); // call QString messageName = message.name(); messageName[ 0 ] = messageName[ 0 ].lower(); KODE::Function callFunc( mNameMapper.escape( messageName ), "void", KODE::Function::Public ); const Message::Part::List parts = message.parts(); Message::Part::List::ConstIterator it; for ( it = parts.begin(); it != parts.end(); ++it ) { newClass.addHeaderIncludes( mTypeMapper.header( (*it).type() ) ); QString lowerName = (*it).name(); lowerName[ 0 ] = lowerName[ 0 ].lower(); callFunc.addArgument( mTypeMapper.argument( mNameMapper.escape( lowerName ), (*it).type() ) ); } KODE::Code code; code += "QDomDocument doc( \"kwsdl\" );"; code += "doc.appendChild( doc.createProcessingInstruction( \"xml\", \"version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"\" ) );"; code += "QDomElement env = doc.createElement( \"SOAP-ENV:Envelope\" );"; code += "env.setAttribute( \"xmlns:SOAP-ENV\", \"http://schemas.xmlsoap.org/soap/envelope/\" );"; code += "env.setAttribute( \"xmlns:xsi\", \"http://www.w3.org/1999/XMLSchema-instance\" );"; code += "env.setAttribute( \"xmlns:xsd\", \"http://www.w3.org/1999/XMLSchema\" );"; code += "doc.appendChild( env );"; code += "QDomElement body = doc.createElement( \"SOAP-ENV:Body\" );"; code += "env.appendChild( body );"; code += "QDomElement method = doc.createElement( \"ns1:" + message.name() + "\" );"; QString nameSpace = mWSDL.findBindingOperation( port.name(), message.name() ).input().nameSpace(); code += "method.setAttribute( \"xmlns:ns1\", \"" + nameSpace + "\" );"; code += "method.setAttribute( \"SOAP-ENV:encodingStyle\", \"http://schemas.xmlsoap.org/soap/encoding/\" );"; code += "body.appendChild( method );"; code.newLine(); for ( it = parts.begin(); it != parts.end(); ++it ) { QString lowerName = (*it).name(); lowerName[ 0 ] = lowerName[ 0 ].lower(); code += "Serializer::marshal( doc, method, \"" + (*it).name() + "\", " + mNameMapper.escape( lowerName ) + " );"; code += "delete " + mNameMapper.escape( lowerName ) + ";"; } code += "qDebug( \"%s\", doc.toString().latin1() );"; code += transport.name() + "->query( doc.toString() );"; callFunc.setBody( code ); newClass.addFunction( callFunc ); }
static KODE::Code createRangeCheckCode( const XSD::SimpleType *type, const QString &variableName, KODE::Class &parentClass ) { KODE::Code code; code += "bool rangeOk = true;"; code.newLine(); // TODO /* WhiteSpaceType facetWhiteSpace() const; int facetTotalDigits() const; int facetFractionDigits() const; */ if ( type->facetType() & XSD::SimpleType::MININC ) code += "rangeOk = rangeOk && (" + variableName + " >= " + QString::number( type->facetMinimumInclusive() ) + ");"; if ( type->facetType() & XSD::SimpleType::MINEX ) code += "rangeOk = rangeOk && (" + variableName + " > " + QString::number( type->facetMinimumExclusive() ) + ");"; if ( type->facetType() & XSD::SimpleType::MAXINC ) code += "rangeOk = rangeOk && (" + variableName + " <= " + QString::number( type->facetMaximumInclusive() ) + ");"; if ( type->facetType() & XSD::SimpleType::MINEX ) code += "rangeOk = rangeOk && (" + variableName + " < " + QString::number( type->facetMaximumExclusive() ) + ");"; if ( type->facetType() & XSD::SimpleType::LENGTH ) code += "rangeOk = rangeOk && (" + variableName + ".length() == " + QString::number( type->facetLength() ) + ");"; if ( type->facetType() & XSD::SimpleType::MINLEN ) code += "rangeOk = rangeOk && (" + variableName + ".length() >= " + QString::number( type->facetMinimumLength() ) + ");"; if ( type->facetType() & XSD::SimpleType::MAXLEN ) code += "rangeOk = rangeOk && (" + variableName + ".length() <= " + QString::number( type->facetMaximumLength() ) + ");"; if ( type->facetType() & XSD::SimpleType::PATTERN ) { code += "QRegExp exp( \"" + type->facetPattern() + "\" );"; code += "rangeOk = rangeOk && exp.exactMatch( " + variableName + " );"; parentClass.addInclude( "QRegExp" ); } return code; }
void Converter::convertSimpleType( const XSD::SimpleType *type ) { const QString typeName( mTypeMap.localType( type->qualifiedName() ) ); KODE::Class newClass( typeName ); newClass.addInclude( QString(), "Serializer" ); KODE::Code ctorBody; KODE::Code dtorBody; QString classDocumentation; if ( type->subType() == XSD::SimpleType::TypeRestriction ) { /** Use setter and getter method for enums as well. */ if ( type->facetType() & XSD::SimpleType::ENUM ) { classDocumentation = "This class is a wrapper for an enumeration.\n"; QStringList enums = type->facetEnums(); for ( int i = 0; i < enums.count(); ++i ) enums[ i ] = escapeEnum( enums[ i ] ); newClass.addEnum( KODE::Enum( "Type", enums ) ); classDocumentation += "Whenever you have to pass an object of type " + newClass.name() + " you can also pass the enum directly (e.g. someMethod( " + newClass.name() + "::" + enums.first() + " ))."; // member variables KODE::MemberVariable variable( "type", "Type" ); newClass.addMemberVariable( variable ); // setter method KODE::Function setter( "setType", "void" ); setter.addArgument( "Type type" ); setter.setBody( variable.name() + " = type;" ); // getter method KODE::Function getter( "type", upperlize( newClass.name() ) + "::Type" ); getter.setBody( "return " + variable.name() + ';' ); getter.setConst( true ); // convenience constructor KODE::Function conctor( upperlize( newClass.name() ) ); conctor.addArgument( "const " + upperlize( newClass.name() ) + "::Type &type" ); KODE::Code code; code += variable.name() + " = type;"; conctor.setBody( code ); // type operator KODE::Function op( "operator const " + upperlize( newClass.name() ) + "::Type" ); op.setBody( "return " + variable.name() + ';' ); op.setConst( true ); newClass.addFunction( conctor ); newClass.addFunction( setter ); newClass.addFunction( getter ); newClass.addFunction( op ); } /** A class can't derive from basic types (e.g. int or unsigned char), so we add setter and getter methods to set the value of this class. */ if ( type->baseTypeName() != XmlAnyType && !type->baseTypeName().isEmpty() && !(type->facetType() & XSD::SimpleType::ENUM) ) { classDocumentation = "This class encapsulates an basic type.\n"; const QName baseName = type->baseTypeName(); const QString typeName = mTypeMap.localType( baseName ); classDocumentation += "Whenever you have to pass an object of type " + newClass.name() + " you can also pass the value directly (e.g. someMethod( (" + typeName + "*)value ))."; // include header newClass.addIncludes( QStringList(), mTypeMap.forwardDeclarations( baseName ) ); // member variables KODE::MemberVariable variable( "value", typeName + '*' ); newClass.addMemberVariable( variable ); ctorBody += variable.name() + " = 0;"; dtorBody += "delete " + variable.name() + "; " + variable.name() + " = 0;"; // setter method KODE::Function setter( "setValue", "void" ); setter.addArgument( typeName + " *value" ); KODE::Code setterBody; setterBody += createRangeCheckCode( type, "(*value)", newClass ); setterBody.newLine(); setterBody += "if ( !rangeOk )"; setterBody.indent(); setterBody += "qDebug( \"Invalid range in " + newClass.name() + "::" + setter.name() + "()\" );"; setterBody.unindent(); setterBody.newLine(); setterBody += variable.name() + " = value;"; setter.setBody( setterBody ); // getter method KODE::Function getter( "value", typeName + '*' ); getter.setBody( "return " + variable.name() + ';' ); getter.setConst( true ); // convenience constructor KODE::Function conctor( upperlize( newClass.name() ) ); conctor.addArgument( typeName + " *value" ); KODE::Code code; code += createRangeCheckCode( type, "(*value)", newClass ); code.newLine(); code += "if ( !rangeOk )"; code.indent(); code += "qDebug( \"Invalid range in " + newClass.name() + "::" + conctor.name() + "()\" );"; code.unindent(); code.newLine(); code += variable.name() + " = value;"; conctor.setBody( code ); if ( typeName == "QString" ) { KODE::Function charctor( upperlize( newClass.name() ) ); charctor.addArgument( "const char *charValue" ); KODE::Code code; code += "QString *value = new QString( charValue );"; code += createRangeCheckCode( type, "(*value)", newClass ); code.newLine(); code += "if ( !rangeOk )"; code.indent(); code += "qDebug( \"Invalid range in " + newClass.name() + "::" + charctor.name() + "()\" );"; code.unindent(); code.newLine(); code += variable.name() + " = value;"; charctor.setBody( code ); newClass.addFunction( charctor ); } // type operator KODE::Function op( "operator const " + typeName + '*' ); op.setBody( "return " + variable.name() + ';' ); op.setConst( true ); newClass.addFunction( conctor ); newClass.addFunction( op ); newClass.addFunction( setter ); newClass.addFunction( getter ); } } else if ( type->subType() == XSD::SimpleType::TypeList ) { classDocumentation = "This class encapsulates a list type."; newClass.addHeaderInclude( "QList" ); const QName baseName = type->listTypeName(); const QString typeName = mTypeMap.localType( baseName ); // include header newClass.addIncludes( QStringList(), mTypeMap.forwardDeclarations( baseName ) ); // member variables KODE::MemberVariable variable( "entries", "QList<" + typeName + "*>*" ); newClass.addMemberVariable( variable ); ctorBody += variable.name() + " = 0;"; dtorBody += "qDeleteAll( *" + variable.name() + " );"; dtorBody += variable.name() + "->clear();"; dtorBody += "delete " + variable.name() + "; " + variable.name() + " = 0;"; // setter method KODE::Function setter( "setEntries", "void" ); setter.addArgument( "QList<" + typeName + "*> *entries" ); setter.setBody( variable.name() + " = entries;" ); // getter method KODE::Function getter( "entries", "QList<" + typeName + "*>*" ); getter.setBody( "return " + variable.name() + ';' ); getter.setConst( true ); newClass.addFunction( setter ); newClass.addFunction( getter ); } if ( !type->documentation().isEmpty() ) newClass.setDocs( type->documentation().simplified() ); else newClass.setDocs( classDocumentation ); createSimpleTypeSerializer( type ); KODE::Function ctor( upperlize( newClass.name() ) ); ctor.setBody( ctorBody ); newClass.addFunction( ctor ); KODE::Function dtor( '~' + upperlize( newClass.name() ) ); dtor.setBody( dtorBody ); newClass.addFunction( dtor ); mClasses.append( newClass ); }
void Converter::createTransportClass() { KODE::Class transport( "Transport" ); transport.addBaseClass( mQObject ); transport.addHeaderInclude( "qobject.h" ); transport.addHeaderInclude( "kio/job.h" ); transport.addInclude( "kdebug.h" ); KODE::MemberVariable url( "url", "QString" ); transport.addMemberVariable( url ); KODE::MemberVariable slotDataVar( "data", "QByteArray" ); transport.addMemberVariable( slotDataVar ); // ctor KODE::Function ctor( "Transport" ); ctor.addArgument( "const QString &url" ); ctor.setBody( url.name() + " = url;" ); transport.addFunction( ctor ); // query KODE::Function query( "query", "void" ); query.addArgument( "const QString &xml" ); KODE::Code queryCode; queryCode += slotDataVar.name() + ".truncate( 0 );"; queryCode.newLine(); queryCode += "QByteArray postData;"; queryCode += "QDataStream stream( postData, IO_WriteOnly );"; queryCode += "stream.writeRawBytes( xml.utf8(), xml.utf8().length() );"; queryCode.newLine(); queryCode += "KIO::TransferJob* job = KIO::http_post( KURL( " + url.name() + " ), postData, false );"; queryCode += "if ( !job ) {"; queryCode.indent(); queryCode += "kdWarning() << \"Unable to create KIO job for \" << " + url.name() + " << endl;"; queryCode += "return;"; queryCode.unindent(); queryCode += "}"; queryCode.newLine(); queryCode += "job->addMetaData( \"UserAgent\", \"KWSDL\" );"; queryCode += "job->addMetaData( \"content-type\", \"Content-Type: text/xml; charset=utf-8\" );"; queryCode.newLine(); queryCode += "connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), this, SLOT( slotData( KIO::Job*, const QByteArray& ) ) );"; queryCode += "connect( job, SIGNAL( result( KIO::Job* ) ), this, SLOT( slotResult( KIO::Job* ) ) );"; query.setBody( queryCode ); transport.addFunction( query ); // signal KODE::Function result( "result", "void", KODE::Function::Signal ); result.addArgument( "const QString &xml" ); transport.addFunction( result ); // data slot KODE::Function slotData( "slotData", "void", KODE::Function::Private | KODE::Function::Slot ); slotData.addArgument( "KIO::Job*" ); slotData.addArgument( "const QByteArray &data" ); KODE::Code slotDataCode; slotDataCode += "unsigned int oldSize = " + slotDataVar.name() + ".size();"; slotDataCode += slotDataVar.name() + ".resize( oldSize + data.size() );"; slotDataCode += "memcpy( " + slotDataVar.name() + ".data() + oldSize, data.data(), data.size() );"; slotData.setBody( slotDataCode ); transport.addFunction( slotData ); // result slot KODE::Function slotResult( "slotResult", "void", KODE::Function::Private | KODE::Function::Slot ); slotResult.addArgument( "KIO::Job* job" ); KODE::Code slotResultCode; slotResultCode += "if ( job->error() != 0 ) {"; slotResultCode.indent(); slotResultCode += "kdWarning() << \"Error occurred \" << job->errorText() << endl;"; slotResultCode += "kdWarning() << " + slotDataVar.name() + " << endl;"; slotResultCode += "return;"; slotResultCode.unindent(); slotResultCode += "}"; slotResultCode.newLine(); slotResultCode += "emit result( QString::fromUtf8( " + slotDataVar.name() + ".data(), " + slotDataVar.name() + ".size() ) );"; slotResult.setBody( slotResultCode ); transport.addFunction( slotResult ); mClasses.append( transport ); }
void Converter::convertSimpleType(const XSD::SimpleType *type, const XSD::SimpleType::List &simpleTypeList) { const QString typeName(mTypeMap.localType(type->qualifiedName())); //qDebug() << "convertSimpleType:" << type->qualifiedName() << typeName; KODE::Class newClass; newClass.setNamespaceAndName(typeName); if (!Settings::self()->exportDeclaration().isEmpty()) { newClass.setExportDeclaration(Settings::self()->exportDeclaration()); } newClass.setNameSpace(Settings::self()->nameSpace()); QString classDocumentation; switch (type->subType()) { case XSD::SimpleType::TypeRestriction: { /** Use setter and getter method for enums as well. */ if (type->facetType() & XSD::SimpleType::ENUM) { classDocumentation = "This class is a wrapper for an enumeration.\n"; NameMapper nameMapper; QStringList enums = type->facetEnums(); for (int i = 0; i < enums.count(); ++i) { enums[ i ] = nameMapper.escape(escapeEnum(enums[ i ])); } newClass.addEnum(KODE::Enum("Type", enums)); classDocumentation += "Whenever you have to pass an object of type " + newClass.name() + " you can also pass the enum directly. Example:\n" + "someMethod(" + newClass.name() + "::" + enums.first() + ")."; // member variables KODE::MemberVariable variable("type", "Type"); variable.setInitializer("Type(0)"); newClass.addMemberVariable(variable); // setter method KODE::Function setter("setType", "void"); setter.addArgument("Type type"); setter.setBody(variable.name() + " = type;"); // getter method KODE::Function getter("type", newClass.qualifiedName() + "::Type"); getter.setBody("return " + variable.name() + ';'); getter.setConst(true); // convenience constructor KODE::Function conctor(newClass.name()); conctor.addArgument("const Type &type"); KODE::Code code; code += variable.name() + " = type;"; conctor.setBody(code); // type operator KODE::Function op("operator Type"); op.setBody("return " + variable.name() + ';'); op.setConst(true); newClass.addFunction(conctor); newClass.addFunction(setter); newClass.addFunction(getter); newClass.addFunction(op); } /** A class can't derive from basic types (e.g. int or unsigned char), so we add setter and getter methods to set the value of this class. */ if (type->baseTypeName() != XmlAnyType && !type->baseTypeName().isEmpty() && !(type->facetType() & XSD::SimpleType::ENUM)) { classDocumentation = "This class encapsulates a simple type.\n"; const QName baseName = type->baseTypeName(); const QString baseTypeName = mTypeMap.localType(baseName); Q_ASSERT(!baseTypeName.isEmpty()); QList<QName> parentBasicTypes; parentBasicTypes.append(baseName); QName currentType = baseName; Q_FOREVER { const XSD::SimpleType simpleType = simpleTypeList.simpleType(currentType); if (!simpleType.isNull() && simpleType.isRestriction()) { currentType = simpleType.baseTypeName(); parentBasicTypes.append(currentType); continue; } break; } classDocumentation += "Whenever you have to pass an object of type " + newClass.name() + " you can also pass the value directly as a " + mTypeMap.localType(currentType) + '.'; // include header newClass.addIncludes(QStringList(), mTypeMap.forwardDeclarations(baseName)); newClass.addHeaderIncludes(mTypeMap.headerIncludes(baseName)); // member variables KODE::MemberVariable variable("value", baseTypeName); addVariableInitializer(variable); newClass.addMemberVariable(variable); // setter method KODE::Function setter("setValue", "void"); const QString inputType = mTypeMap.localInputType(baseName, QName()); setter.addArgument(inputType + " value"); KODE::Code setterBody; if (type->facetType() != XSD::SimpleType::NONE) { const XSD::SimpleType baseSimpleType = simpleTypeList.simpleType(baseName); setterBody += createRangeCheckCode(type, baseTypeName, "value", newClass, baseSimpleType); setterBody.newLine(); setterBody += "if (!rangeOk)"; setterBody.indent(); setterBody += "qDebug( \"Invalid range in " + newClass.name() + "::" + setter.name() + "()\" );"; setterBody.unindent(); setterBody.newLine(); } setterBody += variable.name() + " = value;"; // ### call setValue in base class? setter.setBody(setterBody); newClass.addFunction(setter); // getter method KODE::Function getter("value", baseTypeName); getter.setBody("return " + variable.name() + ';'); getter.setConst(true); newClass.addFunction(getter); // convenience constructor KODE::Function conctor(newClass.name()); conctor.addArgument(inputType + " value"); conctor.addBodyLine("setValue(value);"); newClass.addFunction(conctor); // even more convenient constructor, for the case of multiple-level simple-type restrictions //qDebug() << typeName << ": baseName=" << baseName << "further up:" << parentBasicTypes; if (parentBasicTypes.count() > 1) { parentBasicTypes.removeLast(); // the top-most one is in "currentType", so it's the input arg. KODE::Function baseCtor(conctor.name()); baseCtor.addArgument(mTypeMap.localInputType(currentType, QName()) + " value"); QString beginLine = "setValue("; QString endLine = ")"; Q_FOREACH (const QName &base, parentBasicTypes) { beginLine += mTypeMap.localType(base) + '('; endLine += ')'; } baseCtor.addBodyLine(beginLine + "value" + endLine + ';'); newClass.addFunction(baseCtor); } // type operator KODE::Function op("operator " + baseTypeName); op.setBody("return " + variable.name() + ';'); op.setConst(true); newClass.addFunction(op); }
void Converter::createKDETransport() { KODE::Class transport( "Transport" ); transport.addBaseClass( mQObject ); transport.addHeaderInclude( "QObject" ); transport.addHeaderInclude( "kio/job.h" ); transport.addInclude( "kdebug.h" ); KODE::MemberVariable url( "url", "QString" ); transport.addMemberVariable( url ); KODE::MemberVariable slotDataVar( "data", "QByteArray" ); transport.addMemberVariable( slotDataVar ); // ctor KODE::Function ctor( "Transport" ); ctor.addArgument( "const QString &url" ); ctor.setBody( url.name() + " = url;" ); transport.addFunction( ctor ); // query KODE::Function query( "query", "void" ); query.addArgument( "const QString &xml" ); query.addArgument( "const QString &header" ); KODE::Code queryCode; queryCode += slotDataVar.name() + ".truncate( 0 );"; queryCode.newLine(); queryCode += "QByteArray postData;"; queryCode += "QDataStream stream( &postData, QIODevice::WriteOnly );"; queryCode += "stream.writeRawData( xml.toUtf8(), xml.toUtf8().length() );"; queryCode.newLine(); queryCode += "KIO::TransferJob* job = KIO::http_post( KUrl( " + url.name() + " ), postData, KIO::HideProgressInfo );"; queryCode += "if ( !job ) {"; queryCode.indent(); queryCode += "kWarning() << \"Unable to create KIO job for \" <<" + url.name() +";"; queryCode += "return;"; queryCode.unindent(); queryCode += '}'; queryCode.newLine(); queryCode += "job->addMetaData( \"UserAgent\", \"KWSDL\" );"; queryCode += "job->addMetaData( \"content-type\", \"Content-Type: application/xml; charset=utf-8\" );"; queryCode += "if ( !header.isEmpty() ) {"; queryCode.indent(); queryCode += "job->addMetaData( \"customHTTPHeader\", \"SOAPAction:\" + header );"; queryCode.unindent(); queryCode += '}'; queryCode.newLine(); queryCode += "connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), this, SLOT( slotData( KIO::Job*, const QByteArray& ) ) );"; queryCode += "connect( job, SIGNAL( result( KJob* ) ), this, SLOT( slotResult( KJob* ) ) );"; query.setBody( queryCode ); transport.addFunction( query ); // signal KODE::Function result( "result", "void", KODE::Function::Signal ); result.addArgument( "const QString &xml" ); KODE::Function error( "error", "void", KODE::Function::Signal ); error.addArgument( "const QString &msg" ); transport.addFunction( result ); transport.addFunction( error ); // data slot KODE::Function slotData( "slotData", "void", KODE::Function::Private | KODE::Function::Slot ); slotData.addArgument( "KIO::Job*" ); slotData.addArgument( "const QByteArray &data" ); KODE::Code slotDataCode; slotDataCode += "unsigned int oldSize = " + slotDataVar.name() + ".size();"; slotDataCode += slotDataVar.name() + ".resize( oldSize + data.size() );"; slotDataCode += "memcpy( " + slotDataVar.name() + ".data() + oldSize, data.data(), data.size() );"; slotData.setBody( slotDataCode ); transport.addFunction( slotData ); // result slot KODE::Function slotResult( "slotResult", "void", KODE::Function::Private | KODE::Function::Slot ); slotResult.addArgument( "KJob* job" ); KODE::Code slotResultCode; slotResultCode += "if ( job->error() != 0 ) {"; slotResultCode.indent(); slotResultCode += "emit error( job->errorText() );"; slotResultCode += "return;"; slotResultCode.unindent(); slotResultCode += '}'; slotResultCode.newLine(); slotResultCode += "emit result( QString::fromUtf8( " + slotDataVar.name() + ".data(), " + slotDataVar.name() + ".size() ) );"; slotResult.setBody( slotResultCode ); transport.addFunction( slotResult ); mClasses.append( transport ); }
void Converter::createQtTransport() { KODE::Class transport( "Transport" ); transport.addBaseClass( mQObject ); transport.addHeaderInclude( "QBuffer" ); transport.addHeaderInclude( "QByteArray" ); transport.addHeaderInclude( "QObject" ); transport.addHeaderInclude( "QHttp" ); transport.addHeaderInclude( "QUrl" ); // member variables KODE::MemberVariable bufferVar( "buffer", "QBuffer" ); transport.addMemberVariable( bufferVar ); KODE::MemberVariable dataVar( "data", "QByteArray" ); transport.addMemberVariable( dataVar ); KODE::MemberVariable httpVar( "http", "QHttp*" ); transport.addMemberVariable( httpVar ); KODE::MemberVariable urlVar( "url", "QUrl" ); transport.addMemberVariable( urlVar ); KODE::MemberVariable idVar( "id", "int" ); transport.addMemberVariable( idVar ); // functions KODE::Function ctor( "Transport" ); ctor.addArgument( "const QString &url" ); ctor.addInitializer( "QObject( 0 )" ); ctor.addInitializer( urlVar.name() + "( url )" ); KODE::Function query( "query", "void" ); query.addArgument( "const QString &message" ); query.addArgument( "const QString &headerStr" ); KODE::Function resultSignal( "result", "void", KODE::Function::Signal ); resultSignal.addArgument( "const QString &result" ); KODE::Function errorSignal( "error", "void", KODE::Function::Signal ); errorSignal.addArgument( "const QString &msg" ); KODE::Function finishedSlot( "finished", "void", KODE::Function::Slot | KODE::Function::Private ); finishedSlot.addArgument( "int id" ); finishedSlot.addArgument( "bool errorOccurred" ); // codes KODE::Code code; code += "QUrl server( url );"; code.newLine(); code += httpVar.name() + " = new QHttp( this );"; code += httpVar.name() + "->setHost( server.host(), server.port( 80 ) );"; code.newLine(); code += "connect( " + httpVar.name() + ", SIGNAL( requestFinished( int, bool ) ), this, SLOT( " + finishedSlot.name() + "( int, bool ) ) );"; ctor.setBody( code ); code.clear(); code += dataVar.name() + ".clear();"; code += bufferVar.name() + ".setBuffer( &" + dataVar.name() + " );"; code.newLine(); code += "QHttpRequestHeader header;"; code += "header.setRequest( \"POST\", " + urlVar.name() + ".path() );"; code += "header.addValue( \"Connection\", \"Keep-Alive\" );"; code += "header.addValue( \"Content-Type\", \"application/xml; charset=utf-8\" );"; code += "header.addValue( \"Host\", QUrl( " + urlVar.name() + " ).host() );"; code.newLine(); code += "if ( !headerStr.isEmpty() )"; code.indent(); code += "header.addValue( \"SOAPAction\", headerStr );"; code.unindent(); code.newLine(); code += "QUrl server( " + urlVar.name() + " );"; code += "if ( server.port( 80 ) != 80 )"; code.indent(); code += "header.setValue( \"Host\", server.host() + \":\" + QString::number( server.port() ) );"; code.unindent(); code += "else"; code.indent(); code += "header.setValue( \"Host\", server.host() );"; code.unindent(); code.newLine(); code += idVar.name() + " = " + httpVar.name() + "->request( header, message.toUtf8(), &" + bufferVar.name() + " );"; query.setBody( code ); code.clear(); code += "if ( id != " + idVar.name() + " )"; code.indent(); code += "return;"; code.unindent(); code.newLine(); code += "if ( errorOccurred )"; code.indent(); code += "emit " + errorSignal.name() + "( " + httpVar.name() + "->errorString() );"; code.unindent(); code += "else"; code.indent(); code += "emit " + resultSignal.name() + "( QString::fromUtf8( " + dataVar.name() + " ) );"; code.unindent(); finishedSlot.setBody( code ); transport.addFunction( ctor ); transport.addFunction( query ); transport.addFunction( resultSignal ); transport.addFunction( errorSignal ); transport.addFunction( finishedSlot ); mClasses.append( transport ); }
int create(KCmdLineArgs *args) { KODE::Printer p; if(args->isSet("warning")) p.setCreationWarning(true); bool createKioslave = args->isSet("create-kioslave"); bool createMain = args->isSet("create-main"); QString filename = args->getOption("filename"); if(createMain) { if(filename.isEmpty()) { kdError() << "Error: No file name given." << endl; return 1; } if(filename.endsWith(".cpp")) { filename = filename.left(filename.length() - 4); } } else { if(!args->isSet("classname")) { kdError() << "Error: No class name given." << endl; return 1; } } QString className = args->getOption("classname"); QString protocol; if(createKioslave) { if(!args->isSet("protocol")) { protocol = className.lower(); kdWarning() << "Warning: No protocol for kioslave given. Assuming '" << protocol << "'" << endl; } else { protocol = args->getOption("protocol"); } } KODE::File file; file.setProject(args->getOption("project")); QString authorEmail = args->getOption("author-email"); QString authorName; KABC::Addressee a; if(authorEmail.isEmpty()) { a = KABC::StdAddressBook::self()->whoAmI(); authorEmail = a.preferredEmail(); } else { KABC::Addressee::List as = KABC::StdAddressBook::self()->findByEmail(authorEmail); if(as.isEmpty()) { kdDebug() << "Unable to find '" << authorEmail << "' in address book." << endl; } else { a = as.first(); } } if(!a.isEmpty()) { authorName = a.realName(); } if(!authorEmail.isEmpty()) { file.addCopyright(QDate::currentDate().year(), authorName, authorEmail); } KODE::License l; if(args->isSet("gpl")) l = KODE::License(KODE::License::GPL); if(args->isSet("lgpl")) l = KODE::License(KODE::License::LGPL); l.setQtException(args->isSet("qt-exception")); file.setLicense(l); file.setNameSpace(args->getOption("namespace")); if(createMain) { file.addInclude("kaboutdata.h"); file.addInclude("kapplication.h"); file.addInclude("kdebug"); file.addInclude("klocale"); file.addInclude("kcmdlineargs"); KODE::Code code; code += "static const KCmdLineOptions options[] ="; code += "{"; code += " { \"verbose\", \"Verbose output\", 0 },"; code += " KCmdLineLastOption"; code += "};"; file.addFileCode(code); KODE::Function main("main", "int"); main.addArgument("int argc"); main.addArgument("char **argv"); code.clear(); code += "KAboutData aboutData(\"test\",\"Test\",\"0.1\");"; code += "KCmdLineArgs::init(argc,argv,&aboutData);"; code += "KCmdLineArgs::addCmdLineOptions( options );"; code += ""; code += "KApplication app;"; code += ""; code += "KCmdLineArgs *args = KCmdLineArgs::parsedArgs();"; code += ""; code += "Q_UNUSED( args );"; main.setBody(code); file.addFileFunction(main); file.setFilename(filename); p.printImplementation(file, false); return 0; } KODE::Class c(className); if(args->isSet("create-dialog")) { c.addBaseClass(KODE::Class("KDialogBase")); c.addInclude("kdialogbase.h"); } else if(createKioslave) { c.setDocs("This class implements a kioslave for ..."); c.addBaseClass(KODE::Class("SlaveBase", "KIO")); c.addHeaderInclude("kio/slavebase.h"); KODE::Function get("get", "void"); get.addArgument("const KURL &url"); KODE::Code code; code += "kdDebug(7000) << \"" + className + "::get()\" << endl;"; code += "kdDebug(7000) << \" URL: \" << url.url() << endl;"; code += "#if 1"; code += "kdDebug(7000) << \" Path: \" << url.path() << endl;"; code += "kdDebug(7000) << \" Query: \" << url.query() << endl;"; code += "kdDebug(7000) << \" Protocol: \" << url.protocol() << endl;"; code += "kdDebug(7000) << \" Filename: \" << url.filename() << endl;"; code += "#endif"; code.newLine(); code += "mimeType( \"text/plain\" );"; code.newLine(); code += "QCString str( \"Hello!\" );"; code += "data( str );"; code.newLine(); code += "finished();"; code.newLine(); code += "kdDebug(7000) << \"" + className + "CgiProtocol::get() done\" << endl;"; get.setBody(code); c.addFunction(get); c.addInclude("kinstance.h"); c.addInclude("kdebug.h"); c.addInclude("sys/types.h"); c.addInclude("unistd.h"); c.addInclude("stdlib.h"); KODE::Function main("kdemain", "int"); main.addArgument("int argc"); main.addArgument("char **argv"); code.clear(); code += "KInstance instance( \"kio_" + protocol + "\" );"; code += ""; code += "kdDebug(7000) << \"Starting kio_" + protocol + "(pid: \" << getpid() << \")\" << endl;"; code += ""; code += "if (argc != 4) {"; code.indent(); code += "fprintf( stderr, \"Usage: kio_" + protocol + " protocol domain-socket1 domain-socket2\\n\");"; code += "exit( -1 );"; code.unindent(); code += "}"; code += ""; code += className + " slave( argv[2], argv[3] );"; code += "slave.dispatchLoop();"; code += ""; code += "return 0;"; main.setBody(code); file.addFileFunction(main); file.addExternCDeclaration(p.functionSignature(main)); } KODE::Function constructor(className); if(args->isSet("singleton")) { constructor.setAccess(KODE::Function::Private); KODE::Function self("self", className + " *"); self.setStatic(true); KODE::Code code; code += "if ( !mSelf ) {"; code += " selfDeleter.setObject( mSelf, new " + className + "() );"; code += "}"; code += "return mSelf;"; self.setBody(code); c.addFunction(self); KODE::MemberVariable selfVar("mSelf", className + " *", true); selfVar.setInitializer("0"); c.addMemberVariable(selfVar); KODE::Variable staticDeleter("selfDeleter", "KStaticDeleter<" + className + ">", true); file.addFileVariable(staticDeleter); file.addInclude("kstaticdeleter.h"); } if(createKioslave) { constructor.addArgument("const QCString &pool"); constructor.addArgument("const QCString &app"); constructor.addInitializer("SlaveBase( \"" + protocol + "\", pool, app )"); } c.addFunction(constructor); file.insertClass(c); p.printHeader(file); p.printImplementation(file); if(createKioslave) { // Write automake Makefile KODE::AutoMakefile am; am.addEntry("INCLUDES", "$(all_includes)"); am.newLine(); am.addEntry("noinst_HEADERS", className.lower() + ".h"); am.newLine(); am.addEntry("METASOURCES", "AUTO"); am.newLine(); am.addEntry("kdelnkdir", "$(kde_servicesdir)"); am.addEntry("kdelnk_DATA", protocol + ".protocol"); KODE::AutoMakefile::Target t("kde_module_LTLIBRARIES", "kio_" + protocol + ".la"); t.setSources(className.lower() + ".cpp"); t.setLibAdd("$(LIB_KIO)"); t.setLdFlags("$(all_libraries) -module $(KDE_PLUGIN)"); am.addTarget(t); p.printAutoMakefile(am); // Write protocol file QString protocolFilename = protocol + ".protocol"; QFileInfo fi(protocolFilename); protocolFilename = fi.absFilePath(); KSaveFile::backupFile(protocolFilename, QString::null, ".backup"); QFile::remove(protocolFilename); KSimpleConfig protocolFile(protocolFilename); protocolFile.setGroup("Protocol"); protocolFile.writeEntry("exec", "kio_" + protocol); protocolFile.writeEntry("protocol", protocol); protocolFile.writeEntry("input", "none"); protocolFile.writeEntry("output", "filesystem"); protocolFile.writeEntry("reading", "true"); protocolFile.writeEntry("DocPath", "kioslave/" + protocol + ".html"); protocolFile.sync(); } return 0; }