Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/comphelper/errcode.hxx
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
#pragma once
20
21
#include <config_options.h>
22
#include <rtl/ustring.hxx>
23
#include <comphelper/comphelperdllapi.h>
24
#include <climits>
25
#include <ostream>
26
#include <o3tl/typed_flags_set.hxx>
27
#include <optional>
28
29
#if defined(DBG_UTIL)
30
#include <o3tl/source_location.hxx>
31
#ifdef LIBO_USE_SOURCE_LOCATION
32
// LIBO_USE_SOURCE_LOCATION may be defined without DBG_UTIL, so a separate define is needed
33
#define LIBO_ERRMSG_USE_SOURCE_LOCATION
34
#endif
35
#endif
36
37
/*
38
39
01234567012345670123456701234567
40
||   ||           ||   ||      |
41
Warning           ||   ||      |
42
 |   ||           ||   ||      |
43
 Unused           ||   ||      |
44
      |           ||   ||      |
45
      Subsystemarea|   ||      |
46
                   |   ||      |
47
                   |   ||      |
48
                   |   ||      |
49
                   Class|      |
50
                        |      |
51
                        |      |
52
                        |      |
53
                        Code
54
*/
55
56
1.13G
#define ERRCODE_ERROR_MASK               0x3fffffffUL
57
1.13G
#define ERRCODE_WARNING_MASK             0x80000000UL
58
59
177k
#define ERRCODE_CLASS_SHIFT              8
60
203k
#define ERRCODE_AREA_SHIFT               13
61
#define ERRCODE_DYNAMIC_SHIFT            26
62
63
#define ERRCODE_CLASS_MASK               (31UL << ERRCODE_CLASS_SHIFT)
64
65
enum class ErrCodeArea;
66
enum class ErrCodeClass;
67
68
enum class WarningFlag { Yes };
69
70
class SAL_WARN_UNUSED ErrCode final
71
{
72
public:
73
    explicit constexpr ErrCode(WarningFlag, ErrCodeArea nArea, ErrCodeClass nClass, sal_uInt16 nCode)
74
1.40k
        : m_value(ERRCODE_WARNING_MASK | (sal_uInt32(nArea) << ERRCODE_AREA_SHIFT) | (sal_uInt32(nClass) << ERRCODE_CLASS_SHIFT) | nCode)
75
1.40k
    {
76
1.40k
        assert(nCode <= 0xff && "code out of range");
77
1.40k
    }
78
    explicit constexpr ErrCode(ErrCodeArea nArea, ErrCodeClass nClass, sal_uInt16 nCode)
79
176k
        : m_value((sal_uInt32(nArea) << ERRCODE_AREA_SHIFT) | (sal_uInt32(nClass) << ERRCODE_CLASS_SHIFT) | nCode)
80
176k
    {
81
176k
        assert(nCode <= 0xff && "code out of range");
82
176k
    }
83
    explicit constexpr ErrCode(ErrCodeArea nArea, sal_uInt16 nClassAndCode)
84
26.3k
        : m_value((sal_uInt32(nArea) << ERRCODE_AREA_SHIFT) | nClassAndCode) {}
85
    explicit constexpr ErrCode(sal_uInt32 nValue)
86
1.13G
        : m_value(nValue) {}
87
    constexpr ErrCode()
88
10.9M
        : m_value(0) {}
89
90
40.9k
    explicit operator sal_uInt32() const { return m_value; }
91
221M
    explicit operator bool() const { return m_value != 0; }
92
93
    auto operator<=>(ErrCode const & other) const = default;
94
95
    /** convert to ERRCODE_NONE if it's a warning, else return the error */
96
1.13G
    ErrCode IgnoreWarning() const {
97
1.13G
        return (m_value & ERRCODE_WARNING_MASK)
98
1.13G
              ? ErrCode(0)
99
1.13G
              : ErrCode(static_cast<sal_uInt32>(m_value & ERRCODE_ERROR_MASK));
100
1.13G
    }
101
102
4.03M
    bool IsWarning() const {
103
4.03M
        return m_value & ERRCODE_WARNING_MASK;
104
4.03M
    }
105
106
0
    ErrCode MakeWarning() const {
107
0
        return ErrCode(m_value | ERRCODE_WARNING_MASK);
108
0
    }
Unexecuted instantiation: ErrCode::MakeWarning() const
Unexecuted instantiation: ErrCode::MakeWarning() const
109
110
57.5k
    bool IsError() const {
111
57.5k
        return m_value && !IsWarning();
112
57.5k
    }
113
114
0
    constexpr ErrCode StripWarning() const {
115
0
        return ErrCode(m_value & ~ERRCODE_WARNING_MASK);
116
0
    }
Unexecuted instantiation: ErrCode::StripWarning() const
Unexecuted instantiation: ErrCode::StripWarning() const
117
118
0
    constexpr ErrCodeArea GetArea() const {
119
0
        return static_cast<ErrCodeArea>((m_value >> ERRCODE_AREA_SHIFT) & 0x01fff);
120
0
    }
121
122
0
    constexpr ErrCodeClass GetClass() const {
123
0
        return static_cast<ErrCodeClass>((m_value >> ERRCODE_CLASS_SHIFT) & 0x1f);
124
0
    }
125
126
0
    constexpr sal_uInt8 GetCode() const {
127
0
        return static_cast<sal_uInt8>(m_value & 0xff);
128
0
    }
129
130
0
    OUString toHexString() const {
131
0
        return "0x" + OUString::number(m_value, 16);
132
0
    }
133
134
    /// Return a string suitable for debug output, the same as the operator<< function
135
    COMPHELPER_DLLPUBLIC OUString toString() const;
136
137
    template <typename... Args> bool anyOf(Args... args) const
138
    {
139
        static_assert(sizeof...(args) > 0);
140
        return (... || (*this == args));
141
    }
142
143
private:
144
    sal_uInt32 m_value;
145
};
146
147
COMPHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const ErrCode& err);
148
149
enum class DialogMask
150
{
151
    NONE                    = 0x0000,
152
    ButtonsOk               = 0x0001,
153
    ButtonsCancel           = 0x0002,
154
    ButtonsRetry            = 0x0004,
155
    ButtonsNo               = 0x0008,
156
    ButtonsYes              = 0x0010,
157
    ButtonsYesNo            = 0x0018,
158
159
    ButtonDefaultsOk        = 0x0100,
160
    ButtonDefaultsCancel    = 0x0200,
161
    ButtonDefaultsYes       = 0x0300,
162
    ButtonDefaultsNo        = 0x0400,
163
164
    MessageError            = 0x1000,
165
    MessageWarning          = 0x2000,
166
    MessageInfo             = 0x3000,
167
168
    MAX                     = USHRT_MAX,
169
};
170
namespace o3tl
171
{
172
    template<> struct typed_flags<DialogMask> : is_typed_flags<DialogMask, 0xffff> {};
173
}
174
175
/** Wrap up an ErrCode and an explanation and the source location where the error was created,
176
    helps with debugging when finding the source of a problem.
177
*/
178
class SAL_WARN_UNUSED ErrCodeMsg
179
{
180
public:
181
0
    ErrCodeMsg() : mnCode(0), mnDialogMask(DialogMask::NONE) {}
182
#ifdef LIBO_ERRMSG_USE_SOURCE_LOCATION
183
    ErrCodeMsg(ErrCode code, const OUString& arg, o3tl::source_location loc = o3tl::source_location::current())
184
        : mnCode(code), maArg1(arg),  mnDialogMask(DialogMask::NONE), moLoc(loc) {}
185
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2, o3tl::source_location loc = o3tl::source_location::current())
186
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(DialogMask::NONE), moLoc(loc) {}
187
    ErrCodeMsg(ErrCode code, o3tl::source_location loc = o3tl::source_location::current())
188
        : mnCode(code), mnDialogMask(DialogMask::NONE), moLoc(loc) {}
189
    ErrCodeMsg(ErrCode code, const OUString& arg, DialogMask mask, o3tl::source_location loc = o3tl::source_location::current())
190
        : mnCode(code), maArg1(arg), mnDialogMask(mask), moLoc(loc) {}
191
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2, DialogMask mask, o3tl::source_location loc = o3tl::source_location::current())
192
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(mask), moLoc(loc) {}
193
#else
194
    ErrCodeMsg(ErrCode code, const OUString& arg)
195
0
        : mnCode(code), maArg1(arg), mnDialogMask(DialogMask::NONE) {}
196
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2)
197
0
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(DialogMask::NONE) {}
198
    ErrCodeMsg(ErrCode code)
199
826k
        : mnCode(code), mnDialogMask(DialogMask::NONE) {}
200
    ErrCodeMsg(ErrCode code, const OUString& arg, DialogMask mask)
201
31
        : mnCode(code), maArg1(arg), mnDialogMask(mask) {}
202
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2, DialogMask mask)
203
0
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(mask) {}
204
#endif
205
206
120k
    const ErrCode & GetCode() const { return mnCode; }
207
0
    const OUString & GetArg1() const { return maArg1; }
208
0
    const OUString & GetArg2() const { return maArg2; }
209
0
    DialogMask GetDialogMask() const { return mnDialogMask; }
210
211
#ifdef LIBO_ERRMSG_USE_SOURCE_LOCATION
212
    const std::optional<o3tl::source_location>& GetSourceLocation() const { return moLoc; }
213
#endif
214
215
    /** convert to ERRCODE_NONE if it's a warning, else return the error */
216
153k
    ErrCodeMsg IgnoreWarning() const { return mnCode.IsWarning() ? ErrCodeMsg(ErrCode(0)) : *this; }
217
218
0
    bool IsWarning() const { return mnCode.IsWarning(); }
219
45.9k
    bool IsError() const { return mnCode.IsError(); }
220
465k
    explicit operator bool() const { return bool(mnCode); }
221
0
    bool operator==(const ErrCodeMsg& rOther) const { return mnCode == rOther.mnCode; }
222
0
    bool operator!=(const ErrCodeMsg& rOther) const { return mnCode != rOther.mnCode; }
223
224
    /// Return a string suitable for debug output, the same as the operator<< function
225
    UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OUString toString() const;
226
227
private:
228
    ErrCode mnCode;
229
    OUString maArg1;
230
    OUString maArg2;
231
    DialogMask mnDialogMask;
232
#ifdef LIBO_ERRMSG_USE_SOURCE_LOCATION
233
    std::optional<o3tl::source_location> moLoc;
234
#endif
235
};
236
237
COMPHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const ErrCodeMsg& err);
238
239
79.6k
inline bool operator==(const ErrCodeMsg& lhs, ErrCode rhs) { return lhs.GetCode() == rhs; }
240
0
inline bool operator!=(const ErrCodeMsg& lhs, ErrCode rhs) { return lhs.GetCode() != rhs; }
241
0
inline bool operator==(ErrCode lhs, const ErrCodeMsg& rhs) { return lhs == rhs.GetCode(); }
242
0
inline bool operator!=(ErrCode lhs, const ErrCodeMsg& rhs) { return lhs != rhs.GetCode(); }
243
244
enum class ErrCodeArea {
245
    Io                  = 0 ,
246
    Sfx                 = 2 ,
247
    Inet                = 3 ,
248
    Vcl                 = 4 ,
249
    Svx                 = 8 ,
250
    So                  = 9 ,
251
    Sbx                 = 10,
252
    Uui                 = 13,
253
    Sc                  = 32,
254
    Sd                  = 40,
255
    Sw                  = 56,
256
};
257
258
enum class ErrCodeClass {
259
    NONE               =  0,
260
    Abort              =  1,
261
    General            =  2,
262
    NotExists          =  3,
263
    AlreadyExists      =  4,
264
    Access             =  5,
265
    Path               =  6,
266
    Locking            =  7,
267
    Parameter          =  8,
268
    Space              =  9,
269
    NotSupported       = 10,
270
    Read               = 11,
271
    Write              = 12,
272
    Unknown            = 13,
273
    Version            = 14,
274
    Format             = 15,
275
    Create             = 16,
276
    Import             = 17,
277
    Export             = 18,
278
    So                 = 20,
279
    Sbx                = 21,
280
    Runtime            = 22,
281
    Compiler           = 23
282
};
283
284
constexpr ErrCode ERRCODE_NONE                   {0};
285
286
constexpr ErrCode ERRCODE_IO_MISPLACEDCHAR       { ErrCodeArea::Io, ErrCodeClass::Parameter, 1 };
287
constexpr ErrCode ERRCODE_IO_NOTEXISTS           { ErrCodeArea::Io, ErrCodeClass::NotExists, 2 };
288
constexpr ErrCode ERRCODE_IO_ALREADYEXISTS       { ErrCodeArea::Io, ErrCodeClass::AlreadyExists, 3 };
289
constexpr ErrCode ERRCODE_IO_NOTADIRECTORY       { ErrCodeArea::Io, ErrCodeClass::Parameter, 4 };
290
constexpr ErrCode ERRCODE_IO_NOTAFILE            { ErrCodeArea::Io, ErrCodeClass::Parameter, 5 };
291
constexpr ErrCode ERRCODE_IO_INVALIDDEVICE       { ErrCodeArea::Io, ErrCodeClass::Path, 6 };
292
constexpr ErrCode ERRCODE_IO_ACCESSDENIED        { ErrCodeArea::Io, ErrCodeClass::Access, 7 };
293
constexpr ErrCode ERRCODE_IO_LOCKVIOLATION       { ErrCodeArea::Io, ErrCodeClass::Locking, 8 };
294
constexpr ErrCode ERRCODE_IO_OUTOFSPACE          { ErrCodeArea::Io, ErrCodeClass::Space, 9 };
295
constexpr ErrCode ERRCODE_IO_ISWILDCARD          { ErrCodeArea::Io, ErrCodeClass::Parameter, 11 };
296
constexpr ErrCode ERRCODE_IO_NOTSUPPORTED        { ErrCodeArea::Io, ErrCodeClass::NotSupported, 12 };
297
constexpr ErrCode ERRCODE_IO_GENERAL             { ErrCodeArea::Io, ErrCodeClass::General, 13 };
298
constexpr ErrCode ERRCODE_IO_TOOMANYOPENFILES    { ErrCodeArea::Io, ErrCodeClass::Space, 14 };
299
constexpr ErrCode ERRCODE_IO_CANTREAD            { ErrCodeArea::Io, ErrCodeClass::Read, 15 };
300
constexpr ErrCode ERRCODE_IO_CANTWRITE           { ErrCodeArea::Io, ErrCodeClass::Write, 16 };
301
constexpr ErrCode ERRCODE_IO_OUTOFMEMORY         { ErrCodeArea::Io, ErrCodeClass::Space, 17 };
302
constexpr ErrCode ERRCODE_IO_CANTSEEK            { ErrCodeArea::Io, ErrCodeClass::General, 18 };
303
constexpr ErrCode ERRCODE_IO_CANTTELL            { ErrCodeArea::Io, ErrCodeClass::General, 19 };
304
constexpr ErrCode ERRCODE_IO_WRONGVERSION        { ErrCodeArea::Io, ErrCodeClass::Version, 20 };
305
constexpr ErrCode ERRCODE_IO_WRONGFORMAT         { ErrCodeArea::Io, ErrCodeClass::Format, 21 };
306
constexpr ErrCode ERRCODE_IO_INVALIDCHAR         { ErrCodeArea::Io, ErrCodeClass::Parameter, 22 };
307
constexpr ErrCode ERRCODE_IO_UNKNOWN             { ErrCodeArea::Io, ErrCodeClass::Unknown, 23 };
308
constexpr ErrCode ERRCODE_IO_INVALIDACCESS       { ErrCodeArea::Io, ErrCodeClass::Access, 24 };
309
constexpr ErrCode ERRCODE_IO_CANTCREATE          { ErrCodeArea::Io, ErrCodeClass::Create, 25 };
310
constexpr ErrCode ERRCODE_IO_INVALIDPARAMETER    { ErrCodeArea::Io, ErrCodeClass::Parameter, 26 };
311
constexpr ErrCode ERRCODE_IO_ABORT               { ErrCodeArea::Io, ErrCodeClass::Abort, 27 };
312
constexpr ErrCode ERRCODE_IO_NOTEXISTSPATH       { ErrCodeArea::Io, ErrCodeClass::NotExists, 28 };
313
constexpr ErrCode ERRCODE_IO_PENDING             { ErrCodeArea::Io, ErrCodeClass::NotExists, 29 };
314
constexpr ErrCode ERRCODE_IO_RECURSIVE           { ErrCodeArea::Io, ErrCodeClass::Parameter, 30 };
315
constexpr ErrCode ERRCODE_IO_NAMETOOLONG         { ErrCodeArea::Io, ErrCodeClass::Parameter, 31 };
316
constexpr ErrCode ERRCODE_IO_INVALIDLENGTH       { ErrCodeArea::Io, ErrCodeClass::Parameter, 32 };
317
constexpr ErrCode ERRCODE_IO_CURRENTDIR          { ErrCodeArea::Io, ErrCodeClass::Parameter, 33 };
318
constexpr ErrCode ERRCODE_IO_NOTSAMEDEVICE       { ErrCodeArea::Io, ErrCodeClass::Parameter, 34 };
319
constexpr ErrCode ERRCODE_IO_DEVICENOTREADY      { ErrCodeArea::Io, ErrCodeClass::Read, 35 };
320
constexpr ErrCode ERRCODE_IO_BADCRC              { ErrCodeArea::Io, ErrCodeClass::Read, 36 };
321
constexpr ErrCode ERRCODE_IO_WRITEPROTECTED      { ErrCodeArea::Io, ErrCodeClass::Access, 37 };
322
constexpr ErrCode ERRCODE_IO_BROKENPACKAGE       { ErrCodeArea::Io, ErrCodeClass::Format, 38 };
323
constexpr ErrCode ERRCODE_IO_NOTSTORABLEINBINARYFORMAT { ErrCodeArea::Io, ErrCodeClass::Format, 39 };
324
constexpr ErrCode ERRCODE_IO_FILTERDISABLED      { ErrCodeArea::Io, ErrCodeClass::Format, 40 };
325
326
// StreamErrorCodes
327
328
constexpr ErrCode SVSTREAM_GENERALERROR          = ERRCODE_IO_GENERAL;
329
constexpr ErrCode SVSTREAM_FILE_NOT_FOUND        = ERRCODE_IO_NOTEXISTS;
330
constexpr ErrCode SVSTREAM_PATH_NOT_FOUND        = ERRCODE_IO_NOTEXISTSPATH;
331
constexpr ErrCode SVSTREAM_TOO_MANY_OPEN_FILES   = ERRCODE_IO_TOOMANYOPENFILES;
332
constexpr ErrCode SVSTREAM_ACCESS_DENIED         = ERRCODE_IO_ACCESSDENIED;
333
constexpr ErrCode SVSTREAM_SHARING_VIOLATION     = ERRCODE_IO_LOCKVIOLATION;
334
constexpr ErrCode SVSTREAM_LOCKING_VIOLATION     = ERRCODE_IO_LOCKVIOLATION;
335
constexpr ErrCode SVSTREAM_SHARE_BUFF_EXCEEDED   = ERRCODE_IO_LOCKVIOLATION;
336
337
constexpr ErrCode SVSTREAM_INVALID_ACCESS        = ERRCODE_IO_INVALIDACCESS;
338
constexpr ErrCode SVSTREAM_INVALID_HANDLE        = ERRCODE_IO_GENERAL;
339
constexpr ErrCode SVSTREAM_CANNOT_MAKE           = ERRCODE_IO_CANTCREATE;
340
constexpr ErrCode SVSTREAM_INVALID_PARAMETER     = ERRCODE_IO_INVALIDPARAMETER;
341
342
constexpr ErrCode SVSTREAM_READ_ERROR            = ERRCODE_IO_CANTREAD;
343
constexpr ErrCode SVSTREAM_WRITE_ERROR           = ERRCODE_IO_CANTWRITE;
344
constexpr ErrCode SVSTREAM_SEEK_ERROR            = ERRCODE_IO_CANTSEEK;
345
346
constexpr ErrCode SVSTREAM_OUTOFMEMORY           = ERRCODE_IO_OUTOFMEMORY;
347
348
constexpr ErrCode SVSTREAM_FILEFORMAT_ERROR      = ERRCODE_IO_WRONGFORMAT;
349
constexpr ErrCode SVSTREAM_WRONGVERSION          = ERRCODE_IO_WRONGVERSION;
350
351
constexpr ErrCode SVSTREAM_DISK_FULL             = ERRCODE_IO_OUTOFSPACE;
352
353
constexpr ErrCode PRINTER_ABORT                  = ERRCODE_IO_ABORT;
354
constexpr ErrCode PRINTER_GENERALERROR           = ERRCODE_IO_GENERAL;
355
356
constexpr ErrCode ERRCODE_ABORT                  = ERRCODE_IO_ABORT;
357
358
constexpr ErrCode ERRCODE_INET_NAME_RESOLVE      {ErrCodeArea::Inet, ErrCodeClass::Read,  1};
359
constexpr ErrCode ERRCODE_INET_CONNECT           {ErrCodeArea::Inet, ErrCodeClass::Read,  2};
360
constexpr ErrCode ERRCODE_INET_READ              {ErrCodeArea::Inet, ErrCodeClass::Read,  3};
361
constexpr ErrCode ERRCODE_INET_WRITE             {ErrCodeArea::Inet, ErrCodeClass::Write, 4};
362
constexpr ErrCode ERRCODE_INET_GENERAL           {ErrCodeArea::Inet, ErrCodeClass::Write, 5};
363
constexpr ErrCode ERRCODE_INET_OFFLINE           {ErrCodeArea::Inet, ErrCodeClass::Read,  6};
364
constexpr ErrCode ERRCODE_INET_CONNECT_MSG       {ErrCodeArea::Inet, ErrCodeClass::Read,  7};
365
366
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */