Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svl/source/items/macitem.cxx
Line
Count
Source
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 <sal/config.h>
21
22
#include <o3tl/safeint.hxx>
23
#include <sal/log.hxx>
24
#include <comphelper/fileformat.h>
25
#include <tools/stream.hxx>
26
27
#include <svl/macitem.hxx>
28
#include <algorithm>
29
#include <utility>
30
31
SvxMacro::SvxMacro( OUString _aMacName, const OUString &rLanguage)
32
0
    : aMacName(std::move( _aMacName )), aLibName( rLanguage),
33
0
      eType( EXTENDED_STYPE)
34
0
{
35
0
    if ( rLanguage == SVX_MACRO_LANGUAGE_STARBASIC )
36
0
        eType=STARBASIC;
37
0
    else if ( rLanguage == SVX_MACRO_LANGUAGE_JAVASCRIPT )
38
0
        eType=JAVASCRIPT;
39
0
}
40
41
const OUString & SvxMacro::GetLanguage()const
42
0
{
43
0
    if(eType==STARBASIC)
44
0
    {
45
0
        return SVX_MACRO_LANGUAGE_STARBASIC;
46
0
    }
47
0
    else if(eType==JAVASCRIPT)
48
0
    {
49
0
        return SVX_MACRO_LANGUAGE_JAVASCRIPT;
50
0
    }
51
0
    else if(eType==EXTENDED_STYPE)
52
0
    {
53
0
        return SVX_MACRO_LANGUAGE_SF;
54
55
0
    }
56
0
    return aLibName;
57
0
}
58
59
SvxMacroTableDtor& SvxMacroTableDtor::operator=( const SvxMacroTableDtor& rTbl )
60
5
{
61
5
    if (this != &rTbl)
62
5
    {
63
5
        aSvxMacroTable.clear();
64
5
        aSvxMacroTable.insert(rTbl.aSvxMacroTable.begin(), rTbl.aSvxMacroTable.end());
65
5
    }
66
5
    return *this;
67
5
}
68
69
bool SvxMacroTableDtor::operator==( const SvxMacroTableDtor& rOther ) const
70
2.97k
{
71
    // Count different => odd in any case
72
    // Compare single ones; the sequence matters due to performance reasons
73
2.97k
    return std::equal(aSvxMacroTable.begin(), aSvxMacroTable.end(),
74
2.97k
        rOther.aSvxMacroTable.begin(), rOther.aSvxMacroTable.end(),
75
4.44k
        [](const SvxMacroTable::value_type& rOwnEntry, const SvxMacroTable::value_type& rOtherEntry) {
76
4.44k
            const SvxMacro& rOwnMac = rOwnEntry.second;
77
4.44k
            const SvxMacro& rOtherMac = rOtherEntry.second;
78
4.44k
            return rOwnEntry.first == rOtherEntry.first
79
4.20k
                && rOwnMac.GetLibName() == rOtherMac.GetLibName()
80
4.20k
                && rOwnMac.GetMacName() == rOtherMac.GetMacName();
81
4.44k
        });
82
2.97k
}
83
84
void SvxMacroTableDtor::Read( SvStream& rStrm )
85
0
{
86
0
    sal_uInt16 nVersion;
87
0
    rStrm.ReadUInt16( nVersion );
88
89
0
    short nReadMacro(0);
90
0
    rStrm.ReadInt16(nReadMacro);
91
0
    if (nReadMacro < 0)
92
0
    {
93
0
        SAL_WARN("editeng", "Parsing error: negative value " << nReadMacro);
94
0
        return;
95
0
    }
96
97
0
    auto nMacro = o3tl::make_unsigned(nReadMacro);
98
99
0
    const size_t nMinStringSize = rStrm.GetStreamEncoding() == RTL_TEXTENCODING_UNICODE ? 4 : 2;
100
0
    size_t nMinRecordSize = 2 + 2*nMinStringSize;
101
0
    if( SVX_MACROTBL_VERSION40 <= nVersion )
102
0
        nMinRecordSize+=2;
103
104
0
    const size_t nMaxRecords = rStrm.remainingSize() / nMinRecordSize;
105
0
    if (nMacro > nMaxRecords)
106
0
    {
107
0
        SAL_WARN("editeng", "Parsing error: " << nMaxRecords <<
108
0
                 " max possible entries, but " << nMacro<< " claimed, truncating");
109
0
        nMacro = nMaxRecords;
110
0
    }
111
112
0
    for (decltype(nMacro) i = 0; i < nMacro; ++i)
113
0
    {
114
0
        sal_uInt16 nCurKey, eType = STARBASIC;
115
0
        OUString aLibName, aMacName;
116
0
        rStrm.ReadUInt16( nCurKey );
117
0
        aLibName = rStrm.ReadUniOrByteString();
118
0
        aMacName = rStrm.ReadUniOrByteString();
119
120
0
        if( SVX_MACROTBL_VERSION40 <= nVersion )
121
0
            rStrm.ReadUInt16( eType );
122
123
0
        aSvxMacroTable.emplace( SvMacroItemId(nCurKey), SvxMacro( aMacName, aLibName, static_cast<ScriptType>(eType) ) );
124
0
    }
125
0
}
126
127
SvStream& SvxMacroTableDtor::Write( SvStream& rStream ) const
128
0
{
129
0
    sal_uInt16 nVersion = SOFFICE_FILEFORMAT_31 == rStream.GetVersion()
130
0
                                    ? SVX_MACROTBL_VERSION31
131
0
                                    : SVX_MACROTBL_VERSION40;
132
133
0
    if( SVX_MACROTBL_VERSION40 <= nVersion )
134
0
        rStream.WriteUInt16( nVersion );
135
136
0
    rStream.WriteUInt16( aSvxMacroTable.size() );
137
138
0
    for( const auto& rEntry : aSvxMacroTable )
139
0
    {
140
0
        if (rStream.GetError() != ERRCODE_NONE)
141
0
            break;
142
0
        const SvxMacro& rMac = rEntry.second;
143
0
        rStream.WriteUInt16( static_cast<sal_uInt16>(rEntry.first) );
144
0
        rStream.WriteUniOrByteString(rMac.GetLibName());
145
0
        rStream.WriteUniOrByteString(rMac.GetMacName());
146
147
0
        if( SVX_MACROTBL_VERSION40 <= nVersion )
148
0
            rStream.WriteUInt16( rMac.GetScriptType() );
149
0
    }
150
0
    return rStream;
151
0
}
152
153
// returns NULL if no entry exists, or a pointer to the internal value
154
const SvxMacro* SvxMacroTableDtor::Get(SvMacroItemId nEvent) const
155
0
{
156
0
    SvxMacroTable::const_iterator it = aSvxMacroTable.find(nEvent);
157
0
    return it == aSvxMacroTable.end() ? nullptr : &(it->second);
158
0
}
159
160
// returns NULL if no entry exists, or a pointer to the internal value
161
SvxMacro* SvxMacroTableDtor::Get(SvMacroItemId nEvent)
162
4.25k
{
163
4.25k
    SvxMacroTable::iterator it = aSvxMacroTable.find(nEvent);
164
4.25k
    return it == aSvxMacroTable.end() ? nullptr : &(it->second);
165
4.25k
}
166
167
// return true if the key exists
168
bool SvxMacroTableDtor::IsKeyValid(SvMacroItemId nEvent) const
169
8.05k
{
170
8.05k
    SvxMacroTable::const_iterator it = aSvxMacroTable.find(nEvent);
171
8.05k
    return it != aSvxMacroTable.end();
172
8.05k
}
173
174
// This stores a copy of the rMacro parameter
175
SvxMacro& SvxMacroTableDtor::Insert(SvMacroItemId nEvent, const SvxMacro& rMacro)
176
5.98k
{
177
5.98k
    return aSvxMacroTable.emplace( nEvent, rMacro ).first->second;
178
5.98k
}
179
180
// If the entry exists, remove it from the map and release it's storage
181
void SvxMacroTableDtor::Erase(SvMacroItemId nEvent)
182
4.27k
{
183
4.27k
    SvxMacroTable::iterator it = aSvxMacroTable.find(nEvent);
184
4.27k
    if ( it != aSvxMacroTable.end())
185
3
    {
186
3
        aSvxMacroTable.erase(it);
187
3
    }
188
4.27k
}
189
190
bool SvxMacroItem::operator==( const SfxPoolItem& rAttr ) const
191
2.97k
{
192
2.97k
    assert(SfxPoolItem::operator==(rAttr));
193
194
2.97k
    const SvxMacroTableDtor& rOwn = aMacroTable;
195
2.97k
    const SvxMacroTableDtor& rOther = static_cast<const SvxMacroItem&>(rAttr).aMacroTable;
196
197
2.97k
    return rOwn == rOther;
198
2.97k
}
199
200
SvxMacroItem* SvxMacroItem::Clone( SfxItemPool* ) const
201
517
{
202
517
    return new SvxMacroItem( *this );
203
517
}
204
205
bool SvxMacroItem::GetPresentation
206
(
207
    SfxItemPresentation /*ePres*/,
208
    MapUnit             /*eCoreUnit*/,
209
    MapUnit             /*ePresUnit*/,
210
    OUString&           rText,
211
    const IntlWrapper&
212
)   const
213
0
{
214
/*!!!
215
    SvxMacroTableDtor& rTbl = (SvxMacroTableDtor&)GetMacroTable();
216
    SvxMacro* pMac = rTbl.First();
217
218
    while ( pMac )
219
    {
220
        rText += pMac->GetLibName();
221
        rText += cpDelim;
222
        rText += pMac->GetMacName();
223
        pMac = rTbl.Next();
224
        if ( pMac )
225
            rText += cpDelim;
226
    }
227
*/
228
0
    rText.clear();
229
0
    return false;
230
0
}
231
232
233
void SvxMacroItem::SetMacro( SvMacroItemId nEvent, const SvxMacro& rMacro )
234
4.27k
{
235
    // tdf#141123: emplace doesn't replace the element in the map if already exists
236
    // see https://en.cppreference.com/w/cpp/container/map/emplace
237
    // so first erase the macro if there's one for this event
238
4.27k
    aMacroTable.Erase(nEvent);
239
4.27k
    aMacroTable.Insert( nEvent, rMacro);
240
4.27k
}
241
242
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */