Coverage Report

Created: 2026-04-01 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Fast-DDS/src/cpp/fastdds/topic/TopicImpl.cpp
Line
Count
Source
1
// Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/*
16
 * TopicImpl.cpp
17
 *
18
 */
19
20
#include <fastdds/dds/topic/Topic.hpp>
21
#include <fastdds/topic/TopicImpl.hpp>
22
#include <fastdds/domain/DomainParticipantImpl.hpp>
23
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
24
25
#include <fastdds/dds/topic/TypeSupport.hpp>
26
27
#include <fastdds/dds/log/Log.hpp>
28
29
#include <functional>
30
31
namespace eprosima {
32
namespace fastdds {
33
namespace dds {
34
35
TopicImpl::TopicImpl(
36
        TopicProxyFactory* factory,
37
        DomainParticipantImpl* p,
38
        TypeSupport type_support,
39
        const TopicQos& qos,
40
        TopicListener* listen)
41
0
    : factory_(factory)
42
0
    , participant_(p)
43
0
    , type_support_(type_support)
44
0
    , qos_(&qos == &TOPIC_QOS_DEFAULT ? participant_->get_default_topic_qos() : qos)
45
0
    , listener_(listen)
46
0
{
47
0
}
48
49
TopicImpl::~TopicImpl()
50
0
{
51
0
}
52
53
ReturnCode_t TopicImpl::check_qos_including_resource_limits(
54
        const TopicQos& qos,
55
        const TypeSupport& type)
56
0
{
57
0
    ReturnCode_t check_qos_return = check_qos(qos);
58
0
    if (RETCODE_OK == check_qos_return &&
59
0
            type->is_compute_key_provided)
60
0
    {
61
0
        check_qos_return = check_allocation_consistency(qos);
62
0
    }
63
0
    return check_qos_return;
64
0
}
65
66
ReturnCode_t TopicImpl::check_qos(
67
        const TopicQos& qos)
68
0
{
69
0
    if (BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS == qos.destination_order().kind)
70
0
    {
71
0
        EPROSIMA_LOG_ERROR(DDS_QOS_CHECK, "BY SOURCE TIMESTAMP DestinationOrder not supported");
72
0
        return RETCODE_UNSUPPORTED;
73
0
    }
74
0
    if (AUTOMATIC_LIVELINESS_QOS == qos.liveliness().kind ||
75
0
            MANUAL_BY_PARTICIPANT_LIVELINESS_QOS == qos.liveliness().kind)
76
0
    {
77
0
        if (qos.liveliness().lease_duration < eprosima::fastdds::dds::c_TimeInfinite &&
78
0
                qos.liveliness().lease_duration <= qos.liveliness().announcement_period)
79
0
        {
80
0
            EPROSIMA_LOG_ERROR(DDS_QOS_CHECK, "lease_duration <= announcement period.");
81
0
            return RETCODE_INCONSISTENT_POLICY;
82
0
        }
83
0
    }
84
0
    return RETCODE_OK;
85
0
}
86
87
ReturnCode_t TopicImpl::check_allocation_consistency(
88
        const TopicQos& qos)
89
0
{
90
0
    if ((qos.resource_limits().max_samples > 0) &&
91
0
            (qos.resource_limits().max_samples <
92
0
            (qos.resource_limits().max_instances * qos.resource_limits().max_samples_per_instance)))
93
0
    {
94
0
        EPROSIMA_LOG_ERROR(DDS_QOS_CHECK,
95
0
                "max_samples should be greater than max_instances * max_samples_per_instance");
96
0
        return RETCODE_INCONSISTENT_POLICY;
97
0
    }
98
0
    if ((qos.resource_limits().max_instances <= 0 || qos.resource_limits().max_samples_per_instance <= 0) &&
99
0
            (qos.resource_limits().max_samples > 0))
100
0
    {
101
0
        EPROSIMA_LOG_ERROR(DDS_QOS_CHECK,
102
0
                "max_samples should be infinite when max_instances or max_samples_per_instance are infinite");
103
0
        return RETCODE_INCONSISTENT_POLICY;
104
0
    }
105
0
    return RETCODE_OK;
106
0
}
107
108
void TopicImpl::set_qos(
109
        TopicQos& to,
110
        const TopicQos& from,
111
        bool first_time)
112
0
{
113
0
    (void)first_time;
114
0
    to = from;
115
116
    // Topic Qos is only used to create other Qos, so it can always be updated
117
0
}
118
119
bool TopicImpl::can_qos_be_updated(
120
        const TopicQos& to,
121
        const TopicQos& from)
122
0
{
123
0
    (void)to;
124
0
    (void)from;
125
126
0
    return true;
127
0
}
128
129
const TopicQos& TopicImpl::get_qos() const
130
0
{
131
0
    return qos_;
132
0
}
133
134
ReturnCode_t TopicImpl::set_qos(
135
        const TopicQos& qos)
136
0
{
137
0
    if (&qos == &TOPIC_QOS_DEFAULT)
138
0
    {
139
0
        const TopicQos& default_qos = participant_->get_default_topic_qos();
140
0
        if (!can_qos_be_updated(qos_, default_qos))
141
0
        {
142
0
            return RETCODE_IMMUTABLE_POLICY;
143
0
        }
144
145
0
        set_qos(qos_, default_qos, false);
146
0
        return RETCODE_OK;
147
0
    }
148
149
0
    ReturnCode_t ret_val = check_qos_including_resource_limits(qos, type_support_);
150
0
    if (RETCODE_OK != ret_val)
151
0
    {
152
0
        return ret_val;
153
0
    }
154
155
0
    if (!can_qos_be_updated(qos_, qos))
156
0
    {
157
0
        return RETCODE_IMMUTABLE_POLICY;
158
0
    }
159
160
0
    set_qos(qos_, qos, false);
161
0
    return RETCODE_OK;
162
0
}
163
164
const TopicListener* TopicImpl::get_listener() const
165
0
{
166
0
    return listener_;
167
0
}
168
169
void TopicImpl::set_listener(
170
        TopicListener* listener)
171
0
{
172
0
    listener_ = listener;
173
0
}
174
175
void TopicImpl::set_listener(
176
        TopicListener* listener,
177
        const StatusMask& mask)
178
0
{
179
0
    participant_->set_topic_listener(factory_, this, listener, mask);
180
0
}
181
182
DomainParticipant* TopicImpl::get_participant() const
183
0
{
184
0
    return participant_->get_participant();
185
0
}
186
187
const TypeSupport& TopicImpl::get_type() const
188
0
{
189
0
    return type_support_;
190
0
}
191
192
TopicListener* TopicImpl::get_listener_for(
193
        const StatusMask& status,
194
        const Topic* topic)
195
0
{
196
0
    if (listener_ != nullptr &&
197
0
            topic->get_status_mask().is_active(status))
198
0
    {
199
0
        return listener_;
200
0
    }
201
0
    return participant_->get_listener_for(status);
202
0
}
203
204
} // dds
205
} // fastdds
206
} // eprosima