LibreOffice Module basic (master) 1
sbxbase.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <memory>
21#include <tools/debug.hxx>
22#include <tools/stream.hxx>
23#include <vcl/svapp.hxx>
24
25#include <basic/sbx.hxx>
26#include <sbxfac.hxx>
27#include <sbxform.hxx>
28#include <basic/sbxmeth.hxx>
29#include <sbxprop.hxx>
30#include <sbxbase.hxx>
31
32#include <rtl/ustring.hxx>
33#include <sal/log.hxx>
34#include <filefmt.hxx>
35
36// AppData-Structure for SBX:
37
38
40 : eErrCode(ERRCODE_NONE)
41 , aErrorMsg(OUString())
42 , eBasicFormaterLangType(LANGUAGE_DONTKNOW)
43{
44}
45
47{
49
50 pBasicFormater.reset();
51 // basic manager repository must be destroyed before factories
53}
54
56{
58}
59
61 : SvRefBase( r )
62{
63 nFlags = r.nFlags;
64}
65
67{
68}
69
71{
72 nFlags = r.nFlags;
73 return *this;
74}
75
77{
78 return SbxEMPTY;
79}
80
81bool SbxBase::IsFixed() const
82{
83 return IsSet( SbxFlagBits::Fixed );
84}
85
87{
89 return;
90 if( b )
92 else
94}
95
97{
99}
100
101OUString const & SbxBase::GetErrorMsg()
102{
103 return GetSbxData_Impl().aErrorMsg;
104}
105
106void SbxBase::SetError(ErrCode e, const OUString& rMsg)
107{
109 if (e && r.eErrCode == ERRCODE_NONE)
110 {
111 r.eErrCode = e;
112 r.aErrorMsg = rMsg;
113 }
114}
115
117{
119 if( e && r.eErrCode == ERRCODE_NONE )
120 r.eErrCode = e;
121}
122
124{
126}
127
129{
131 GetSbxData_Impl().aErrorMsg = OUString();
132}
133
135{
136 GetSbxData_Impl().m_Factories.emplace_back(pFac);
137}
138
140{
141 if (!IsSbxData_Impl())
142 return;
144 auto it = std::find(r.m_Factories.begin(), r.m_Factories.end(), pFac);
145 if (it != r.m_Factories.end())
146 r.m_Factories.erase( it );
147}
148
149
150SbxBaseRef SbxBase::Create( sal_uInt16 nSbxId, sal_uInt32 nCreator )
151{
152 // #91626: Hack to skip old Basic dialogs
153 // Problem: There does not exist a factory any more,
154 // so we have to create a dummy SbxVariable instead
155 if( nSbxId == 0x65 ) // Dialog Id
156 return new SbxVariable;
157
158 if( nCreator == SBXCR_SBX )
159 switch( nSbxId )
160 {
161 case SBXID_VALUE: return new SbxValue;
162 case SBXID_VARIABLE: return new SbxVariable;
163 case SBXID_ARRAY: return new SbxArray;
164 case SBXID_DIMARRAY: return new SbxDimArray;
165 case SBXID_OBJECT: return new SbxObject( "" );
166 case SBXID_COLLECTION: return new SbxCollection;
168 return new SbxStdCollection;
169 case SBXID_METHOD: return new SbxMethod( "", SbxEMPTY );
170 case SBXID_PROPERTY: return new SbxProperty( "", SbxEMPTY );
171 }
172 // Unknown type: go over the factories!
174 SbxBaseRef pNew;
175 for (auto const& rpFac : r.m_Factories)
176 {
177 pNew = rpFac->Create( nSbxId, nCreator );
178 if( pNew )
179 break;
180 }
181 SAL_WARN_IF(!pNew, "basic", "No factory for SBX ID " << nSbxId);
182 return pNew;
183}
184
185SbxObjectRef SbxBase::CreateObject( const OUString& rClass )
186{
188 SbxObjectRef pNew;
189 for (auto const& rpFac : r.m_Factories)
190 {
191 pNew = rpFac->CreateObject( rClass );
192 if( pNew )
193 break;
194 }
195 SAL_WARN_IF(!pNew, "basic", "No factory for object class " << rClass);
196 return pNew;
197}
198
199namespace {
200
201// coverity[ -taint_source ]
202[[nodiscard]] SbxFlagBits CorrectFlags(SbxFlagBits nFlags)
203{
204 // Correcting a foolishness of mine:
205 if (nFlags & SbxFlagBits::Reserved)
207 return nFlags & ~SbxFlagBits::Reserved;
208}
209
210}
211
213{
214 sal_uInt16 nSbxId(0), nFlagsTmp(0), nVer(0);
215 sal_uInt32 nCreator(0), nSize(0);
216 rStrm.ReadUInt32( nCreator ).ReadUInt16( nSbxId ).ReadUInt16( nFlagsTmp ).ReadUInt16( nVer );
217 SbxFlagBits nFlags = CorrectFlags(static_cast<SbxFlagBits>(nFlagsTmp));
218
219 sal_uInt64 nOldPos = rStrm.Tell();
220 rStrm.ReadUInt32( nSize );
221 SbxBaseRef p = Create( nSbxId, nCreator );
222 if( p )
223 {
224 p->nFlags = nFlags;
225 if( p->LoadData( rStrm, nVer ) )
226 {
227 sal_uInt64 const nNewPos = rStrm.Tell();
228 nOldPos += nSize;
229 DBG_ASSERT( nOldPos >= nNewPos, "SBX: Too much data loaded" );
230 if( nOldPos != nNewPos )
231 rStrm.Seek( nOldPos );
232 if( !p->LoadCompleted() )
233 {
234 // Deleting of the object
235 SbxBaseRef xDeleteRef( p );
236 p = nullptr;
237 }
238 }
239 else
240 {
242 // Deleting of the object
243 SbxBaseRef xDeleteRef( p );
244 p = nullptr;
245 }
246 }
247 else
249 return p;
250}
251
252std::pair<bool, sal_uInt32> SbxBase::Store( SvStream& rStrm )
253{
255 {
258 .WriteUInt16( static_cast<sal_uInt16>(GetFlags()) )
260 sal_uInt64 const nOldPos = rStrm.Tell();
261 rStrm.WriteUInt32( 0 );
262 auto [bRes, nVersion] = StoreData(rStrm);
263 sal_uInt64 const nNewPos = rStrm.Tell();
264 rStrm.Seek( nOldPos );
265 rStrm.WriteUInt32( nNewPos - nOldPos );
266 rStrm.Seek( nNewPos );
267 if( rStrm.GetError() != ERRCODE_NONE )
268 bRes = false;
269 if( bRes )
270 bRes = true;
271 return { bRes, nVersion };
272 }
273 else
274 return { true, B_IMG_VERSION_12 };
275}
276
278{
279 return true;
280}
281
283
285{
286}
287
288SbxBaseRef SbxFactory::Create( sal_uInt16, sal_uInt32 )
289{
290 return nullptr;
291}
292
294{
295 return nullptr;
296}
297
299
300SbxInfo::~SbxInfo()
301{}
302
303void SbxInfo::AddParam(const OUString& rName, SbxDataType eType, SbxFlagBits nFlags)
304{
305 m_Params.push_back(std::make_unique<SbxParamInfo>(rName, eType, nFlags));
306}
307
308const SbxParamInfo* SbxInfo::GetParam( sal_uInt16 n ) const
309{
310 if (n < 1 || n > m_Params.size())
311 return nullptr;
312 else
313 return m_Params[n - 1].get();
314}
315
316void SbxInfo::LoadData( SvStream& rStrm, sal_uInt16 nVer )
317{
318 m_Params.clear();
319 sal_uInt16 nParam;
321 RTL_TEXTENCODING_ASCII_US);
323 RTL_TEXTENCODING_ASCII_US);
324 rStrm.ReadUInt32( nHelpId ).ReadUInt16( nParam );
325 while( nParam-- )
326 {
327 sal_uInt16 nType(0), nFlagsTmp(0);
328 sal_uInt32 nUserData = 0;
330 RTL_TEXTENCODING_ASCII_US);
331 rStrm.ReadUInt16( nType ).ReadUInt16( nFlagsTmp );
332 SbxFlagBits nFlags = static_cast<SbxFlagBits>(nFlagsTmp);
333 if( nVer > 1 )
334 rStrm.ReadUInt32( nUserData );
335 AddParam( aName, static_cast<SbxDataType>(nType), nFlags );
336 SbxParamInfo& p(*m_Params.back());
337 p.nUserData = nUserData;
338 }
339}
340
341void SbxInfo::StoreData( SvStream& rStrm ) const
342{
344 RTL_TEXTENCODING_ASCII_US );
346 RTL_TEXTENCODING_ASCII_US);
347 rStrm.WriteUInt32( nHelpId ).WriteUInt16( m_Params.size() );
348 for (auto const& i : m_Params)
349 {
351 RTL_TEXTENCODING_ASCII_US);
352 rStrm.WriteUInt16( i->eType )
353 .WriteUInt16( static_cast<sal_uInt16>(i->nFlags) )
354 .WriteUInt32( i->nUserData );
355 }
356}
357
358/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsSbxData_Impl()
returns true if the SbxAppData is still valid, used to check if we are in shutdown.
Definition: basrdll.cxx:128
SbxAppData & GetSbxData_Impl()
Definition: basrdll.cxx:123
Definition: sbx.hxx:95
virtual bool IsFixed() const
Definition: sbxbase.cxx:81
static OUString const & GetErrorMsg()
Definition: sbxbase.cxx:101
SbxFlagBits nFlags
Definition: sbxcore.hxx:53
SbxBase & operator=(const SbxBase &)
Definition: sbxbase.cxx:70
virtual bool LoadCompleted()
Definition: sbxbase.cxx:277
static void SetError(ErrCode)
Definition: sbxbase.cxx:116
static void AddFactory(SbxFactory *)
Definition: sbxbase.cxx:134
static ErrCode const & GetError()
Definition: sbxbase.cxx:96
bool IsSet(SbxFlagBits n) const
Definition: sbxcore.hxx:114
void SetFlag(SbxFlagBits n)
Definition: sbxcore.hxx:108
virtual sal_uInt16 GetSbxId() const =0
SbxFlagBits GetFlags() const
Definition: sbxcore.hxx:105
static SbxObjectRef CreateObject(const OUString &)
Definition: sbxbase.cxx:185
SbxBase()
Definition: sbxbase.cxx:55
static SbxBaseRef Create(sal_uInt16, sal_uInt32)
Definition: sbxbase.cxx:150
virtual ~SbxBase() override
Definition: sbxbase.cxx:66
virtual sal_uInt16 GetVersion() const =0
virtual void SetModified(bool)
Definition: sbxbase.cxx:86
static bool IsError()
Definition: sbxbase.cxx:123
virtual std::pair< bool, sal_uInt32 > StoreData(SvStream &) const =0
std::pair< bool, sal_uInt32 > Store(SvStream &)
Definition: sbxbase.cxx:252
static SbxBaseRef Load(SvStream &)
Definition: sbxbase.cxx:212
static void RemoveFactory(SbxFactory const *)
Definition: sbxbase.cxx:139
virtual SbxDataType GetType() const
Definition: sbxbase.cxx:76
static void ResetError()
Definition: sbxbase.cxx:128
void ResetFlag(SbxFlagBits n)
Definition: sbxcore.hxx:111
virtual ~SbxFactory()
Definition: sbxbase.cxx:284
virtual SbxBaseRef Create(sal_uInt16 nSbxId, sal_uInt32)
Definition: sbxbase.cxx:288
virtual SbxObjectRef CreateObject(const OUString &)
Definition: sbxbase.cxx:293
sal_uInt64 Tell() const
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & WriteUInt32(sal_uInt32 nUInt32)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
void SetError(ErrCode nErrorCode)
sal_uInt64 Seek(sal_uInt64 nPos)
ErrCode GetError() const
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
#define DBG_ASSERT(sCon, aError)
#define SVSTREAM_FILEFORMAT_ERROR
#define ERRCODE_NONE
sal_Int16 nVersion
#define B_IMG_VERSION_12
Definition: filefmt.hxx:48
OUString aName
void * p
sal_Int64 n
#define LANGUAGE_DONTKNOW
#define SAL_WARN_IF(condition, area, stream)
int i
void SvStream & rStrm
QPRO_FUNC_TYPE nType
constexpr auto SBXID_PROPERTY
Definition: sbxdef.hxx:177
constexpr auto SBXID_VARIABLE
Definition: sbxdef.hxx:170
constexpr auto SBXID_ARRAY
Definition: sbxdef.hxx:171
constexpr auto SBXID_METHOD
Definition: sbxdef.hxx:176
constexpr auto SBXID_VALUE
Definition: sbxdef.hxx:169
constexpr auto SBXID_FIXCOLLECTION
Definition: sbxdef.hxx:175
SbxDataType
Definition: sbxdef.hxx:37
@ SbxEMPTY
Definition: sbxdef.hxx:38
constexpr auto SBXID_COLLECTION
Definition: sbxdef.hxx:174
SbxFlagBits
Definition: sbxdef.hxx:131
constexpr auto SBXID_OBJECT
Definition: sbxdef.hxx:173
constexpr auto SBXCR_SBX
Definition: sbxdef.hxx:164
constexpr auto SBXID_DIMARRAY
Definition: sbxdef.hxx:172
OUString read_uInt16_lenPrefixed_uInt8s_ToOUString(SvStream &rStrm, rtl_TextEncoding eEnc)
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream &rStrm, std::u16string_view rStr, rtl_TextEncoding eEnc)
std::unique_ptr< SbxBasicFormater > pBasicFormater
Definition: sbxbase.hxx:45
std::vector< SbxFactory * > m_Factories
Definition: sbxbase.hxx:41
OUString aErrorMsg
Definition: sbxbase.hxx:39
tools::SvRef< SvRefBase > mrImplRepository
Definition: sbxbase.hxx:42
~SbxAppData()
Definition: sbxbase.cxx:46
SbxAppData()
Definition: sbxbase.cxx:39
ErrCode eErrCode
Definition: sbxbase.hxx:38