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/document/IndexedPropertyValues.hpp>
14 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
15 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
16 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
17 #include <com/sun/star/ui/ItemType.hpp>
19 #include <comphelper/documentinfo.hxx>
20 #include <comphelper/processfactory.hxx>
21 #include <comphelper/sequence.hxx>
22 #include <o3tl/safeint.hxx>
23 #include <sfx2/objsh.hxx>
24 #include <tools/diagnose_ex.h>
25 #include <unotools/configmgr.hxx>
27 #include <sal/log.hxx>
29 using namespace com::sun::star
;
31 // no. of visual data elements in a SwCTB ( fixed )
32 const short nVisualData
= 5;
34 typedef std::map
< sal_Int16
, OUString
> IdToString
;
38 class MSOWordCommandConvertor
: public MSOCommandConvertor
40 IdToString msoToOOcmd
;
41 IdToString tcidToOOcmd
;
44 MSOWordCommandConvertor();
45 virtual OUString
MSOCommandToOOCommand( sal_Int16 msoCmd
) override
;
46 virtual OUString
MSOTCIDToOOCommand( sal_Int16 key
) override
;
51 MSOWordCommandConvertor::MSOWordCommandConvertor()
53 // mso command id to ooo command string
54 // #FIXME and *HUNDREDS* of id's to added here
55 msoToOOcmd
[ 0x20b ] = ".uno:CloseDoc";
56 msoToOOcmd
[ 0x50 ] = ".uno:Open";
58 // mso tcid to ooo command string
59 // #FIXME and *HUNDREDS* of id's to added here
60 tcidToOOcmd
[ 0x9d9 ] = ".uno:Print";
63 OUString
MSOWordCommandConvertor::MSOCommandToOOCommand( sal_Int16 key
)
65 IdToString::iterator it
= msoToOOcmd
.find( key
);
66 if ( it
!= msoToOOcmd
.end() )
71 OUString
MSOWordCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key
)
73 IdToString::iterator it
= tcidToOOcmd
.find( key
);
74 if ( it
!= tcidToOOcmd
.end() )
79 SwCTBWrapper::SwCTBWrapper() :
91 SwCTBWrapper::~SwCTBWrapper()
95 Customization
* SwCTBWrapper::GetCustomizaton( sal_Int16 index
)
97 if ( index
< 0 || index
>= static_cast<sal_Int16
>( rCustomizations
.size() ) )
99 return &rCustomizations
[ index
];
102 SwCTB
* SwCTBWrapper::GetCustomizationData( const OUString
& sTBName
)
104 auto it
= std::find_if(rCustomizations
.begin(), rCustomizations
.end(),
105 [&sTBName
](Customization
& rCustomization
) {
106 SwCTB
* pCTB
= rCustomization
.GetCustomizationData();
107 return pCTB
&& pCTB
->GetName() == sTBName
;
109 if (it
!= rCustomizations
.end())
110 return it
->GetCustomizationData();
114 bool SwCTBWrapper::Read( SvStream
& rS
)
116 SAL_INFO("sw.ww8","SwCTBWrapper::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
118 Tcg255SubStruct::Read( rS
);
119 rS
.ReadUInt16( reserved2
).ReadUChar( reserved3
).ReadUInt16( reserved4
).ReadUInt16( reserved5
);
120 rS
.ReadInt16( cbTBD
).ReadUInt16( cCust
).ReadInt32( cbDTBC
);
121 tools::Long nExpectedPos
= rS
.Tell() + cbDTBC
;
124 // cbDTBC is the size in bytes of the SwTBC array
125 // but the size of a SwTBC element is dynamic ( and this relates to TBDelta's
126 int nStart
= rS
.Tell();
129 // cbDTBC specifies the size ( in bytes ) taken by an array ( of unspecified size )
130 // of SwTBC records ( SwTBC records have dynamic length, so we need to check our position
135 if ( !aTBC
.Read( rS
) )
137 rtbdc
.push_back( aTBC
);
138 bytesToRead
= cbDTBC
- ( rS
.Tell() - nStart
);
139 } while ( bytesToRead
> 0 );
141 if ( static_cast< tools::Long
>( rS
.Tell() ) != nExpectedPos
)
143 // Strange error condition, shouldn't happen ( but does in at least
144 // one test document ) In the case where it happens the SwTBC &
145 // TBCHeader records seem blank??? ( and incorrect )
146 SAL_WARN_IF( static_cast< tools::Long
>(rS
.Tell()) != nExpectedPos
, "sw.ww8","### Error: Expected pos not equal to actual pos after reading rtbdc");
147 SAL_INFO("sw.ww8","\tPos now is 0x" << std::hex
<< rS
.Tell() << " should be 0x" << std::hex
<< nExpectedPos
);
148 // seek to correct position after rtbdc
149 rS
.Seek( nExpectedPos
);
153 //Each customization takes a min of 8 bytes
154 size_t nMaxPossibleRecords
= rS
.remainingSize() / 8;
155 if (cCust
> nMaxPossibleRecords
)
159 for (sal_uInt16 index
= 0; index
< cCust
; ++index
)
161 Customization
aCust( this );
162 if ( !aCust
.Read( rS
) )
164 rCustomizations
.push_back( aCust
);
167 for ( const auto& rIndex
: dropDownMenuIndices
)
169 if (rIndex
< 0 || o3tl::make_unsigned(rIndex
) >= rCustomizations
.size())
171 rCustomizations
[rIndex
].bIsDroppedMenuTB
= true;
176 SwTBC
* SwCTBWrapper::GetTBCAtOffset( sal_uInt32 nStreamOffset
)
178 auto it
= std::find_if(rtbdc
.begin(), rtbdc
.end(),
179 [&nStreamOffset
](SwTBC
& rItem
) { return rItem
.GetOffset() == nStreamOffset
; });
180 if ( it
!= rtbdc
.end() )
185 bool SwCTBWrapper::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
187 for ( auto& rCustomization
: rCustomizations
)
191 css::uno::Reference
<css::ui::XUIConfigurationManager
> xCfgMgr
;
192 if (!utl::ConfigManager::IsFuzzing())
194 uno::Reference
< uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
195 uno::Reference
< ui::XModuleUIConfigurationManagerSupplier
> xAppCfgSupp( ui::theModuleUIConfigurationManagerSupplier::get(xContext
) );
196 xCfgMgr
= xAppCfgSupp
->getUIConfigurationManager("com.sun.star.text.TextDocument");
198 CustomToolBarImportHelper
helper(rDocSh
, xCfgMgr
);
199 helper
.setMSOCommandMap( new MSOWordCommandConvertor() );
201 if ( !rCustomization
.ImportCustomToolBar( *this, helper
) )
212 Customization::Customization( SwCTBWrapper
* wrapper
)
216 , pWrapper( wrapper
)
217 , bIsDroppedMenuTB( false )
221 bool Customization::Read( SvStream
&rS
)
223 SAL_INFO("sw.ww8","Customization::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
225 rS
.ReadInt32( tbidForTBD
).ReadUInt16( reserved1
).ReadUInt16( ctbds
);
228 //each TBDelta is at least 18 bytes in size
229 size_t nMaxAvailableRecords
= rS
.remainingSize() / 18;
230 if (ctbds
> nMaxAvailableRecords
)
232 for (sal_uInt16 index
= 0; index
< ctbds
; ++index
)
235 if (!aTBDelta
.Read( rS
) )
237 customizationDataTBDelta
.push_back( aTBDelta
);
238 // Only set the drop down for menus associated with standard toolbar
239 if ( aTBDelta
.ControlDropsToolBar() && tbidForTBD
== 0x25 )
240 pWrapper
->InsertDropIndex( aTBDelta
.CustomizationIndex() );
245 customizationDataCTB
= std::make_shared
<SwCTB
>();
246 if ( !customizationDataCTB
->Read( rS
) )
252 bool Customization::ImportMenu( SwCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
254 if ( tbidForTBD
== 0x25 ) // we can handle in a limited way additions the built-in menu bar
256 for ( auto& rTBDelta
: customizationDataTBDelta
)
258 // for each new menu ( control that drops a toolbar )
260 if ( rTBDelta
.ControlIsInserted() && rTBDelta
.ControlDropsToolBar() )
262 Customization
* pCust
= pWrapper
->GetCustomizaton( rTBDelta
.CustomizationIndex() );
265 // currently only support built-in menu
266 const OUString
sMenuBar( "private:resource/menubar/menubar" );
269 SwTBC
* pTBC
= pWrapper
->GetTBCAtOffset( rTBDelta
.TBCStreamOffset() );
272 const OUString sMenuName
= pTBC
->GetCustomText().replace('&','~');
274 // see if the document has already setting for the menubar
276 uno::Reference
< container::XIndexContainer
> xIndexContainer
;
277 bool bHasSettings
= false;
278 if ( helper
.getCfgManager()->hasSettings( sMenuBar
) )
280 xIndexContainer
.set( helper
.getCfgManager()->getSettings( sMenuBar
, true ), uno::UNO_QUERY_THROW
);
285 if ( helper
.getAppCfgManager()->hasSettings( sMenuBar
) )
286 xIndexContainer
.set( helper
.getAppCfgManager()->getSettings( sMenuBar
, true ), uno::UNO_QUERY_THROW
);
288 xIndexContainer
.set( helper
.getAppCfgManager()->createSettings(), uno::UNO_SET_THROW
);
291 uno::Reference
< lang::XSingleComponentFactory
> xSCF( xIndexContainer
, uno::UNO_QUERY_THROW
);
292 uno::Reference
< uno::XComponentContext
> xContext(
293 comphelper::getProcessComponentContext() );
294 // create the popup menu
295 uno::Sequence
< beans::PropertyValue
> aPopupMenu( 4 );
296 aPopupMenu
[0].Name
= "CommandURL";
297 aPopupMenu
[0].Value
<<= "vnd.openoffice.org:" + sMenuName
;
298 aPopupMenu
[1].Name
= "Label";
299 aPopupMenu
[1].Value
<<= sMenuName
;
300 aPopupMenu
[2].Name
= "Type";
301 aPopupMenu
[2].Value
<<= sal_Int32( 0 );
302 aPopupMenu
[3].Name
= "ItemDescriptorContainer";
303 uno::Reference
< container::XIndexContainer
> xMenuContainer( xSCF
->createInstanceWithContext( xContext
), uno::UNO_QUERY_THROW
);
304 aPopupMenu
[3].Value
<<= xMenuContainer
;
305 if ( pCust
->customizationDataCTB
&& !pCust
->customizationDataCTB
->ImportMenuTB( rWrapper
, xMenuContainer
, helper
) )
307 SAL_INFO("sw.ww8","** there are " << xIndexContainer
->getCount() << " menu items on the bar, inserting after that");
308 xIndexContainer
->insertByIndex( xIndexContainer
->getCount(), uno::makeAny( aPopupMenu
) );
311 helper
.getCfgManager()->replaceSettings( sMenuBar
, uno::Reference
< container::XIndexAccess
>( xIndexContainer
, uno::UNO_QUERY_THROW
) );
313 helper
.getCfgManager()->insertSettings( sMenuBar
, uno::Reference
< container::XIndexAccess
>( xIndexContainer
, uno::UNO_QUERY_THROW
) );
315 uno::Reference
< ui::XUIConfigurationPersistence
> xPersistence( helper
.getCfgManager(), uno::UNO_QUERY_THROW
);
316 xPersistence
->store();
325 bool Customization::ImportCustomToolBar( SwCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
327 if ( tbidForTBD
== 0x25 )
328 return ImportMenu( rWrapper
, helper
);
329 if ( !customizationDataCTB
)
331 if ( !customizationDataCTB
->IsMenuToolbar() )
333 if ( !customizationDataCTB
->ImportCustomToolBar( rWrapper
, helper
) )
350 bool TBDelta::ControlIsInserted()
352 return ( ( doprfatendFlags
& 0x3 ) == 0x1 );
355 bool TBDelta::ControlDropsToolBar()
357 return !( CiTBDE
& 0x8000 );
361 sal_Int16
TBDelta::CustomizationIndex()
363 sal_Int16 nIndex
= CiTBDE
;
364 nIndex
= nIndex
>> 1;
365 nIndex
&= 0x1ff; // only 13 bits are relevant
369 bool TBDelta::Read(SvStream
&rS
)
371 SAL_INFO("sw.ww8","TBDelta::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
373 rS
.ReadUChar( doprfatendFlags
).ReadUChar( ibts
).ReadInt32( cidNext
).ReadInt32( cid
).ReadInt32( fc
) ;
374 rS
.ReadUInt16( CiTBDE
).ReadUInt16( cbTBC
);
378 SwCTB::SwCTB() : cbTBData( 0 )
390 bool SwCTB::IsMenuToolbar() const
392 return tb
.IsMenuToolbar();
395 bool SwCTB::Read( SvStream
&rS
)
397 SAL_INFO("sw.ww8","SwCTB::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
399 if ( !name
.Read( rS
) )
401 rS
.ReadInt32( cbTBData
);
402 if ( !tb
.Read( rS
) )
404 for ( short index
= 0; index
< nVisualData
; ++index
)
406 TBVisualData aVisData
;
408 rVisualData
.push_back( aVisData
);
411 rS
.ReadInt32( iWCTBl
).ReadUInt16( reserved
).ReadUInt16( unused
).ReadInt32( cCtls
);
415 for ( sal_Int32 index
= 0; index
< cCtls
; ++index
)
418 if ( !aTBC
.Read( rS
) )
420 rTBC
.push_back( aTBC
);
426 bool SwCTB::ImportCustomToolBar( SwCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
431 if ( !tb
.IsEnabled() )
432 return true; // didn't fail, just ignoring
433 // Create default setting
434 uno::Reference
< container::XIndexContainer
> xIndexContainer( helper
.getCfgManager()->createSettings(), uno::UNO_SET_THROW
);
435 uno::Reference
< container::XIndexAccess
> xIndexAccess( xIndexContainer
, uno::UNO_QUERY_THROW
);
436 uno::Reference
< beans::XPropertySet
> xProps( xIndexContainer
, uno::UNO_QUERY_THROW
);
438 // set UI name for toolbar
439 xProps
->setPropertyValue( "UIName", uno::makeAny( name
.getString() ) );
441 const OUString sToolBarName
= "private:resource/toolbar/custom_" + name
.getString();
442 for ( auto& rItem
: rTBC
)
444 // createToolBar item for control
445 if ( !rItem
.ImportToolBarControl( rWrapper
, xIndexContainer
, helper
, IsMenuToolbar() ) )
449 SAL_INFO("sw.ww8","Name of toolbar :-/ " << sToolBarName
);
451 helper
.getCfgManager()->insertSettings( sToolBarName
, xIndexAccess
);
453 #if 1 // don't think this is necessary
454 uno::Reference
< ui::XUIConfigurationPersistence
> xPersistence( helper
.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW
);
455 xPersistence
->store();
457 xPersistence
.set( helper
.getCfgManager(), uno::UNO_QUERY_THROW
);
458 xPersistence
->store();
462 catch( const uno::Exception
& )
464 TOOLS_INFO_EXCEPTION("sw.ww8","***** For some reason we have an" );
470 bool SwCTB::ImportMenuTB( SwCTBWrapper
& rWrapper
, const css::uno::Reference
< css::container::XIndexContainer
>& xIndexContainer
, CustomToolBarImportHelper
& rHelper
)
472 for ( auto& rItem
: rTBC
)
474 // createToolBar item for control
475 if ( !rItem
.ImportToolBarControl( rWrapper
, xIndexContainer
, rHelper
, true ) )
485 bool SwTBC::Read( SvStream
&rS
)
487 SAL_INFO("sw.ww8","SwTBC::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
489 if ( !tbch
.Read( rS
) )
491 if ( tbch
.getTcID() != 0x1 && tbch
.getTcID() != 0x1051 )
493 cid
= std::make_shared
<sal_uInt32
>();
494 rS
.ReadUInt32( *cid
);
496 // MUST exist if tbch.tct is not equal to 0x16
497 if ( tbch
.getTct() != 0x16 )
499 tbcd
= std::make_shared
<TBCData
>( tbch
);
500 if ( !tbcd
->Read( rS
) )
507 SwTBC::ImportToolBarControl( SwCTBWrapper
& rWrapper
, const css::uno::Reference
< css::container::XIndexContainer
>& toolbarcontainer
, CustomToolBarImportHelper
& helper
, bool bIsMenuBar
)
509 // cmtFci 0x1 Command based on a built-in command. See CidFci.
510 // cmtMacro 0x2 Macro command. See CidMacro.
511 // cmtAllocated 0x3 Allocated command. See CidAllocated.
512 // cmtNil 0x7 No command. See Cid.
513 bool bBuiltin
= false;
517 const sal_uInt32 nCid
= ( *cid
& 0xFFFF );
519 const sal_uInt8 cmt
= static_cast<sal_uInt8
>( nCid
& 0x7 );
520 const sal_Int16 arg2
= static_cast<sal_Int16
>( nCid
>> 3 );
525 SAL_INFO("sw.ww8","cmt is cmtFci builtin command 0x" << std::hex
<< arg2
);
530 SAL_INFO("sw.ww8","cmt is cmtMacro macro 0x" << std::hex
<< arg2
);
533 SAL_INFO("sw.ww8","cmt is cmtAllocated [???] 0x" << std::hex
<< arg2
);
536 SAL_INFO("sw.ww8","cmt is cmNill no-thing 0x" << std::hex
<< arg2
);
539 SAL_INFO("sw.ww8","illegal 0x" << std::hex
<< cmt
);
546 std::vector
< css::beans::PropertyValue
> props
;
549 const OUString sCommand
= helper
.MSOCommandToOOCommand( cmdId
);
550 if ( !sCommand
.isEmpty() )
552 beans::PropertyValue aProp
;
554 aProp
.Name
= "CommandURL";
555 aProp
.Value
<<= sCommand
;
556 props
.push_back( aProp
);
559 bool bBeginGroup
= false;
560 tbcd
->ImportToolBarControl( helper
, props
, bBeginGroup
, bIsMenuBar
);
562 TBCMenuSpecific
* pMenu
= tbcd
->getMenuSpecific();
565 SAL_INFO("sw.ww8","** control has a menu, name of toolbar with menu items is " << pMenu
->Name() );
566 // search for SwCTB with the appropriate name ( it contains the
567 // menu items, although we cannot import ( or create ) a menu on
568 // a custom toolbar we can import the menu items in a separate
569 // toolbar ( better than nothing )
570 SwCTB
* pCustTB
= rWrapper
.GetCustomizationData( pMenu
->Name() );
573 uno::Reference
< container::XIndexContainer
> xMenuDesc
= document::IndexedPropertyValues::create( comphelper::getProcessComponentContext() );
574 if ( !pCustTB
->ImportMenuTB( rWrapper
,xMenuDesc
, helper
) )
578 if ( !helper
.createMenu( pMenu
->Name(), xMenuDesc
) )
583 beans::PropertyValue aProp
;
584 aProp
.Name
= "ItemDescriptorContainer";
585 aProp
.Value
<<= xMenuDesc
;
586 props
.push_back( aProp
);
594 uno::Sequence
< beans::PropertyValue
> sProps( 1 );
595 sProps
[ 0 ].Name
= "Type";
596 sProps
[ 0 ].Value
<<= ui::ItemType::SEPARATOR_LINE
;
597 toolbarcontainer
->insertByIndex( toolbarcontainer
->getCount(), uno::makeAny( sProps
) );
600 toolbarcontainer
->insertByIndex( toolbarcontainer
->getCount(), uno::makeAny( comphelper::containerToSequence(props
) ) );
606 SwTBC::GetCustomText()
609 return tbcd
->getGeneralInfo().CustomText();
614 Xst::Read( SvStream
& rS
)
616 SAL_INFO("sw.ww8","Xst::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
618 sString
= read_uInt16_PascalString(rS
);
622 Tcg::Tcg() : nTcgVer( -1 )
626 bool Tcg::Read(SvStream
&rS
)
628 SAL_INFO("sw.ww8","Tcg::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
630 rS
.ReadSChar( nTcgVer
);
633 tcg
.reset( new Tcg255() );
634 return tcg
->Read( rS
);
637 bool Tcg::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
640 return tcg
->ImportCustomToolBar( rDocSh
);
652 bool Tcg255::processSubStruct( sal_uInt8 nId
, SvStream
&rS
)
654 std::unique_ptr
<Tcg255SubStruct
> xSubStruct
;
659 xSubStruct
.reset(new PlfMcd
);
664 xSubStruct
.reset(new PlfAcd
);
670 xSubStruct
.reset(new PlfKme
);
675 xSubStruct
.reset(new TcgSttbf
);
680 xSubStruct
.reset(new MacroNames
);
685 xSubStruct
.reset(new SwCTBWrapper
);
689 SAL_INFO("sw.ww8","Unknown id 0x" << std::hex
<< nId
);
692 xSubStruct
->ch
= nId
;
693 if (!xSubStruct
->Read(rS
))
695 rgtcgData
.push_back(std::move(xSubStruct
));
699 bool Tcg255::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
701 // Find the SwCTBWrapper
702 for ( const auto & rSubStruct
: rgtcgData
)
704 if ( rSubStruct
->id() == 0x12 )
706 // not so great, shouldn't really have to do a horror casting
707 SwCTBWrapper
* pCTBWrapper
= dynamic_cast< SwCTBWrapper
* > ( rSubStruct
.get() );
710 // tdf#127048 set this flag if we might import something
711 uno::Reference
<frame::XModel
> const xModel(rDocSh
.GetBaseModel());
712 comphelper::DocumentInfo::notifyMacroEventRead(xModel
);
714 if ( !pCTBWrapper
->ImportCustomToolBar( rDocSh
) )
722 bool Tcg255::Read(SvStream
&rS
)
724 SAL_INFO("sw.ww8","Tcg255::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
726 sal_uInt8 nId
= 0x40;
728 while ( nId
!= 0x40 )
730 if ( !processSubStruct( nId
, rS
) )
739 Tcg255SubStruct::Tcg255SubStruct( ) : ch(0)
743 bool Tcg255SubStruct::Read(SvStream
&rS
)
745 SAL_INFO("sw.ww8","Tcg255SubStruct::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
755 bool PlfMcd::Read(SvStream
&rS
)
757 SAL_INFO("sw.ww8","PffMcd::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
759 Tcg255SubStruct::Read( rS
);
760 rS
.ReadInt32( iMac
);
763 auto nMaxPossibleRecords
= rS
.remainingSize() / 24 /*sizeof MCD*/;
764 if (o3tl::make_unsigned(iMac
) > nMaxPossibleRecords
)
766 SAL_WARN("sw.ww8", iMac
<< " records claimed, but max possible is " << nMaxPossibleRecords
);
767 iMac
= nMaxPossibleRecords
;
772 for ( sal_Int32 index
= 0; index
< iMac
; ++index
)
774 if ( !rgmcd
[ index
].Read( rS
) )
790 bool PlfAcd::Read( SvStream
&rS
)
792 SAL_INFO("sw.ww8","PffAcd::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
794 Tcg255SubStruct::Read( rS
);
795 rS
.ReadInt32( iMac
);
798 auto nMaxPossibleRecords
= rS
.remainingSize() / (sizeof(sal_uInt16
)*2);
799 if (o3tl::make_unsigned(iMac
) > nMaxPossibleRecords
)
801 SAL_WARN("sw.ww8", iMac
<< " records claimed, but max possible is " << nMaxPossibleRecords
);
802 iMac
= nMaxPossibleRecords
;
806 rgacd
.reset( new Acd
[ iMac
] );
807 for ( sal_Int32 index
= 0; index
< iMac
; ++index
)
809 if ( !rgacd
[ index
].Read( rS
) )
825 bool PlfKme::Read(SvStream
&rS
)
827 SAL_INFO("sw.ww8","PlfKme::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
829 Tcg255SubStruct::Read( rS
);
830 rS
.ReadInt32( iMac
);
833 //each Kme is 14 bytes in size
834 size_t nMaxAvailableRecords
= rS
.remainingSize() / 14;
835 if (o3tl::make_unsigned(iMac
) > nMaxAvailableRecords
)
838 rgkme
.reset( new Kme
[ iMac
] );
839 for( sal_Int32 index
=0; index
<iMac
; ++index
)
841 if ( !rgkme
[ index
].Read( rS
) )
852 bool TcgSttbf::Read( SvStream
&rS
)
854 SAL_INFO("sw.ww8","TcgSttbf::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
856 Tcg255SubStruct::Read( rS
);
857 return sttbf
.Read( rS
);
860 TcgSttbfCore::TcgSttbfCore() : fExtend( 0 )
866 TcgSttbfCore::~TcgSttbfCore()
870 bool TcgSttbfCore::Read( SvStream
& rS
)
872 SAL_INFO("sw.ww8","TcgSttbfCore::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
874 rS
.ReadUInt16( fExtend
).ReadUInt16( cData
).ReadUInt16( cbExtra
);
877 if (cData
> rS
.remainingSize() / 4) //definitely an invalid record
879 dataItems
.reset( new SBBItem
[ cData
] );
880 for ( sal_Int32 index
= 0; index
< cData
; ++index
)
882 rS
.ReadUInt16( dataItems
[ index
].cchData
);
883 dataItems
[ index
].data
= read_uInt16s_ToOUString(rS
, dataItems
[index
].cchData
);
884 rS
.ReadUInt16( dataItems
[ index
].extraData
);
890 MacroNames::MacroNames() :
895 MacroNames::~MacroNames()
899 bool MacroNames::Read( SvStream
&rS
)
901 SAL_INFO("sw.ww8","MacroNames::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
903 Tcg255SubStruct::Read( rS
);
904 rS
.ReadUInt16( iMac
);
907 //even an empty MacroName will take 2 bytes
908 size_t nMaxAvailableRecords
= rS
.remainingSize()/sizeof(sal_uInt16
);
909 if (iMac
> nMaxAvailableRecords
)
911 rgNames
.reset( new MacroName
[ iMac
] );
912 for ( sal_Int32 index
= 0; index
< iMac
; ++index
)
914 if ( !rgNames
[ index
].Read( rS
) )
921 MacroName::MacroName():ibst(0)
925 bool MacroName::Read(SvStream
&rS
)
927 SAL_INFO("sw.ww8","MacroName::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
929 rS
.ReadUInt16( ibst
);
930 return xstz
.Read( rS
);
933 Xstz::Xstz():chTerm(0)
938 Xstz::Read(SvStream
&rS
)
940 SAL_INFO("sw.ww8","Xstz::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
942 if ( !xst
.Read( rS
) )
944 rS
.ReadUInt16( chTerm
);
945 if ( chTerm
!= 0 ) // should be an assert
950 Kme::Kme() : reserved1(0)
964 Kme::Read(SvStream
&rS
)
966 SAL_INFO("sw.ww8","Kme::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
968 rS
.ReadInt16( reserved1
).ReadInt16( reserved2
).ReadUInt16( kcm1
).ReadUInt16( kcm2
).ReadUInt16( kt
).ReadUInt32( param
);
972 Acd::Acd() : ibst( 0 )
977 bool Acd::Read(SvStream
&rS
)
979 SAL_INFO("sw.ww8","Acd::Read() stream pos 0x" << std::hex
<< rS
.Tell() );
981 rS
.ReadInt16( ibst
).ReadUInt16( fciBasedOnABC
);
985 MCD::MCD() : reserved1(0x56)
997 bool MCD::Read(SvStream
&rS
)
999 SAL_INFO("sw.ww8","MCD::Read() stream pos 0x" << rS
.Tell() );
1000 nOffSet
= rS
.Tell();
1001 rS
.ReadSChar( reserved1
).ReadUChar( reserved2
).ReadUInt16( ibst
).ReadUInt16( ibstName
).ReadUInt16( reserved3
);
1002 rS
.ReadUInt32( reserved4
).ReadUInt32( reserved5
).ReadUInt32( reserved6
).ReadUInt32( reserved7
);
1006 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */