diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /idl/source/objects | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'idl/source/objects')
-rw-r--r-- | idl/source/objects/basobj.cxx | 141 | ||||
-rw-r--r-- | idl/source/objects/bastype.cxx | 120 | ||||
-rw-r--r-- | idl/source/objects/module.cxx | 34 | ||||
-rw-r--r-- | idl/source/objects/object.cxx | 347 | ||||
-rw-r--r-- | idl/source/objects/slot.cxx | 620 | ||||
-rw-r--r-- | idl/source/objects/types.cxx | 320 |
6 files changed, 1582 insertions, 0 deletions
diff --git a/idl/source/objects/basobj.cxx b/idl/source/objects/basobj.cxx new file mode 100644 index 000000000..872b42b39 --- /dev/null +++ b/idl/source/objects/basobj.cxx @@ -0,0 +1,141 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <sal/config.h> + +#include <rtl/character.hxx> + +#include <basobj.hxx> +#include <database.hxx> + +void SvMetaObject::WriteTab( SvStream & rOutStm, sal_uInt16 nTab ) +{ + while( nTab-- ) + rOutStm.WriteCharPtr( " " ); +} + +void SvMetaObject::WriteStars( SvStream & rOutStm ) +{ + rOutStm.WriteChar( '/' ); + for( int i = 6; i > 0; i-- ) + rOutStm.WriteCharPtr( "**********" ); + rOutStm.WriteChar( '/' ) << endl; +} + +void SvMetaObject::Back2Delimiter( SvStream & rOutStm ) +{ + // write no empty brackets + sal_uInt64 nPos = rOutStm.Tell(); + rOutStm.SeekRel( -1 ); + char c = 0; + rOutStm.ReadChar( c ); + + while( rtl::isAsciiWhiteSpace( static_cast<unsigned char>(c) ) + && rOutStm.Tell() != 1 ) + { + rOutStm.SeekRel( -2 ); + rOutStm.ReadChar( c ); + } + + if( c == ';' || c == ',' ) + rOutStm.SeekRel( -1 ); + else + rOutStm.Seek( nPos ); +} + +SvMetaObject::SvMetaObject() +{ +} + +void SvMetaObject::SetName( const OString& rName ) +{ + aName = rName; +} + +bool SvMetaObject::ReadNameSvIdl( SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + // read module name + if( rTok.IsIdentifier() ) + { + SetName( rTok.GetString() ); + return true; + } + + rInStm.Seek( nTokPos ); + return false; +} + +void SvMetaObject::ReadAttributesSvIdl( SvIdlDataBase & , + SvTokenStream & ) +{ +} + +void SvMetaObject::DoReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadContextSvIdl( rBase, rInStm ); + rInStm.ReadIfDelimiter(); + } +} + +void SvMetaObject::ReadContextSvIdl( SvIdlDataBase &, SvTokenStream & ) +{ +} + +bool SvMetaObject::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = true; + if( rInStm.ReadIf( '[' ) ) + { + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadAttributesSvIdl( rBase, rInStm ); + rInStm.ReadIfDelimiter(); + } + bOk = rInStm.ReadIf( ']' ); + } + + if( bOk && rInStm.ReadIf( '{' ) ) + { + DoReadContextSvIdl( rBase, rInStm ); + bOk = rInStm.ReadIf( '}' ); + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + + +SvMetaReference::SvMetaReference() +{ +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/bastype.cxx b/idl/source/objects/bastype.cxx new file mode 100644 index 000000000..6a36db617 --- /dev/null +++ b/idl/source/objects/bastype.cxx @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + + +#include <bastype.hxx> +#include <lex.hxx> +#include <hash.hxx> +#include <database.hxx> + +bool SvBOOL::ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + if( rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( !rTok.IsBool() ) + throw SvParseException(rInStm, "xxx"); + *this = rTok.GetBool(); + rInStm.GetToken_Next(); + } + else + *this = true; //default action set to TRUE + return true; + } + rInStm.Seek( nTokPos ); + return false; +} + +void SvIdentifier::ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + bool bOk = true; + bool bBracket = rInStm.ReadIf( '(' ); + if( bBracket || rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( rTok.IsIdentifier() ) + { + setString(rTok.GetString()); + rInStm.GetToken_Next(); + } + if( bOk && bBracket ) + bOk = rInStm.ReadIf( ')' ); + } + if( bOk ) + return; + } + rInStm.Seek( nTokPos ); +} + +void SvIdentifier::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.IsIdentifier() ) + { + sal_uInt32 n; + if( !rBase.FindId( rTok.GetString(), &n ) ) + rBase.SetAndWriteError( rInStm, "no value for identifier <" + getString() + "> " ); + setString(rTok.GetString()); + nValue = n; + return; + } + rInStm.Seek( nTokPos ); +} + +bool ReadStringSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm, OString& aRetString ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + bool bOk = true; + bool bBracket = rInStm.ReadIf( '(' ); + if( bBracket || rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aRetString = rTok.GetString(); + rInStm.GetToken_Next(); + } + if( bOk && bBracket ) + bOk = rInStm.ReadIf( ')' ); + } + if( bOk ) + return true; + } + rInStm.Seek( nTokPos ); + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/module.cxx b/idl/source/objects/module.cxx new file mode 100644 index 000000000..dc692f608 --- /dev/null +++ b/idl/source/objects/module.cxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <module.hxx> +#include <database.hxx> + +SvMetaModule::SvMetaModule() {} + +void SvMetaModule::WriteSfx(SvIdlDataBase& rBase, SvStream& rOutStm) +{ + for (size_t n = 0; n < aClassList.size(); n++) + { + SvMetaClass* pClass = aClassList[n]; + pClass->WriteSfx(rBase, rOutStm); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/object.cxx b/idl/source/objects/object.cxx new file mode 100644 index 000000000..510d3a8a7 --- /dev/null +++ b/idl/source/objects/object.cxx @@ -0,0 +1,347 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <sal/config.h> + +#include <algorithm> + +#include <rtl/strbuf.hxx> +#include <sal/log.hxx> + +#include <object.hxx> +#include <globals.hxx> +#include <database.hxx> +#include <slot.hxx> + + +SvClassElement::SvClassElement() +{ +}; + +SvMetaClass::SvMetaClass() +{ +} + +void SvMetaClass::ReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( SvHash_import() ) ) + { + SvMetaClass * pClass = rBase.ReadKnownClass( rInStm ); + if( !pClass ) + throw SvParseException( rInStm, "unknown imported interface" ); + SvClassElement aEle; + aEle.SetClass( pClass ); + aClassElementList.push_back( aEle ); + + rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aEle.SetPrefix( rTok.GetString() ); + rInStm.GetToken_Next(); + } + return; + } + else + { + rInStm.Seek( nTokPos ); + SvMetaType * pType = rBase.ReadKnownType( rInStm ); + + bool bOk = false; + tools::SvRef<SvMetaAttribute> xAttr; + if( !pType || pType->IsItem() ) + { + xAttr = new SvMetaSlot( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + else + { + xAttr = new SvMetaAttribute( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + + if( bOk ) + bOk = TestAttribute( rBase, rInStm, *xAttr ); + if( bOk ) + { + if( !xAttr->GetSlotId().IsSet() ) + { + SvIdentifier aI; + aI.SetValue( rBase.GetUniqueId() ); + xAttr->SetSlotId( aI ); + } + aAttrList.push_back( xAttr.get() ); + return; + } + } + rInStm.Seek( nTokPos ); +} + +bool SvMetaClass::TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm, + SvMetaAttribute & rAttr ) const +{ + if ( !rAttr.GetRef() && dynamic_cast<const SvMetaSlot *>(&rAttr) ) + { + SAL_WARN( "idl", "new slot : " << rAttr.GetSlotId().getString() ); + } + + for( size_t n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pS = aAttrList[n]; + if( pS->GetName() == rAttr.GetName() ) + { + // values have to match + if( pS->GetSlotId().GetValue() != rAttr.GetSlotId().GetValue() ) + { + throw SvParseException( rInStm, "Attribute's " + pS->GetName() + " with different id's"); + } + } + else + { + sal_uInt32 nId1 = pS->GetSlotId().GetValue(); + sal_uInt32 nId2 = rAttr.GetSlotId().GetValue(); + if( nId1 == nId2 && nId1 != 0 ) + { + OString aStr = "Attribute " + pS->GetName() + " and Attribute " + rAttr.GetName() + " with equal id's"; + throw SvParseException(rInStm, aStr); + } + } + } + SvMetaClass * pSC = aSuperClass.get(); + if( pSC ) + return pSC->TestAttribute( rBase, rInStm, rAttr ); + return true; +} + +sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase, + SvSlotElementList & rSlotList, + SvStream & rOutStm ) +{ + sal_uInt16 nCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm ); + } + + return nCount; +} + +sal_uInt16 SvMetaClass::WriteSlots( std::string_view rShellName, + SvSlotElementList & rSlotList, + SvIdlDataBase & rBase, + SvStream & rOutStm ) +{ + sal_uInt16 nSCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot * pAttr = rSlotList[ i ]; + nSCount = nSCount + pAttr->WriteSlotMap( rShellName, nSCount, + rSlotList, i, rBase, + rOutStm ); + } + + return nSCount; +} + +void SvMetaClass::InsertSlots( SvSlotElementList& rList, std::vector<sal_uLong>& rSuperList, + SvMetaClassList &rClassList, + const OString& rPrefix, SvIdlDataBase& rBase) +{ + // was this class already written? + for ( size_t i = 0, n = rClassList.size(); i < n ; ++i ) + if ( rClassList[ i ] == this ) + return; + + rClassList.push_back( this ); + + // write all direct attributes + sal_uLong n; + for( n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pAttr = aAttrList[n]; + + sal_uLong nId = pAttr->GetSlotId().GetValue(); + + std::vector<sal_uLong>::iterator iter = std::find(rSuperList.begin(), + rSuperList.end(),nId); + + if( iter == rSuperList.end() ) + { + // Write only if not already written by subclass or + // imported interface. + rSuperList.push_back(nId); + pAttr->Insert(rList); + } + } + + // All Interfaces already imported by SuperShell should not be + // written any more. + // It is prohibited that Shell and SuperShell directly import the same + // class. + if( GetMetaTypeType() == MetaTypeType::Shell && aSuperClass.is() ) + aSuperClass->FillClasses( rClassList ); + + // Write all attributes of the imported classes, as long as they have + // not already been imported by the superclass. + for( n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + OStringBuffer rPre(rPrefix.getLength() + 1 + rElement.GetPrefix().getLength()); + rPre.append(rPrefix); + if( !rPre.isEmpty() && !rElement.GetPrefix().isEmpty() ) + rPre.append('.'); + rPre.append(rElement.GetPrefix()); + + // first of all write direct imported interfaces + pCl->InsertSlots( rList, rSuperList, rClassList, + rPre.makeStringAndClear(), rBase ); + } + + // only write superclass if no shell and not in the list + if( GetMetaTypeType() != MetaTypeType::Shell && aSuperClass.is() ) + { + aSuperClass->InsertSlots( rList, rSuperList, rClassList, rPrefix, rBase ); + } +} + +void SvMetaClass::FillClasses( SvMetaClassList & rList ) +{ + // Am I not yet in? + for ( size_t i = 0, n = rList.size(); i < n; ++i ) + if ( rList[ i ] == this ) + return; + + rList.push_back( this ); + + // my imports + for( size_t n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + pCl->FillClasses( rList ); + } + + // my superclass + if( aSuperClass.is() ) + aSuperClass->FillClasses( rList ); +} + + +void SvMetaClass::WriteSlotStubs( std::string_view rShellName, + SvSlotElementList & rSlotList, + std::vector<OString> & rList, + SvStream & rOutStm ) +{ + // write all attributes + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + pAttr->WriteSlotStubs( rShellName, rList, rOutStm ); + } +} + +void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + WriteStars( rOutStm ); + // define class + rOutStm.WriteCharPtr( "#ifdef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass" ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#define ShellClass " ).WriteOString( GetName() ) << endl; + + // no slotmaps get written for interfaces + if( GetMetaTypeType() != MetaTypeType::Shell ) + { + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + return; + } + // write parameter array + rOutStm.WriteCharPtr("static SfxFormalArgument a").WriteOString(GetName()).WriteCharPtr("Args_Impl[] =") << endl; + rOutStm.WriteChar('{') << endl; + + std::vector<sal_uLong> aSuperList; + SvMetaClassList classList; + SvSlotElementList aSlotList; + InsertSlots(aSlotList, aSuperList, classList, OString(), rBase); + for ( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pSlot = aSlotList[ i ]; + pSlot->SetListPos( i ); + } + + size_t nSlotCount = aSlotList.size(); + + // write all attributes + sal_uInt16 nArgCount = WriteSlotParamArray( rBase, aSlotList, rOutStm ); + if( nArgCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl << endl; + + std::vector<OString> aStringList; + WriteSlotStubs( GetName(), aSlotList, aStringList, rOutStm ); + aStringList.clear(); + + rOutStm << endl; + + // write slotmap + rOutStm.WriteCharPtr("static SfxSlot a").WriteOString(GetName()).WriteCharPtr("Slots_Impl[] =") << endl; + rOutStm.WriteChar( '{' ) << endl; + + // write all attributes + WriteSlots( GetName(), aSlotList, rBase, rOutStm ); + if( nSlotCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteOString( GetName() ) + .WriteCharPtr( ", 0, SfxGroupId::NONE, " ) + .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," ) + .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," ) + .WriteCharPtr( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + + for( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot* pAttr = aSlotList[ i ]; + pAttr->ResetSlotPointer(); + } + + aSlotList.clear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/slot.cxx b/idl/source/objects/slot.cxx new file mode 100644 index 000000000..17b8970ed --- /dev/null +++ b/idl/source/objects/slot.cxx @@ -0,0 +1,620 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <osl/diagnose.h> +#include <tools/debug.hxx> +#include <slot.hxx> +#include <globals.hxx> +#include <database.hxx> + + +SvMetaSlot::SvMetaSlot() + : aRecordPerSet( true ) + , aRecordAbsolute( false ) + , pNextSlot(nullptr) + , nListPos(0) + , aReadOnlyDoc ( true ) +{ +} + +SvMetaSlot::SvMetaSlot( SvMetaType * pType ) + : SvMetaAttribute( pType ) + , aRecordPerSet( true ) + , aRecordAbsolute( false ) + , pNextSlot(nullptr) + , nListPos(0) + , aReadOnlyDoc ( true ) +{ +} + +bool SvMetaSlot::GetReadOnlyDoc() const +{ + if( aReadOnlyDoc.IsSet() || !GetRef() ) return aReadOnlyDoc; + return static_cast<SvMetaSlot *>(GetRef())->GetReadOnlyDoc(); +} + +bool SvMetaSlot::IsVariable() const +{ + SvMetaType * pType = GetType(); + return pType->GetMetaTypeType() != MetaTypeType::Method; +} + +bool SvMetaSlot::IsMethod() const +{ + SvMetaType * pType = GetType(); + return pType->GetMetaTypeType() == MetaTypeType::Method; +} + +/************************************************************************* +|* reference +|* +|* description Second FALSE in the SvBOOL-Objects means +|* IsSet() provides FALSE (default initialization). +*************************************************************************/ +/** reference disbandment **/ +const OString& SvMetaSlot::GetGroupId() const +{ + if( !aGroupId.getString().isEmpty() || !GetRef() ) return aGroupId.getString(); + return static_cast<SvMetaSlot *>(GetRef())->GetGroupId(); +} +const OString& SvMetaSlot::GetDisableFlags() const +{ + if( !aDisableFlags.isEmpty() || !GetRef() ) return aDisableFlags; + return static_cast<SvMetaSlot *>(GetRef())->GetDisableFlags(); +} +const OString& SvMetaSlot::GetExecMethod() const +{ + if( !aExecMethod.getString().isEmpty() || !GetRef() ) return aExecMethod.getString(); + return static_cast<SvMetaSlot *>(GetRef())->GetExecMethod(); +} +const OString& SvMetaSlot::GetStateMethod() const +{ + if( !aStateMethod.getString().isEmpty() || !GetRef() ) return aStateMethod.getString(); + return static_cast<SvMetaSlot *>(GetRef())->GetStateMethod(); +} +bool SvMetaSlot::GetToggle() const +{ + if( aToggle.IsSet() || !GetRef() ) return aToggle; + return static_cast<SvMetaSlot *>(GetRef())->GetToggle(); +} +bool SvMetaSlot::GetAutoUpdate() const +{ + if( aAutoUpdate.IsSet() || !GetRef() ) return aAutoUpdate; + return static_cast<SvMetaSlot *>(GetRef())->GetAutoUpdate(); +} +bool SvMetaSlot::GetAsynchron() const +{ + // Synchron and Asynchron are exclusive + if( !GetRef() || aAsynchron.IsSet() ) + return aAsynchron; + return static_cast<SvMetaSlot *>(GetRef())->GetAsynchron(); +} +bool SvMetaSlot::GetRecordPerItem() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aRecordPerItem; + return static_cast<SvMetaSlot *>(GetRef())->GetRecordPerItem(); +} +bool SvMetaSlot::GetRecordPerSet() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aRecordPerSet; + return static_cast<SvMetaSlot *>(GetRef())->GetRecordPerSet(); +} +bool SvMetaSlot::GetNoRecord() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aNoRecord; + return static_cast<SvMetaSlot *>(GetRef())->GetNoRecord(); +} +bool SvMetaSlot::GetRecordAbsolute() const +{ + if( !GetRef() || aRecordAbsolute.IsSet() ) + return aRecordAbsolute; + return static_cast<SvMetaSlot *>(GetRef())->GetRecordAbsolute(); +} +bool SvMetaSlot::GetMenuConfig() const +{ + if( aMenuConfig.IsSet() || !GetRef() ) return aMenuConfig; + return static_cast<SvMetaSlot *>(GetRef())->GetMenuConfig(); +} +bool SvMetaSlot::GetToolBoxConfig() const +{ + if( aToolBoxConfig.IsSet() || !GetRef() ) return aToolBoxConfig; + return static_cast<SvMetaSlot *>(GetRef())->GetToolBoxConfig(); +} +bool SvMetaSlot::GetAccelConfig() const +{ + if( aAccelConfig.IsSet() || !GetRef() ) return aAccelConfig; + return static_cast<SvMetaSlot *>(GetRef())->GetAccelConfig(); +} +bool SvMetaSlot::GetFastCall() const +{ + if( aFastCall.IsSet() || !GetRef() ) return aFastCall; + return static_cast<SvMetaSlot *>(GetRef())->GetFastCall(); +} +bool SvMetaSlot::GetContainer() const +{ + if( aContainer.IsSet() || !GetRef() ) return aContainer; + return static_cast<SvMetaSlot *>(GetRef())->GetContainer(); +} + +void SvMetaSlot::ReadAttributesSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + SvMetaAttribute::ReadAttributesSvIdl( rBase, rInStm ); + + aGroupId.ReadSvIdl( SvHash_GroupId(), rInStm ); + aExecMethod.ReadSvIdl( SvHash_ExecMethod(), rInStm ); + aStateMethod.ReadSvIdl( SvHash_StateMethod(), rInStm ); + ReadStringSvIdl( SvHash_DisableFlags(), rInStm, aDisableFlags ); + aReadOnlyDoc.ReadSvIdl( SvHash_ReadOnlyDoc(), rInStm ); + aToggle.ReadSvIdl( SvHash_Toggle(), rInStm ); + aAutoUpdate.ReadSvIdl( SvHash_AutoUpdate(), rInStm ); + aAsynchron.ReadSvIdl( SvHash_Asynchron(), rInStm ); + aRecordAbsolute.ReadSvIdl( SvHash_RecordAbsolute(), rInStm ); + + if( aRecordPerItem.ReadSvIdl( SvHash_RecordPerItem(), rInStm ) ) + { + SetRecordPerItem( aRecordPerItem ); + } + if( aRecordPerSet.ReadSvIdl( SvHash_RecordPerSet(), rInStm ) ) + { + SetRecordPerSet( aRecordPerSet ); + } + if( aNoRecord.ReadSvIdl( SvHash_NoRecord(), rInStm ) ) + { + SetNoRecord( aNoRecord ); + } + + aMenuConfig.ReadSvIdl( SvHash_MenuConfig(), rInStm ); + aToolBoxConfig.ReadSvIdl( SvHash_ToolBoxConfig(), rInStm ); + aAccelConfig.ReadSvIdl( SvHash_AccelConfig(), rInStm ); + + aFastCall.ReadSvIdl( SvHash_FastCall(), rInStm ); + aContainer.ReadSvIdl( SvHash_Container(), rInStm ); +} + +bool SvMetaSlot::Test( SvTokenStream & rInStm ) +{ + bool bOk = SvMetaAttribute::Test( rInStm ); + if( bOk ) + { + SvMetaType * pType = GetType(); + if( pType->GetMetaTypeType() == MetaTypeType::Method ) + pType = pType->GetReturnType(); + if( !pType->IsItem() ) + { + throw SvParseException( rInStm, "this attribute is not a slot" ); + } + } + + return bOk; +} + +bool SvMetaSlot::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = true; + + SvMetaAttribute * pAttr = rBase.ReadKnownAttr( rInStm, GetType() ); + if( pAttr ) + { + // c + SvMetaSlot * pKnownSlot = dynamic_cast<SvMetaSlot*>( pAttr ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr->GetName() + " is method or variable but not a slot" ); + SetRef( pKnownSlot ); + SetName( pKnownSlot->GetName() ); + bOk = SvMetaObject::ReadSvIdl( rBase, rInStm ); + } + else + { + bOk = SvMetaAttribute::ReadSvIdl( rBase, rInStm ); + + SvMetaAttribute *pAttr2 = rBase.FindKnownAttr( GetSlotId() ); + if( pAttr2 ) + { + // for testing purposes: reference in case of complete definition + SvMetaSlot * pKnownSlot = dynamic_cast<SvMetaSlot*>( pAttr2 ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr2->GetName() + " is method or variable but not a slot" ); + SetRef( pKnownSlot ); + + // names may differ, because explicitly given + if ( pKnownSlot->GetName() != GetName() ) + { + OSL_FAIL("Illegal definition!"); + rInStm.Seek( nTokPos ); + return false; + } + + SetName( pKnownSlot->GetName() ); + } + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + + return bOk; +} + +void SvMetaSlot::Insert( SvSlotElementList& rList) +{ + // get insert position through binary search in slotlist + sal_uInt16 nId = static_cast<sal_uInt16>(GetSlotId().GetValue()); + sal_uInt16 nListCount = static_cast<sal_uInt16>(rList.size()); + sal_uInt16 nPos; + + if ( !nListCount ) + nPos = 0; + else if ( nListCount == 1 ) + nPos = rList[ 0 ]->GetSlotId().GetValue() >= nId ? 0 : 1; + else + { + sal_uInt16 nMid = 0, nLow = 0; + sal_uInt16 nHigh = nListCount - 1; + bool bFound = false; + while ( !bFound && nLow <= nHigh ) + { + nMid = (nLow + nHigh) >> 1; + DBG_ASSERT( nMid < nListCount, "bsearch is buggy" ); + int nDiff = static_cast<int>(nId) - static_cast<int>(rList[ nMid ]->GetSlotId().GetValue()); + if ( nDiff < 0) + { + if ( nMid == 0 ) + break; + nHigh = nMid - 1; + } + else if ( nDiff > 0 ) + { + nLow = nMid + 1; + if ( nLow == 0 ) + break; + } + else + bFound = true; + } + + DBG_ASSERT(!bFound, "Duplicate SlotId!"); + nPos = bFound ? nMid : nLow; + } + + DBG_ASSERT( nPos <= nListCount, + "nPos too large" ); + DBG_ASSERT( nPos == nListCount || nId <= + static_cast<sal_uInt16>(rList[ nPos ]->GetSlotId().GetValue()), + "Successor has lower SlotId" ); + DBG_ASSERT( nPos == 0 || nId > + static_cast<sal_uInt16>(rList[ nPos-1 ]->GetSlotId().GetValue()), + "Predecessor has higher SlotId" ); + DBG_ASSERT( nPos+1 >= nListCount || nId < + static_cast<sal_uInt16>(rList[ nPos+1 ]->GetSlotId().GetValue()), + "Successor has lower SlotId" ); + + if ( nPos < rList.size() ) + { + SvSlotElementList::iterator it = rList.begin(); + std::advance( it, nPos ); + rList.insert( it, this ); + } + else + { + rList.push_back( this ); + } +} + + +static OString MakeSlotName( SvStringHashEntry const * pEntry ) +{ + return "SfxSlotMode::" + pEntry->GetName().toAsciiUpperCase(); +}; + +void SvMetaSlot::WriteSlotStubs( std::string_view rShellName, + std::vector<OString> & rList, + SvStream & rOutStm ) const +{ + OString aMethodName( GetExecMethod() ); + if ( !aMethodName.isEmpty() && + aMethodName != "NoExec" ) + { + bool bIn = false; + for( size_t n = 0; n < rList.size(); n++ ) + { + if (rList[n] == aMethodName) + { + bIn = true; + break; + } + } + + if ( !bIn ) + { + rList.push_back( aMethodName ); + rOutStm.WriteCharPtr( "SFX_EXEC_STUB(" ) + .WriteOString( rShellName ) + .WriteChar( ',' ) + .WriteOString( aMethodName ) + .WriteChar( ')' ) << endl; + } + } + + aMethodName = GetStateMethod(); + if (aMethodName.isEmpty() || aMethodName == "NoState") + return; + + bool bIn = false; + for ( size_t n=0; n < rList.size(); n++ ) + { + if (rList[n] == aMethodName) + { + bIn = true; + break; + } + } + + if ( !bIn ) + { + rList.push_back( aMethodName ); + rOutStm.WriteCharPtr( "SFX_STATE_STUB(" ) + .WriteOString( rShellName ) + .WriteChar( ',' ) + .WriteOString( aMethodName ) + .WriteChar( ')' ) << endl; + } +} + +void SvMetaSlot::WriteSlot( std::string_view rShellName, sal_uInt16 nCount, + std::string_view rSlotId, + SvSlotElementList& rSlotList, + size_t nStart, + SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + rOutStm.WriteCharPtr( "// Slot Nr. " ) + .WriteOString( OString::number(nListPos) ) + .WriteCharPtr( " : " ); + OString aSlotIdValue(OString::number(GetSlotId().GetValue())); + rOutStm.WriteOString( aSlotIdValue ) << endl; + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr( "SFX_NEW_SLOT_ARG( " ).WriteOString( rShellName ).WriteChar( ',' ) ; + + rOutStm.WriteOString( rSlotId ).WriteChar( ',' ); + + // GroupId + if( !GetGroupId().isEmpty() ) + rOutStm.WriteOString( GetGroupId() ); + else + rOutStm.WriteCharPtr( "SfxGroupId::NONE" ); + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + // look for the next slot with the same StateMethod like me + // the slotlist is set to the current slot + size_t i = nStart; + SvMetaSlot* pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + while ( pNextSlot ) + { + if ( !pNextSlot->pNextSlot && + pNextSlot->GetStateMethod() == GetStateMethod() + ) { + break; + } + pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + } + + if ( !pNextSlot ) + { + // There is no slot behind me that has the same ExecMethod. + // So I search for the first slot with it (could be myself). + i = 0; + pEle = rSlotList.empty() ? nullptr : rSlotList[ i ]; + pNextSlot = pEle; + while (pNextSlot && pNextSlot != this) + { + if ( pNextSlot->GetStateMethod() == GetStateMethod() ) + break; + pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + } + } + + assert(pNextSlot); + + rOutStm.WriteCharPtr( "&a" ).WriteOString( rShellName ).WriteCharPtr( "Slots_Impl[" ) + .WriteOString( OString::number(pNextSlot->GetListPos()) ) + .WriteCharPtr( "] /*Offset Next*/, " ) << endl; + + WriteTab( rOutStm, 4 ); + + // write ExecMethod, with standard name if not specified + if( !GetExecMethod().isEmpty() && + GetExecMethod() != "NoExec") + { + rOutStm.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName ).WriteChar( ',' ) + .WriteOString( GetExecMethod() ).WriteChar( ')' ); + } + else + rOutStm.WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE" ); + rOutStm.WriteChar( ',' ); + + // write StateMethod, with standard name if not specified + if( !GetStateMethod().isEmpty() && + GetStateMethod() != "NoState") + { + rOutStm.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName ).WriteChar( ',' ) + .WriteOString( GetStateMethod() ).WriteChar( ')' ); + } + else + rOutStm.WriteCharPtr( "SFX_STUB_PTR_STATE_NONE" ); + + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + // write flags + if( GetToggle() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Toggle() ) ).WriteChar( '|' ); + if( GetAutoUpdate() ) + rOutStm.WriteOString( MakeSlotName( SvHash_AutoUpdate() ) ).WriteChar( '|' ); + if( GetAsynchron() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Asynchron() ) ).WriteChar( '|' ); + if( GetRecordPerItem() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordPerItem() ) ).WriteChar( '|' ); + if( GetRecordPerSet() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordPerSet() ) ).WriteChar( '|' ); + if( GetNoRecord() ) + rOutStm.WriteOString( MakeSlotName( SvHash_NoRecord() ) ).WriteChar( '|' ); + if( GetRecordAbsolute() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordAbsolute() ) ).WriteChar( '|' ); + if( GetMenuConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_MenuConfig() ) ).WriteChar( '|' ); + if( GetToolBoxConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_ToolBoxConfig() ) ).WriteChar( '|' ); + if( GetAccelConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_AccelConfig() ) ).WriteChar( '|' ); + if( GetFastCall() ) + rOutStm.WriteOString( MakeSlotName( SvHash_FastCall() ) ).WriteChar( '|' ); + if( GetContainer() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Container() ) ).WriteChar( '|' ); + if ( GetReadOnlyDoc() ) + rOutStm.WriteOString( MakeSlotName( SvHash_ReadOnlyDoc() ) ).WriteChar( '|' ); + rOutStm.WriteCharPtr( "SfxSlotMode::NONE" ); + + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + if ( GetDisableFlags().isEmpty() ) + rOutStm.WriteCharPtr( "SfxDisableFlags::NONE" ); + else + rOutStm.WriteOString( GetDisableFlags() ); + + // write attribute type + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + SvMetaType * pT = GetType(); + if( !IsVariable() ) + { + SvMetaType * pRT = GetType()->GetReturnType(); + pT = pRT ? pRT : rBase.FindType( "SfxVoidItem" ); + } + + if( pT ) + { + assert(pT->IsItem()); + rOutStm.WriteOString( pT->GetName() ); + if( !SvIdlDataBase::FindType( pT, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pT ); + } + else + rOutStm.WriteCharPtr( "SfxVoidItem not defined" ); + + { + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + rOutStm + .WriteOString( OString::number(nCount) ) + .WriteCharPtr( "/*Offset*/, " ); + + if( IsMethod() ) + { + SvMetaType * pType = GetType(); + sal_uLong nSCount = pType->GetAttrCount(); + rOutStm + .WriteOString( OString::number(nSCount) ) + .WriteCharPtr( "/*Count*/," ); + } + else + rOutStm.WriteCharPtr( "0," ); + + rOutStm.WriteCharPtr( " " ); + + // Method/Property flags + if( IsMethod() ) + rOutStm.WriteCharPtr( "SfxSlotMode::METHOD|" ); + + rOutStm.WriteCharPtr( "SfxSlotMode::NONE" ); + } + + { + rOutStm.WriteCharPtr( ",\"" ); + rOutStm.WriteOString( GetName() ); + rOutStm.WriteCharPtr( "\"" ); + } + + rOutStm.WriteCharPtr( " )," ) << endl; +} + +sal_uInt16 SvMetaSlot::WriteSlotParamArray( SvIdlDataBase & rBase, SvStream & rOutStm ) const +{ + if( !IsMethod() ) + return 0; + + SvMetaType * pType = GetType(); + + if( !SvIdlDataBase::FindType( pType, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pType ); + + const SvRefMemberList<SvMetaAttribute *>& rList = + pType->GetAttrList(); + for( size_t n = 0; n < rList.size(); n++ ) + { + SvMetaAttribute * pPar = rList[n]; + SvMetaType * pPType = pPar->GetType(); + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr("{ (const SfxType*) &a") + // item type + .WriteOString(pPType->GetName()).WriteCharPtr("_Impl, ") + // parameter name + .WriteCharPtr("\"").WriteOString(pPar->GetName()).WriteCharPtr("\", ") + // slot id + .WriteOString(pPar->GetSlotId().getString()).WriteCharPtr(" },") << endl; + if( !SvIdlDataBase::FindType( pPType, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pPType ); + } + return static_cast<sal_uInt16>(rList.size()); +} + +sal_uInt16 SvMetaSlot::WriteSlotMap( std::string_view rShellName, sal_uInt16 nCount, + SvSlotElementList& rSlotList, + size_t nStart, + SvIdlDataBase & rBase, + SvStream & rOutStm ) +{ + // SlotId, if not specified generate from name + OString slotId = GetSlotId().getString(); + + sal_uInt16 nSCount = 0; + if( IsMethod() ) + { + SvMetaType * pType = GetType(); + nSCount = static_cast<sal_uInt16>(pType->GetAttrCount()); + } + + WriteSlot( rShellName, nCount, slotId, rSlotList, nStart, rBase, rOutStm ); + return nSCount; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/types.cxx b/idl/source/objects/types.cxx new file mode 100644 index 000000000..08492b4b6 --- /dev/null +++ b/idl/source/objects/types.cxx @@ -0,0 +1,320 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <sal/config.h> + +#include <algorithm> + +#include <tools/debug.hxx> + +#include <types.hxx> +#include <globals.hxx> +#include <database.hxx> + +SvMetaAttribute::SvMetaAttribute() +{ +} + +SvMetaAttribute::SvMetaAttribute( SvMetaType * pType ) + : aType( pType ) +{ +} + +SvMetaType * SvMetaAttribute::GetType() const +{ + if( aType.is() || !GetRef() ) return aType.get(); + return static_cast<SvMetaAttribute *>(GetRef())->GetType(); +} + +const SvIdentifier & SvMetaAttribute::GetSlotId() const +{ + if( aSlotId.IsSet() || !GetRef() ) return aSlotId; + return static_cast<SvMetaAttribute *>(GetRef())->GetSlotId(); +} + +bool SvMetaAttribute::Test( SvTokenStream & rInStm ) +{ + if( GetType()->IsItem() && !GetSlotId().IsSet() ) + { + throw SvParseException( rInStm, "slot without id declared" ); + } + return true; +} + +bool SvMetaAttribute::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + if( !GetType() ) + // no type in ctor passed on + aType = rBase.ReadKnownType( rInStm ); + bool bOk = false; + if( GetType() ) + { + ReadNameSvIdl( rInStm ); + aSlotId.ReadSvIdl( rBase, rInStm ); + + bOk = true; + SvToken& rTok = rInStm.GetToken(); + if( rTok.IsChar() && rTok.GetChar() == '(' ) + { + tools::SvRef<SvMetaType> xT(new SvMetaType() ); + xT->SetRef( GetType() ); + aType = xT; + bOk = aType->ReadMethodArgs( rBase, rInStm ); + } + if( bOk ) + bOk = SvMetaObject::ReadSvIdl( rBase, rInStm ); + } + else + { + SvToken& rTok = rInStm.GetToken(); + rBase.SetError( "unknown type of token. Each new SID needs an " + "item statement in an SDI file, eg. " + "SfxVoidItem FooItem " + rTok.GetTokenAsString() + + " ... which describes the slot more fully", rTok ); + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + +size_t SvMetaAttribute::MakeSfx( OStringBuffer& rAttrArray ) const +{ + SvMetaType * pType = GetType(); + DBG_ASSERT( pType, "no type for attribute" ); + SvMetaType * pBaseType = pType->GetBaseType(); + DBG_ASSERT( pBaseType, "no base type for attribute" ); + if( pBaseType->GetMetaTypeType() == MetaTypeType::Struct ) + return pBaseType->MakeSfx( rAttrArray ); + else + { + rAttrArray.append('{'); + rAttrArray.append(GetSlotId().getString()); + rAttrArray.append(",\""); + rAttrArray.append(GetName()); + rAttrArray.append("\"}"); + return 1; + } +} + +void SvMetaAttribute::Insert(SvSlotElementList&) +{ +} + +SvMetaType::SvMetaType() + : nType( MetaTypeType::Base ) + , bIsItem( false ) +{ +} + +SvMetaType::SvMetaType( const OString& rName ) + : SvMetaType() +{ + SetName( rName ); +} + +SvMetaType::~SvMetaType() +{} + +void SvMetaType::SetType( MetaTypeType nT ) +{ + nType = nT; +} + +SvMetaType * SvMetaType::GetBaseType() const +{ + if( GetRef() && GetMetaTypeType() == MetaTypeType::Base ) + return static_cast<SvMetaType *>(GetRef())->GetBaseType(); + return const_cast<SvMetaType *>(this); +} + +SvMetaType * SvMetaType::GetReturnType() const +{ + DBG_ASSERT( GetMetaTypeType() == MetaTypeType::Method, "no method" ); + DBG_ASSERT( GetRef(), "no return type" ); + return static_cast<SvMetaType *>(GetRef()); +} + +bool SvMetaType::ReadHeaderSvIdl( SvTokenStream & rInStm ) +{ + bool bOk = false; + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( SvHash_interface() ) ) + { + SetType( MetaTypeType::Interface ); + bOk = ReadNameSvIdl( rInStm ); + } + else if( rTok.Is( SvHash_shell() ) ) + { + SetType( MetaTypeType::Shell ); + bOk = ReadNameSvIdl( rInStm ); + } + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + +bool SvMetaType::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + if( ReadHeaderSvIdl( rInStm ) ) + { + rBase.Write(OString('.')); + return SvMetaReference::ReadSvIdl( rBase, rInStm ); + } + return false; +} + +void SvMetaType::ReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + tools::SvRef<SvMetaAttribute> xAttr( new SvMetaAttribute() ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + { + if( xAttr->Test( rInStm ) ) + GetAttrList().push_back( xAttr.get() ); + } +} + +size_t SvMetaType::MakeSfx( OStringBuffer& rAttrArray ) +{ + size_t nC = 0; + + if( GetBaseType()->GetMetaTypeType() == MetaTypeType::Struct ) + { + size_t nAttrCount = GetAttrCount(); + // write the single attributes + for( size_t n = 0; n < nAttrCount; n++ ) + { + nC += aAttrList[n]->MakeSfx( rAttrArray ); + if( n +1 < nAttrCount ) + rAttrArray.append(", "); + } + } + return nC; +} + +void SvMetaType::WriteSfxItem( + std::string_view rItemName, SvIdlDataBase const & rBase, SvStream& rOutStm ) +{ + WriteStars( rOutStm ); + OString aVarName = OString::Concat(" a") + rItemName + "_Impl"; + + OStringBuffer aAttrArray(1024); + size_t nAttrCount = MakeSfx( aAttrArray ); + OString aAttrCount( OString::number(nAttrCount)); + OString aTypeName = "SfxType" + aAttrCount; + + bool bExport = false, bReturn = false; + // these are exported from sfx library + if (rItemName == "SfxBoolItem" || + rItemName == "SfxInt16Item" || + rItemName == "SfxStringItem" || + rItemName == "SfxUInt16Item" || + rItemName == "SfxUInt32Item" || + rItemName == "SfxVoidItem") + { + bExport = true; + if (!rBase.sSlotMapFile.endsWith("sfxslots.hxx")) + bReturn = true; + } + + rOutStm.WriteCharPtr( "extern " ); + if (bExport) + rOutStm.WriteCharPtr( "SFX2_DLLPUBLIC " ); + rOutStm.WriteOString( aTypeName ) + .WriteOString( aVarName ).WriteChar( ';' ) << endl; + if (bReturn) + return; + + // write the implementation part + rOutStm.WriteCharPtr( "#ifdef SFX_TYPEMAP" ) << endl; + rOutStm.WriteCharPtr( "#if !defined(_WIN32) && (defined(DISABLE_DYNLOADING) && (defined(ANDROID) || defined(IOS) || defined(EMSCRIPTEN) || defined(LINUX)))" ) << endl; + rOutStm.WriteCharPtr( "__attribute__((__weak__))" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl; + rOutStm.WriteOString( aTypeName ).WriteOString( aVarName ) + .WriteCharPtr( " = " ) << endl; + rOutStm.WriteChar( '{' ) << endl; + + rOutStm.WriteCharPtr( "\tcreateSfxPoolItem<" ).WriteOString( rItemName ) + .WriteCharPtr(">, &typeid(").WriteOString( rItemName ).WriteCharPtr( "), " ); + rOutStm.WriteOString( aAttrCount ); + if( nAttrCount ) + { + rOutStm.WriteCharPtr( ", { " ); + // write the single attributes + rOutStm.WriteCharPtr( aAttrArray.getStr() ); + rOutStm.WriteCharPtr( " }" ); + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; +} + +void SvMetaType::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + if( IsItem() ) + { + if( GetBaseType()->GetMetaTypeType() == MetaTypeType::Struct ) + GetBaseType()->WriteSfxItem( GetName(), rBase, rOutStm ); + else + WriteSfxItem( GetName(), rBase, rOutStm ); + } +} + +bool SvMetaType::ReadMethodArgs( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + if( rInStm.ReadIf( '(' ) ) + { + DoReadContextSvIdl( rBase, rInStm ); + if( rInStm.ReadIf( ')' ) ) + { + SetType( MetaTypeType::Method ); + return true; + } + } + rInStm.Seek( nTokPos ); + return false; +} + +SvMetaTypeString::SvMetaTypeString() + : SvMetaType( "String" ) +{ +} + +SvMetaEnumValue::SvMetaEnumValue() +{ +} + +SvMetaTypeEnum::SvMetaTypeEnum() +{ +} + +SvMetaTypevoid::SvMetaTypevoid() + : SvMetaType( "void" ) +{ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |