1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include "ww8toolbar.hxx"
11 #include "ww8scan.hxx"
12 #include <com/sun/star/beans/XPropertySet.hpp>
13 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
14 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
15 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
16 #include <com/sun/star/ui/ItemType.hpp>
18 #include <comphelper/documentinfo.hxx>
19 #include <comphelper/indexedpropertyvalues.hxx>
20 #include <comphelper/processfactory.hxx>
21 #include <comphelper/propertyvalue.hxx>
22 #include <comphelper/sequence.hxx>
23 #include <o3tl/safeint.hxx>
24 #include <sfx2/objsh.hxx>
25 #include <comphelper/diagnose_ex.hxx>
26 #include <comphelper/configuration.hxx>
27 #include <rtl/ref.hxx>
29 #include <sal/log.hxx>
31 using namespace com::sun::star
;
33 // no. of visual data elements in a SwCTB ( fixed )
34 const short nVisualData
= 5;
36 typedef std::map
< sal_Int16
, OUString
> IdToString
;
40 class MSOWordCommandConvertor
: public MSOCommandConvertor
42 IdToString m_MSOToOOcmd
;
43 IdToString m_TCIDToOOcmd
;
46 MSOWordCommandConvertor();
47 virtual OUString
MSOCommandToOOCommand( sal_Int16 msoCmd
) override
;
48 virtual OUString
MSOTCIDToOOCommand( sal_Int16 key
) override
;
53 MSOWordCommandConvertor::MSOWordCommandConvertor()
55 // mso command id to ooo command string
56 // #FIXME and *HUNDREDS* of id's to added here
57 m_MSOToOOcmd
[ 0x20b ] = ".uno:CloseDoc";
58 m_MSOToOOcmd
[ 0x50 ] = ".uno:Open";
60 // mso tcid to ooo command string
61 // #FIXME and *HUNDREDS* of id's to added here
62 m_TCIDToOOcmd
[ 0x9d9 ] = ".uno:Print";
65 OUString
MSOWordCommandConvertor::MSOCommandToOOCommand( sal_Int16 key
)
67 IdToString::iterator it
= m_MSOToOOcmd
.find( key
);
68 if ( it
!= m_MSOToOOcmd
.end() )
73 OUString
MSOWordCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key
)
75 IdToString::iterator it
= m_TCIDToOOcmd
.find( key
);
76 if ( it
!= m_TCIDToOOcmd
.end() )
81 SwCTBWrapper::SwCTBWrapper() :
93 SwCTBWrapper::~SwCTBWrapper()
97 Customization
* SwCTBWrapper::GetCustomizaton( sal_Int16 index
)
99 if ( index
< 0 || o3tl::make_unsigned(index
) >= m_rCustomizations
.size() )
101 return &m_rCustomizations
[ index
];
104 SwCTB
* SwCTBWrapper::GetCustomizationData( const OUString
& sTBName
)
106 auto it
= std::find_if(m_rCustomizations
.begin(), m_rCustomizations
.end(),
107 [&sTBName
](Customization
& rCustomization
) {
108 SwCTB
* pCTB
= rCustomization
.GetCustomizationData();
109 return pCTB
&& pCTB
->GetName() == sTBName
;
111 if (it
!= m_rCustomizations
.end())
112 return it
->GetCustomizationData();
116 bool SwCTBWrapper::Read( SvStream
& rS
)
118 SAL_INFO("sw.ww8","SwCTBWrapper::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
120 Tcg255SubStruct::Read( rS
);
121 rS
.ReadUInt16( m_reserved2
).ReadUChar( m_reserved3
).ReadUInt16( m_reserved4
).ReadUInt16( m_reserved5
);
122 rS
.ReadInt16( m_cbTBD
).ReadUInt16( m_cCust
).ReadInt32( m_cbDTBC
);
123 sal_uInt64 nExpectedPos
= rS
.Tell() + m_cbDTBC
;
126 // cbDTBC is the size in bytes of the SwTBC array
127 // but the size of a SwTBC element is dynamic ( and this relates to TBDelta's
128 int nStart
= rS
.Tell();
131 // cbDTBC specifies the size ( in bytes ) taken by an array ( of unspecified size )
132 // of SwTBC records ( SwTBC records have dynamic length, so we need to check our position
137 if ( !aTBC
.Read( rS
) )
139 m_rtbdc
.push_back( aTBC
);
140 bytesToRead
= m_cbDTBC
- ( rS
.Tell() - nStart
);
141 } while ( bytesToRead
> 0 );
143 if ( rS
.Tell() != nExpectedPos
)
145 // Strange error condition, shouldn't happen ( but does in at least
146 // one test document ) In the case where it happens the SwTBC &
147 // TBCHeader records seem blank??? ( and incorrect )
148 SAL_WARN_IF( rS
.Tell() != nExpectedPos
, "sw.ww8","### Error: Expected pos not equal to actual pos after reading rtbdc");
149 SAL_INFO("sw.ww8","\tPos now is 0x" << std::hex
<< rS
.Tell() << " should be 0x" << std::hex
<< nExpectedPos
);
150 // seek to correct position after rtbdc
151 rS
.Seek( nExpectedPos
);
155 //Each customization takes a min of 8 bytes
156 size_t nMaxPossibleRecords
= rS
.remainingSize() / 8;
157 if (m_cCust
> nMaxPossibleRecords
)
161 for (sal_uInt16 index
= 0; index
< m_cCust
; ++index
)
163 Customization
aCust( this );
164 if ( !aCust
.Read( rS
) )
166 m_rCustomizations
.push_back( aCust
);
169 for ( const auto& rIndex
: m_dropDownMenuIndices
)
171 if (rIndex
< 0 || o3tl::make_unsigned(rIndex
) >= m_rCustomizations
.size())
173 m_rCustomizations
[rIndex
].m_bIsDroppedMenuTB
= true;
178 SwTBC
* SwCTBWrapper::GetTBCAtOffset( sal_uInt32 nStreamOffset
)
180 auto it
= std::find_if(m_rtbdc
.begin(), m_rtbdc
.end(),
181 [&nStreamOffset
](SwTBC
& rItem
) { return rItem
.GetOffset() == nStreamOffset
; });
182 if ( it
!= m_rtbdc
.end() )
187 bool SwCTBWrapper::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
189 for ( auto& rCustomization
: m_rCustomizations
)
193 css::uno::Reference
<css::ui::XUIConfigurationManager
> xCfgMgr
;
194 if (!comphelper::IsFuzzing())
196 const uno::Reference
< uno::XComponentContext
>& xContext
= ::comphelper::getProcessComponentContext();
197 uno::Reference
< ui::XModuleUIConfigurationManagerSupplier
> xAppCfgSupp( ui::theModuleUIConfigurationManagerSupplier::get(xContext
) );
198 xCfgMgr
= xAppCfgSupp
->getUIConfigurationManager(u
"com.sun.star.text.TextDocument"_ustr
);
200 CustomToolBarImportHelper
helper(rDocSh
, xCfgMgr
);
201 helper
.setMSOCommandMap( new MSOWordCommandConvertor() );
203 if ( !rCustomization
.ImportCustomToolBar( *this, helper
) )
214 Customization::Customization( SwCTBWrapper
* wrapper
)
218 , m_pWrapper( wrapper
)
219 , m_bIsDroppedMenuTB( false )
223 bool Customization::Read( SvStream
&rS
)
225 SAL_INFO("sw.ww8","Customization::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
227 rS
.ReadInt32( m_tbidForTBD
).ReadUInt16( m_reserved1
).ReadUInt16( m_ctbds
);
230 //each TBDelta is at least 18 bytes in size
231 size_t nMaxAvailableRecords
= rS
.remainingSize() / 18;
232 if (m_ctbds
> nMaxAvailableRecords
)
234 for (sal_uInt16 index
= 0; index
< m_ctbds
; ++index
)
237 if (!aTBDelta
.Read( rS
) )
239 m_customizationDataTBDelta
.push_back( aTBDelta
);
240 // Only set the drop down for menus associated with standard toolbar
241 if ( aTBDelta
.ControlDropsToolBar() && m_tbidForTBD
== 0x25 )
242 m_pWrapper
->InsertDropIndex( aTBDelta
.CustomizationIndex() );
247 m_customizationDataCTB
= std::make_shared
<SwCTB
>();
248 if ( !m_customizationDataCTB
->Read( rS
) )
254 bool Customization::ImportMenu( SwCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
256 if ( m_tbidForTBD
== 0x25 ) // we can handle in a limited way additions the built-in menu bar
258 for ( auto& rTBDelta
: m_customizationDataTBDelta
)
260 // for each new menu ( control that drops a toolbar )
262 if ( rTBDelta
.ControlIsInserted() && rTBDelta
.ControlDropsToolBar() )
264 Customization
* pCust
= m_pWrapper
->GetCustomizaton( rTBDelta
.CustomizationIndex() );
267 // currently only support built-in menu
268 static constexpr OUString
sMenuBar( u
"private:resource/menubar/menubar"_ustr
);
271 SwTBC
* pTBC
= m_pWrapper
->GetTBCAtOffset( rTBDelta
.TBCStreamOffset() );
274 const OUString sMenuName
= pTBC
->GetCustomText().replace('&','~');
276 // see if the document has already setting for the menubar
278 uno::Reference
< container::XIndexContainer
> xIndexContainer
;
279 bool bHasSettings
= false;
280 if ( helper
.getCfgManager()->hasSettings( sMenuBar
) )
282 xIndexContainer
.set( helper
.getCfgManager()->getSettings( sMenuBar
, true ), uno::UNO_QUERY_THROW
);
287 if ( helper
.getAppCfgManager()->hasSettings( sMenuBar
) )
288 xIndexContainer
.set( helper
.getAppCfgManager()->getSettings( sMenuBar
, true ), uno::UNO_QUERY_THROW
);
290 xIndexContainer
.set( helper
.getAppCfgManager()->createSettings(), uno::UNO_SET_THROW
);
293 uno::Reference
< lang::XSingleComponentFactory
> xSCF( xIndexContainer
, uno::UNO_QUERY_THROW
);
294 const uno::Reference
< uno::XComponentContext
>& xContext(
295 comphelper::getProcessComponentContext() );
296 uno::Reference
< container::XIndexContainer
> xMenuContainer( xSCF
->createInstanceWithContext( xContext
), uno::UNO_QUERY_THROW
);
297 // create the popup menu
298 uno::Sequence
< beans::PropertyValue
> aPopupMenu
{
299 comphelper::makePropertyValue(u
"CommandURL"_ustr
, "vnd.openoffice.org:" + sMenuName
),
300 comphelper::makePropertyValue(u
"Label"_ustr
, sMenuName
),
301 comphelper::makePropertyValue(u
"Type"_ustr
, sal_Int32( 0 )),
302 comphelper::makePropertyValue(u
"ItemDescriptorContainer"_ustr
, xMenuContainer
)
304 if ( pCust
->m_customizationDataCTB
&& !pCust
->m_customizationDataCTB
->ImportMenuTB( rWrapper
, xMenuContainer
, helper
) )
306 SAL_INFO("sw.ww8","** there are " << xIndexContainer
->getCount() << " menu items on the bar, inserting after that");
307 xIndexContainer
->insertByIndex( xIndexContainer
->getCount(), uno::Any( aPopupMenu
) );
310 helper
.getCfgManager()->replaceSettings( sMenuBar
, uno::Reference
< container::XIndexAccess
>( xIndexContainer
, uno::UNO_QUERY_THROW
) );
312 helper
.getCfgManager()->insertSettings( sMenuBar
, uno::Reference
< container::XIndexAccess
>( xIndexContainer
, uno::UNO_QUERY_THROW
) );
314 uno::Reference
< ui::XUIConfigurationPersistence
> xPersistence( helper
.getCfgManager(), uno::UNO_QUERY_THROW
);
315 xPersistence
->store();
324 bool Customization::ImportCustomToolBar( SwCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
326 if ( m_tbidForTBD
== 0x25 )
327 return ImportMenu( rWrapper
, helper
);
328 if ( !m_customizationDataCTB
)
330 if ( !m_customizationDataCTB
->IsMenuToolbar() )
332 if ( !m_customizationDataCTB
->ImportCustomToolBar( rWrapper
, helper
) )
339 : m_doprfatendFlags(0)
349 bool TBDelta::ControlIsInserted()
351 return ( ( m_doprfatendFlags
& 0x3 ) == 0x1 );
354 bool TBDelta::ControlDropsToolBar()
356 return !( m_CiTBDE
& 0x8000 );
360 sal_Int16
TBDelta::CustomizationIndex()
362 sal_Int16 nIndex
= m_CiTBDE
;
363 nIndex
= nIndex
>> 1;
364 nIndex
&= 0x1ff; // only 13 bits are relevant
368 bool TBDelta::Read(SvStream
&rS
)
370 SAL_INFO("sw.ww8","TBDelta::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
372 rS
.ReadUChar( m_doprfatendFlags
).ReadUChar( m_ibts
).ReadInt32( m_cidNext
).ReadInt32( m_cid
).ReadInt32( m_fc
) ;
373 rS
.ReadUInt16( m_CiTBDE
).ReadUInt16( m_cbTBC
);
377 SwCTB::SwCTB() : m_cbTBData( 0 )
389 bool SwCTB::IsMenuToolbar() const
391 return m_tb
.IsMenuToolbar();
394 bool SwCTB::Read( SvStream
&rS
)
396 SAL_INFO("sw.ww8","SwCTB::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
398 if ( !m_name
.Read( rS
) )
400 rS
.ReadInt32( m_cbTBData
);
401 if ( !m_tb
.Read( rS
) )
403 for ( short index
= 0; index
< nVisualData
; ++index
)
405 TBVisualData aVisData
;
407 m_rVisualData
.push_back( aVisData
);
410 rS
.ReadInt32( m_iWCTBl
).ReadUInt16( m_reserved
).ReadUInt16( m_unused
).ReadInt32( m_cCtls
);
414 for ( sal_Int32 index
= 0; index
< m_cCtls
; ++index
)
417 if ( !aTBC
.Read( rS
) )
419 m_rTBC
.push_back( aTBC
);
425 bool SwCTB::ImportCustomToolBar( SwCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
430 if ( !m_tb
.IsEnabled() )
431 return true; // didn't fail, just ignoring
432 // Create default setting
433 uno::Reference
< container::XIndexContainer
> xIndexContainer( helper
.getCfgManager()->createSettings(), uno::UNO_SET_THROW
);
434 uno::Reference
< container::XIndexAccess
> xIndexAccess( xIndexContainer
, uno::UNO_QUERY_THROW
);
435 uno::Reference
< beans::XPropertySet
> xProps( xIndexContainer
, uno::UNO_QUERY_THROW
);
437 // set UI name for toolbar
438 xProps
->setPropertyValue( u
"UIName"_ustr
, uno::Any( m_name
.getString() ) );
440 const OUString sToolBarName
= "private:resource/toolbar/custom_" + m_name
.getString();
441 for ( auto& rItem
: m_rTBC
)
443 // createToolBar item for control
444 if ( !rItem
.ImportToolBarControl( rWrapper
, xIndexContainer
, helper
, IsMenuToolbar() ) )
448 SAL_INFO("sw.ww8","Name of toolbar :-/ " << sToolBarName
);
450 helper
.getCfgManager()->insertSettings( sToolBarName
, xIndexAccess
);
452 #if 1 // don't think this is necessary
453 uno::Reference
< ui::XUIConfigurationPersistence
> xPersistence( helper
.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW
);
454 xPersistence
->store();
456 xPersistence
.set( helper
.getCfgManager(), uno::UNO_QUERY_THROW
);
457 xPersistence
->store();
461 catch( const uno::Exception
& )
463 TOOLS_INFO_EXCEPTION("sw.ww8","***** For some reason we have an" );
469 bool SwCTB::ImportMenuTB( SwCTBWrapper
& rWrapper
, const css::uno::Reference
< css::container::XIndexContainer
>& xIndexContainer
, CustomToolBarImportHelper
& rHelper
)
471 for ( auto& rItem
: m_rTBC
)
473 // createToolBar item for control
474 if ( !rItem
.ImportToolBarControl( rWrapper
, xIndexContainer
, rHelper
, true ) )
484 bool SwTBC::Read( SvStream
&rS
)
486 SAL_INFO("sw.ww8","SwTBC::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
488 if ( !m_tbch
.Read( rS
) )
490 if ( m_tbch
.getTcID() != 0x1 && m_tbch
.getTcID() != 0x1051 )
492 m_cid
= std::make_shared
<sal_uInt32
>();
493 rS
.ReadUInt32( *m_cid
);
495 // MUST exist if tbch.tct is not equal to 0x16
496 if ( m_tbch
.getTct() != 0x16 )
498 m_tbcd
= std::make_shared
<TBCData
>( m_tbch
);
499 if ( !m_tbcd
->Read( rS
) )
506 SwTBC::ImportToolBarControl( SwCTBWrapper
& rWrapper
, const css::uno::Reference
< css::container::XIndexContainer
>& toolbarcontainer
, CustomToolBarImportHelper
& helper
, bool bIsMenuBar
)
508 // cmtFci 0x1 Command based on a built-in command. See CidFci.
509 // cmtMacro 0x2 Macro command. See CidMacro.
510 // cmtAllocated 0x3 Allocated command. See CidAllocated.
511 // cmtNil 0x7 No command. See Cid.
512 bool bBuiltin
= false;
516 const sal_uInt32 nCid
= ( *m_cid
& 0xFFFF );
518 const sal_uInt8 cmt
= static_cast<sal_uInt8
>( nCid
& 0x7 );
519 const sal_Int16 arg2
= static_cast<sal_Int16
>( nCid
>> 3 );
524 SAL_INFO("sw.ww8","cmt is cmtFci builtin command 0x" << std::hex
<< arg2
);
529 SAL_INFO("sw.ww8","cmt is cmtMacro macro 0x" << std::hex
<< arg2
);
532 SAL_INFO("sw.ww8","cmt is cmtAllocated [???] 0x" << std::hex
<< arg2
);
535 SAL_INFO("sw.ww8","cmt is cmNill no-thing 0x" << std::hex
<< arg2
);
538 SAL_INFO("sw.ww8","illegal 0x" << std::hex
<< cmt
);
545 std::vector
< css::beans::PropertyValue
> props
;
548 const OUString sCommand
= helper
.MSOCommandToOOCommand( cmdId
);
549 if ( !sCommand
.isEmpty() )
551 beans::PropertyValue aProp
;
553 aProp
.Name
= "CommandURL";
554 aProp
.Value
<<= sCommand
;
555 props
.push_back( aProp
);
558 bool bBeginGroup
= false;
559 m_tbcd
->ImportToolBarControl( helper
, props
, bBeginGroup
, bIsMenuBar
);
561 TBCMenuSpecific
* pMenu
= m_tbcd
->getMenuSpecific();
564 SAL_INFO("sw.ww8","** control has a menu, name of toolbar with menu items is " << pMenu
->Name() );
565 // search for SwCTB with the appropriate name ( it contains the
566 // menu items, although we cannot import ( or create ) a menu on
567 // a custom toolbar we can import the menu items in a separate
568 // toolbar ( better than nothing )
569 SwCTB
* pCustTB
= rWrapper
.GetCustomizationData( pMenu
->Name() );
572 rtl::Reference
< comphelper::IndexedPropertyValuesContainer
> xMenuDesc
= new comphelper::IndexedPropertyValuesContainer();
573 if ( !pCustTB
->ImportMenuTB( rWrapper
,xMenuDesc
, helper
) )
577 if ( !helper
.createMenu( pMenu
->Name(), xMenuDesc
) )
582 beans::PropertyValue aProp
;
583 aProp
.Name
= "ItemDescriptorContainer";
584 aProp
.Value
<<= uno::Reference
< container::XIndexContainer
>(xMenuDesc
);
585 props
.push_back( aProp
);
593 uno::Sequence
< beans::PropertyValue
> sProps
{ comphelper::makePropertyValue(
594 u
"Type"_ustr
, ui::ItemType::SEPARATOR_LINE
) };
595 toolbarcontainer
->insertByIndex( toolbarcontainer
->getCount(), uno::Any( sProps
) );
598 toolbarcontainer
->insertByIndex( toolbarcontainer
->getCount(), uno::Any( comphelper::containerToSequence(props
) ) );
604 SwTBC::GetCustomText()
607 return m_tbcd
->getGeneralInfo().CustomText();
608 return EMPTY_OUSTRING
;
612 Xst::Read( SvStream
& rS
)
614 SAL_INFO("sw.ww8","Xst::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
616 m_sString
= read_uInt16_PascalString(rS
);
620 Tcg::Tcg() : m_nTcgVer( -1 )
624 bool Tcg::Read(SvStream
&rS
)
626 SAL_INFO("sw.ww8","Tcg::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
628 rS
.ReadSChar( m_nTcgVer
);
629 if ( m_nTcgVer
!= -1 )
631 m_tcg
.reset( new Tcg255() );
632 return m_tcg
->Read( rS
);
635 bool Tcg::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
638 return m_tcg
->ImportCustomToolBar( rDocSh
);
650 bool Tcg255::processSubStruct( sal_uInt8 nId
, SvStream
&rS
)
652 std::unique_ptr
<Tcg255SubStruct
> xSubStruct
;
657 xSubStruct
.reset(new PlfMcd
);
662 xSubStruct
.reset(new PlfAcd
);
668 xSubStruct
.reset(new PlfKme
);
673 xSubStruct
.reset(new TcgSttbf
);
678 xSubStruct
.reset(new MacroNames
);
683 xSubStruct
.reset(new SwCTBWrapper
);
687 SAL_INFO("sw.ww8","Unknown id 0x" << std::hex
<< nId
);
690 xSubStruct
->m_ch
= nId
;
691 if (!xSubStruct
->Read(rS
))
693 m_rgtcgData
.push_back(std::move(xSubStruct
));
697 bool Tcg255::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
699 // Find the SwCTBWrapper
700 for ( const auto & rSubStruct
: m_rgtcgData
)
702 if ( rSubStruct
->id() == 0x12 )
704 // not so great, shouldn't really have to do a horror casting
705 SwCTBWrapper
* pCTBWrapper
= dynamic_cast< SwCTBWrapper
* > ( rSubStruct
.get() );
708 // tdf#127048 set this flag if we might import something
709 uno::Reference
<frame::XModel
> const xModel(rDocSh
.GetBaseModel());
710 comphelper::DocumentInfo::notifyMacroEventRead(xModel
);
712 if ( !pCTBWrapper
->ImportCustomToolBar( rDocSh
) )
720 bool Tcg255::Read(SvStream
&rS
)
722 SAL_INFO("sw.ww8","Tcg255::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
724 sal_uInt8 nId
= 0x40;
726 while ( nId
!= 0x40 )
728 if ( !processSubStruct( nId
, rS
) )
737 Tcg255SubStruct::Tcg255SubStruct( ) : m_ch(0)
741 bool Tcg255SubStruct::Read(SvStream
&rS
)
743 SAL_INFO("sw.ww8","Tcg255SubStruct::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
753 bool PlfMcd::Read(SvStream
&rS
)
755 SAL_INFO("sw.ww8","PffMcd::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
757 Tcg255SubStruct::Read( rS
);
758 rS
.ReadInt32( m_iMac
);
761 auto nMaxPossibleRecords
= rS
.remainingSize() / 24 /*sizeof MCD*/;
762 if (o3tl::make_unsigned(m_iMac
) > nMaxPossibleRecords
)
764 SAL_WARN("sw.ww8", m_iMac
<< " records claimed, but max possible is " << nMaxPossibleRecords
);
765 m_iMac
= nMaxPossibleRecords
;
769 m_rgmcd
.resize(m_iMac
);
770 for ( sal_Int32 index
= 0; index
< m_iMac
; ++index
)
772 if ( !m_rgmcd
[ index
].Read( rS
) )
788 bool PlfAcd::Read( SvStream
&rS
)
790 SAL_INFO("sw.ww8","PffAcd::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
792 Tcg255SubStruct::Read( rS
);
793 rS
.ReadInt32( m_iMac
);
796 auto nMaxPossibleRecords
= rS
.remainingSize() / (sizeof(sal_uInt16
)*2);
797 if (o3tl::make_unsigned(m_iMac
) > nMaxPossibleRecords
)
799 SAL_WARN("sw.ww8", m_iMac
<< " records claimed, but max possible is " << nMaxPossibleRecords
);
800 m_iMac
= nMaxPossibleRecords
;
804 m_rgacd
.reset( new Acd
[ m_iMac
] );
805 for ( sal_Int32 index
= 0; index
< m_iMac
; ++index
)
807 if ( !m_rgacd
[ index
].Read( rS
) )
823 bool PlfKme::Read(SvStream
&rS
)
825 SAL_INFO("sw.ww8","PlfKme::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
827 Tcg255SubStruct::Read( rS
);
828 rS
.ReadInt32( m_iMac
);
831 //each Kme is 14 bytes in size
832 size_t nMaxAvailableRecords
= rS
.remainingSize() / 14;
833 if (o3tl::make_unsigned(m_iMac
) > nMaxAvailableRecords
)
836 m_rgkme
.reset( new Kme
[ m_iMac
] );
837 for( sal_Int32 index
=0; index
<m_iMac
; ++index
)
839 if ( !m_rgkme
[ index
].Read( rS
) )
850 bool TcgSttbf::Read( SvStream
&rS
)
852 SAL_INFO("sw.ww8","TcgSttbf::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
854 Tcg255SubStruct::Read( rS
);
855 return m_sttbf
.Read( rS
);
858 TcgSttbfCore::TcgSttbfCore() : m_fExtend( 0 )
864 TcgSttbfCore::~TcgSttbfCore()
868 bool TcgSttbfCore::Read( SvStream
& rS
)
870 SAL_INFO("sw.ww8","TcgSttbfCore::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
872 rS
.ReadUInt16( m_fExtend
).ReadUInt16( m_cData
).ReadUInt16( m_cbExtra
);
875 if (m_cData
> rS
.remainingSize() / 4) //definitely an invalid record
877 m_dataItems
.reset( new SBBItem
[ m_cData
] );
878 for ( sal_Int32 index
= 0; index
< m_cData
; ++index
)
880 rS
.ReadUInt16( m_dataItems
[ index
].cchData
);
881 m_dataItems
[ index
].data
= read_uInt16s_ToOUString(rS
, m_dataItems
[index
].cchData
);
882 rS
.ReadUInt16( m_dataItems
[ index
].extraData
);
888 MacroNames::MacroNames() :
893 MacroNames::~MacroNames()
897 bool MacroNames::Read( SvStream
&rS
)
899 SAL_INFO("sw.ww8","MacroNames::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
901 Tcg255SubStruct::Read( rS
);
902 rS
.ReadUInt16( m_iMac
);
905 //even an empty MacroName will take 2 bytes
906 size_t nMaxAvailableRecords
= rS
.remainingSize()/sizeof(sal_uInt16
);
907 if (m_iMac
> nMaxAvailableRecords
)
909 m_rgNames
.reset( new MacroName
[ m_iMac
] );
910 for ( sal_Int32 index
= 0; index
< m_iMac
; ++index
)
912 if ( !m_rgNames
[ index
].Read( rS
) )
919 MacroName::MacroName():m_ibst(0)
923 bool MacroName::Read(SvStream
&rS
)
925 SAL_INFO("sw.ww8","MacroName::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
927 rS
.ReadUInt16( m_ibst
);
928 return m_xstz
.Read( rS
);
931 Xstz::Xstz():m_chTerm(0)
936 Xstz::Read(SvStream
&rS
)
938 SAL_INFO("sw.ww8","Xstz::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
940 if ( !m_xst
.Read( rS
) )
942 rS
.ReadUInt16( m_chTerm
);
943 if ( m_chTerm
!= 0 ) // should be an assert
948 Kme::Kme() : m_reserved1(0)
962 Kme::Read(SvStream
&rS
)
964 SAL_INFO("sw.ww8","Kme::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
966 rS
.ReadInt16( m_reserved1
).ReadInt16( m_reserved2
).ReadUInt16( m_kcm1
).ReadUInt16( m_kcm2
).ReadUInt16( m_kt
).ReadUInt32( m_param
);
970 Acd::Acd() : m_ibst( 0 )
971 , m_fciBasedOnABC( 0 )
975 bool Acd::Read(SvStream
&rS
)
977 SAL_INFO("sw.ww8","Acd::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
979 rS
.ReadInt16( m_ibst
).ReadUInt16( m_fciBasedOnABC
);
983 MCD::MCD() : m_reserved1(0x56)
987 ,m_reserved3( 0xFFFF )
995 bool MCD::Read(SvStream
&rS
)
997 SAL_INFO("sw.ww8","MCD::Read() stream pos 0x" << rS
.Tell() );
999 rS
.ReadSChar( m_reserved1
).ReadUChar( m_reserved2
).ReadUInt16( m_ibst
).ReadUInt16( m_ibstName
).ReadUInt16( m_reserved3
);
1000 rS
.ReadUInt32( m_reserved4
).ReadUInt32( m_reserved5
).ReadUInt32( m_reserved6
).ReadUInt32( m_reserved7
);
1004 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */