Coverage Report

Created: 2026-07-25 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/port/cpl_error_internal.h
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * Name:     cpl_error_internal.h
4
 * Project:  CPL - Common Portability Library
5
 * Purpose:  CPL Error handling
6
 * Author:   Even Rouault, <even.rouault at spatialys.com>
7
 *
8
 **********************************************************************
9
 * Copyright (c) 2019, Even Rouault, <even.rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#ifndef CPL_ERROR_INTERNAL_H_INCLUDED
15
#define CPL_ERROR_INTERNAL_H_INCLUDED
16
17
#if defined(GDAL_COMPILATION) || defined(DOXYGEN_SKIP)
18
// internal only
19
20
#include "cpl_error.h"
21
#include "cpl_string.h"
22
23
#include <mutex>
24
#include <vector>
25
26
/************************************************************************/
27
/*                   CPLErrorHandlerAccumulatorStruct                   */
28
/************************************************************************/
29
30
/** Class that stores details about an emitted error.
31
 *
32
 * Returned by CPLErrorAccumulator::GetErrors()
33
 *
34
 * @since 3.11
35
 */
36
class CPL_DLL CPLErrorHandlerAccumulatorStruct
37
{
38
  public:
39
    /** Error level */
40
    CPLErr type;
41
42
    /** Error number */
43
    CPLErrorNum no;
44
45
    /** Error message */
46
    CPLString msg{};
47
48
    /** Default constructor */
49
    CPLErrorHandlerAccumulatorStruct() : type(CE_None), no(CPLE_None)
50
0
    {
51
0
    }
52
53
    /** Constructor */
54
    CPLErrorHandlerAccumulatorStruct(CPLErr eErrIn, CPLErrorNum noIn,
55
                                     const char *msgIn)
56
0
        : type(eErrIn), no(noIn), msg(msgIn)
57
0
    {
58
0
    }
59
};
60
61
/************************************************************************/
62
/*                         CPLErrorAccumulator                          */
63
/************************************************************************/
64
65
/** Class typically used by a worker thread to store errors emitted by their
66
 * worker functions, and replay them in the main thread.
67
 *
68
 * An instance of CPLErrorAccumulator can be shared by several
69
 * threads. Each thread calls InstallForCurrentScope() in its processing
70
 * function. The main thread may invoke ReplayErrors() to replay errors (and
71
 * warnings).
72
 *
73
 * @since 3.11
74
 */
75
class CPL_DLL CPLErrorAccumulator
76
{
77
  public:
78
    /** Constructor */
79
0
    CPLErrorAccumulator() = default;
80
81
    /** Object returned by InstallForCurrentScope() during life-time of which,
82
     * errors are redirected to the CPLErrorAccumulator instance.
83
     */
84
    struct CPL_DLL Context
85
    {
86
        /*! @cond Doxygen_Suppress */
87
        ~Context();
88
89
        Context(const Context &) = delete;
90
        Context &operator=(const Context &) = delete;
91
        Context(Context &&) = delete;
92
        Context &operator=(Context &&) = delete;
93
94
      private:
95
        friend class CPLErrorAccumulator;
96
        explicit Context(CPLErrorAccumulator &sAccumulator);
97
        /*! @endcond Doxygen_Suppress */
98
    };
99
100
    /** Install a temporary error handler that will store errors and warnings.
101
     */
102
    Context InstallForCurrentScope() CPL_WARN_UNUSED_RESULT;
103
104
    /** Return error list. */
105
    const std::vector<CPLErrorHandlerAccumulatorStruct> &GetErrors() const
106
0
    {
107
0
        return errors;
108
0
    }
109
110
    /** Clear any accumulated errors.
111
     */
112
    void ClearErrors()
113
0
    {
114
0
        std::lock_guard oLock(mutex);
115
0
        errors.clear();
116
0
    }
117
118
    /** Replay stored errors. */
119
    void ReplayErrors();
120
121
  private:
122
    std::mutex mutex{};
123
    std::vector<CPLErrorHandlerAccumulatorStruct> errors{};
124
125
    static void CPL_STDCALL Accumulator(CPLErr eErr, CPLErrorNum no,
126
                                        const char *msg);
127
};
128
129
#endif
130
131
#endif  // CPL_ERROR_INTERNAL_H_INCLUDED