| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_codemaker.hxx" |
| |
| #include <algorithm> |
| #include <map> |
| #include <set> |
| #include <stdio.h> |
| #include <string.h> |
| #include <vector> |
| |
| #include "registry/reader.hxx" |
| #include "rtl/alloc.h" |
| #include "rtl/ustring.hxx" |
| #include "rtl/strbuf.hxx" |
| |
| #include "codemaker/dependencies.hxx" |
| #include "codemaker/exceptiontree.hxx" |
| #include "codemaker/generatedtypeset.hxx" |
| #include "codemaker/unotype.hxx" |
| |
| #include "cpputype.hxx" |
| #include "cppuoptions.hxx" |
| #include "dumputils.hxx" |
| #include "includes.hxx" |
| |
| using namespace rtl; |
| using namespace codemaker::cpp; |
| |
| namespace { |
| |
| rtl::OString translateSimpleUnoType(rtl::OString const & unoType, bool cppuUnoType=false) { |
| static rtl::OString const trans[codemaker::UnoType::SORT_COMPLEX + 1] = { |
| "void", "::sal_Bool", "::sal_Int8", "::sal_Int16", "::sal_uInt16", |
| "::sal_Int32", "::sal_uInt32", "::sal_Int64", "::sal_uInt64", "float", |
| "double", "::sal_Unicode", "::rtl::OUString", |
| "::com::sun::star::uno::Type", "::com::sun::star::uno::Any", |
| rtl::OString() }; |
| |
| const codemaker::UnoType::Sort sort = codemaker::UnoType::getSort(unoType); |
| if (cppuUnoType && |
| (sort == codemaker::UnoType::SORT_UNSIGNED_SHORT || |
| sort == codemaker::UnoType::SORT_CHAR) ) |
| { |
| if (sort == codemaker::UnoType::SORT_CHAR) |
| return "::cppu::UnoCharType"; |
| else |
| return "::cppu::UnoUnsignedShortType"; |
| } |
| |
| return trans[sort]; |
| } |
| |
| } |
| |
| //************************************************************************* |
| // CppuType |
| //************************************************************************* |
| CppuType::CppuType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : m_inheritedMemberCount(0) |
| , m_cppuTypeLeak(sal_False) |
| , m_cppuTypeDynamic(sal_True) |
| , m_indentLength(0) |
| , m_typeName(typeName) |
| , m_name(typeName.copy(typeName.lastIndexOf('/') + 1)) |
| , m_reader(typeReader) |
| , m_typeMgr(typeMgr) |
| , m_dependencies(typeMgr, typeName) |
| {} |
| |
| CppuType::~CppuType() |
| { |
| |
| } |
| |
| void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) |
| const |
| { |
| if (m_typeName.equals("com/sun/star/uno/XInterface") |
| || m_typeName.equals("com/sun/star/uno/Exception")) |
| { |
| includes.addType(); |
| includes.addCppuUnotypeHxx(); |
| includes.addSalTypesH(); |
| includes.addTypelibTypeclassH(); |
| includes.addTypelibTypedescriptionH(); |
| } else if (m_cppuTypeLeak) { |
| addLightGetCppuTypeIncludes(includes); |
| } else if (m_cppuTypeDynamic) { |
| addNormalGetCppuTypeIncludes(includes); |
| } else { |
| addComprehensiveGetCppuTypeIncludes(includes); |
| } |
| } |
| |
| bool CppuType::dumpFiles(CppuOptions * options, rtl::OString const & outPath) { |
| return dumpFile(options, ".hdl", m_typeName, outPath) |
| && dumpFile(options, ".hpp", m_typeName, outPath); |
| } |
| |
| void CppuType::addLightGetCppuTypeIncludes( |
| codemaker::cppumaker::Includes & includes) const |
| { |
| //TODO: Determine what is really needed, instead of relying on |
| // addDefaultHxxIncludes |
| includes.addCppuUnotypeHxx(); |
| } |
| |
| void CppuType::addNormalGetCppuTypeIncludes( |
| codemaker::cppumaker::Includes & includes) const |
| { |
| //TODO: Determine what is really needed, instead of relying on |
| // addDefaultHxxIncludes |
| includes.addCppuUnotypeHxx(); |
| } |
| |
| void CppuType::addComprehensiveGetCppuTypeIncludes( |
| codemaker::cppumaker::Includes & includes) const |
| { |
| //TODO: Determine what is really needed, instead of relying on |
| // addDefaultHxxIncludes |
| includes.addCppuUnotypeHxx(); |
| } |
| |
| bool CppuType::isPolymorphic() const { return false; } |
| |
| void CppuType::dumpTemplateHead(FileStream &) const {} |
| |
| void CppuType::dumpTemplateParameters(FileStream &) const {} |
| |
| void CppuType::dumpGetCppuTypePreamble(FileStream & out) { |
| if (isPolymorphic()) { |
| out << "namespace cppu {\n\n"; |
| dumpTemplateHead(out); |
| out << "class UnoType< "; |
| dumpType(out, m_typeName); |
| dumpTemplateParameters(out); |
| out << " > {\npublic:\n"; |
| inc(); |
| out << indent() |
| << "static inline ::com::sun::star::uno::Type const & get() {\n"; |
| } else { |
| if (codemaker::cppumaker::dumpNamespaceOpen(out, m_typeName, false)) { |
| out << "\n\n"; |
| } |
| out << ("inline ::com::sun::star::uno::Type const &" |
| " cppu_detail_getUnoType("); |
| dumpType(out, m_typeName, false, false, true); |
| out << " const *) {\n"; |
| } |
| inc(); |
| } |
| |
| void CppuType::dumpGetCppuTypePostamble(FileStream & out) { |
| dec(); |
| if (isPolymorphic()) { |
| out << indent() << "}\n\nprivate:\n" |
| << indent() << "UnoType(UnoType &); // not defined\n" |
| << indent() << "~UnoType(); // not defined\n" |
| << indent() |
| << "void operator =(UnoType); // not defined\n};\n\n}\n\n"; |
| } else { |
| out << "}\n\n"; |
| if (codemaker::cppumaker::dumpNamespaceClose(out, m_typeName, false)) { |
| out << "\n\n"; |
| } |
| } |
| dumpTemplateHead(out); |
| out << "inline ::com::sun::star::uno::Type const & SAL_CALL getCppuType("; |
| dumpType(out, m_typeName); |
| dumpTemplateParameters(out); |
| out << " const *) SAL_THROW(()) {\n"; |
| inc(); |
| out << indent() << "return ::cppu::UnoType< "; |
| dumpType(out, m_typeName); |
| dumpTemplateParameters(out); |
| out << " >::get();\n"; |
| dec(); |
| out << indent() << "}\n"; |
| } |
| |
| sal_Bool CppuType::dump(CppuOptions* pOptions) |
| throw( CannotDumpException ) |
| { |
| if (!m_dependencies.isValid()) { |
| return false; |
| } |
| addSpecialDependencies(); |
| |
| // -CS was used as an undocumented option to generate static getCppuType |
| // functions; since the introduction of cppu::UnoType this no longer is |
| // meaningful (getCppuType is just a forward to cppu::UnoType::get now), and |
| // -CS is handled the same way as -C now: |
| if (pOptions->isValid("-L")) |
| m_cppuTypeLeak = sal_True; |
| if (pOptions->isValid("-C") || pOptions->isValid("-CS")) |
| m_cppuTypeDynamic = sal_False; |
| |
| OString outPath; |
| if (pOptions->isValid("-O")) |
| outPath = pOptions->getOption("-O"); |
| |
| return dumpFiles(pOptions, outPath); |
| } |
| |
| sal_Bool CppuType::dumpFile(CppuOptions* pOptions, |
| const OString& sExtension, |
| const OString& sName, |
| const OString& sOutPath ) |
| throw( CannotDumpException ) |
| { |
| sal_Bool ret = sal_False; |
| |
| OString sTmpExt(".tml"); |
| sal_Bool bHdl = sal_True; ; |
| if (sExtension.equals(".hpp")) { |
| sTmpExt = ".tmp"; |
| bHdl = sal_False; |
| } |
| |
| OString sFileName = createFileNameFromType(sOutPath, sName, sExtension); |
| if ( sFileName.isEmpty() ) |
| return sal_False; |
| |
| sal_Bool bFileExists = fileExists( sFileName ); |
| sal_Bool bFileCheck = sal_False; |
| |
| if ( bFileExists && pOptions->isValid("-G") ) |
| return sal_True; |
| |
| if ( bFileExists && pOptions->isValid("-Gc") ) |
| bFileCheck = sal_True; |
| |
| OString sTmpDir = getTempDir(sFileName); |
| FileStream oFile; |
| oFile.createTempFile(sTmpDir); |
| OString sTmpFileName; |
| |
| if(!oFile.isValid()) |
| { |
| OString message("cannot open "); |
| message += sFileName + " for writing"; |
| throw CannotDumpException(message); |
| } else |
| sTmpFileName = oFile.getName(); |
| |
| codemaker::cppumaker::Includes includes(m_typeMgr, m_dependencies, !bHdl); |
| if (bHdl) |
| ret = dumpHFile(oFile, includes); |
| else { |
| addGetCppuTypeIncludes(includes); |
| ret = dumpHxxFile(oFile, includes); |
| } |
| |
| oFile.close(); |
| |
| if (ret) { |
| ret = makeValidTypeFile(sFileName, sTmpFileName, bFileCheck); |
| } else { |
| // remove existing type file if something goes wrong to ensure consistency |
| if (fileExists(sFileName)) |
| removeTypeFile(sFileName); |
| |
| // remove tmp file if something goes wrong |
| removeTypeFile(sTmpFileName); |
| } |
| |
| return ret; |
| } |
| |
| void CppuType::dumpDependedTypes( |
| codemaker::GeneratedTypeSet & generated, CppuOptions * options) |
| { |
| codemaker::Dependencies::Map const & map(m_dependencies.getMap()); |
| for (codemaker::Dependencies::Map::const_iterator i(map.begin()); |
| i != map.end(); ++i) |
| { |
| if (!produceType(i->first, m_typeMgr, generated, options)) { |
| fprintf( |
| stderr, "%s ERROR: cannot dump Type '%s'\n", |
| options->getProgramName().getStr(), i->first.getStr()); |
| exit(99); |
| } |
| } |
| } |
| |
| OString CppuType::dumpHeaderDefine( |
| FileStream& o, char const * prefix, sal_Bool bExtended) |
| { |
| if (m_typeName.equals("/")) |
| { |
| bExtended = sal_False; |
| m_typeName = "global"; |
| } |
| |
| sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix); |
| |
| if (bExtended) |
| length += m_name.getLength() + 1; |
| |
| OStringBuffer tmpBuf(length); |
| |
| tmpBuf.append("INCLUDED_"); |
| tmpBuf.append(m_typeName); |
| tmpBuf.append('_'); |
| if (bExtended) |
| { |
| tmpBuf.append(m_name); |
| tmpBuf.append('_'); |
| } |
| tmpBuf.append(prefix); |
| |
| OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); |
| |
| o << "#ifndef " << tmp << "\n#define " << tmp << "\n"; |
| |
| return tmp; |
| } |
| |
| void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes & includes) |
| const |
| { |
| //TODO: Only include what is really needed |
| includes.addCppuMacrosHxx(); |
| if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE) { |
| includes.addReference(); |
| } |
| } |
| |
| void CppuType::addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes) |
| const |
| { |
| //TODO: Only include what is really needed |
| includes.addOslMutexHxx(); |
| includes.addType(); |
| if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE) { |
| includes.addReference(); |
| } |
| } |
| |
| void CppuType::dumpInitializer( |
| FileStream & out, bool parameterized, rtl::OUString const & type) const |
| { |
| out << "("; |
| if (!parameterized) { |
| for (rtl::OString t( |
| rtl::OUStringToOString(type, RTL_TEXTENCODING_UTF8));;) |
| { |
| sal_Int32 rank; |
| std::vector< rtl::OString > args; |
| t = codemaker::UnoType::decompose(t, &rank, &args); |
| if (rank == 0) { |
| switch (codemaker::UnoType::getSort(t)) { |
| case codemaker::UnoType::SORT_BOOLEAN: |
| out << "false"; |
| break; |
| |
| case codemaker::UnoType::SORT_BYTE: |
| case codemaker::UnoType::SORT_SHORT: |
| case codemaker::UnoType::SORT_UNSIGNED_SHORT: |
| case codemaker::UnoType::SORT_LONG: |
| case codemaker::UnoType::SORT_UNSIGNED_LONG: |
| case codemaker::UnoType::SORT_HYPER: |
| case codemaker::UnoType::SORT_UNSIGNED_HYPER: |
| case codemaker::UnoType::SORT_FLOAT: |
| case codemaker::UnoType::SORT_DOUBLE: |
| case codemaker::UnoType::SORT_CHAR: |
| out << "0"; |
| break; |
| |
| case codemaker::UnoType::SORT_COMPLEX: |
| switch (m_typeMgr.getTypeClass(t)) { |
| case RT_TYPE_ENUM: |
| { |
| typereg::Reader reader(m_typeMgr.getTypeReader(t)); |
| OSL_ASSERT(reader.isValid()); |
| out << scopedCppName(t) << "_" |
| << rtl::OUStringToOString( |
| reader.getFieldName(0), |
| RTL_TEXTENCODING_UTF8); |
| break; |
| } |
| |
| case RT_TYPE_TYPEDEF: |
| t = resolveTypedefs(t); |
| continue; |
| |
| default: |
| break; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| } |
| break; |
| } |
| } |
| out << ")"; |
| } |
| |
| void CppuType::dumpGetCppuType(FileStream & out) { |
| if (m_typeName.equals("com/sun/star/uno/XInterface")) { |
| out << indent() |
| << ("inline ::com::sun::star::uno::Type const & SAL_CALL" |
| " getCppuType("); |
| dumpType(out, m_typeName, true, false); |
| out << " *) SAL_THROW(()) {\n"; |
| inc(); |
| out << indent() |
| << ("return ::cppu::UnoType< ::com::sun::star::uno::XInterface" |
| " >::get();\n"); |
| dec(); |
| out << indent() << "}\n"; |
| } else if (m_typeName.equals("com/sun/star/uno/Exception")) { |
| out << indent() |
| << ("inline ::com::sun::star::uno::Type const & SAL_CALL" |
| " getCppuType("); |
| dumpType(out, m_typeName, true, false); |
| out << " *) SAL_THROW(()) {\n"; |
| inc(); |
| out << indent() |
| << ("return ::cppu::UnoType< ::com::sun::star::uno::Exception" |
| " >::get();\n"); |
| dec(); |
| out << indent() << "}\n"; |
| } else if (m_cppuTypeLeak) { |
| dumpLightGetCppuType(out); |
| } else if (m_cppuTypeDynamic) { |
| dumpNormalGetCppuType(out); |
| } else { |
| dumpComprehensiveGetCppuType(out); |
| } |
| } |
| |
| void CppuType::dumpLightGetCppuType(FileStream& o) |
| { |
| dumpGetCppuTypePreamble(o); |
| o << indent() |
| << "static typelib_TypeDescriptionReference * the_type = 0;\n"; |
| |
| o << indent() << "if ( !the_type )\n" << indent() << "{\n"; |
| inc(); |
| o << indent() << "typelib_static_type_init( &the_type, " |
| << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\" );\n"; |
| dec(); |
| o << indent() << "}\n"; |
| o << indent() |
| << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >(" |
| " &the_type );\n"); |
| dumpGetCppuTypePostamble(o); |
| } |
| |
| void CppuType::dumpNormalGetCppuType(FileStream& o) |
| { |
| dumpGetCppuTypePreamble(o); |
| |
| o << indent() |
| << "static typelib_TypeDescriptionReference * the_type = 0;\n"; |
| |
| o << indent() << "if ( !the_type )\n" << indent() << "{\n"; |
| inc(); |
| |
| OString superType; |
| if (m_reader.getSuperTypeCount() >= 1) { |
| superType = rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| sal_Bool bIsBaseException = sal_False; |
| if ( !superType.isEmpty() ) |
| { |
| if ( superType.equals("com/sun/star/uno/Exception") ) |
| { |
| bIsBaseException = sal_True; |
| } else |
| { |
| o << indent() << "const ::com::sun::star::uno::Type& rBaseType = ::cppu::UnoType< "; |
| dumpType(o, superType, true, false, false, true); |
| o << " >::get();\n\n"; |
| } |
| } |
| |
| sal_uInt32 count = getMemberCount(); |
| if (count) |
| { |
| o << indent() << "typelib_TypeDescriptionReference * aMemberRefs[" << count << "];\n"; |
| |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldType, fieldName; |
| OString scope = m_typeName.replace('/', '.'); |
| OString modFieldType; |
| StringSet generatedTypeSet; |
| StringSet::iterator findIter; |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = checkRealBaseType( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8), |
| sal_True); |
| |
| modFieldType = typeToIdentifier(fieldType); |
| |
| findIter = generatedTypeSet.find(fieldType); |
| if ( findIter == generatedTypeSet.end() ) |
| { |
| generatedTypeSet.insert(fieldType); |
| o << indent() << "const ::com::sun::star::uno::Type& rMemberType_" |
| << modFieldType/*i*/ << " = ::cppu::UnoType< "; |
| dumpType(o, fieldType, false, false, false, true); |
| o << " >::get();\n"; |
| } |
| |
| o << indent() << "aMemberRefs[" << i << "] = rMemberType_" |
| << modFieldType/*i*/ << ".getTypeLibType();\n"; |
| } |
| o << "\n"; |
| } |
| |
| o << indent() << "typelib_static_compound_type_init( &the_type, " |
| << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\", "; |
| if ( !superType.isEmpty() || bIsBaseException ) |
| { |
| if ( bIsBaseException ) |
| { |
| o << "* ::typelib_static_type_getByTypeClass( typelib_TypeClass_EXCEPTION ), " |
| << count << ", "; |
| } else |
| { |
| o << "rBaseType.getTypeLibType(), " << count << ", "; |
| } |
| } else |
| { |
| o << "0, " << count << ", "; |
| } |
| |
| if (count) |
| { |
| o << " aMemberRefs );\n"; |
| } else |
| { |
| o << " 0 );\n"; |
| } |
| dec(); |
| o << indent() << "}\n"; |
| o << indent() |
| << ("return * reinterpret_cast< const ::com::sun::star::uno::Type * >(" |
| " &the_type );\n"); |
| |
| dumpGetCppuTypePostamble(o); |
| } |
| |
| void CppuType::dumpComprehensiveGetCppuType(FileStream& o) |
| { |
| dumpGetCppuTypePreamble(o); |
| |
| o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n"; |
| |
| o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; |
| inc(); |
| o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"; |
| |
| o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; |
| inc(); |
| o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << m_typeName.replace('/', '.') << "\") );\n\n"; |
| |
| o << indent() << "// Start inline typedescription generation\n" |
| << indent() << "typelib_TypeDescription * pTD = 0;\n"; |
| |
| OString superType; |
| if (m_reader.getSuperTypeCount() >= 1) { |
| superType = rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| if ( !superType.isEmpty() ) { |
| o << indent() |
| << "const ::com::sun::star::uno::Type& rSuperType = ::cppu::UnoType< "; |
| dumpType(o, superType, false, false, false, true); |
| o << " >::get();\n"; |
| } |
| |
| dumpCppuGetTypeMemberDecl(o, CPPUTYPEDECL_ALLTYPES); |
| |
| sal_uInt32 count = getMemberCount(); |
| if (count) |
| { |
| o << "\n" << indent() << "typelib_CompoundMember_Init aMembers[" |
| << count << "];\n"; |
| |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldType, fieldName; |
| OString scope = m_typeName.replace('/', '.'); |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) { |
| continue; |
| } |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = checkRealBaseType( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8), |
| sal_True); |
| |
| o << indent() << "::rtl::OUString sMemberType" << i |
| << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << fieldType.replace('/', '.') << "\") );\n"; |
| o << indent() << "::rtl::OUString sMemberName" << i |
| << "( RTL_CONSTASCII_USTRINGPARAM(\""; |
| o << fieldName << "\") );\n"; |
| o << indent() << "aMembers[" << i << "].eTypeClass = " |
| << "(typelib_TypeClass)" << getTypeClass(fieldType) << ";\n" |
| << indent() << "aMembers[" << i << "].pTypeName = sMemberType" |
| << i << ".pData;\n" |
| << indent() << "aMembers[" << i << "].pMemberName = sMemberName" |
| << i << ".pData;\n"; |
| } |
| } |
| |
| o << "\n" << indent() << "typelib_typedescription_new(\n"; |
| inc(); |
| o << indent() << "&pTD,\n" << indent() << "(typelib_TypeClass)" |
| << getTypeClass() << ", sTypeName.pData,\n"; |
| |
| if ( !superType.isEmpty() ) { |
| o << indent() << "rSuperType.getTypeLibType(),\n"; |
| } else { |
| o << indent() << "0,\n"; |
| } |
| |
| if ( count ) { |
| o << indent() << count << ",\n" << indent() << "aMembers );\n\n"; |
| } else { |
| o << indent() << count << ",\n" << indent() << "0 );\n\n"; |
| } |
| |
| dec(); |
| o << indent() |
| << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD" |
| " );\n\n"); |
| |
| o << indent() << "typelib_typedescription_release( pTD );\n" |
| << indent() << "// End inline typedescription generation\n\n"; |
| |
| o << indent() << "static ::com::sun::star::uno::Type the_staticType( " |
| << getTypeClass(m_typeName) << ", sTypeName );\n"; |
| o << indent() << "the_pType = &the_staticType;\n"; |
| |
| dec(); |
| o << indent() << "}\n"; |
| dec(); |
| o << indent() << "}\n\n"; |
| o << indent() << "return *the_pType;\n"; |
| dumpGetCppuTypePostamble(o); |
| } |
| |
| void CppuType::dumpCppuGetTypeMemberDecl(FileStream& o, CppuTypeDecl eDeclFlag) |
| { |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| |
| StringSet aFinishedTypes; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID |
| || (access & RT_ACCESS_PARAMETERIZED_TYPE) != 0) |
| continue; |
| |
| rtl::OString typeName( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); |
| if (aFinishedTypes.count(typeName) == 0) |
| { |
| aFinishedTypes.insert(typeName); |
| dumpCppuGetType(o, typeName, sal_True, eDeclFlag); |
| } |
| } |
| } |
| |
| IdentifierTranslationMode CppuType::isGlobal() const { |
| if ( m_typeName.indexOf('/') < 0 ) |
| return ITM_GLOBAL; |
| else |
| return ITM_NONGLOBAL; |
| } |
| |
| sal_uInt32 CppuType::getMemberCount() |
| { |
| sal_uInt16 count = m_reader.getMethodCount(); |
| |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) |
| count++; |
| } |
| return count; |
| } |
| |
| sal_uInt32 CppuType::checkInheritedMemberCount(const typereg::Reader* pReader) |
| { |
| sal_Bool bSelfCheck = sal_True; |
| if (!pReader) |
| { |
| bSelfCheck = sal_False; |
| pReader = &m_reader; |
| } |
| |
| sal_uInt32 count = 0; |
| OString superType; |
| if (pReader->getSuperTypeCount() >= 1) { |
| superType = rtl::OUStringToOString( |
| pReader->getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| if ( !superType.isEmpty() ) |
| { |
| typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType)); |
| if ( aSuperReader.isValid() ) |
| { |
| count = checkInheritedMemberCount(&aSuperReader); |
| } |
| } |
| |
| if (bSelfCheck) |
| { |
| count += pReader->getMethodCount(); |
| sal_uInt16 fieldCount = pReader->getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = pReader->getFieldFlags(i); |
| |
| if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) |
| { |
| count++; |
| } |
| } |
| } |
| |
| return count; |
| } |
| |
| sal_uInt32 CppuType::getInheritedMemberCount() |
| { |
| if (m_inheritedMemberCount == 0) |
| { |
| m_inheritedMemberCount = checkInheritedMemberCount(0); |
| } |
| |
| return m_inheritedMemberCount; |
| } |
| |
| OString CppuType::getTypeClass(const OString& type, sal_Bool bCStyle) |
| { |
| OString typeName = (!type.isEmpty() ? type : m_typeName); |
| RTTypeClass rtTypeClass = RT_TYPE_INVALID; |
| |
| if ( !type.isEmpty() ) |
| { |
| typeName = type; |
| rtTypeClass = m_typeMgr.getTypeClass(typeName); |
| } else |
| { |
| typeName = m_typeName; |
| rtTypeClass = m_reader.getTypeClass(); |
| } |
| |
| if (codemaker::UnoType::isSequenceType(typeName)) |
| return bCStyle ? "typelib_TypeClass_SEQUENCE" : "::com::sun::star::uno::TypeClass_SEQUENCE"; |
| |
| switch (rtTypeClass) |
| { |
| case RT_TYPE_INTERFACE: |
| return bCStyle ? "typelib_TypeClass_INTERFACE" : "::com::sun::star::uno::TypeClass_INTERFACE"; |
| case RT_TYPE_MODULE: |
| return bCStyle ? "typelib_TypeClass_MODULE" : "::com::sun::star::uno::TypeClass_MODULE"; |
| case RT_TYPE_STRUCT: |
| return bCStyle ? "typelib_TypeClass_STRUCT" : "::com::sun::star::uno::TypeClass_STRUCT"; |
| case RT_TYPE_ENUM: |
| return bCStyle ? "typelib_TypeClass_ENUM" : "::com::sun::star::uno::TypeClass_ENUM"; |
| case RT_TYPE_EXCEPTION: |
| return bCStyle ? "typelib_TypeClass_EXCEPTION" : "::com::sun::star::uno::TypeClass_EXCEPTION"; |
| case RT_TYPE_TYPEDEF: |
| { |
| OString realType = checkRealBaseType( typeName ); |
| return getTypeClass( realType, bCStyle ); |
| } |
| case RT_TYPE_SERVICE: |
| return bCStyle ? "typelib_TypeClass_SERVICE" : "::com::sun::star::uno::TypeClass_SERVICE"; |
| case RT_TYPE_INVALID: |
| { |
| if (type.equals("long")) |
| return bCStyle ? "typelib_TypeClass_LONG" : "::com::sun::star::uno::TypeClass_LONG"; |
| if (type.equals("short")) |
| return bCStyle ? "typelib_TypeClass_SHORT" : "::com::sun::star::uno::TypeClass_SHORT"; |
| if (type.equals("hyper")) |
| return bCStyle ? "typelib_TypeClass_HYPER" : "::com::sun::star::uno::TypeClass_HYPER"; |
| if (type.equals("string")) |
| return bCStyle ? "typelib_TypeClass_STRING" : "::com::sun::star::uno::TypeClass_STRING"; |
| if (type.equals("boolean")) |
| return bCStyle ? "typelib_TypeClass_BOOLEAN" : "::com::sun::star::uno::TypeClass_BOOLEAN"; |
| if (type.equals("char")) |
| return bCStyle ? "typelib_TypeClass_CHAR" : "::com::sun::star::uno::TypeClass_CHAR"; |
| if (type.equals("byte")) |
| return bCStyle ? "typelib_TypeClass_BYTE" : "::com::sun::star::uno::TypeClass_BYTE"; |
| if (type.equals("any")) |
| return bCStyle ? "typelib_TypeClass_ANY" : "::com::sun::star::uno::TypeClass_ANY"; |
| if (type.equals("type")) |
| return bCStyle ? "typelib_TypeClass_TYPE" : "::com::sun::star::uno::TypeClass_TYPE"; |
| if (type.equals("float")) |
| return bCStyle ? "typelib_TypeClass_FLOAT" : "::com::sun::star::uno::TypeClass_FLOAT"; |
| if (type.equals("double")) |
| return bCStyle ? "typelib_TypeClass_DOUBLE" : "::com::sun::star::uno::TypeClass_DOUBLE"; |
| if (type.equals("void")) |
| return bCStyle ? "typelib_TypeClass_VOID" : "::com::sun::star::uno::TypeClass_VOID"; |
| if (type.equals("unsigned long")) |
| return bCStyle ? "typelib_TypeClass_UNSIGNED_LONG" : "::com::sun::star::uno::TypeClass_UNSIGNED_LONG"; |
| if (type.equals("unsigned short")) |
| return bCStyle ? "typelib_TypeClass_UNSIGNED_SHORT" : "::com::sun::star::uno::TypeClass_UNSIGNED_SHORT"; |
| if (type.equals("unsigned hyper")) |
| return bCStyle ? "typelib_TypeClass_UNSIGNED_HYPER" : "::com::sun::star::uno::TypeClass_UNSIGNED_HYPER"; |
| } |
| break; |
| default: |
| OSL_ASSERT(false); |
| break; |
| } |
| |
| return bCStyle ? "typelib_TypeClass_UNKNOWN" : "::com::sun::star::uno::TypeClass_UNKNOWN"; |
| } |
| |
| void CppuType::dumpType(FileStream& o, const OString& type, |
| bool bConst, bool bRef, bool bNative, bool cppuUnoType) |
| const throw( CannotDumpException ) |
| { |
| sal_Int32 seqNum; |
| std::vector< rtl::OString > args; |
| rtl::OString relType( |
| codemaker::UnoType::decompose( |
| checkRealBaseType(type, true), &seqNum, &args)); |
| |
| RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); |
| |
| if (bConst) o << "const "; |
| |
| {for (sal_Int32 i = 0; i < seqNum; ++i) { |
| if (cppuUnoType) |
| o << "::cppu::UnoSequenceType< "; |
| else |
| o << "::com::sun::star::uno::Sequence< "; |
| }} |
| |
| switch (typeClass) |
| { |
| case RT_TYPE_INTERFACE: |
| if (bNative) |
| o << scopedCppName(relType); |
| else |
| o << "::com::sun::star::uno::Reference< " |
| << scopedCppName(relType) << " >"; |
| break; |
| case RT_TYPE_INVALID: |
| { |
| OString tmp(translateSimpleUnoType(relType, cppuUnoType)); |
| if ( !tmp.isEmpty() ) |
| { |
| o << tmp; |
| } else |
| throw CannotDumpException("Unknown type '" + relType + |
| "', incomplete type library."); |
| } |
| break; |
| case RT_TYPE_STRUCT: |
| case RT_TYPE_ENUM: |
| case RT_TYPE_TYPEDEF: |
| case RT_TYPE_EXCEPTION: |
| { |
| o << scopedCppName(relType); |
| if (!args.empty()) { |
| o << "< "; |
| for (std::vector< rtl::OString >::iterator i(args.begin()); |
| i != args.end(); ++i) |
| { |
| if (i != args.begin()) { |
| o << ", "; |
| } |
| dumpType(o, *i); |
| } |
| o << " >"; |
| } |
| break; |
| } |
| default: |
| OSL_ASSERT(false); |
| break; |
| } |
| |
| {for (sal_Int32 i = 0; i < seqNum; ++i) { |
| o << " >"; |
| }} |
| |
| if (bRef) o << "&"; |
| } |
| |
| void CppuType::dumpCppuGetType(FileStream& o, const OString& type, sal_Bool bDecl, CppuTypeDecl eDeclFlag) |
| { |
| rtl::OString relType( |
| codemaker::UnoType::decompose(checkRealBaseType(type, true))); |
| |
| if (eDeclFlag == CPPUTYPEDECL_ONLYINTERFACES) |
| { |
| if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) |
| { |
| o << indent() << "::cppu::UnoType< "; |
| dumpType(o, type, false, false, false, true); |
| o << " >::get()"; |
| |
| if (bDecl) |
| o << ";\n"; |
| } |
| } else |
| { |
| if (codemaker::UnoType::getSort(type) |
| != codemaker::UnoType::SORT_COMPLEX) |
| { |
| return; |
| } else |
| { |
| if (eDeclFlag == CPPUTYPEDECL_NOINTERFACES && |
| m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) |
| return; |
| |
| // if (m_typeMgr.getTypeClass(type) == RT_TYPE_TYPEDEF) |
| // { |
| // o << indent() << "get_" << type.replace('/', '_') << "_Type()"; |
| // } else |
| // { |
| o << indent() << "::cppu::UnoType< "; |
| dumpType(o, type, false, false, false, true); |
| o << " >::get()"; |
| // } |
| } |
| if (bDecl) |
| o << ";\n"; |
| } |
| } |
| |
| OString CppuType::typeToIdentifier(const OString& type) |
| { |
| sal_Int32 seqNum; |
| rtl::OString relType(codemaker::UnoType::decompose(type, &seqNum)); |
| OString sIdentifier; |
| |
| while( seqNum > 0 ) |
| { |
| sIdentifier += OString("seq"); |
| |
| if ( --seqNum == 0 ) |
| { |
| sIdentifier += OString("_"); |
| } |
| } |
| |
| sIdentifier += relType.replace( |
| ((codemaker::UnoType::getSort(relType) |
| == codemaker::UnoType::SORT_COMPLEX) |
| ? '/' : ' '), |
| '_'); |
| |
| // TODO: find better solution to create an identifier |
| sIdentifier = sIdentifier.replace('<', '_'); |
| sIdentifier = sIdentifier.replace('>', '_'); |
| sIdentifier = sIdentifier.replace(',', '_'); |
| |
| return sIdentifier; |
| } |
| |
| bool CppuType::passByReference(rtl::OString const & unoType) { |
| rtl::OString type(resolveTypedefs(unoType)); |
| switch (codemaker::UnoType::getSort(type)) { |
| default: |
| return false; |
| |
| case codemaker::UnoType::SORT_STRING: |
| case codemaker::UnoType::SORT_TYPE: |
| case codemaker::UnoType::SORT_ANY: |
| return true; |
| |
| case codemaker::UnoType::SORT_COMPLEX: |
| return m_typeMgr.getTypeClass(type) != RT_TYPE_ENUM; |
| } |
| } |
| |
| OString CppuType::resolveTypedefs(const OString& type) const |
| { |
| OString baseType(type); |
| |
| RegistryKey key; |
| RTTypeClass typeClass; |
| sal_Bool isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); |
| typereg::Reader reader; |
| |
| while (isTypeDef) |
| { |
| reader = m_typeMgr.getTypeReader(baseType); |
| |
| if (reader.isValid()) |
| { |
| typeClass = reader.getTypeClass(); |
| |
| if (typeClass == RT_TYPE_TYPEDEF) |
| baseType = rtl::OUStringToOString( |
| reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| else |
| isTypeDef = sal_False; |
| } else |
| { |
| break; |
| } |
| } |
| |
| return baseType; |
| } |
| |
| OString CppuType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly) const |
| { |
| sal_Int32 rank; |
| rtl::OString baseType(codemaker::UnoType::decompose(type, &rank)); |
| |
| RegistryKey key; |
| RTTypeClass typeClass; |
| sal_Bool mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); |
| typereg::Reader reader; |
| |
| while (mustBeChecked) |
| { |
| reader = m_typeMgr.getTypeReader(baseType); |
| |
| if (reader.isValid()) |
| { |
| typeClass = reader.getTypeClass(); |
| |
| if (typeClass == RT_TYPE_TYPEDEF) |
| { |
| sal_Int32 n; |
| baseType = codemaker::UnoType::decompose( |
| rtl::OUStringToOString( |
| reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8), |
| &n); |
| OSL_ASSERT(n <= SAL_MAX_INT32 - rank); //TODO |
| rank += n; |
| } else |
| mustBeChecked = sal_False; |
| } else |
| { |
| break; |
| } |
| } |
| |
| if (bResolveTypeOnly) { |
| rtl::OStringBuffer buf; |
| for (sal_Int32 i = 0; i < rank; ++i) { |
| buf.append(RTL_CONSTASCII_STRINGPARAM("[]")); |
| } |
| baseType = buf.makeStringAndClear() + baseType; |
| } |
| |
| return baseType; |
| } |
| |
| void CppuType::dumpConstantValue(FileStream& o, sal_uInt16 index) |
| { |
| RTConstValue constValue = m_reader.getFieldValue(index); |
| |
| switch (constValue.m_type) |
| { |
| case RT_TYPE_NONE: |
| break; |
| case RT_TYPE_BOOL: |
| if (constValue.m_value.aBool) |
| o << "sal_True"; |
| else |
| o << "sal_False"; |
| break; |
| case RT_TYPE_BYTE: |
| o << "(sal_Int8)" |
| << sal::static_int_cast< sal_Int8 >(constValue.m_value.aByte); |
| break; |
| case RT_TYPE_INT16: |
| o << "(sal_Int16)" << constValue.m_value.aShort; |
| break; |
| case RT_TYPE_UINT16: |
| o << "(sal_uInt16)" << constValue.m_value.aUShort; |
| break; |
| case RT_TYPE_INT32: |
| // Avoid C++ compiler warnings about (un)signedness of literal |
| // -2^31: |
| if (constValue.m_value.aLong == SAL_MIN_INT32) { |
| o << "SAL_MIN_INT32"; |
| } else { |
| o << "(sal_Int32)" << constValue.m_value.aLong; |
| } |
| break; |
| case RT_TYPE_UINT32: |
| o << "(sal_uInt32)" |
| << OString::valueOf( |
| static_cast< sal_Int64 >(constValue.m_value.aULong)).getStr() |
| << "U"; |
| break; |
| case RT_TYPE_INT64: |
| // Avoid C++ compiler warnings about (un)signedness of literal |
| // -2^63: |
| if (constValue.m_value.aHyper == SAL_MIN_INT64) { |
| o << "SAL_MIN_INT64"; |
| } else { |
| ::rtl::OString tmp(OString::valueOf(constValue.m_value.aHyper)); |
| o << "(sal_Int64) SAL_CONST_INT64(" << tmp.getStr() << ")"; |
| } |
| break; |
| case RT_TYPE_UINT64: |
| { |
| o << "SAL_CONST_UINT64("; |
| sal_uInt64 n = constValue.m_value.aUHyper; |
| if (n == 0) { |
| o << "0"; |
| } else { |
| std::vector< char > buf; |
| for (; n != 0; n /= 10) { |
| buf.push_back('0' + static_cast< char >(n % 10)); |
| } |
| for (std::vector< char >::reverse_iterator i(buf.rbegin()); |
| i != buf.rend(); ++i) |
| { |
| o << rtl::OString::valueOf(*i).getStr(); |
| } |
| } |
| o << ")"; |
| } |
| break; |
| case RT_TYPE_FLOAT: |
| { |
| ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) ); |
| o << "(float)" << tmp.getStr(); |
| } |
| break; |
| case RT_TYPE_DOUBLE: |
| { |
| ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) ); |
| o << "(double)" << tmp.getStr(); |
| } |
| break; |
| case RT_TYPE_STRING: |
| { |
| ::rtl::OUString aUStr(constValue.m_value.aString); |
| ::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US); |
| o << "::rtl::OUString::createFromAscii(\"" << aStr.getStr() << "\")"; |
| } |
| break; |
| } |
| } |
| |
| void CppuType::inc(sal_Int32 num) |
| { |
| m_indentLength += num; |
| } |
| |
| void CppuType::dec(sal_Int32 num) |
| { |
| m_indentLength = std::max< sal_Int32 >(m_indentLength - num, 0); |
| } |
| |
| OString CppuType::indent() const |
| { |
| OStringBuffer tmp(m_indentLength); |
| |
| for (sal_Int32 i=0; i < m_indentLength; i++) |
| { |
| tmp.append(' '); |
| } |
| return tmp.makeStringAndClear(); |
| } |
| |
| //************************************************************************* |
| // InterfaceType |
| //************************************************************************* |
| InterfaceType::InterfaceType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : CppuType(typeReader, typeName, typeMgr) |
| { |
| m_inheritedMemberCount = 0; |
| m_hasAttributes = sal_False; |
| m_hasMethods = sal_False; |
| } |
| |
| InterfaceType::~InterfaceType() |
| { |
| |
| } |
| |
| sal_Bool InterfaceType::dumpHFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HDL")); |
| o << "\n"; |
| |
| addDefaultHIncludes(includes); |
| if (m_reader.getMethodCount() != 0) { |
| includes.add("com/sun/star/uno/RuntimeException"); |
| } |
| includes.dump(o, 0); |
| o << ("\nnamespace com { namespace sun { namespace star { namespace uno {\n" |
| "class Type;\n} } } }\n\n"); |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| dumpDeclaration(o); |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| o << "\ninline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; |
| dumpType(o, m_typeName, sal_True, sal_False); |
| o << "* ) SAL_THROW( () );\n\n"; |
| |
| o << "#endif // "<< headerDefine << "\n"; |
| return sal_True; |
| } |
| |
| sal_Bool InterfaceType::dumpDeclaration(FileStream& o) |
| throw( CannotDumpException ) |
| { |
| // rtl::OString cppName(translateUnoToCppIdentifier( |
| // m_name, "interface", ITM_KEYWORDSONLY, &m_name)); |
| |
| // o << "\nclass SAL_NO_VTABLE " << cppName; |
| o << "\nclass SAL_NO_VTABLE " << m_name; |
| |
| for (sal_Int16 i = 0; i < m_reader.getSuperTypeCount(); ++i) { |
| o << (i == 0 ? " :" : ",") << " public " |
| << scopedCppName(rtl::OUStringToOString( |
| m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8)); |
| } |
| |
| o << "\n{\npublic:\n"; |
| |
| inc(); |
| |
| dumpAttributes(o); |
| dumpMethods(o); |
| |
| o << "\n" << indent() |
| << ("static inline ::com::sun::star::uno::Type const & SAL_CALL" |
| " static_type(void * = 0);\n"); |
| |
| dec(); |
| o << "};\n\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool InterfaceType::dumpHxxFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HPP")); |
| o << "\n"; |
| |
| addDefaultHxxIncludes(includes); |
| includes.dump(o, &m_typeName); |
| o << "\n"; |
| |
| dumpGetCppuType(o); |
| |
| // rtl::OString cppName(translateUnoToCppIdentifier( |
| // m_name, "interface", ITM_KEYWORDSONLY, &m_name)); |
| |
| o << "\n::com::sun::star::uno::Type const & " |
| << scopedCppName(m_typeName) |
| << "::static_type(void *) {\n"; |
| inc(); |
| o << indent() << "return ::getCppuType(static_cast< "; |
| dumpType(o, m_typeName); |
| o << " * >(0));\n"; |
| dec(); |
| o << "}\n"; |
| |
| o << "\n#endif // "<< headerDefine << "\n"; |
| return sal_True; |
| } |
| |
| void InterfaceType::dumpAttributes(FileStream& o) |
| { |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| sal_Bool first=sal_True; |
| |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| rtl::OUString name(m_reader.getFieldName(i)); |
| fieldName = rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (first) |
| { |
| first = sal_False; |
| o << "\n" << indent() << "// Attributes\n"; |
| } |
| |
| o << indent() << "virtual "; |
| dumpType(o, fieldType); |
| o << " SAL_CALL get" << fieldName << "()"; |
| dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_GET); |
| o << " = 0;\n"; |
| |
| if ((access & RT_ACCESS_READONLY) == 0) |
| { |
| bool byRef = passByReference(fieldType); |
| o << indent() << "virtual void SAL_CALL set" << fieldName << "( "; |
| dumpType(o, fieldType, byRef, byRef); |
| o << " _" << fieldName.toAsciiLowerCase() << " )"; |
| dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_SET); |
| o << " = 0;\n"; |
| } |
| } |
| } |
| |
| void InterfaceType::dumpMethods(FileStream& o) |
| { |
| sal_uInt16 methodCount = m_reader.getMethodCount(); |
| sal_Bool first=sal_True; |
| |
| OString methodName, returnType, paramType, paramName; |
| sal_uInt16 paramCount = 0; |
| RTMethodMode methodMode = RT_MODE_INVALID; |
| RTParamMode paramMode = RT_PARAM_INVALID; |
| |
| sal_Bool bRef = sal_False; |
| sal_Bool bConst = sal_False; |
| sal_Bool bWithRunTimeExcp = sal_True; |
| |
| for (sal_uInt16 i=0; i < methodCount; i++) |
| { |
| methodMode = m_reader.getMethodFlags(i); |
| if (methodMode == RT_MODE_ATTRIBUTE_GET |
| || methodMode == RT_MODE_ATTRIBUTE_SET) |
| { |
| continue; |
| } |
| |
| methodName = rtl::OUStringToOString( |
| m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8); |
| returnType = rtl::OUStringToOString( |
| m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8); |
| paramCount = m_reader.getMethodParameterCount(i); |
| |
| if ( methodName.equals("acquire") || methodName.equals("release") ) |
| { |
| bWithRunTimeExcp = sal_False; |
| } |
| |
| if (first) |
| { |
| first = sal_False; |
| o << "\n" << indent() << "// Methods\n"; |
| } |
| |
| o << indent() << "virtual "; |
| dumpType(o, returnType); |
| o << " SAL_CALL " << methodName << "( "; |
| for (sal_uInt16 j=0; j < paramCount; j++) |
| { |
| paramName = rtl::OUStringToOString( |
| m_reader.getMethodParameterName(i, j), RTL_TEXTENCODING_UTF8); |
| paramType = rtl::OUStringToOString( |
| m_reader.getMethodParameterTypeName(i, j), |
| RTL_TEXTENCODING_UTF8); |
| paramMode = m_reader.getMethodParameterFlags(i, j); |
| |
| switch (paramMode) |
| { |
| case RT_PARAM_IN: |
| bConst = passByReference(paramType); |
| bRef = bConst; |
| break; |
| case RT_PARAM_OUT: |
| case RT_PARAM_INOUT: |
| bConst = sal_False; |
| bRef = sal_True; |
| break; |
| default: |
| break; |
| } |
| |
| dumpType(o, paramType, bConst, bRef); |
| // o << " " << translateUnoToCppIdentifier( |
| // paramName, "param", ITM_KEYWORDSONLY, NULL); |
| o << " " << paramName; |
| |
| if (j+1 < (sal_uInt16)paramCount) o << ", "; |
| } |
| o << " )"; |
| dumpExceptionSpecification(o, i, bWithRunTimeExcp); |
| o << " = 0;\n"; |
| } |
| } |
| |
| void InterfaceType::dumpNormalGetCppuType(FileStream& o) |
| { |
| dumpGetCppuTypePreamble(o); |
| |
| o << indent() |
| << "static typelib_TypeDescriptionReference * the_type = 0;\n"; |
| |
| o << indent() << "if ( !the_type )\n" << indent() << "{\n"; |
| inc(); |
| sal_Int16 nBases = m_reader.getSuperTypeCount(); |
| OSL_ASSERT(nBases > 0); |
| if (nBases == 1 |
| && m_reader.getSuperTypeName(0).equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface"))) |
| { |
| nBases = 0; |
| } |
| if (nBases > 0) { |
| o << indent() << "typelib_TypeDescriptionReference * aSuperTypes[" |
| << nBases << "];\n"; |
| for (sal_Int16 i = 0; i < nBases; ++i) { |
| o << indent() << "aSuperTypes[" << i << "] = ::cppu::UnoType< "; |
| dumpType( |
| o, |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8), |
| true, false, false, true); |
| o << " >::get().getTypeLibType();\n"; |
| } |
| } |
| |
| o << indent() << "typelib_static_mi_interface_type_init( &the_type, \"" |
| << m_typeName.replace('/', '.') << "\", " << nBases << ", "; |
| |
| if ( nBases > 0 ) |
| { |
| o << "aSuperTypes );\n"; |
| } else |
| { |
| o << "0 );\n"; |
| } |
| |
| dec(); |
| o << indent() << "}\n"; |
| o << indent() |
| << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >(" |
| " &the_type );\n"); |
| |
| dumpGetCppuTypePostamble(o); |
| } |
| |
| void InterfaceType::dumpComprehensiveGetCppuType(FileStream& o) |
| { |
| dumpGetCppuTypePreamble(o); |
| |
| o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n"; |
| |
| o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; |
| inc(); |
| o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"; |
| |
| o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; |
| inc(); |
| o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << m_typeName.replace('/', '.') << "\") );\n\n"; |
| |
| o << indent() << "// Start inline typedescription generation\n" |
| << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n\n"; |
| |
| OSL_ASSERT(m_reader.getSuperTypeCount() > 0); |
| o << indent() << "typelib_TypeDescriptionReference * aSuperTypes[" |
| << m_reader.getSuperTypeCount() << "];\n"; |
| for (sal_Int16 i = 0; i < m_reader.getSuperTypeCount(); ++i) { |
| o << indent() << "aSuperTypes[" << i << "] = ::cppu::UnoType< "; |
| dumpType( |
| o, |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8), |
| false, false, false, true); |
| o << " >::get().getTypeLibType();\n"; |
| } |
| |
| sal_uInt32 count = getMemberCount(); |
| if (count) |
| { |
| o << indent() << "typelib_TypeDescriptionReference * pMembers[" << count |
| << "] = { "; |
| for (sal_uInt32 i = 0; i < count; i++) |
| { |
| o << "0"; |
| if (i+1 < count) { |
| o << ","; |
| } else { |
| o << " };\n"; |
| } |
| } |
| |
| sal_uInt32 index = 0; |
| dumpCppuAttributeRefs(o, index); |
| dumpCppuMethodRefs(o, index); |
| } |
| |
| o << "\n" << indent() << "typelib_typedescription_newMIInterface(\n"; |
| inc(); |
| o << indent() << "&pTD,\n" << indent() << "sTypeName.pData, "; |
| |
| o << "0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000,\n"; // UIK |
| |
| o << indent() << m_reader.getSuperTypeCount() << ", aSuperTypes,\n"; |
| |
| if ( count ) { |
| o << indent() << count << ",\n" << indent() << "pMembers );\n\n"; |
| } else { |
| o << indent() << count << ",\n" << indent() << "0 );\n\n"; |
| } |
| dec(); |
| |
| o << indent() |
| << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD" |
| " );\n"); |
| if ( count ) |
| { |
| for (sal_uInt16 i=0; i < count; i++) |
| { |
| o << indent() |
| << "typelib_typedescriptionreference_release( pMembers[" << i |
| << "] );\n"; |
| } |
| } |
| o << indent() |
| << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD" |
| " );\n\n"); |
| |
| o << indent() << "static ::com::sun::star::uno::Type the_staticType( " |
| << getTypeClass(m_typeName) << ", sTypeName );\n"; |
| o << indent() << "the_pType = &the_staticType;\n"; |
| |
| StringSet aTypes; |
| // type for RuntimeException is always needed |
| OString sRunTimeExceptionType("com/sun/star/uno/RuntimeException"); |
| aTypes.insert(sRunTimeExceptionType); |
| dumpCppuGetType(o, sRunTimeExceptionType, sal_True, CPPUTYPEDECL_ALLTYPES); |
| |
| dumpAttributesCppuDecl(o, &aTypes, CPPUTYPEDECL_ALLTYPES); |
| dumpMethodsCppuDecl(o, &aTypes, CPPUTYPEDECL_ALLTYPES); |
| |
| if (count) |
| { |
| sal_uInt32 index = getInheritedMemberCount(); |
| dumpCppuAttributes(o, index); |
| dumpCppuMethods(o, index); |
| } |
| |
| o << indent() << "// End inline typedescription generation\n"; |
| |
| dec(); |
| o << indent() << "}\n"; |
| dec(); |
| o << indent() << "}\n\n" |
| << indent() << "return *the_pType;\n"; |
| |
| dumpGetCppuTypePostamble(o); |
| } |
| |
| void InterfaceType::dumpCppuAttributeRefs(FileStream& o, sal_uInt32& index) |
| { |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString scope = m_typeName.replace('/', '.'); |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| |
| o << indent() << "::rtl::OUString sAttributeName" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << scope.replace('/', '.') << "::" << fieldName << "\") );\n"; |
| o << indent() << "typelib_typedescriptionreference_new( &pMembers[" |
| << index << "],\n"; |
| inc(38); |
| o << indent() << "(typelib_TypeClass)::com::sun::star::uno::TypeClass_INTERFACE_ATTRIBUTE,\n" |
| << indent() << "sAttributeName" << i << ".pData );\n"; |
| dec(38); |
| index++; |
| } |
| } |
| |
| void InterfaceType::dumpCppuMethodRefs(FileStream& o, sal_uInt32& index) |
| { |
| sal_uInt16 methodCount = m_reader.getMethodCount(); |
| OString methodName; |
| OString scope = m_typeName.replace('/', '.'); |
| |
| for (sal_uInt16 i = 0; i < methodCount; i++) |
| { |
| RTMethodMode flags = m_reader.getMethodFlags(i); |
| if (flags == RT_MODE_ATTRIBUTE_GET || flags == RT_MODE_ATTRIBUTE_SET) { |
| continue; |
| } |
| |
| methodName = rtl::OUStringToOString( |
| m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8); |
| |
| o << indent() << "::rtl::OUString sMethodName" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << scope.replace('/', '.') << "::" << methodName << "\") );\n"; |
| o << indent() << "typelib_typedescriptionreference_new( &pMembers[" |
| << index << "],\n"; |
| inc(38); |
| o << indent() << "(typelib_TypeClass)::com::sun::star::uno::TypeClass_INTERFACE_METHOD,\n" |
| << indent() << "sMethodName" << i << ".pData );\n"; |
| dec(38); |
| index++; |
| } |
| } |
| |
| sal_uInt32 InterfaceType::getMemberCount() { |
| sal_uInt16 count = 0; |
| sal_uInt16 methodCount = m_reader.getMethodCount(); |
| {for (sal_uInt16 i = 0; i < methodCount; ++i) { |
| RTMethodMode flags = m_reader.getMethodFlags(i); |
| if (flags != RT_MODE_ATTRIBUTE_GET && flags != RT_MODE_ATTRIBUTE_SET) { |
| m_hasMethods = true; |
| ++count; |
| } |
| }} |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| {for (sal_uInt16 i = 0; i < fieldCount; ++i) { |
| RTFieldAccess flags = m_reader.getFieldFlags(i); |
| if (flags != RT_ACCESS_CONST && flags != RT_ACCESS_INVALID) { |
| m_hasAttributes = true; |
| ++count; |
| } |
| }} |
| return count; |
| } |
| |
| namespace { |
| |
| class BaseOffset { |
| public: |
| BaseOffset(TypeManager const & theManager, typereg::Reader const & reader); |
| |
| sal_Int32 get() const { return offset; } |
| |
| private: |
| void calculateBases(typereg::Reader const & reader); |
| |
| void calculate(typereg::Reader const & reader); |
| |
| TypeManager const & manager; |
| std::set< rtl::OString > set; |
| sal_Int32 offset; |
| }; |
| |
| BaseOffset::BaseOffset( |
| TypeManager const & theManager, typereg::Reader const & reader): |
| manager(theManager) |
| { |
| offset = 0; |
| calculateBases(reader); |
| } |
| |
| void BaseOffset::calculateBases(typereg::Reader const & reader) { |
| for (sal_Int16 i = 0; i < reader.getSuperTypeCount(); ++i) { |
| typereg::Reader super( |
| manager.getTypeReader( |
| rtl::OUStringToOString( |
| reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8))); |
| if (super.isValid()) { |
| calculate(super); |
| } |
| } |
| } |
| |
| void BaseOffset::calculate(typereg::Reader const & reader) { |
| if (set.insert( |
| rtl::OUStringToOString(reader.getTypeName(), RTL_TEXTENCODING_UTF8)) |
| .second) |
| { |
| calculateBases(reader); |
| {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) { |
| RTMethodMode flags = reader.getMethodFlags(i); |
| if (flags != RT_MODE_ATTRIBUTE_GET |
| && flags != RT_MODE_ATTRIBUTE_SET) |
| { |
| ++offset; |
| } |
| }} |
| {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) { |
| RTFieldAccess flags = reader.getFieldFlags(i); |
| if (flags != RT_ACCESS_CONST && flags != RT_ACCESS_INVALID) { |
| ++offset; |
| } |
| }} |
| } |
| } |
| |
| } |
| |
| void InterfaceType::addSpecialDependencies() { |
| if (m_reader.getMethodCount() > 0 || m_reader.getFieldCount() > 0) { |
| m_dependencies.add("com/sun/star/uno/RuntimeException"); |
| } |
| } |
| |
| void InterfaceType::addComprehensiveGetCppuTypeIncludes( |
| codemaker::cppumaker::Includes & includes) const |
| { |
| // The comprehensive getCppuType method always includes a line |
| // "getCppuType( (const ::com::sun::star::uno::RuntimeException*)0 );": |
| includes.addCppuUnotypeHxx(); |
| includes.add("com/sun/star/uno/RuntimeException"); |
| } |
| |
| sal_uInt32 InterfaceType::checkInheritedMemberCount(const typereg::Reader*) |
| { |
| return BaseOffset(m_typeMgr, m_reader).get(); |
| } |
| |
| sal_uInt32 InterfaceType::getInheritedMemberCount() |
| { |
| if (m_inheritedMemberCount == 0) |
| { |
| m_inheritedMemberCount = checkInheritedMemberCount(0); |
| } |
| |
| return m_inheritedMemberCount; |
| } |
| |
| void InterfaceType::dumpCppuAttributes(FileStream& o, sal_uInt32& index) |
| { |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| OString scope = m_typeName.replace('/', '.'); |
| |
| sal_uInt32 absoluteIndex = index; |
| |
| if (m_hasAttributes) |
| { |
| o << "\n" << indent() << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n"; |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| rtl::OUString name(m_reader.getFieldName(i)); |
| fieldName = rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8); |
| fieldType = checkRealBaseType( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8), |
| sal_True); |
| |
| o << indent() << "{\n"; |
| inc(); |
| o << indent() << "::rtl::OUString sAttributeType" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << fieldType.replace('/', '.') << "\") );\n"; |
| sal_Int32 getExceptions = dumpAttributeExceptionTypeNames( |
| o, "get", name, RT_MODE_ATTRIBUTE_GET); |
| sal_Int32 setExceptions = dumpAttributeExceptionTypeNames( |
| o, "set", name, RT_MODE_ATTRIBUTE_SET); |
| o << indent() |
| << ("typelib_typedescription_newExtendedInterfaceAttribute(" |
| " &pAttribute,\n"); |
| inc(); |
| o << indent() << absoluteIndex++ << ", sAttributeName" << i << ".pData,\n"; |
| o << indent() << "(typelib_TypeClass)" << getTypeClass(fieldType) |
| << ", sAttributeType" << i << ".pData,\n"; |
| o << indent() << "sal_" |
| << ((access & RT_ACCESS_READONLY) == 0 ? "False" : "True") << ", " |
| << getExceptions << ", " |
| << (getExceptions == 0 ? "0" : "the_getExceptions") << ", " |
| << setExceptions << ", " |
| << (setExceptions == 0 ? "0" : "the_setExceptions") << " );\n"; |
| dec(); |
| o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pAttribute );\n"; |
| dec(); |
| o << indent() << "}\n"; |
| } |
| o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pAttribute );\n"; |
| |
| index = absoluteIndex; |
| } |
| } |
| |
| void InterfaceType::dumpCppuMethods(FileStream& o, sal_uInt32& index) |
| { |
| sal_uInt16 methodCount = m_reader.getMethodCount(); |
| OString methodName, returnType, paramType, paramName; |
| sal_uInt16 paramCount = 0; |
| RTMethodMode methodMode = RT_MODE_INVALID; |
| RTParamMode paramMode = RT_PARAM_INVALID; |
| sal_Bool bWithRuntimeException = sal_True; |
| |
| sal_uInt32 absoluteIndex = index; |
| |
| if (m_hasMethods) |
| { |
| o << "\n" << indent() << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n"; |
| |
| for (sal_uInt16 i=0; i < methodCount; i++) |
| { |
| methodMode = m_reader.getMethodFlags(i); |
| if (methodMode == RT_MODE_ATTRIBUTE_GET |
| || methodMode == RT_MODE_ATTRIBUTE_SET) |
| { |
| continue; |
| } |
| |
| methodName = rtl::OUStringToOString( |
| m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8); |
| returnType = checkRealBaseType( |
| rtl::OUStringToOString( |
| m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8), |
| sal_True); |
| paramCount = m_reader.getMethodParameterCount(i); |
| |
| if ( methodName.equals("acquire") || methodName.equals("release") ) |
| { |
| bWithRuntimeException = sal_False; |
| } |
| |
| o << indent() << "{\n"; |
| inc(); |
| |
| if (paramCount) |
| { |
| o << indent() << "typelib_Parameter_Init aParameters[" << paramCount << "];\n"; |
| } |
| |
| sal_uInt16 j; |
| for (j=0; j < paramCount; j++) |
| { |
| paramName = rtl::OUStringToOString( |
| m_reader.getMethodParameterName(i, j), |
| RTL_TEXTENCODING_UTF8); |
| paramType = checkRealBaseType( |
| rtl::OUStringToOString( |
| m_reader.getMethodParameterTypeName(i, j), |
| RTL_TEXTENCODING_UTF8), |
| sal_True); |
| paramMode = m_reader.getMethodParameterFlags(i, j); |
| |
| o << indent() << "::rtl::OUString sParamName" << j << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << paramName << "\") );\n"; |
| o << indent() << "::rtl::OUString sParamType" << j << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << paramType.replace('/', '.') << "\") );\n"; |
| o << indent() << "aParameters[" << j << "].pParamName = sParamName" << j << ".pData;\n"; |
| o << indent() << "aParameters[" << j << "].eTypeClass = (typelib_TypeClass)" |
| << getTypeClass(paramType) << ";\n"; |
| o << indent() << "aParameters[" << j << "].pTypeName = sParamType" << j << ".pData;\n"; |
| |
| if (paramMode == RT_PARAM_IN || paramMode == RT_PARAM_INOUT) |
| o << indent() << "aParameters[" << j << "].bIn = sal_True;\n"; |
| else |
| o << indent() << "aParameters[" << j << "].bIn = sal_False;\n"; |
| |
| if (paramMode == RT_PARAM_OUT || paramMode == RT_PARAM_INOUT) |
| o << indent() << "aParameters[" << j << "].bOut = sal_True;\n"; |
| else |
| o << indent() << "aParameters[" << j << "].bOut = sal_False;\n"; |
| } |
| |
| sal_Int32 excCount = dumpExceptionTypeNames( |
| o, "", i, bWithRuntimeException); |
| |
| o << indent() << "::rtl::OUString sReturnType" << i << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << returnType.replace('/', '.') << "\") );\n"; |
| o << indent() << "typelib_typedescription_newInterfaceMethod( &pMethod,\n"; |
| inc(); |
| o << indent() << absoluteIndex++ << ", "; |
| if (methodMode == RT_MODE_ONEWAY || methodMode == RT_MODE_ONEWAY_CONST) |
| o << "sal_True,\n"; |
| else |
| o << "sal_False,\n"; |
| o << indent() << "sMethodName" << i << ".pData,\n"; |
| o << indent() << "(typelib_TypeClass)" << getTypeClass(returnType) |
| << ", sReturnType" << i << ".pData,\n"; |
| if (paramCount) |
| o << indent() << paramCount << ", aParameters,\n"; |
| else |
| o << indent() << "0, 0,\n"; |
| o << indent() << excCount << ", " |
| << (excCount == 0 ? "0" : "the_Exceptions") << " );\n"; |
| |
| dec(); |
| o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );\n"; |
| |
| dec(); |
| o << indent() << "}\n"; |
| } |
| o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pMethod );\n"; |
| |
| index = absoluteIndex; |
| } |
| } |
| |
| void InterfaceType::dumpAttributesCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag) |
| { |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (pFinishedTypes->count(fieldType) == 0) |
| { |
| pFinishedTypes->insert(fieldType); |
| dumpCppuGetType(o, fieldType, sal_True, eDeclFlag); |
| } |
| } |
| } |
| |
| void InterfaceType::dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag) |
| { |
| sal_uInt16 methodCount = m_reader.getMethodCount(); |
| OString returnType, paramType, excType; |
| sal_uInt16 paramCount = 0; |
| sal_uInt16 excCount = 0; |
| |
| for (sal_uInt16 i=0; i < methodCount; i++) |
| { |
| returnType = rtl::OUStringToOString( |
| m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8); |
| paramCount = m_reader.getMethodParameterCount(i); |
| excCount = m_reader.getMethodExceptionCount(i); |
| |
| if (pFinishedTypes->count(returnType) == 0) |
| { |
| pFinishedTypes->insert(returnType); |
| dumpCppuGetType(o, returnType, sal_True, eDeclFlag); |
| } |
| sal_uInt16 j; |
| for (j=0; j < paramCount; j++) |
| { |
| paramType = rtl::OUStringToOString( |
| m_reader.getMethodParameterTypeName(i, j), |
| RTL_TEXTENCODING_UTF8); |
| |
| if (pFinishedTypes->count(paramType) == 0) |
| { |
| pFinishedTypes->insert(paramType); |
| dumpCppuGetType(o, paramType, sal_True, eDeclFlag); |
| } |
| } |
| |
| for (j=0; j < excCount; j++) |
| { |
| excType = rtl::OUStringToOString( |
| m_reader.getMethodExceptionTypeName(i, j), |
| RTL_TEXTENCODING_UTF8); |
| if (pFinishedTypes->count(excType) == 0) |
| { |
| pFinishedTypes->insert(excType); |
| dumpCppuGetType(o, excType, sal_True, eDeclFlag); |
| } |
| } |
| } |
| } |
| |
| void InterfaceType::dumpExceptionSpecification( |
| FileStream & out, sal_uInt32 methodIndex, bool runtimeException) |
| { |
| out << " throw ("; |
| bool first = true; |
| if (methodIndex <= SAL_MAX_UINT16) { |
| sal_uInt16 count = m_reader.getMethodExceptionCount( |
| static_cast< sal_uInt16 >(methodIndex)); |
| for (sal_uInt16 i = 0; i < count; ++i) { |
| rtl::OUString name( |
| m_reader.getMethodExceptionTypeName( |
| static_cast< sal_uInt16 >(methodIndex), i)); |
| if (!name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( |
| "com/sun/star/uno/RuntimeException"))) |
| { |
| if (!first) { |
| out << ", "; |
| } |
| first = false; |
| out << scopedCppName( |
| rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8)); |
| } |
| } |
| } |
| if (runtimeException) { |
| if (!first) { |
| out << ", "; |
| } |
| out << "::com::sun::star::uno::RuntimeException"; |
| } |
| out << ")"; |
| } |
| |
| void InterfaceType::dumpAttributeExceptionSpecification( |
| FileStream & out, rtl::OUString const & name, RTMethodMode sort) |
| { |
| sal_uInt16 methodCount = m_reader.getMethodCount(); |
| for (sal_uInt16 i = 0; i < methodCount; ++i) { |
| if (m_reader.getMethodFlags(i) == sort |
| && m_reader.getMethodName(i) == name) |
| { |
| dumpExceptionSpecification(out, i, true); |
| return; |
| } |
| } |
| dumpExceptionSpecification(out, 0xFFFFFFFF, true); |
| } |
| |
| void InterfaceType::dumpExceptionTypeName( |
| FileStream & out, char const * prefix, sal_uInt32 index, rtl::OUString name) |
| { |
| out << indent() << "::rtl::OUString the_" << prefix << "ExceptionName" |
| << index << "(RTL_CONSTASCII_USTRINGPARAM(\"" |
| << rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).replace('/', '.') |
| << "\"));\n"; |
| } |
| |
| sal_Int32 InterfaceType::dumpExceptionTypeNames( |
| FileStream & out, char const * prefix, sal_uInt16 methodIndex, |
| bool runtimeException) |
| { |
| sal_Int32 count = 0; |
| sal_uInt16 n = m_reader.getMethodExceptionCount(methodIndex); |
| for (sal_uInt16 i = 0; i < n; ++i) { |
| rtl::OUString name(m_reader.getMethodExceptionTypeName(methodIndex, i)); |
| if (!name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( |
| "com/sun/star/uno/RuntimeException"))) |
| { |
| dumpExceptionTypeName(out, prefix, count++, name); |
| } |
| } |
| if (runtimeException) { |
| dumpExceptionTypeName( |
| out, prefix, count++, |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com/sun/star/uno/RuntimeException"))); |
| } |
| if (count > 0) { |
| out << indent() << "rtl_uString * the_" << prefix << "Exceptions[] = {"; |
| for (sal_Int32 i = 0; i < count; ++i) { |
| out << (i == 0 ? " " : ", ") << "the_" << prefix << "ExceptionName" |
| << i << ".pData"; |
| } |
| out << " };\n"; |
| } |
| return count; |
| } |
| |
| sal_Int32 InterfaceType::dumpAttributeExceptionTypeNames( |
| FileStream & out, char const * prefix, rtl::OUString const & name, |
| RTMethodMode sort) |
| { |
| sal_uInt16 methodCount = m_reader.getMethodCount(); |
| for (sal_uInt16 i = 0; i < methodCount; ++i) { |
| if (m_reader.getMethodFlags(i) == sort |
| && m_reader.getMethodName(i) == name) |
| { |
| return dumpExceptionTypeNames(out, prefix, i, false); |
| } |
| } |
| return 0; |
| } |
| |
| //************************************************************************* |
| // ConstantsType |
| //************************************************************************* |
| ConstantsType::ConstantsType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : CppuType(typeReader, typeName, typeMgr) |
| { |
| } |
| |
| ConstantsType::~ConstantsType() |
| { |
| |
| } |
| |
| sal_Bool ConstantsType::dump(CppuOptions* pOptions) |
| throw( CannotDumpException ) |
| { |
| if (!m_dependencies.isValid()) { |
| return false; |
| } |
| addSpecialDependencies(); |
| |
| if (pOptions->isValid("-U")) |
| m_cppuTypeDynamic = sal_True; |
| |
| OString outPath; |
| if (pOptions->isValid("-O")) |
| outPath = pOptions->getOption("-O"); |
| |
| return dumpFiles(pOptions, outPath); |
| } |
| |
| sal_Bool ConstantsType::dumpHFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| sal_Bool bSpecialDefine = sal_True; |
| |
| if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS) |
| { |
| bSpecialDefine = sal_False; |
| } |
| |
| OString headerDefine(dumpHeaderDefine(o, "HDL", bSpecialDefine)); |
| o << "\n"; |
| |
| addDefaultHIncludes(includes); |
| includes.dump(o, 0); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, true)) { |
| o << "\n"; |
| } |
| o << "\n"; |
| |
| dumpDeclaration(o); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, true)) { |
| o << "\n"; |
| } |
| o << "\n#endif // "<< headerDefine << "\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool ConstantsType::dumpDeclaration(FileStream& o) |
| throw( CannotDumpException ) |
| { |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| OString fieldName; |
| OString fieldType; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| o << "static const "; |
| dumpType(o, fieldType); |
| o << " " << fieldName << " = "; |
| dumpConstantValue(o, i); |
| o << ";\n"; |
| } |
| |
| return sal_True; |
| } |
| |
| sal_Bool ConstantsType::hasConstants() |
| { |
| return m_reader.getFieldCount() > 0; |
| } |
| |
| sal_Bool ConstantsType::dumpHxxFile( |
| FileStream& o, codemaker::cppumaker::Includes &) |
| throw( CannotDumpException ) |
| { |
| sal_Bool bSpecialDefine = sal_True; |
| |
| if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS) |
| { |
| bSpecialDefine = sal_False; |
| } |
| |
| OString headerDefine(dumpHeaderDefine(o, "HPP", bSpecialDefine)); |
| o << "\n"; |
| |
| rtl::OString suffix; |
| if (bSpecialDefine) { |
| suffix = m_name; |
| } |
| codemaker::cppumaker::Includes::dumpInclude(o, m_typeName, false, suffix); |
| |
| o << "\n#endif // "<< headerDefine << "\n"; |
| |
| return sal_True; |
| } |
| |
| //************************************************************************* |
| // ModuleType |
| //************************************************************************* |
| ModuleType::ModuleType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : ConstantsType(typeReader, typeName, typeMgr) |
| { |
| } |
| |
| ModuleType::~ModuleType() |
| { |
| |
| } |
| |
| bool ModuleType::dumpFiles( |
| CppuOptions * options, rtl::OString const & outPath) |
| { |
| rtl::OString tmpName(m_typeName); |
| if (tmpName.equals("/")) { |
| tmpName = "global"; |
| } else { |
| tmpName += "/" + m_typeName.copy(m_typeName.lastIndexOf('/') + 1); |
| } |
| return dumpFile(options, ".hdl", tmpName, outPath) |
| && dumpFile(options, ".hpp", tmpName, outPath); |
| } |
| |
| //************************************************************************* |
| // StructureType |
| //************************************************************************* |
| |
| namespace { |
| |
| void dumpTypeParameterName(FileStream & out, rtl::OString const & name) { |
| // Prefix all type parameters with "typeparam_" to avoid problems when a |
| // struct member has the same name as a type parameter, as in |
| // struct<T> { T T; }; |
| out << "typeparam_" << name; |
| } |
| |
| } |
| |
| StructureType::StructureType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : CppuType(typeReader, typeName, typeMgr) |
| { |
| } |
| |
| StructureType::~StructureType() |
| { |
| |
| } |
| |
| sal_Bool StructureType::dumpHFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HDL")); |
| o << "\n"; |
| |
| addDefaultHIncludes(includes); |
| includes.dump(o, 0); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| dumpDeclaration(o); |
| |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" |
| << "class Type;\n} } } }\n\n"; |
| |
| dumpTemplateHead(o); |
| o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; |
| dumpType(o, m_typeName, sal_True, sal_False); |
| dumpTemplateParameters(o); |
| o << "* );\n\n"; |
| |
| o << "#endif // "<< headerDefine << "\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool StructureType::dumpDeclaration(FileStream& o) |
| throw( CannotDumpException ) |
| { |
| o << "\n#ifdef SAL_W32\n" |
| << "# pragma pack(push, 8)\n" |
| << "#elif defined(SAL_OS2)\n" |
| << "# pragma pack(8)\n" |
| << "#endif\n\n"; |
| |
| OSL_ASSERT(!isPolymorphic() || m_reader.getSuperTypeCount() == 0); //TODO |
| o << indent(); |
| dumpTemplateHead(o); |
| o << "struct " << m_name; |
| rtl::OString base; |
| if (m_reader.getSuperTypeCount() != 0) { |
| base = rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| OSL_ASSERT( !base.isEmpty() ); //TODO |
| } |
| if ( !base.isEmpty() ) { |
| o << ": public " << scopedCppName(base); |
| } |
| o << " {\n"; |
| inc(); |
| o << indent() << "inline " << m_name << "() SAL_THROW(());\n"; |
| sal_uInt16 members = m_reader.getFieldCount(); |
| if (members > 0 || getInheritedMemberCount() > 0) { |
| o << "\n" << indent() << "inline " << m_name << "("; |
| bool prev = dumpSuperMember(o, base, true); |
| for (sal_uInt16 i = 0; i < members; ++i) { |
| if (prev) { |
| o << ", "; |
| } |
| prev = true; |
| rtl::OString type( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); |
| if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) |
| { |
| dumpTypeParameterName(o, type); |
| o << " const &"; |
| } else { |
| dumpType(o, type, true, true); |
| } |
| o << " " |
| << rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) |
| << "_"; |
| } |
| o << ") SAL_THROW(());\n"; |
| } |
| if (members > 0) { |
| o << "\n"; |
| for (sal_uInt16 i = 0; i < members; ++i) { |
| o << indent(); |
| bool parameterized |
| = ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) |
| != 0); |
| rtl::OString type( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); |
| if (parameterized) { |
| dumpTypeParameterName(o, type); |
| } else { |
| dumpType(o, type); |
| } |
| o << " " |
| << rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| if (i == 0 && !base.isEmpty() && type != "double" |
| && type != "hyper" && type != "unsigned hyper") |
| { |
| OSL_ASSERT(!parameterized); |
| o << " CPPU_GCC3_ALIGN(" << scopedCppName(base) << ")"; |
| } |
| o << ";\n"; |
| } |
| } |
| dec(); |
| o << "};\n\n"; |
| |
| o << "#ifdef SAL_W32\n" |
| << "# pragma pack(pop)\n" |
| << "#elif defined(SAL_OS2)\n" |
| << "# pragma pack()\n" |
| << "#endif\n\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool StructureType::dumpHxxFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HPP")); |
| o << "\n"; |
| |
| includes.dump(o, &m_typeName); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| o << "\n"; |
| |
| dumpTemplateHead(o); |
| o << "inline " << m_name; |
| dumpTemplateParameters(o); |
| o << "::" << m_name << "() SAL_THROW( () )\n"; |
| inc(); |
| OString superType; |
| if (m_reader.getSuperTypeCount() >= 1) { |
| superType = rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| sal_Bool first = sal_True; |
| if ( !superType.isEmpty() ) |
| { |
| o << indent() << ": " << scopedCppName(superType) << "()\n"; |
| first = sal_False; |
| } |
| |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (first) |
| { |
| first = sal_False; |
| o << indent() << ": "; |
| } else |
| o << indent() << ", "; |
| |
| o << fieldName; |
| dumpInitializer( |
| o, (access & RT_ACCESS_PARAMETERIZED_TYPE) != 0, |
| m_reader.getFieldTypeName(i)); |
| o << "\n"; |
| } |
| dec(); |
| o << "{\n}\n\n"; |
| |
| if (fieldCount > 0 || getInheritedMemberCount() > 0) |
| { |
| dumpTemplateHead(o); |
| o << "inline " << m_name; |
| dumpTemplateParameters(o); |
| o << "::" << m_name << "("; |
| |
| sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True); |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (superHasMember) |
| o << ", "; |
| else |
| superHasMember = sal_True; |
| |
| if ((access & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { |
| dumpTypeParameterName(o, fieldType); |
| o << " const &"; |
| } else { |
| dumpType(o, fieldType, sal_True, sal_True); |
| } |
| // o << " __" << fieldName; |
| o << " " << fieldName << "_"; |
| } |
| o << ") SAL_THROW( () )\n"; |
| |
| inc(); |
| first = sal_True; |
| if ( !superType.isEmpty() ) |
| { |
| o << indent() << ": " << scopedCppName(superType) << "("; |
| dumpSuperMember(o, superType, sal_False); |
| o << ")\n"; |
| first = sal_False; |
| } |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (first) |
| { |
| first = sal_False; |
| o << indent() << ": "; |
| } else |
| o << indent() << ", "; |
| |
| // o << fieldName << "(__" << fieldName << ")\n"; |
| o << fieldName << "(" << fieldName << "_)\n"; |
| } |
| |
| dec(); |
| o << "{\n}\n\n"; |
| } |
| |
| if (isPolymorphic() && fieldCount > 0) { |
| o << indent(); |
| dumpTemplateHead(o); |
| o << "\n"; |
| o << indent(); |
| o << "inline " << m_name; |
| dumpTemplateParameters(o); |
| o << "\n"; |
| o << indent(); |
| o << "make_" << m_name << "("; |
| for (sal_uInt16 i = 0; i < fieldCount; ++i) { |
| if (i > 0) { |
| o << ", "; |
| } |
| rtl::OString type( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); |
| if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) |
| { |
| dumpTypeParameterName(o, type); |
| o << " const &"; |
| } else { |
| dumpType(o, type, true, true); |
| } |
| o << " " |
| << rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) |
| << "_"; |
| } |
| o << ") SAL_THROW(())\n"; |
| o << indent() << "{\n"; |
| inc(); |
| o << indent() << "return " << m_name; |
| dumpTemplateParameters(o); |
| o << "("; |
| for (sal_uInt16 i = 0; i < fieldCount; ++i) { |
| if (i > 0) { |
| o << ", "; |
| } |
| o << rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) |
| << "_"; |
| } |
| o << ");\n"; |
| dec(); |
| o << indent() << "}\n\n"; |
| } |
| |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| o << "\n"; |
| dumpGetCppuType(o); |
| |
| o << "\n#endif // "<< headerDefine << "\n"; |
| |
| return sal_True; |
| } |
| |
| void StructureType::dumpLightGetCppuType(FileStream & out) { |
| dumpGetCppuTypePreamble(out); |
| out << indent() |
| << ("//TODO: On certain platforms with weak memory models, the" |
| " following code can result in some threads observing that the_type" |
| " points to garbage\n") |
| << indent() |
| << "static ::typelib_TypeDescriptionReference * the_type = 0;\n" |
| << indent() << "if (the_type == 0) {\n"; |
| inc(); |
| if (isPolymorphic()) { |
| out << indent() << "::rtl::OStringBuffer the_buffer(\"" |
| << m_typeName.replace('/', '.') << "<\");\n"; |
| sal_uInt16 n = m_reader.getReferenceCount(); |
| for (sal_uInt16 i = 0; i < n; ++i) { |
| out << indent() |
| << ("the_buffer.append(::rtl::OUStringToOString(" |
| "::cppu::getTypeFavourChar(static_cast< "); |
| dumpTypeParameterName( |
| out, |
| rtl::OUStringToOString( |
| m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); |
| out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n"; |
| if (i != n - 1) { |
| out << indent() << "the_buffer.append(',');\n"; |
| } |
| } |
| out << indent() << "the_buffer.append('>');\n"; |
| } |
| out << indent() << "::typelib_static_type_init(&the_type, " |
| << getTypeClass(m_typeName, true) << ", "; |
| if (isPolymorphic()) { |
| out << "the_buffer.getStr()"; |
| } else { |
| out << "\"" << m_typeName.replace('/', '.') << "\""; |
| } |
| out << ");\n"; |
| dec(); |
| out << indent() << "}\n" << indent() |
| << ("return *reinterpret_cast< ::com::sun::star::uno::Type * >(" |
| "&the_type);\n"); |
| dumpGetCppuTypePostamble(out); |
| } |
| |
| void StructureType::dumpNormalGetCppuType(FileStream & out) { |
| dumpGetCppuTypePreamble(out); |
| out << indent() |
| << ("//TODO: On certain platforms with weak memory models, the" |
| " following code can result in some threads observing that the_type" |
| " points to garbage\n") |
| << indent() |
| << "static ::typelib_TypeDescriptionReference * the_type = 0;\n" |
| << indent() << "if (the_type == 0) {\n"; |
| inc(); |
| if (isPolymorphic()) { |
| out << indent() << "::rtl::OStringBuffer the_buffer(\"" |
| << m_typeName.replace('/', '.') << "<\");\n"; |
| sal_uInt16 n = m_reader.getReferenceCount(); |
| for (sal_uInt16 i = 0; i < n; ++i) { |
| out << indent() |
| << ("the_buffer.append(::rtl::OUStringToOString(" |
| "::cppu::getTypeFavourChar(static_cast< "); |
| dumpTypeParameterName( |
| out, |
| rtl::OUStringToOString( |
| m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); |
| out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n"; |
| if (i != n - 1) { |
| out << indent() << "the_buffer.append(',');\n"; |
| } |
| } |
| out << indent() << "the_buffer.append('>');\n"; |
| } |
| out << indent() |
| << "::typelib_TypeDescriptionReference * the_members[] = {\n"; |
| inc(); |
| sal_uInt16 fields = m_reader.getFieldCount(); |
| for (sal_uInt16 i = 0; i < fields; ++i) { |
| out << indent(); |
| rtl::OString type( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); |
| if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { |
| out << "::cppu::getTypeFavourChar(static_cast< "; |
| dumpTypeParameterName(out, type); |
| out << " * >(0))"; |
| } else { |
| out << "::cppu::UnoType< "; |
| dumpType(out, type, false, false, false, true); |
| out << " >::get()"; |
| } |
| out << ".getTypeLibType()" << (i == fields - 1 ? " };" : ",") |
| << "\n"; |
| } |
| dec(); |
| if (isPolymorphic()) { |
| out << indent() |
| << "static ::sal_Bool const the_parameterizedTypes[] = { "; |
| for (sal_uInt16 i = 0; i < fields; ++i) { |
| if (i != 0) { |
| out << ", "; |
| } |
| out << (((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) |
| == 0) |
| ? "false" : "true"); |
| } |
| out << " };\n"; |
| } |
| out << indent() << "::typelib_static_struct_type_init(&the_type, "; |
| if (isPolymorphic()) { |
| out << "the_buffer.getStr()"; |
| } else { |
| out << "\"" << m_typeName.replace('/', '.') << "\""; |
| } |
| out << ", "; |
| if (m_reader.getSuperTypeCount() == 0) { |
| out << "0"; |
| } else { |
| out << "::cppu::UnoType< "; |
| dumpType( |
| out, |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8), |
| false, false, false, true); |
| out << " >::get().getTypeLibType()"; |
| } |
| out << ", " << fields << ", the_members, " |
| << (isPolymorphic() ? "the_parameterizedTypes" : "0") << ");\n"; |
| dec(); |
| out << indent() << "}\n" << indent() |
| << ("return *reinterpret_cast< ::com::sun::star::uno::Type * >(" |
| "&the_type);\n"); |
| dumpGetCppuTypePostamble(out); |
| } |
| |
| void StructureType::dumpComprehensiveGetCppuType(FileStream & out) { |
| dumpGetCppuTypePreamble(out); |
| out << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n" |
| << indent() << "if (the_pType == 0) {\n"; |
| inc(); |
| out << indent() |
| << "::osl::MutexGuard the_guard(::osl::Mutex::getGlobalMutex());\n" |
| << indent() << "if (the_pType == 0) {\n"; |
| inc(); |
| if (isPolymorphic()) { |
| out << indent() << "::rtl::OUStringBuffer the_buffer;\n" << indent() |
| << "the_buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM(\"" |
| << m_typeName.replace('/', '.') << "<\"));\n"; |
| sal_uInt16 n = m_reader.getReferenceCount(); |
| for (sal_uInt16 i = 0; i < n; ++i) { |
| out << indent() |
| << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< "; |
| dumpTypeParameterName( |
| out, |
| rtl::OUStringToOString( |
| m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); |
| out << " * >(0)).getTypeName());\n"; |
| if (i != n - 1) { |
| out << indent() |
| << ("the_buffer.append(" |
| "static_cast< ::sal_Unicode >(','));\n"); |
| } |
| } |
| out << indent() |
| << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n" |
| << indent() |
| << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n"; |
| } else { |
| out << indent() |
| << "::rtl::OUString the_name(RTL_CONSTASCII_USTRINGPARAM(\"" |
| << m_typeName.replace('/', '.') << "\"));\n"; |
| } |
| sal_uInt16 fields = m_reader.getFieldCount(); |
| typedef std::map< rtl::OString, sal_uInt32 > Map; |
| Map parameters; |
| Map types; |
| {for (sal_uInt16 i = 0; i < fields; ++i) { |
| rtl::OString type( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); |
| if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { |
| if (parameters.insert( |
| Map::value_type( |
| type, static_cast< sal_uInt32 >(parameters.size()))). |
| second) |
| { |
| sal_uInt32 n = static_cast< sal_uInt32 >(parameters.size() - 1); |
| out << indent() |
| << "::com::sun::star::uno::Type const & the_ptype" << n |
| << " = ::cppu::getTypeFavourChar(static_cast< "; |
| dumpTypeParameterName(out, type); |
| out << " * >(0));\n" << indent() |
| << "::typelib_TypeClass the_pclass" << n |
| << " = (::typelib_TypeClass) the_ptype" << n |
| << ".getTypeClass();\n" << indent() |
| << "::rtl::OUString the_pname" << n << "(the_ptype" << n |
| << ".getTypeName());\n"; |
| } |
| } else if (types.insert( |
| Map::value_type( |
| type, static_cast< sal_uInt32 >(types.size()))). |
| second) |
| { |
| if ((codemaker::UnoType::getSort(type) == |
| codemaker::UnoType::SORT_COMPLEX) && |
| codemaker::UnoType::decompose(type) != m_typeName) |
| // take care of recursion like struct S { sequence<S> x; }; |
| { |
| out << indent() << "::cppu::UnoType< "; |
| dumpType(out, type, false, false, false, true); |
| out << " >::get();\n"; |
| } |
| // For typedefs, use the resolved type name, as there will be no |
| // information available about the typedef itself at runtime (the |
| // above getCppuType call will make available information about the |
| // resolved type); no extra #include for the resolved type is |
| // needed, as the header for the typedef includes it already: |
| out << indent() << "::rtl::OUString the_tname" |
| << static_cast< sal_uInt32 >(types.size() - 1) |
| << "(RTL_CONSTASCII_USTRINGPARAM(\"" |
| << checkRealBaseType(type, true).replace('/', '.') << "\"));\n"; |
| } |
| out << indent() << "::rtl::OUString the_name" << i |
| << "(RTL_CONSTASCII_USTRINGPARAM(\"" |
| << rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8).replace( |
| '/', '.') |
| << "\"));\n"; |
| }} |
| out << indent() << "::typelib_StructMember_Init the_members[] = {\n"; |
| inc(); |
| {for (sal_uInt16 i = 0; i < fields; ++i) { |
| out << indent() << "{ { "; |
| rtl::OString type( |
| rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8)); |
| if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) { |
| sal_uInt32 n = parameters.find(type)->second; |
| out << "the_pclass" << n << ", the_pname" << n << ".pData"; |
| } else { |
| out << getTypeClass(type, true) << ", the_tname" |
| << types.find(type)->second << ".pData"; |
| } |
| out << ", the_name" << i << ".pData }, " |
| << ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) == 0 |
| ? "false" : "true") |
| << " }" << (i == fields - 1 ? " };" : ",") << "\n"; |
| }} |
| dec(); |
| out << indent() << "::typelib_TypeDescription * the_newType = 0;\n"; |
| out << indent() |
| << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, "; |
| if (m_reader.getSuperTypeCount() == 0) { |
| out << "0"; |
| } else { |
| out << "::cppu::UnoType< "; |
| dumpType( |
| out, |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8), |
| false, false, false, true); |
| out << " >::get().getTypeLibType()"; |
| } |
| out << ", " << fields << ", the_members);\n"; |
| out << indent() << "::typelib_typedescription_register(&the_newType);\n"; |
| out << indent() << "::typelib_typedescription_release(the_newType);\n"; |
| out << indent() << "static ::com::sun::star::uno::Type the_staticType(" |
| << getTypeClass(m_typeName) << ", the_name);\n"; |
| out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"; |
| out << indent() << "the_pType = &the_staticType;\n"; |
| dec(); |
| out << indent() << "}\n"; |
| dec(); |
| out << indent() << "} else {\n"; |
| inc(); |
| out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"; |
| dec(); |
| out << indent() << "}\n" << indent() << "return *the_pType;\n"; |
| dumpGetCppuTypePostamble(out); |
| } |
| |
| sal_Bool StructureType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType) |
| { |
| sal_Bool hasMember = sal_False; |
| |
| if ( !superType.isEmpty() ) |
| { |
| typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType)); |
| |
| if (aSuperReader.isValid()) |
| { |
| rtl::OString superSuper; |
| if (aSuperReader.getSuperTypeCount() >= 1) { |
| superSuper = rtl::OUStringToOString( |
| aSuperReader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| hasMember = dumpSuperMember(o, superSuper, bWithType); |
| |
| sal_uInt16 fieldCount = aSuperReader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = aSuperReader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| aSuperReader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| aSuperReader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (hasMember) |
| { |
| o << ", "; |
| } else |
| { |
| hasMember = (fieldCount > 0); |
| } |
| |
| if (bWithType) |
| { |
| dumpType(o, fieldType, sal_True, sal_True); |
| o << " "; |
| } |
| // o << "__" << fieldName; |
| o << fieldName << "_"; |
| } |
| } |
| } |
| |
| return hasMember; |
| } |
| |
| void StructureType::addLightGetCppuTypeIncludes( |
| codemaker::cppumaker::Includes & includes) const |
| { |
| includes.addType(); |
| includes.addCppuUnotypeHxx(); |
| includes.addSalTypesH(); |
| includes.addTypelibTypeclassH(); |
| includes.addTypelibTypedescriptionH(); |
| if (isPolymorphic()) { |
| includes.addRtlStrbufHxx(); |
| includes.addRtlTextencH(); |
| includes.addRtlUstringHxx(); |
| } |
| } |
| |
| void StructureType::addNormalGetCppuTypeIncludes( |
| codemaker::cppumaker::Includes & includes) const |
| { |
| includes.addType(); |
| includes.addCppuUnotypeHxx(); |
| includes.addSalTypesH(); |
| includes.addTypelibTypeclassH(); |
| includes.addTypelibTypedescriptionH(); |
| if (isPolymorphic()) { |
| includes.addRtlStrbufHxx(); |
| includes.addRtlTextencH(); |
| includes.addRtlUstringHxx(); |
| } |
| } |
| |
| void StructureType::addComprehensiveGetCppuTypeIncludes( |
| codemaker::cppumaker::Includes & includes) const |
| { |
| includes.addType(); |
| includes.addCppuUnotypeHxx(); |
| includes.addOslDoublecheckedlockingH(); |
| includes.addOslMutexHxx(); |
| includes.addRtlUstringH(); |
| includes.addRtlUstringHxx(); |
| includes.addSalTypesH(); |
| includes.addTypelibTypeclassH(); |
| includes.addTypelibTypedescriptionH(); |
| if (isPolymorphic()) { |
| includes.addRtlStringH(); |
| includes.addRtlUstrbufHxx(); |
| } |
| } |
| |
| bool StructureType::isPolymorphic() const { |
| return m_reader.getReferenceCount() > 0; |
| } |
| |
| void StructureType::dumpTemplateHead(FileStream & out) const { |
| if (isPolymorphic()) { |
| out << "template< "; |
| for (sal_uInt16 i = 0; i < m_reader.getReferenceCount(); ++i) { |
| if (i != 0) { |
| out << ", "; |
| } |
| OSL_ASSERT( |
| m_reader.getReferenceFlags(i) == RT_ACCESS_INVALID |
| && m_reader.getReferenceSort(i) == RT_REF_TYPE_PARAMETER); |
| out << "typename "; |
| dumpTypeParameterName( |
| out, |
| rtl::OUStringToOString( |
| m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); |
| } |
| out << " > "; |
| } |
| } |
| |
| void StructureType::dumpTemplateParameters(FileStream & out) const { |
| if (isPolymorphic()) { |
| out << "< "; |
| for (sal_uInt16 i = 0; i < m_reader.getReferenceCount(); ++i) { |
| if (i != 0) { |
| out << ", "; |
| } |
| OSL_ASSERT( |
| m_reader.getReferenceFlags(i) == RT_ACCESS_INVALID |
| && m_reader.getReferenceSort(i) == RT_REF_TYPE_PARAMETER); |
| dumpTypeParameterName( |
| out, |
| rtl::OUStringToOString( |
| m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8)); |
| } |
| out << " >"; |
| } |
| } |
| |
| //************************************************************************* |
| // ExceptionType |
| //************************************************************************* |
| ExceptionType::ExceptionType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : CppuType(typeReader, typeName, typeMgr) |
| { |
| } |
| |
| ExceptionType::~ExceptionType() |
| { |
| |
| } |
| |
| sal_Bool ExceptionType::dumpHFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HDL")); |
| o << "\n"; |
| |
| addDefaultHIncludes(includes); |
| includes.dump(o, 0); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| dumpDeclaration(o); |
| |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" |
| << "class Type;\n} } } }\n\n"; |
| |
| o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; |
| dumpType(o, m_typeName, sal_True, sal_False); |
| o << "* ) SAL_THROW( () );\n\n"; |
| |
| o << "#endif // "<< headerDefine << "\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool ExceptionType::dumpDeclaration(FileStream& o) |
| throw( CannotDumpException ) |
| { |
| o << "\nclass CPPU_GCC_DLLPUBLIC_EXPORT " << m_name; |
| |
| OString superType; |
| if (m_reader.getSuperTypeCount() >= 1) { |
| superType = rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| if ( !superType.isEmpty() ) |
| o << " : public " << scopedCppName(superType); |
| |
| o << "\n{\npublic:\n"; |
| inc(); |
| o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name |
| << "() SAL_THROW( () );\n\n"; |
| |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| sal_uInt16 i = 0; |
| |
| if (fieldCount > 0 || getInheritedMemberCount() > 0) |
| { |
| o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << "("; |
| |
| sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True); |
| |
| for (i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (superHasMember) |
| o << ", "; |
| else |
| superHasMember = sal_True; |
| |
| dumpType(o, fieldType, sal_True, sal_True); |
| // o << " __" << fieldName; |
| o << " " << fieldName << "_"; |
| } |
| o << ") SAL_THROW( () );\n\n"; |
| } |
| o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << "(" << m_name |
| << " const &);\n\n" |
| << indent() << "inline CPPU_GCC_DLLPRIVATE ~" << m_name << "();\n\n" |
| << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << " & operator =(" |
| << m_name << " const &);\n\n"; |
| |
| for (i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| o << indent(); |
| dumpType(o, fieldType); |
| o << " " << fieldName; |
| if (i == 0 && !superType.isEmpty() && |
| !fieldType.equals("double") && !fieldType.equals("hyper") && !fieldType.equals("unsigned hyper")) |
| { |
| o << " CPPU_GCC3_ALIGN( " << scopedCppName(superType) << " )"; |
| } |
| o << ";\n"; |
| } |
| |
| |
| dec(); |
| o << "};\n\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool ExceptionType::dumpHxxFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HPP")); |
| o << "\n"; |
| |
| addDefaultHxxIncludes(includes); |
| includes.dump(o, &m_typeName); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| o << "\n"; |
| |
| o << "inline " << m_name << "::" << m_name << "() SAL_THROW( () )\n"; |
| inc(); |
| OString superType; |
| if (m_reader.getSuperTypeCount() >= 1) { |
| superType = rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| sal_Bool first = sal_True; |
| if ( !superType.isEmpty() ) |
| { |
| o << indent() << ": " << scopedCppName(superType) << "()\n"; |
| first = sal_False; |
| } |
| |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (first) |
| { |
| first = sal_False; |
| o << indent() << ": "; |
| } else |
| o << indent() << ", "; |
| |
| o << fieldName; |
| dumpInitializer(o, false, m_reader.getFieldTypeName(i)); |
| o << "\n"; |
| } |
| dec(); |
| if ( !m_cppuTypeDynamic ) |
| { |
| o << "{\n"; |
| inc(); |
| dumpCppuGetType(o, m_typeName, sal_True); |
| dec(); |
| o << "}\n\n"; |
| } else |
| { |
| o << "{ }\n\n"; |
| } |
| |
| if (fieldCount > 0 || getInheritedMemberCount() > 0) |
| { |
| o << indent() << "inline " << m_name << "::" << m_name << "("; |
| |
| sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True); |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (superHasMember) |
| o << ", "; |
| else |
| superHasMember = sal_True; |
| |
| dumpType(o, fieldType, sal_True, sal_True); |
| // o << " __" << fieldName; |
| o << " " << fieldName << "_"; |
| } |
| o << ") SAL_THROW( () )\n"; |
| |
| inc(); |
| first = sal_True; |
| if ( !superType.isEmpty() ) |
| { |
| o << indent() << ": " << scopedCppName(superType) << "("; |
| dumpSuperMember(o, superType, sal_False); |
| o << ")\n"; |
| first = sal_False; |
| } |
| |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (first) |
| { |
| first = sal_False; |
| o << indent() << ": "; |
| } else |
| o << indent() << ", "; |
| |
| // o << fieldName << "(__" << fieldName << ")\n"; |
| o << fieldName << "(" << fieldName << "_)\n"; |
| } |
| |
| dec(); |
| if ( !m_cppuTypeDynamic ) |
| { |
| o << "{\n"; |
| inc(); |
| dumpCppuGetType(o, m_typeName, sal_True); |
| dec(); |
| o << "}\n\n"; |
| } else |
| { |
| o << "{ }\n\n"; |
| } |
| } |
| o << indent() << m_name << "::" << m_name << "(" << m_name |
| << " const & the_other)"; |
| first = true; |
| if ( !superType.isEmpty() ) { |
| o << ": " << scopedCppName(superType) << "(the_other)"; |
| first = false; |
| } |
| for (sal_uInt16 i = 0; i < fieldCount; ++i) { |
| rtl::OString name( |
| rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)); |
| o << (first ? ": " : ", ") << name << "(the_other." << name << ")"; |
| first = false; |
| } |
| o << indent() << " {}\n\n" |
| << indent() << m_name << "::~" << m_name << "() {}\n\n" |
| << indent() << m_name << " & " << m_name << "::operator =(" << m_name |
| << " const & the_other) {\n"; |
| inc(); |
| o << indent() |
| << ("//TODO: Just like its implicitly-defined counterpart, this function" |
| " definition is not exception-safe\n"); |
| if ( !superType.isEmpty() ) { |
| o << indent() << scopedCppName(superType) |
| << "::operator =(the_other);\n"; |
| } |
| for (sal_uInt16 i = 0; i < fieldCount; ++i) { |
| rtl::OString name( |
| rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)); |
| o << indent() << name << " = the_other." << name << ";\n"; |
| } |
| o << indent() << "return *this;\n"; |
| dec(); |
| o << indent() << "}\n\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| o << "\n"; |
| dumpGetCppuType(o); |
| |
| o << "\n#endif // "<< headerDefine << "\n"; |
| return sal_True; |
| } |
| |
| sal_Bool ExceptionType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType) |
| { |
| sal_Bool hasMember = sal_False; |
| |
| if ( !superType.isEmpty() ) |
| { |
| typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType)); |
| |
| if (aSuperReader.isValid()) |
| { |
| rtl::OString superSuper; |
| if (aSuperReader.getSuperTypeCount() >= 1) { |
| superSuper = rtl::OUStringToOString( |
| aSuperReader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8); |
| } |
| hasMember = dumpSuperMember(o, superSuper, bWithType); |
| |
| sal_uInt16 fieldCount = aSuperReader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| OString fieldName; |
| OString fieldType; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = aSuperReader.getFieldFlags(i); |
| |
| if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| aSuperReader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| fieldType = rtl::OUStringToOString( |
| aSuperReader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8); |
| |
| if (hasMember) |
| { |
| o << ", "; |
| } else |
| { |
| hasMember = (fieldCount > 0); |
| } |
| |
| if (bWithType) |
| { |
| dumpType(o, fieldType, sal_True, sal_True); |
| o << " "; |
| } |
| // o << "__" << fieldName; |
| o << fieldName << "_"; |
| } |
| } |
| } |
| |
| return hasMember; |
| } |
| |
| //************************************************************************* |
| // EnumType |
| //************************************************************************* |
| EnumType::EnumType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : CppuType(typeReader, typeName, typeMgr) |
| { |
| } |
| |
| EnumType::~EnumType() |
| { |
| |
| } |
| |
| sal_Bool EnumType::dumpHFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HDL")); |
| o << "\n"; |
| |
| addDefaultHIncludes(includes); |
| includes.dump(o, 0); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| dumpDeclaration(o); |
| |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" |
| << "class Type;\n} } } }\n\n"; |
| |
| o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( "; |
| dumpType(o, m_typeName, sal_True, sal_False); |
| o << "* ) SAL_THROW( () );\n\n"; |
| |
| o << "#endif // "<< headerDefine << "\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool EnumType::dumpDeclaration(FileStream& o) |
| throw( CannotDumpException ) |
| { |
| o << "\nenum " << m_name << "\n{\n"; |
| inc(); |
| |
| sal_uInt16 fieldCount = m_reader.getFieldCount(); |
| RTFieldAccess access = RT_ACCESS_INVALID; |
| RTConstValue constValue; |
| OString fieldName; |
| sal_Int32 value=0; |
| for (sal_uInt16 i=0; i < fieldCount; i++) |
| { |
| access = m_reader.getFieldFlags(i); |
| |
| if (access != RT_ACCESS_CONST) |
| continue; |
| |
| fieldName = rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8); |
| constValue = m_reader.getFieldValue(i); |
| |
| if (constValue.m_type == RT_TYPE_INT32) |
| value = constValue.m_value.aLong; |
| else |
| value++; |
| |
| o << indent() << m_name << "_" << fieldName << " = " << value << ",\n"; |
| } |
| |
| o << indent() << m_name << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n"; |
| |
| dec(); |
| o << "};\n\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool EnumType::dumpHxxFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HPP")); |
| o << "\n"; |
| |
| addDefaultHxxIncludes(includes); |
| includes.dump(o, &m_typeName); |
| o << "\n"; |
| |
| dumpGetCppuType(o); |
| |
| o << "\n#endif // "<< headerDefine << "\n"; |
| return sal_True; |
| } |
| |
| void EnumType::dumpNormalGetCppuType(FileStream& o) |
| { |
| dumpGetCppuTypePreamble(o); |
| |
| o << indent() |
| << "static typelib_TypeDescriptionReference * the_type = 0;\n"; |
| |
| o << indent() << "if ( !the_type )\n" << indent() << "{\n"; |
| inc(); |
| |
| o << indent() << "typelib_static_enum_type_init( &the_type,\n"; |
| inc(31); |
| o << indent() << "\"" << m_typeName.replace('/', '.') << "\",\n" |
| << indent() << scopedCppName(m_typeName) << "_" |
| << rtl::OUStringToOString(m_reader.getFieldName(0), RTL_TEXTENCODING_UTF8) |
| << " );\n"; |
| dec(31); |
| dec(); |
| o << indent() << "}\n"; |
| o << indent() |
| << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >(" |
| " &the_type );\n"); |
| dumpGetCppuTypePostamble(o); |
| } |
| |
| void EnumType::dumpComprehensiveGetCppuType(FileStream& o) |
| { |
| dumpGetCppuTypePreamble(o); |
| |
| o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n"; |
| |
| o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; |
| inc(); |
| o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"; |
| |
| o << indent() << "if (the_pType == 0)\n" << indent() << "{\n"; |
| inc(); |
| o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << m_typeName.replace('/', '.') << "\") );\n\n"; |
| |
| o << indent() << "// Start inline typedescription generation\n" |
| << indent() << "typelib_TypeDescription * pTD = 0;\n\n"; |
| |
| sal_uInt16 count = m_reader.getFieldCount(); |
| o << indent() << "rtl_uString* enumValueNames[" << count << "];\n"; |
| sal_uInt16 i; |
| for (i = 0; i < count; i++) |
| { |
| o << indent() << "::rtl::OUString sEnumValue" << i |
| << "( RTL_CONSTASCII_USTRINGPARAM(\"" |
| << rtl::OUStringToOString( |
| m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8) |
| << "\") );\n"; |
| o << indent() << "enumValueNames[" << i << "] = sEnumValue" << i |
| << ".pData;\n"; |
| } |
| |
| o << "\n" << indent() << "sal_Int32 enumValues[" << count << "];\n"; |
| RTConstValue constValue; |
| sal_Int32 value=0; |
| for (i = 0; i < count; i++) |
| { |
| o << indent() << "enumValues[" << i << "] = "; |
| constValue = m_reader.getFieldValue(i); |
| if (constValue.m_type == RT_TYPE_INT32) |
| value = constValue.m_value.aLong; |
| else |
| value++; |
| o << value << ";\n"; |
| } |
| |
| o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n"; |
| inc(); |
| o << indent() << "sTypeName.pData,\n" |
| << indent() << "(sal_Int32)" << scopedCppName(m_typeName, sal_False) |
| << "_" |
| << rtl::OUStringToOString(m_reader.getFieldName(0), RTL_TEXTENCODING_UTF8) |
| << ",\n" |
| << indent() << count << ", enumValueNames, enumValues );\n\n"; |
| dec(); |
| |
| o << indent() |
| << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD" |
| " );\n"); |
| o << indent() << "typelib_typedescription_release( pTD );\n" |
| << indent() << "// End inline typedescription generation\n\n"; |
| |
| o << indent() << "static ::com::sun::star::uno::Type the_staticType( " |
| << getTypeClass(m_typeName) << ", sTypeName );\n"; |
| o << indent() << "the_pType = &the_staticType;\n"; |
| |
| dec(); |
| o << indent() << "}\n"; |
| dec(); |
| o << indent() << "}\n\n" |
| << indent() << "return *the_pType;\n"; |
| |
| dumpGetCppuTypePostamble(o); |
| } |
| |
| //************************************************************************* |
| // TypeDefType |
| //************************************************************************* |
| TypeDefType::TypeDefType(typereg::Reader& typeReader, |
| const OString& typeName, |
| const TypeManager& typeMgr) |
| : CppuType(typeReader, typeName, typeMgr) |
| { |
| } |
| |
| TypeDefType::~TypeDefType() |
| { |
| |
| } |
| |
| sal_Bool TypeDefType::dumpHFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HDL")); |
| o << "\n"; |
| |
| addDefaultHIncludes(includes); |
| includes.dump(o, 0); |
| o << "\n"; |
| |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| dumpDeclaration(o); |
| |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| |
| // o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" |
| // << "class Type;\n} } } }\n\n"; |
| // o << "inline const ::com::sun::star::uno::Type& SAL_CALL get_" << m_typeName.replace('/', '_') |
| // << "_Type( ) SAL_THROW( () );\n\n"; |
| |
| o << "#endif // "<< headerDefine << "\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool TypeDefType::dumpDeclaration(FileStream& o) |
| throw( CannotDumpException ) |
| { |
| o << "\ntypedef "; |
| dumpType( |
| o, |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); |
| o << " " << m_name << ";\n\n"; |
| |
| return sal_True; |
| } |
| |
| sal_Bool TypeDefType::dumpHxxFile( |
| FileStream& o, codemaker::cppumaker::Includes & includes) |
| throw( CannotDumpException ) |
| { |
| OString headerDefine(dumpHeaderDefine(o, "HPP")); |
| o << "\n"; |
| |
| addDefaultHxxIncludes(includes); |
| includes.dump(o, &m_typeName); |
| o << "\n"; |
| |
| o << "\n#endif // "<< headerDefine << "\n"; |
| return sal_True; |
| } |
| |
| //************************************************************************* |
| // ConstructiveType |
| //************************************************************************* |
| |
| sal_Bool ConstructiveType::dumpHFile( |
| FileStream &, codemaker::cppumaker::Includes &) throw (CannotDumpException) |
| { |
| OSL_ASSERT(false); |
| return false; |
| } |
| |
| bool ConstructiveType::dumpFiles( |
| CppuOptions * options, rtl::OString const & outPath) |
| { |
| return dumpFile(options, ".hpp", m_typeName, outPath); |
| } |
| |
| //************************************************************************* |
| // ServiceType |
| //************************************************************************* |
| |
| namespace { |
| |
| void includeExceptions( |
| codemaker::cppumaker::Includes & includes, |
| codemaker::ExceptionTreeNode const * node) |
| { |
| if (node->present) { |
| includes.add(node->name); |
| } else { |
| for (codemaker::ExceptionTreeNode::Children::const_iterator i( |
| node->children.begin()); |
| i != node->children.end(); ++i) |
| { |
| includeExceptions(includes, *i); |
| } |
| } |
| } |
| |
| } |
| |
| bool ServiceType::isSingleInterfaceBased() { |
| return m_reader.getSuperTypeCount() == 1; |
| } |
| |
| sal_Bool ServiceType::dumpHxxFile( |
| FileStream & o, codemaker::cppumaker::Includes & includes) |
| throw (CannotDumpException) |
| { |
| sal_uInt16 ctors = m_reader.getMethodCount(); |
| if (ctors > 0) { |
| //TODO: Decide whether the types added to includes should rather be |
| // added to m_dependencies (and thus be generated during |
| // dumpDependedTypes): |
| includes.addReference(); |
| includes.addRtlUstringH(); |
| includes.addRtlUstringHxx(); |
| includes.add("com/sun/star/lang/XMultiComponentFactory"); |
| includes.add("com/sun/star/uno/DeploymentException"); |
| includes.add("com/sun/star/uno/XComponentContext"); |
| for (sal_uInt16 i = 0; i < ctors; ++i) { |
| if (isDefaultConstructor(i)) { |
| includes.add("com/sun/star/uno/Exception"); |
| includes.add("com/sun/star/uno/RuntimeException"); |
| } else { |
| if (!hasRestParameter(i)) { |
| includes.addAny(); |
| includes.addSequence(); |
| sal_uInt16 params = m_reader.getMethodParameterCount(i); |
| for (sal_uInt16 j = 0; j < params; ++j) { |
| if (codemaker::UnoType::getSort( |
| codemaker::UnoType::decompose( |
| rtl::OUStringToOString( |
| m_reader.getMethodParameterTypeName( |
| i, j), |
| RTL_TEXTENCODING_UTF8), |
| 0, 0)) |
| == codemaker::UnoType::SORT_CHAR) |
| { |
| includes.addCppuUnotypeHxx(); |
| break; |
| } |
| } |
| } |
| codemaker::ExceptionTree tree; |
| for (sal_uInt16 j = 0; j < m_reader.getMethodExceptionCount(i); |
| ++j) |
| { |
| tree.add( |
| rtl::OUStringToOString( |
| m_reader.getMethodExceptionTypeName(i, j), |
| RTL_TEXTENCODING_UTF8), |
| m_typeMgr); |
| } |
| if (!tree.getRoot()->present) { |
| includes.add("com/sun/star/uno/Exception"); |
| includes.add("com/sun/star/uno/RuntimeException"); |
| includeExceptions(includes, tree.getRoot()); |
| } |
| } |
| } |
| } |
| rtl::OString cppName(translateUnoToCppIdentifier( |
| m_name, "service", isGlobal())); |
| rtl::OString headerDefine(dumpHeaderDefine(o, "HPP")); |
| o << "\n"; |
| includes.dump(o, 0); |
| o << "\n"; |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| o << "\nclass " << cppName << " {\n"; |
| inc(); |
| if (ctors > 0) { |
| rtl::OString fullName(m_typeName.replace('/', '.')); |
| rtl::OString baseName( |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); |
| rtl::OString fullBaseName(baseName.replace('/', '.')); |
| rtl::OString scopedBaseName(scopedCppName(baseName)); |
| o << "public:\n"; |
| for (sal_uInt16 i = 0; i < ctors; ++i) { |
| if (isDefaultConstructor(i)) { |
| o << indent() << "static ::com::sun::star::uno::Reference< " |
| << scopedBaseName << " > " |
| << translateUnoToCppIdentifier( |
| "create", "method", ITM_NONGLOBAL, &cppName) |
| << ("(::com::sun::star::uno::Reference<" |
| " ::com::sun::star::uno::XComponentContext > const &" |
| " the_context) {\n"); |
| inc(); |
| o << indent() |
| << ("::com::sun::star::uno::Reference<" |
| " ::com::sun::star::lang::XMultiComponentFactory >" |
| " the_factory(the_context->getServiceManager());\n") |
| << indent() << "if (!the_factory.is()) {\n"; |
| inc(); |
| o << indent() |
| << ("throw ::com::sun::star::uno::DeploymentException(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"component" |
| " context fails to supply service manager\"))," |
| " the_context);\n"); |
| dec(); |
| o << indent() << "}\n" << indent() |
| << "::com::sun::star::uno::Reference< " << scopedBaseName |
| << " > the_instance;\n" << indent() << "try {\n"; |
| inc(); |
| o << indent() |
| << "the_instance = ::com::sun::star::uno::Reference< " |
| << scopedBaseName |
| << (" >(the_factory->createInstanceWithContext(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"") |
| << fullName |
| << "\")), the_context), ::com::sun::star::uno::UNO_QUERY);\n"; |
| dec(); |
| o << indent() |
| << "} catch (::com::sun::star::uno::RuntimeException &) {\n"; |
| inc(); |
| o << indent() << "throw;\n"; |
| dec(); |
| o << indent() |
| << ("} catch (::com::sun::star::uno::Exception &" |
| " the_exception) {\n"); |
| inc(); |
| o << indent() |
| << ("throw ::com::sun::star::uno::DeploymentException(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" |
| "\"component context fails to supply service ") |
| << fullName << " of type " << fullBaseName |
| << ": \")) + the_exception.Message, the_context);\n"; |
| dec(); |
| o << indent() << "}\n" << indent() |
| << "if (!the_instance.is()) {\n"; |
| inc(); |
| o << indent() |
| << ("throw ::com::sun::star::uno::DeploymentException(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" |
| "\"component context fails to supply service ") |
| << fullName << " of type " << fullBaseName |
| << "\")), the_context);\n"; |
| dec(); |
| o << indent() << "}\n" << indent() << "return the_instance;\n"; |
| dec(); |
| o << indent() << "}\n\n"; |
| } else { |
| o << indent() << "static ::com::sun::star::uno::Reference< " |
| << scopedBaseName << " > " |
| << translateUnoToCppIdentifier( |
| rtl::OUStringToOString( |
| m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8), |
| "method", ITM_NONGLOBAL, &cppName) |
| << ("(::com::sun::star::uno::Reference<" |
| " ::com::sun::star::uno::XComponentContext > const &" |
| " the_context"); |
| sal_uInt16 params = m_reader.getMethodParameterCount(i); |
| bool rest = hasRestParameter(i); |
| for (sal_uInt16 j = 0; j < params; ++j) { |
| o << ", "; |
| rtl::OStringBuffer buf; |
| if ((m_reader.getMethodParameterFlags(i, j) & RT_PARAM_REST) |
| != 0) |
| { |
| buf.append(RTL_CONSTASCII_STRINGPARAM("[]")); |
| } |
| buf.append( |
| rtl::OUStringToOString( |
| m_reader.getMethodParameterTypeName(i, j), |
| RTL_TEXTENCODING_UTF8)); |
| rtl::OString type(buf.makeStringAndClear()); |
| bool byRef = passByReference(type); |
| dumpType(o, type, byRef, byRef); |
| o << " " |
| << translateUnoToCppIdentifier( |
| rtl::OUStringToOString( |
| m_reader.getMethodParameterName(i, j), |
| RTL_TEXTENCODING_UTF8), |
| "param", ITM_NONGLOBAL); |
| } |
| o << ") {\n"; |
| inc(); |
| o << indent() |
| << ("::com::sun::star::uno::Reference<" |
| " ::com::sun::star::lang::XMultiComponentFactory >" |
| " the_factory(the_context->getServiceManager());\n") |
| << indent() << "if (!the_factory.is()) {\n"; |
| inc(); |
| o << indent() |
| << ("throw com::sun::star::uno::DeploymentException(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" |
| "\"component context fails to supply service manager\"))," |
| " the_context);\n"); |
| dec(); |
| o << indent() << "}\n"; |
| if (!rest && params > 0) { |
| o << indent() |
| << ("::com::sun::star::uno::Sequence<" |
| " ::com::sun::star::uno::Any > the_arguments(") |
| << params << ");\n"; |
| for (sal_uInt16 j = 0; j < params; ++j) { |
| o << indent() << "the_arguments[" << j << "] "; |
| rtl::OString param( |
| translateUnoToCppIdentifier( |
| rtl::OUStringToOString( |
| m_reader.getMethodParameterName(i, j), |
| RTL_TEXTENCODING_UTF8), |
| "param", ITM_NONGLOBAL)); |
| sal_Int32 rank; |
| if (codemaker::UnoType::getSort( |
| codemaker::UnoType::decompose( |
| rtl::OUStringToOString( |
| m_reader.getMethodParameterTypeName( |
| i, j), |
| RTL_TEXTENCODING_UTF8), |
| &rank, 0)) |
| == codemaker::UnoType::SORT_CHAR) |
| { |
| o << "= ::com::sun::star::uno::Any(&" << param |
| << ", ::cppu::UnoType< "; |
| for (sal_Int32 k = 0; k < rank; ++k) { |
| o << "::cppu::UnoSequenceType< "; |
| } |
| o << "::cppu::UnoCharType"; |
| for (sal_Int32 k = 0; k < rank; ++k) { |
| o << " >"; |
| } |
| o << " >::get())"; |
| } else { |
| o << "<<= " << param; |
| } |
| o << ";\n"; |
| } |
| } |
| o << indent() << "::com::sun::star::uno::Reference< " |
| << scopedBaseName << " > the_instance;\n"; |
| codemaker::ExceptionTree tree; |
| sal_uInt16 exceptions = m_reader.getMethodExceptionCount(i); |
| for (sal_uInt16 j = 0; j < exceptions; ++j) { |
| tree.add( |
| rtl::OUStringToOString( |
| m_reader.getMethodExceptionTypeName(i, j), |
| RTL_TEXTENCODING_UTF8), |
| m_typeMgr); |
| } |
| if (!tree.getRoot()->present) { |
| o << indent() << "try {\n"; |
| inc(); |
| } |
| o << indent() |
| << "the_instance = ::com::sun::star::uno::Reference< " |
| << scopedBaseName |
| << (" >(the_factory->createInstanceWithArgumentsAndContext(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"") |
| << fullName << "\")), "; |
| if (rest) { |
| o << translateUnoToCppIdentifier( |
| rtl::OUStringToOString( |
| m_reader.getMethodParameterName(i, 0), |
| RTL_TEXTENCODING_UTF8), |
| "param", ITM_NONGLOBAL); |
| } else if (params == 0) { |
| o << ("::com::sun::star::uno::Sequence<" |
| " ::com::sun::star::uno::Any >()"); |
| } else { |
| o << "the_arguments"; |
| } |
| o << ", the_context), ::com::sun::star::uno::UNO_QUERY);\n"; |
| if (!tree.getRoot()->present) { |
| dec(); |
| o << indent() |
| << ("} catch (::com::sun::star::uno::RuntimeException &)" |
| " {\n"); |
| inc(); |
| o << indent() << "throw;\n"; |
| dec(); |
| dumpCatchClauses(o, tree.getRoot()); |
| o << indent() |
| << ("} catch (::com::sun::star::uno::Exception &" |
| " the_exception) {\n"); |
| inc(); |
| o << indent() |
| << ("throw ::com::sun::star::uno::DeploymentException(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" |
| "\"component context fails to supply service ") |
| << fullName << " of type " << fullBaseName |
| << ": \")) + the_exception.Message, the_context);\n"; |
| dec(); |
| o << indent() << "}\n"; |
| } |
| o << indent() << "if (!the_instance.is()) {\n"; |
| inc(); |
| o << indent() |
| << ("throw ::com::sun::star::uno::DeploymentException(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" |
| "\"component context fails to supply service ") |
| << fullName << " of type " << fullBaseName |
| << "\")), the_context);\n"; |
| dec(); |
| o << indent() << "}\n" << indent() << "return the_instance;\n"; |
| dec(); |
| o << indent() << "}\n\n"; |
| } |
| } |
| } |
| o << "private:\n"; |
| o << indent() << cppName << "(); // not implemented\n" |
| << indent() << cppName << "(" << cppName << " &); // not implemented\n" |
| << indent() << "~" << cppName << "(); // not implemented\n" |
| << indent() << "void operator =(" << cppName << "); // not implemented\n"; |
| dec(); |
| o << "};\n\n"; |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| o << "\n#endif // "<< headerDefine << "\n"; |
| return true; |
| } |
| |
| void ServiceType::addSpecialDependencies() { |
| if (m_reader.getMethodCount() > 0) { |
| OSL_ASSERT(m_reader.getSuperTypeCount() == 1); |
| m_dependencies.add( |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); |
| } |
| } |
| |
| bool ServiceType::isDefaultConstructor(sal_uInt16 ctorIndex) const { |
| return m_reader.getMethodName(ctorIndex).isEmpty(); |
| } |
| |
| bool ServiceType::hasRestParameter(sal_uInt16 ctorIndex) const { |
| return m_reader.getMethodParameterCount(ctorIndex) == 1 |
| && ((m_reader.getMethodParameterFlags(ctorIndex, 0) & RT_PARAM_REST) |
| != 0); |
| } |
| |
| void ServiceType::dumpCatchClauses( |
| FileStream & out, codemaker::ExceptionTreeNode const * node) |
| { |
| if (node->present) { |
| out << indent() << "} catch ("; |
| dumpType(out, node->name); |
| out << " &) {\n"; |
| inc(); |
| out << indent() << "throw;\n"; |
| dec(); |
| } else { |
| for (codemaker::ExceptionTreeNode::Children::const_iterator i( |
| node->children.begin()); |
| i != node->children.end(); ++i) |
| { |
| dumpCatchClauses(out, *i); |
| } |
| } |
| } |
| |
| //************************************************************************* |
| // SingletonType |
| //************************************************************************* |
| |
| bool SingletonType::isInterfaceBased() { |
| return (m_typeMgr.getTypeClass( |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8))) |
| == RT_TYPE_INTERFACE; |
| } |
| |
| sal_Bool SingletonType::dumpHxxFile( |
| FileStream & o, codemaker::cppumaker::Includes & includes) |
| throw (CannotDumpException) |
| { |
| rtl::OString cppName(translateUnoToCppIdentifier( |
| m_name, "singleton", isGlobal())); |
| rtl::OString fullName(m_typeName.replace('/', '.')); |
| rtl::OString baseName( |
| rtl::OUStringToOString( |
| m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)); |
| rtl::OString fullBaseName(baseName.replace('/', '.')); |
| rtl::OString scopedBaseName(scopedCppName(baseName)); |
| rtl::OString headerDefine(dumpHeaderDefine(o, "HPP")); |
| o << "\n"; |
| //TODO: Decide whether the types added to includes should rather be added to |
| // m_dependencies (and thus be generated during dumpDependedTypes): |
| includes.add("com/sun/star/uno/DeploymentException"); |
| includes.add("com/sun/star/uno/XComponentContext"); |
| includes.addAny(); |
| includes.addReference(); |
| includes.addRtlUstringH(); |
| includes.addRtlUstringHxx(); |
| includes.dump(o, 0); |
| o << "\n"; |
| if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| o << "\nclass " << cppName << " {\npublic:\n"; |
| inc(); |
| o << indent() << "static ::com::sun::star::uno::Reference< " |
| << scopedBaseName << " > " |
| << translateUnoToCppIdentifier("get", "method", ITM_NONGLOBAL, &cppName) |
| << ("(::com::sun::star::uno::Reference<" |
| " ::com::sun::star::uno::XComponentContext > const & context) {\n"); |
| inc(); |
| o << indent() << "::com::sun::star::uno::Reference< " << scopedBaseName |
| << " > instance;\n" << indent() |
| << ("if (!(context->getValueByName(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"/singletons/") |
| << fullName << "\"))) >>= instance) || !instance.is()) {\n"; |
| inc(); |
| o << indent() |
| << ("throw ::com::sun::star::uno::DeploymentException(" |
| "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"component context" |
| " fails to supply singleton ") |
| << fullName << " of type " << fullBaseName << "\")), context);\n"; |
| dec(); |
| o << indent() << "}\n" << indent() << "return instance;\n"; |
| dec(); |
| o << indent() << "}\n\n"; |
| o << "private:\n"; |
| o << indent() << cppName << "(); // not implemented\n" |
| << indent() << cppName << "(" << cppName << " &); // not implemented\n" |
| << indent() << "~" << cppName << "(); // not implemented\n" |
| << indent() << "void operator =(" << cppName << "); // not implemented\n"; |
| dec(); |
| o << "};\n\n"; |
| if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) { |
| o << "\n"; |
| } |
| o << "\n#endif // "<< headerDefine << "\n"; |
| return true; |
| } |
| |
| //************************************************************************* |
| // produceType |
| //************************************************************************* |
| bool produceType(const OString& typeName, |
| TypeManager const & typeMgr, |
| codemaker::GeneratedTypeSet & generated, |
| CppuOptions* pOptions) |
| throw( CannotDumpException ) |
| { |
| if (typeName.equals("/") || typeName.equals(typeMgr.getBase()) || |
| TypeManager::isBaseType(typeName) || generated.contains(typeName)) |
| { |
| return true; |
| } |
| |
| sal_Bool bIsExtraType = sal_False; |
| typereg::Reader reader(typeMgr.getTypeReader(typeName, &bIsExtraType)); |
| if (bIsExtraType) { |
| generated.add(typeName); |
| return true; |
| } |
| |
| if (!reader.isValid()) { |
| return false; |
| } |
| |
| RTTypeClass typeClass = reader.getTypeClass(); |
| bool ret = false; |
| switch (typeClass) |
| { |
| case RT_TYPE_INTERFACE: |
| { |
| InterfaceType iType(reader, typeName, typeMgr); |
| ret = iType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| iType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_MODULE: |
| { |
| ModuleType mType(reader, typeName, typeMgr); |
| if (mType.hasConstants()) |
| { |
| ret = mType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| } else |
| { |
| generated.add(typeName); |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_STRUCT: |
| { |
| StructureType sType(reader, typeName, typeMgr); |
| ret = sType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| sType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_ENUM: |
| { |
| EnumType enType(reader, typeName, typeMgr); |
| ret = enType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| enType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_EXCEPTION: |
| { |
| ExceptionType eType(reader, typeName, typeMgr); |
| ret = eType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| eType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_TYPEDEF: |
| { |
| TypeDefType tdType(reader, typeName, typeMgr); |
| ret = tdType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| tdType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_CONSTANTS: |
| { |
| ConstantsType cType(reader, typeName, typeMgr); |
| if (cType.hasConstants()) |
| { |
| ret = cType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| } else |
| { |
| generated.add(typeName); |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_SERVICE: |
| { |
| ServiceType t(reader, typeName, typeMgr); |
| if (t.isSingleInterfaceBased()) { |
| ret = t.dump(pOptions); |
| if (ret) { |
| generated.add(typeName); |
| t.dumpDependedTypes(generated, pOptions); |
| } |
| } else { |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_SINGLETON: |
| { |
| SingletonType t(reader, typeName, typeMgr); |
| if (t.isInterfaceBased()) { |
| ret = t.dump(pOptions); |
| if (ret) { |
| generated.add(typeName); |
| t.dumpDependedTypes(generated, pOptions); |
| } |
| } else { |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_OBJECT: |
| ret = true; |
| break; |
| default: |
| OSL_ASSERT(false); |
| break; |
| } |
| |
| return ret; |
| } |
| |
| bool produceType(RegistryKey& rTypeKey, bool bIsExtraType, |
| TypeManager const & typeMgr, |
| codemaker::GeneratedTypeSet & generated, |
| CppuOptions* pOptions) |
| throw( CannotDumpException ) |
| { |
| OString typeName = typeMgr.getTypeName(rTypeKey); |
| |
| if (typeName.equals("/") ||typeName.equals(typeMgr.getBase()) || |
| TypeManager::isBaseType(typeName) || generated.contains(typeName)) |
| { |
| return true; |
| } |
| |
| if (bIsExtraType) { |
| generated.add(typeName); |
| return true; |
| } |
| |
| typereg::Reader reader(typeMgr.getTypeReader(rTypeKey)); |
| if (!reader.isValid()) { |
| return false; |
| } |
| |
| RTTypeClass typeClass = reader.getTypeClass(); |
| bool ret = false; |
| switch (typeClass) |
| { |
| case RT_TYPE_INTERFACE: |
| { |
| InterfaceType iType(reader, typeName, typeMgr); |
| ret = iType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| iType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_MODULE: |
| { |
| ModuleType mType(reader, typeName, typeMgr); |
| if (mType.hasConstants()) |
| { |
| ret = mType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| } else |
| { |
| generated.add(typeName); |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_STRUCT: |
| { |
| StructureType sType(reader, typeName, typeMgr); |
| ret = sType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| sType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_ENUM: |
| { |
| EnumType enType(reader, typeName, typeMgr); |
| ret = enType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| enType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_EXCEPTION: |
| { |
| ExceptionType eType(reader, typeName, typeMgr); |
| ret = eType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| eType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_TYPEDEF: |
| { |
| TypeDefType tdType(reader, typeName, typeMgr); |
| ret = tdType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| tdType.dumpDependedTypes(generated, pOptions); |
| } |
| break; |
| case RT_TYPE_CONSTANTS: |
| { |
| ConstantsType cType(reader, typeName, typeMgr); |
| if (cType.hasConstants()) |
| { |
| ret = cType.dump(pOptions); |
| if (ret) generated.add(typeName); |
| } else |
| { |
| generated.add(typeName); |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_SERVICE: |
| { |
| ServiceType t(reader, typeName, typeMgr); |
| if (t.isSingleInterfaceBased()) { |
| ret = t.dump(pOptions); |
| if (ret) { |
| generated.add(typeName); |
| t.dumpDependedTypes(generated, pOptions); |
| } |
| } else { |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_SINGLETON: |
| { |
| SingletonType t(reader, typeName, typeMgr); |
| if (t.isInterfaceBased()) { |
| ret = t.dump(pOptions); |
| if (ret) { |
| generated.add(typeName); |
| t.dumpDependedTypes(generated, pOptions); |
| } |
| } else { |
| ret = true; |
| } |
| } |
| break; |
| case RT_TYPE_OBJECT: |
| ret = true; |
| break; |
| default: |
| OSL_ASSERT(false); |
| break; |
| } |
| |
| return ret; |
| } |
| |
| //************************************************************************* |
| // scopedName |
| //************************************************************************* |
| /* |
| OString scopedName(const OString& scope, const OString& type, |
| sal_Bool bNoNameSpace) |
| { |
| sal_Int32 nPos = type.lastIndexOf( '/' ); |
| if (nPos == -1) |
| return type; |
| |
| OStringBuffer tmpBuf(type.getLength()*2); |
| nPos = 0; |
| do |
| { |
| tmpBuf.append("::"); |
| OString token(type.getToken(0, '/', nPos)); |
| if (nPos != -1) |
| tmpBuf.append(translateUnoToCppIndentifier( |
| token, "module", ITM_KEYWORDSONLY)); |
| else |
| tmpBuf.append(translateUnoToCppIndentifier( |
| token, "interface", ITM_KEYWORDSONLY)); |
| } while( nPos != -1 ); |
| |
| return tmpBuf.makeStringAndClear(); |
| } |
| */ |