blob: a6bfd5f9121c4e3fba89742a66ea500ec9ef9296 [file] [log] [blame]
/**************************************************************
*
* 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 <stdio.h>
#include <rtl/alloc.h>
#include <rtl/ustring.hxx>
#include <rtl/strbuf.hxx>
#include "idltype.hxx"
#include "idloptions.hxx"
using namespace rtl;
//*************************************************************************
// IdlType
//*************************************************************************
IdlType::IdlType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: m_inheritedMemberCount(0)
, m_indentLength(0)
, m_typeName(typeName)
, m_reader(typeReader)
, m_typeMgr((TypeManager&)typeMgr)
, m_dependencies(typeDependencies)
{
sal_Int32 i = typeName.lastIndexOf('/');
m_name = typeName.copy( i != -1 ? i+1 : 0 );
}
IdlType::~IdlType()
{
}
sal_Bool IdlType::dump(IdlOptions* pOptions)
throw( CannotDumpException )
{
sal_Bool ret = sal_False;
OString outPath;
if (pOptions->isValid("-O"))
outPath = pOptions->getOption("-O");
OString tmpFileName;
OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl");
sal_Bool bFileExists = sal_False;
sal_Bool bFileCheck = sal_False;
if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
{
bFileExists = fileExists( hFileName );
ret = sal_True;
}
if ( bFileExists && pOptions->isValid("-Gc") )
{
tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml");
bFileCheck = sal_True;
}
if ( !bFileExists || bFileCheck )
{
FileStream hFile;
if ( bFileCheck )
hFile.open(tmpFileName);
else
hFile.open(hFileName);
if(!hFile.isValid())
{
OString message("cannot open ");
message += hFileName + " for writing";
throw CannotDumpException(message);
}
ret = dumpHFile(hFile);
hFile.close();
if (ret && bFileCheck)
{
ret = checkFileContent(hFileName, tmpFileName);
}
}
return ret;
}
sal_Bool IdlType::dumpDependedTypes(IdlOptions* pOptions)
throw( CannotDumpException )
{
sal_Bool ret = sal_True;
TypeUsingSet usingSet(m_dependencies.getDependencies(m_typeName));
TypeUsingSet::const_iterator iter = usingSet.begin();
OString typeName;
sal_uInt32 index = 0;
while (iter != usingSet.end())
{
typeName = (*iter).m_type;
if ((index = typeName.lastIndexOf(']')) > 0)
typeName = typeName.copy(index + 1);
if ( getBaseType(typeName).isEmpty() )
{
if (!produceType(typeName,
m_typeMgr,
m_dependencies,
pOptions))
{
fprintf(stderr, "%s ERROR: %s\n",
pOptions->getProgramName().getStr(),
OString("cannot dump Type '" + typeName + "'").getStr());
exit(99);
}
}
++iter;
}
return ret;
}
OString IdlType::dumpHeaderDefine(FileStream& o, sal_Char* prefix )
{
if (m_typeName.equals("/"))
{
m_typeName = "global";
}
sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix);
OStringBuffer tmpBuf(length);
tmpBuf.append('_');
tmpBuf.append(m_typeName);
tmpBuf.append('_');
tmpBuf.append(prefix);
tmpBuf.append('_');
OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase());
o << "#ifndef " << tmp << "\n#define " << tmp << "\n";
return tmp;
}
void IdlType::dumpDefaultHIncludes(FileStream& o)
{
}
void IdlType::dumpInclude(FileStream& o, const OString& genTypeName, const OString& typeName, sal_Char* prefix )
{
sal_uInt32 length = 3+ m_typeName.getLength() + strlen(prefix);
OStringBuffer tmpBuf(length);
tmpBuf.append('_');
tmpBuf.append(typeName);
tmpBuf.append('_');
tmpBuf.append(prefix);
tmpBuf.append('_');
OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase());
length = 1 + typeName.getLength() + strlen(prefix);
tmpBuf.ensureCapacity(length);
tmpBuf.append(typeName);
tmpBuf.append('.');
tmpBuf.append(prefix);
o << "#ifndef " << tmp << "\n#include <";
tmp = tmpBuf.makeStringAndClear();
sal_Int32 nIndex = 0;
do
{
genTypeName.getToken(0, '/', nIndex);
o << "../";
} while( nIndex != -1 );
// sal_Int32 nSlashes = genTypeName.getTokenCount( '/');
// for( sal_Int32 i = 1; i < nSlashes; i++ )
// o << "../";
o << tmp;
o << ">\n#endif\n";
}
void IdlType::dumpDepIncludes(FileStream& o, const OString& typeName, sal_Char* prefix)
{
TypeUsingSet usingSet(m_dependencies.getDependencies(typeName));
TypeUsingSet::const_iterator iter = usingSet.begin();
OString sPrefix(OString(prefix).toAsciiUpperCase());
sal_uInt32 index = 0;
sal_uInt32 seqNum = 0;
OString relType;
while (iter != usingSet.end())
{
index = (*iter).m_type.lastIndexOf(']');
seqNum = (index > 0 ? ((index+1) / 2) : 0);
relType = (*iter).m_type;
if (index > 0)
relType = relType.copy(index+1);
OString defPrefix("IDL");
if ( getBaseType(relType).isEmpty() &&
m_typeName != relType)
{
if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
{
if (!((*iter).m_use & TYPEUSE_SUPER))
{
o << "\n";
dumpNameSpace(o, sal_True, sal_False, relType);
o << "\ninterface " << scopedName(m_typeName, relType, sal_True) << ";\n";
dumpNameSpace(o, sal_False, sal_False, relType);
o << "\n\n";
}
}
dumpInclude(o, typeName, relType, prefix);
}
else if (relType == "type")
{
o << "module CORBA {\n"
<< "\tinterface TypeCode;\n"
<< "};\n\n";
}
if( seqNum != 0 )
{
// write typedef for sequences to support Rational Rose 2000 import
OString aST = relType;
OString aScope;
dumpNameSpace( o, sal_True, sal_False, relType );
for( sal_uInt32 i = 0; i < seqNum; i++ )
{
o << "typedef sequence< " << scopedName("", aST) << " > ";
if( i == 0 )
{
aST = aST.replace( '/', '_' );
aST = aST.replace( ' ', '_' );
}
aST = aST + "_Sequence" ;
o << aST << ";\n";
}
dumpNameSpace( o, sal_False, sal_False, relType );
}
++iter;
}
}
void IdlType::dumpNameSpace(FileStream& o, sal_Bool bOpen, sal_Bool bFull, const OString& type)
{
OString typeName(type);
sal_Bool bOneLine = sal_True;
if ( typeName.isEmpty() )
{
typeName = m_typeName;
bOneLine = sal_False;
}
if (typeName == "/")
return;
if (typeName.indexOf( '/' ) == -1 && !bFull)
return;
if (!bFull)
typeName = typeName.copy( 0, typeName.lastIndexOf( '/' ) );
if (bOpen)
{
sal_Int32 nIndex = 0;
do
{
o << "module " << typeName.getToken(0, '/', nIndex);
if (bOneLine)
o << " { ";
else
o << "\n{\n";
} while( nIndex != -1 );
} else
{
sal_Int32 nPos = 0;
do
{
nPos = typeName.lastIndexOf( '/' );
o << "};";
if( bOneLine )
o << " ";
else
o << " /* " << typeName.copy( nPos+1 ) << " */\n";
if( nPos != -1 )
typeName = typeName.copy( 0, nPos );
} while( nPos != -1 );
}
}
sal_uInt32 IdlType::getMemberCount()
{
sal_uInt32 count = m_reader.getMethodCount();
sal_uInt32 fieldCount = m_reader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = m_reader.getFieldAccess(i);
if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
count++;
}
return count;
}
sal_uInt32 IdlType::checkInheritedMemberCount(const TypeReader* pReader)
{
sal_Bool bSelfCheck = sal_True;
if (!pReader)
{
bSelfCheck = sal_False;
pReader = &m_reader;
}
sal_uInt32 count = 0;
OString superType(pReader->getSuperTypeName());
if ( !superType.isEmpty() )
{
TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
if ( aSuperReader.isValid() )
{
count = checkInheritedMemberCount(&aSuperReader);
}
}
if (bSelfCheck)
{
count += pReader->getMethodCount();
sal_uInt32 fieldCount = pReader->getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = pReader->getFieldAccess(i);
if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
{
count++;
}
}
}
return count;
}
sal_uInt32 IdlType::getInheritedMemberCount()
{
if (m_inheritedMemberCount == 0)
{
m_inheritedMemberCount = checkInheritedMemberCount(0);
}
return m_inheritedMemberCount;
}
void IdlType::dumpType(FileStream& o, const OString& type )
throw( CannotDumpException )
{
OString sType(checkRealBaseType(type, sal_True));
sal_uInt32 index = sType.lastIndexOf(']');
sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0);
OString relType = (index > 0 ? (sType).copy(index+1) : type);
RTTypeClass typeClass = m_typeMgr.getTypeClass(relType);
sal_uInt32 i;
/*
for (i=0; i < seqNum; i++)
{
//o << "sequence< ";
}
*/
switch (typeClass)
{
case RT_TYPE_INVALID:
{
OString tmp(getBaseType(relType));
if ( !tmp.isEmpty() )
{
tmp = tmp.replace( ' ', '_' );
o << tmp;
} else
throw CannotDumpException("Unknown type '" + relType + "', incomplete type library.");
}
break;
case RT_TYPE_INTERFACE:
case RT_TYPE_STRUCT:
case RT_TYPE_ENUM:
case RT_TYPE_TYPEDEF:
case RT_TYPE_EXCEPTION:
if( seqNum )
{
OString aST = relType.replace( '/', '_' );
aST = aST.replace( ' ', '_' );
o << aST;
}
else
o << scopedName(m_typeName, relType);
break;
}
for (i=0; i < seqNum; i++)
{
//o << " >";
// use typedef for sequences to support Rational Rose 2000 import
o << "_Sequence";
}
}
OString IdlType::getBaseType(const OString& type)
{
if (type.equals("long"))
return type;
if (type.equals("short"))
return type;
if (type.equals("hyper"))
return "long long";
if (type.equals("string"))
return "string";
if (type.equals("boolean"))
return type;
if (type.equals("char"))
return "char";
if (type.equals("byte"))
return "byte";
if (type.equals("any"))
return type;
if (type.equals("type"))
return "CORBA::TypeCode";
if (type.equals("float"))
return type;
if (type.equals("double"))
return type;
if (type.equals("octet"))
return type;
if (type.equals("void"))
return type;
if (type.equals("unsigned long"))
return type;
if (type.equals("unsigned short"))
return type;
if (type.equals("unsigned hyper"))
return "unsigned long long";
return OString();
}
void IdlType::dumpIdlGetType(FileStream& o, const OString& type, sal_Bool bDecl, IdlTypeDecl eDeclFlag)
{
OString sType( checkRealBaseType(type, sal_True) );
sal_uInt32 index = sType.lastIndexOf(']');
OString relType = (index > 0 ? (sType).copy(index+1) : type);
if (eDeclFlag == CPPUTYPEDECL_ONLYINTERFACES)
{
if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
{
o << indent() << "getIdlType( (";
dumpType(o, type);
o << "*)0 )";
if (bDecl)
o << ";\n";
}
} else
{
if (isBaseType(type))
{
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() << "getIdlType( (";
dumpType(o, type);
o << "*)0 )";
// }
}
if (bDecl)
o << ";\n";
}
}
BASETYPE IdlType::isBaseType(const OString& type)
{
if (type.equals("long"))
return BT_LONG;
if (type.equals("short"))
return BT_SHORT;
if (type.equals("hyper"))
return BT_HYPER;
if (type.equals("string"))
return BT_STRING;
if (type.equals("boolean"))
return BT_BOOLEAN;
if (type.equals("char"))
return BT_CHAR;
if (type.equals("byte"))
return BT_BYTE;
if (type.equals("any"))
return BT_ANY;
if (type.equals("float"))
return BT_FLOAT;
if (type.equals("double"))
return BT_DOUBLE;
if (type.equals("void"))
return BT_VOID;
if (type.equals("unsigned long"))
return BT_UNSIGNED_LONG;
if (type.equals("unsigned short"))
return BT_UNSIGNED_SHORT;
if (type.equals("unsigned hyper"))
return BT_UNSIGNED_HYPER;
return BT_INVALID;
}
OString IdlType::checkSpecialIdlType(const OString& type)
{
OString baseType(type);
RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader();
RegistryKey key;
sal_uInt8* pBuffer=NULL;
RTTypeClass typeClass;
sal_Bool isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
TypeReader reader;
while (isTypeDef)
{
reader = m_typeMgr.getTypeReader(baseType);
if (reader.isValid())
{
typeClass = reader.getTypeClass();
if (typeClass == RT_TYPE_TYPEDEF)
baseType = reader.getSuperTypeName();
else
isTypeDef = sal_False;
} else
{
break;
}
}
return baseType;
}
OString IdlType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly)
{
sal_uInt32 index = type.lastIndexOf(']');
OString baseType = (index > 0 ? ((OString)type).copy(index+1) : type);
OString seqPrefix = (index > 0 ? ((OString)type).copy(0, index+1) : OString());
RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader();
RegistryKey key;
sal_uInt8* pBuffer=NULL;
RTTypeClass typeClass;
sal_Bool mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
TypeReader reader;
while (mustBeChecked)
{
reader = m_typeMgr.getTypeReader(baseType);
if (reader.isValid())
{
typeClass = reader.getTypeClass();
if (typeClass == RT_TYPE_TYPEDEF)
{
baseType = reader.getSuperTypeName();
index = baseType.lastIndexOf(']');
if (index > 0)
{
seqPrefix += baseType.copy(0, index+1);
baseType = baseType.copy(index+1);
}
} else
mustBeChecked = sal_False;
} else
{
break;
}
}
if ( bResolveTypeOnly )
baseType = seqPrefix + baseType;
return baseType;
}
void IdlType::dumpConstantValue(FileStream& o, sal_uInt16 index)
{
RTConstValue constValue = m_reader.getFieldConstValue(index);
switch (constValue.m_type)
{
case RT_TYPE_BOOL:
if (constValue.m_value.aBool)
o << "true";
else
o << "false";
break;
case RT_TYPE_BYTE:
{
char tmp[16];
snprintf(tmp, sizeof(tmp), "0x%x", (sal_Int8)constValue.m_value.aByte);
o << tmp;
}
break;
case RT_TYPE_INT16:
o << constValue.m_value.aShort;
break;
case RT_TYPE_UINT16:
o << constValue.m_value.aUShort;
break;
case RT_TYPE_INT32:
o << constValue.m_value.aLong;
break;
case RT_TYPE_UINT32:
o << constValue.m_value.aULong;
break;
case RT_TYPE_INT64:
{
::rtl::OString tmp( OString::valueOf(constValue.m_value.aHyper) );
o << tmp.getStr();
}
break;
case RT_TYPE_UINT64:
{
::rtl::OString tmp( OString::valueOf((sal_Int64)constValue.m_value.aUHyper) );
o << tmp.getStr();
}
break;
case RT_TYPE_FLOAT:
{
::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) );
o << tmp.getStr();
}
break;
case RT_TYPE_DOUBLE:
{
::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) );
o << 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 << "\"" << aStr.getStr() << "\")";
}
break;
}
}
void IdlType::inc(sal_uInt32 num)
{
m_indentLength += num;
}
void IdlType::dec(sal_uInt32 num)
{
if (m_indentLength - num < 0)
m_indentLength = 0;
else
m_indentLength -= num;
}
OString IdlType::indent()
{
OStringBuffer tmp(m_indentLength);
for (sal_uInt32 i=0; i < m_indentLength; i++)
{
tmp.append(' ');
}
return tmp.makeStringAndClear();
}
OString IdlType::indent(sal_uInt32 num)
{
OStringBuffer tmp(m_indentLength + num);
for (sal_uInt32 i=0; i < m_indentLength + num; i++)
{
tmp.append(' ');
}
return tmp.makeStringAndClear();
}
//*************************************************************************
// InterfaceType
//*************************************************************************
InterfaceType::InterfaceType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
m_inheritedMemberCount = 0;
m_hasAttributes = sal_False;
m_hasMethods = sal_False;
}
InterfaceType::~InterfaceType()
{
}
sal_Bool InterfaceType::dumpHFile(FileStream& o)
throw( CannotDumpException )
{
OString headerDefine(dumpHeaderDefine(o, "IDL"));
o << "\n";
dumpDefaultHIncludes(o);
o << "\n";
dumpDepIncludes(o, m_typeName, "idl");
o << "\n";
dumpNameSpace(o);
// write documentation
OString aDoc = m_reader.getDoku();
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << "\ninterface " << m_name;
OString superType(m_reader.getSuperTypeName());
if ( !superType.isEmpty() )
o << " : " << scopedName(m_typeName, superType);
o << "\n{\n";
inc();
dumpAttributes(o);
dumpMethods(o);
dec();
o << "};\n\n";
dumpNameSpace(o, sal_False);
// o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n"
// << "class Type;\n} } } }\n\n";
o << "#endif /* "<< headerDefine << "*/" << "\n";
return sal_True;
}
void InterfaceType::dumpAttributes(FileStream& o)
{
sal_uInt32 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.getFieldAccess(i);
if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
continue;
fieldName = m_reader.getFieldName(i);
fieldType = m_reader.getFieldType(i);
if (first)
{
first = sal_False;
o << "\n";
}
// write documentation
OString aDoc = m_reader.getFieldDoku(i);
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/\n";
if (access == RT_ACCESS_READONLY)
o << indent() << "readonly attribute ";
else
o << indent() << "attribute ";
dumpType(o, fieldType);
o << " " << fieldName << ";\n";
}
}
void InterfaceType::dumpMethods(FileStream& o)
{
sal_uInt32 methodCount = m_reader.getMethodCount();
OString methodName, returnType, paramType, paramName;
sal_uInt32 paramCount = 0;
sal_uInt32 excCount = 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_Int16 i=0; i < methodCount; i++)
{
methodName = m_reader.getMethodName(i);
returnType = m_reader.getMethodReturnType(i);
paramCount = m_reader.getMethodParamCount(i);
excCount = m_reader.getMethodExcCount(i);
methodMode = m_reader.getMethodMode(i);
if ( methodName.equals("acquire") || methodName.equals("release") )
{
bWithRunTimeExcp = sal_False;
}
// write documentation
OString aDoc = m_reader.getMethodDoku(i);
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/\n";
o << indent();
dumpType(o, returnType);
o << " " << methodName << "( ";
sal_uInt16 j;
for (j=0; j < paramCount; j++)
{
paramName = m_reader.getMethodParamName(i, j);
paramType = m_reader.getMethodParamType(i, j);
paramMode = m_reader.getMethodParamMode(i, j);
switch (paramMode)
{
case RT_PARAM_IN:
o << "in ";
break;
case RT_PARAM_OUT:
o << "out ";
break;
case RT_PARAM_INOUT:
o << "inout ";
break;
break;
}
dumpType(o, paramType);
if( paramName == "Object" )
o << " _Object";
else
o << " " << paramName;
if (j+1 < paramCount) o << ", ";
}
o << " )";
if( excCount )
{
o << " raises(";
OString excpName;
sal_Bool bWriteComma = sal_False;
sal_Bool bRTExceptionWritten = sal_False;
for (j=0; j < excCount; j++)
{
excpName = m_reader.getMethodExcType(i, j);
if( bWriteComma )
o << ", ";
o << scopedName(m_typeName, excpName);
bWriteComma = sal_True;
if(excpName == "com/sun/star/uno/RuntimeException")
bRTExceptionWritten = sal_True;
}
if ( bWithRunTimeExcp && !bRTExceptionWritten )
{
if( bWriteComma )
o << ", ";
o << "::com::sun::star::uno::RuntimeException";
}
o << ");\n";
}
else if ( bWithRunTimeExcp )
{
o << "raises( ::com::sun::star::uno::RuntimeException );\n";
}
else
{
o << ";\n";
}
}
}
sal_uInt32 InterfaceType::getMemberCount()
{
sal_uInt32 count = m_reader.getMethodCount();
if (count)
m_hasMethods = sal_True;
sal_uInt32 fieldCount = m_reader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = m_reader.getFieldAccess(i);
if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
{
m_hasAttributes = sal_True;
count++;
}
}
return count;
}
sal_uInt32 InterfaceType::checkInheritedMemberCount(const TypeReader* pReader)
{
sal_uInt32 cout = 0;
sal_Bool bSelfCheck = sal_True;
if (!pReader)
{
bSelfCheck = sal_False;
pReader = &m_reader;
}
sal_uInt32 count = 0;
OString superType(pReader->getSuperTypeName());
if ( !superType.isEmpty() )
{
TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
if (aSuperReader.isValid())
{
count = checkInheritedMemberCount(&aSuperReader);
}
}
if (bSelfCheck)
{
count += pReader->getMethodCount();
sal_uInt32 fieldCount = pReader->getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = pReader->getFieldAccess(i);
if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
{
count++;
}
}
}
return count;
}
sal_uInt32 InterfaceType::getInheritedMemberCount()
{
if (m_inheritedMemberCount == 0)
{
m_inheritedMemberCount = checkInheritedMemberCount(0);
}
return m_inheritedMemberCount;
}
//*************************************************************************
// ModuleType
//*************************************************************************
ModuleType::ModuleType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}
ModuleType::~ModuleType()
{
}
sal_Bool ModuleType::dump(IdlOptions* pOptions)
throw( CannotDumpException )
{
sal_Bool ret = sal_False;
OString outPath;
if (pOptions->isValid("-O"))
outPath = pOptions->getOption("-O");
OString tmpName(m_typeName);
if (tmpName.equals("/"))
tmpName = "global";
else
// tmpName += "/" + m_typeName.getToken(m_typeName.getTokenCount('/') - 1, '/');
tmpName += "/" + m_name;
OString tmpFileName;
OString hFileName = createFileNameFromType(outPath, tmpName, ".idl");
sal_Bool bFileExists = sal_False;
sal_Bool bFileCheck = sal_False;
if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
{
bFileExists = fileExists( hFileName );
ret = sal_True;
}
if ( bFileExists && pOptions->isValid("-Gc") )
{
tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml");
bFileCheck = sal_True;
}
if ( !bFileExists || bFileCheck )
{
FileStream hFile;
if ( bFileCheck )
hFile.open(tmpFileName);
else
hFile.open(hFileName);
if(!hFile.isValid())
{
OString message("cannot open ");
message += hFileName + " for writing";
throw CannotDumpException(message);
}
ret = dumpHFile(hFile);
hFile.close();
if (ret && bFileCheck)
{
ret = checkFileContent(hFileName, tmpFileName);
}
}
return ret;
}
sal_Bool ModuleType::dumpHFile(FileStream& o)
throw( CannotDumpException )
{
OString headerDefine(dumpHeaderDefine(o, "IDL"));
o << "\n";
dumpDefaultHIncludes(o);
o << "\n";
dumpDepIncludes(o, m_typeName, "idl");
o << "\n";
dumpNameSpace(o, sal_True, sal_True);
o << "\n";
sal_uInt32 fieldCount = m_reader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
OString fieldName;
OString fieldType;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = m_reader.getFieldAccess(i);
if (access == RT_ACCESS_CONST)
{
fieldName = m_reader.getFieldName(i);
fieldType = m_reader.getFieldType(i);
o << "const ";
dumpType(o, fieldType);
o << " " << fieldName << " = ";
dumpConstantValue(o, i);
o << ";\n";
}
}
o << "\n";
dumpNameSpace(o, sal_False, sal_True);
o << "\n#endif /* "<< headerDefine << "*/" << "\n";
return sal_True;
}
sal_Bool ModuleType::hasConstants()
{
sal_uInt32 fieldCount = m_reader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = m_reader.getFieldAccess(i);
if (access == RT_ACCESS_CONST)
return sal_True;
}
return sal_False;
}
//*************************************************************************
// ConstantsType
//*************************************************************************
ConstantsType::ConstantsType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: ModuleType(typeReader, typeName, typeMgr, typeDependencies)
{
}
ConstantsType::~ConstantsType()
{
}
sal_Bool ConstantsType::dump(IdlOptions* pOptions)
throw( CannotDumpException )
{
sal_Bool ret = sal_False;
OString outPath;
if (pOptions->isValid("-O"))
outPath = pOptions->getOption("-O");
OString tmpFileName;
OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl");
sal_Bool bFileExists = sal_False;
sal_Bool bFileCheck = sal_False;
if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
{
bFileExists = fileExists( hFileName );
ret = sal_True;
}
if ( bFileExists && pOptions->isValid("-Gc") )
{
tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml");
bFileCheck = sal_True;
}
if ( !bFileExists || bFileCheck )
{
FileStream hFile;
if ( bFileCheck )
hFile.open(tmpFileName);
else
hFile.open(hFileName);
if(!hFile.isValid())
{
OString message("cannot open ");
message += hFileName + " for writing";
throw CannotDumpException(message);
}
ret = dumpHFile(hFile);
hFile.close();
if (ret && bFileCheck)
{
ret = checkFileContent(hFileName, tmpFileName);
}
}
return ret;
}
//*************************************************************************
// StructureType
//*************************************************************************
StructureType::StructureType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}
StructureType::~StructureType()
{
}
sal_Bool StructureType::dumpHFile(FileStream& o)
throw( CannotDumpException )
{
OString headerDefine(dumpHeaderDefine(o, "IDL"));
o << "\n";
dumpDefaultHIncludes(o);
o << "\n";
dumpDepIncludes(o, m_typeName, "idl");
o << "\n";
dumpNameSpace(o);
// write documentation
OString aDoc = m_reader.getDoku();
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << "\nstruct " << m_name;
o << "\n{\n";
inc();
OString superType(m_reader.getSuperTypeName());
if ( !superType.isEmpty() )
dumpSuperMember(o, superType);
sal_uInt32 fieldCount = m_reader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
OString fieldName;
OString fieldType;
sal_uInt16 i=0;
for (i=0; i < fieldCount; i++)
{
access = m_reader.getFieldAccess(i);
if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
continue;
fieldName = m_reader.getFieldName(i);
fieldType = m_reader.getFieldType(i);
// write documentation
OString aDoc = m_reader.getFieldDoku(i);
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << indent();
dumpType(o, fieldType);
o << " " << fieldName << ";\n";
}
dec();
o << "};\n\n";
dumpNameSpace(o, sal_False);
o << "#endif /* "<< headerDefine << "*/" << "\n";
return sal_True;
}
void StructureType::dumpSuperMember(FileStream& o, const OString& superType)
{
if ( !superType.isEmpty() )
{
TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
if (aSuperReader.isValid())
{
dumpSuperMember(o, aSuperReader.getSuperTypeName());
sal_uInt32 fieldCount = aSuperReader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
OString fieldName;
OString fieldType;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = aSuperReader.getFieldAccess(i);
if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
continue;
fieldName = aSuperReader.getFieldName(i);
fieldType = aSuperReader.getFieldType(i);
// write documentation
OString aDoc = aSuperReader.getFieldDoku(i);
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << indent();
dumpType(o, fieldType);
o << " ";
o << fieldName << ";\n";
}
}
}
}
//*************************************************************************
// ExceptionType
//*************************************************************************
ExceptionType::ExceptionType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}
ExceptionType::~ExceptionType()
{
}
sal_Bool ExceptionType::dumpHFile(FileStream& o)
throw( CannotDumpException )
{
OString headerDefine(dumpHeaderDefine(o, "IDL"));
o << "\n";
dumpDefaultHIncludes(o);
o << "\n";
dumpDepIncludes(o, m_typeName, "idl");
o << "\n";
dumpNameSpace(o);
// write documentation
OString aDoc = m_reader.getDoku();
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << "\nexception " << m_name;
o << "\n{\n";
inc();
// Write extra member for derived exceptions
o << indent() << "/*extra member to hold a derived exception */\n";
o << indent() << "any _derivedException;\n";
OString superType(m_reader.getSuperTypeName());
if ( !superType.isEmpty() )
dumpSuperMember(o, superType);
sal_uInt32 fieldCount = m_reader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
OString fieldName;
OString fieldType;
sal_uInt16 i = 0;
for (i=0; i < fieldCount; i++)
{
access = m_reader.getFieldAccess(i);
if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
continue;
fieldName = m_reader.getFieldName(i);
fieldType = m_reader.getFieldType(i);
// write documentation
OString aDoc = m_reader.getFieldDoku(i);
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << indent();
dumpType(o, fieldType);
o << " " << fieldName << ";\n";
}
dec();
o << "};\n\n";
dumpNameSpace(o, sal_False);
o << "#endif /* "<< headerDefine << "*/" << "\n";
return sal_True;
}
void ExceptionType::dumpSuperMember(FileStream& o, const OString& superType)
{
if ( !superType.isEmpty() )
{
TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
if (aSuperReader.isValid())
{
dumpSuperMember(o, aSuperReader.getSuperTypeName());
sal_uInt32 fieldCount = aSuperReader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
OString fieldName;
OString fieldType;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = aSuperReader.getFieldAccess(i);
if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
continue;
fieldName = aSuperReader.getFieldName(i);
fieldType = aSuperReader.getFieldType(i);
// write documentation
OString aDoc = aSuperReader.getFieldDoku(i);
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << indent();
dumpType(o, fieldType);
o << " ";
o << fieldName << ";\n";
}
}
}
}
//*************************************************************************
// EnumType
//*************************************************************************
EnumType::EnumType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}
EnumType::~EnumType()
{
}
sal_Bool EnumType::dumpHFile(FileStream& o)
throw( CannotDumpException )
{
OString headerDefine(dumpHeaderDefine(o, "IDL"));
o << "\n";
dumpDefaultHIncludes(o);
o << "\n";
dumpNameSpace(o);
// write documentation
OString aDoc = m_reader.getDoku();
if( !aDoc.isEmpty() )
o << "/**\n" << aDoc << "\n*/";
o << "\nenum " << m_name << "\n{\n";
inc();
sal_uInt32 fieldCount = m_reader.getFieldCount();
RTFieldAccess access = RT_ACCESS_INVALID;
RTConstValue constValue;
OString fieldName;
sal_uInt32 value=0;
for (sal_uInt16 i=0; i < fieldCount; i++)
{
access = m_reader.getFieldAccess(i);
if (access != RT_ACCESS_CONST)
continue;
fieldName = m_reader.getFieldName(i);
constValue = m_reader.getFieldConstValue(i);
if (constValue.m_type == RT_TYPE_INT32)
value = constValue.m_value.aLong;
else
value++;
/* doesn't work with rational rose 2000
// write documentation
OString aDoc = m_reader.getFieldDoku(i);
if( aDoc.getLength() )
*/
// o << "/**\n" << aDoc << "\n*/\n";
o << indent() << fieldName;
if( i +1 < fieldCount )
o << ",\n";
}
dec();
o << "\n};\n\n";
dumpNameSpace(o, sal_False);
o << "#endif /* "<< headerDefine << "*/" << "\n";
return sal_True;
}
//*************************************************************************
// TypeDefType
//*************************************************************************
TypeDefType::TypeDefType(TypeReader& typeReader,
const OString& typeName,
const TypeManager& typeMgr,
const TypeDependency& typeDependencies)
: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}
TypeDefType::~TypeDefType()
{
}
sal_Bool TypeDefType::dumpHFile(FileStream& o)
throw( CannotDumpException )
{
OString headerDefine(dumpHeaderDefine(o, "IDL"));
o << "\n";
dumpDefaultHIncludes(o);
o << "\n";
dumpDepIncludes(o, m_typeName, "idl");
o << "\n";
dumpNameSpace(o);
o << "\ntypedef ";
dumpType(o, m_reader.getSuperTypeName());
o << " " << m_name << ";\n\n";
dumpNameSpace(o, sal_False);
o << "#endif /* "<< headerDefine << "*/" << "\n";
return sal_True;
}
//*************************************************************************
// produceType
//*************************************************************************
sal_Bool produceType(const OString& typeName,
TypeManager& typeMgr,
TypeDependency& typeDependencies,
IdlOptions* pOptions)
throw( CannotDumpException )
{
if (typeDependencies.isGenerated(typeName))
return sal_True;
TypeReader reader(typeMgr.getTypeReader(typeName));
if (!reader.isValid())
{
if (typeName.equals("/"))
return sal_True;
else
return sal_False;
}
if( !checkTypeDependencies(typeMgr, typeDependencies, typeName))
return sal_False;
RTTypeClass typeClass = reader.getTypeClass();
sal_Bool ret = sal_False;
switch (typeClass)
{
case RT_TYPE_INTERFACE:
{
InterfaceType iType(reader, typeName, typeMgr, typeDependencies);
ret = iType.dump(pOptions);
if (ret) typeDependencies.setGenerated(typeName);
ret = iType.dumpDependedTypes(pOptions);
}
break;
case RT_TYPE_MODULE:
{
ModuleType mType(reader, typeName, typeMgr, typeDependencies);
if (mType.hasConstants())
{
ret = mType.dump(pOptions);
if (ret) typeDependencies.setGenerated(typeName);
// ret = mType.dumpDependedTypes(pOptions);
} else
{
typeDependencies.setGenerated(typeName);
ret = sal_True;
}
}
break;
case RT_TYPE_STRUCT:
{
StructureType sType(reader, typeName, typeMgr, typeDependencies);
ret = sType.dump(pOptions);
if (ret) typeDependencies.setGenerated(typeName);
ret = sType.dumpDependedTypes(pOptions);
}
break;
case RT_TYPE_ENUM:
{
EnumType enType(reader, typeName, typeMgr, typeDependencies);
ret = enType.dump(pOptions);
if (ret) typeDependencies.setGenerated(typeName);
ret = enType.dumpDependedTypes(pOptions);
}
break;
case RT_TYPE_EXCEPTION:
{
ExceptionType eType(reader, typeName, typeMgr, typeDependencies);
ret = eType.dump(pOptions);
if (ret) typeDependencies.setGenerated(typeName);
ret = eType.dumpDependedTypes(pOptions);
}
break;
case RT_TYPE_TYPEDEF:
{
TypeDefType tdType(reader, typeName, typeMgr, typeDependencies);
ret = tdType.dump(pOptions);
if (ret) typeDependencies.setGenerated(typeName);
ret = tdType.dumpDependedTypes(pOptions);
}
break;
case RT_TYPE_CONSTANTS:
{
ConstantsType cType(reader, typeName, typeMgr, typeDependencies);
if (cType.hasConstants())
{
ret = cType.dump(pOptions);
if (ret) typeDependencies.setGenerated(typeName);
// ret = cType.dumpDependedTypes(pOptions);
} else
{
typeDependencies.setGenerated(typeName);
ret = sal_True;
}
}
break;
case RT_TYPE_SERVICE:
case RT_TYPE_OBJECT:
ret = sal_True;
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;
if (bNoNameSpace)
return type.copy(nPos+1);
OStringBuffer tmpBuf(type.getLength()*2);
nPos = 0;
do
{
tmpBuf.append("::");
tmpBuf.append(type.getToken(0, '/', nPos));
} while( nPos != -1 );
return tmpBuf.makeStringAndClear();
}
//*************************************************************************
// shortScopedName
//*************************************************************************
OString scope(const OString& scope, const OString& type )
{
sal_Int32 nPos = type.lastIndexOf( '/' );
if( nPos == -1 )
return OString();
// scoped name only if the namespace is not equal
if (scope.lastIndexOf('/') > 0)
{
OString tmpScp(scope.copy(0, scope.lastIndexOf('/')));
OString tmpScp2(type.copy(0, nPos));
if (tmpScp == tmpScp2)
return OString();
}
OString aScope( type.copy( 0, nPos ) );
OStringBuffer tmpBuf(aScope.getLength()*2);
nPos = 0;
do
{
tmpBuf.append("::");
tmpBuf.append(aScope.getToken(0, '/', nPos));
} while( nPos != -1 );
return tmpBuf.makeStringAndClear();
}