Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppu/source/threadpool/current.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 <rtl/byteseq.h>
23
24
#include <uno/current_context.h>
25
#include <uno/environment.hxx>
26
#include <uno/mapping.hxx>
27
#include <typelib/typedescription.h>
28
29
#include "current.hxx"
30
31
32
using namespace ::rtl;
33
using namespace ::cppu;
34
using namespace ::com::sun::star::uno;
35
36
namespace cppu
37
{
38
39
static typelib_InterfaceTypeDescription * impl_get_type_XCurrentContext()
40
0
{
41
0
    OUString sTypeName(u"com.sun.star.uno.XCurrentContext"_ustr);
42
0
    typelib_InterfaceTypeDescription* pTD = nullptr;
43
0
    typelib_TypeDescriptionReference* pMembers[1] = { nullptr };
44
0
    OUString sMethodName0(u"com.sun.star.uno.XCurrentContext::getValueByName"_ustr);
45
0
    typelib_typedescriptionreference_new(&pMembers[0], typelib_TypeClass_INTERFACE_METHOD,
46
0
                                         sMethodName0.pData);
47
0
    typelib_typedescription_newInterface(
48
0
        &pTD, sTypeName.pData, 0, 0, 0, 0, 0,
49
0
        *typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE), 1, pMembers);
50
51
0
    typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription**>(&pTD));
52
0
    typelib_typedescriptionreference_release(pMembers[0]);
53
54
0
    typelib_InterfaceMethodTypeDescription* pMethod = nullptr;
55
0
    typelib_Parameter_Init aParameters[1];
56
0
    OUString sParamName0(u"Name"_ustr);
57
0
    OUString sParamType0(u"string"_ustr);
58
0
    aParameters[0].pParamName = sParamName0.pData;
59
0
    aParameters[0].eTypeClass = typelib_TypeClass_STRING;
60
0
    aParameters[0].pTypeName = sParamType0.pData;
61
0
    aParameters[0].bIn = true;
62
0
    aParameters[0].bOut = false;
63
0
    rtl_uString* pExceptions[1];
64
0
    OUString sExceptionName0(u"com.sun.star.uno.RuntimeException"_ustr);
65
0
    pExceptions[0] = sExceptionName0.pData;
66
0
    OUString sReturnType0(u"any"_ustr);
67
0
    typelib_typedescription_newInterfaceMethod(&pMethod, 3, false, sMethodName0.pData,
68
0
                                               typelib_TypeClass_ANY, sReturnType0.pData, 1,
69
0
                                               aParameters, 1, pExceptions);
70
0
    typelib_typedescription_register(reinterpret_cast<typelib_TypeDescription**>(&pMethod));
71
0
    typelib_typedescription_release(&pMethod->aBase.aBase);
72
    // another static ref:
73
0
    ++reinterpret_cast<typelib_TypeDescription*>(pTD)->nStaticRefCount;
74
0
    return pTD;
75
0
}
76
77
static typelib_InterfaceTypeDescription * get_type_XCurrentContext()
78
0
{
79
0
    static typelib_InterfaceTypeDescription* s_type_XCurrentContext = impl_get_type_XCurrentContext();
80
0
    return s_type_XCurrentContext;
81
0
}
82
83
IdContainer::IdContainer()
84
1
    : pCurrentContext(nullptr)
85
1
    , pCurrentContextEnv(nullptr)
86
1
    , pLocalThreadId(nullptr)
87
1
    , pCurrentId(nullptr)
88
1
    , nRefCountOfCurrentId(0)
89
1
    , bInit(false)
90
1
{
91
1
}
92
93
IdContainer::~IdContainer()
94
1
{
95
1
    if (pCurrentContext)
96
0
    {
97
0
        (*pCurrentContextEnv->releaseInterface)(
98
0
            pCurrentContextEnv, pCurrentContext );
99
0
        (*pCurrentContextEnv->aBase.release)(
100
0
            &pCurrentContextEnv->aBase );
101
0
    }
102
1
    if (bInit)
103
0
    {
104
0
        ::rtl_byte_sequence_release( pLocalThreadId );
105
0
        ::rtl_byte_sequence_release( pCurrentId );
106
0
    }
107
1
}
108
109
IdContainer& getIdContainer()
110
308
{
111
308
    static thread_local IdContainer aId;
112
308
    return aId;
113
308
}
114
115
}
116
117
extern "C" sal_Bool SAL_CALL uno_setCurrentContext(
118
    void * pCurrentContext,
119
    rtl_uString * pEnvTypeName, void * pEnvContext ) noexcept
120
154
{
121
154
    IdContainer& id = getIdContainer();
122
123
    // free old one
124
154
    if (id.pCurrentContext)
125
77
    {
126
77
        (*id.pCurrentContextEnv->releaseInterface)(
127
77
            id.pCurrentContextEnv, id.pCurrentContext );
128
77
        (*id.pCurrentContextEnv->aBase.release)(
129
77
            &id.pCurrentContextEnv->aBase );
130
77
        id.pCurrentContextEnv = nullptr;
131
132
77
        id.pCurrentContext = nullptr;
133
77
    }
134
135
154
    if (!pCurrentContext)
136
77
        return true;
137
138
77
    uno_Environment * pEnv = nullptr;
139
77
    ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext );
140
77
    OSL_ASSERT( pEnv && pEnv->pExtEnv );
141
77
    if (pEnv)
142
77
    {
143
77
        if (pEnv->pExtEnv)
144
77
        {
145
77
            id.pCurrentContextEnv = pEnv->pExtEnv;
146
77
            (*id.pCurrentContextEnv->acquireInterface)(
147
77
                id.pCurrentContextEnv, pCurrentContext );
148
77
            id.pCurrentContext = pCurrentContext;
149
77
        }
150
0
        else
151
0
        {
152
0
            (*pEnv->release)( pEnv );
153
0
            return false;
154
0
        }
155
77
    }
156
0
    else
157
0
    {
158
0
        return false;
159
0
    }
160
77
    return true;
161
77
}
162
163
extern "C" sal_Bool SAL_CALL uno_getCurrentContext(
164
    void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext ) noexcept
165
154
{
166
154
    IdContainer& id = getIdContainer();
167
168
154
    Environment target_env;
169
170
    // release inout parameter
171
154
    if (*ppCurrentContext)
172
0
    {
173
0
        target_env = Environment(OUString(pEnvTypeName), pEnvContext);
174
0
        OSL_ASSERT( target_env.is() );
175
0
        if (! target_env.is())
176
0
            return false;
177
0
        uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv;
178
0
        OSL_ASSERT( nullptr != pEnv );
179
0
        if (nullptr == pEnv)
180
0
            return false;
181
0
        (*pEnv->releaseInterface)( pEnv, *ppCurrentContext );
182
183
0
        *ppCurrentContext = nullptr;
184
0
    }
185
186
    // case: null-ref
187
154
    if (nullptr == id.pCurrentContext)
188
154
        return true;
189
190
0
    if (! target_env.is())
191
0
    {
192
0
        target_env = Environment(OUString(pEnvTypeName), pEnvContext);
193
0
        OSL_ASSERT( target_env.is() );
194
0
        if (! target_env.is())
195
0
            return false;
196
0
    }
197
198
0
    Mapping mapping(&id.pCurrentContextEnv->aBase, target_env.get());
199
0
    OSL_ASSERT( mapping.is() );
200
0
    if (! mapping.is())
201
0
        return false;
202
203
0
    mapping.mapInterface(ppCurrentContext, id.pCurrentContext, ::cppu::get_type_XCurrentContext());
204
205
0
    return true;
206
0
}
207
208
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */