2 * Copyright 2010 The WebRTC Project Authors. All rights reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
11 #include "pc/session_description.h"
13 #include "absl/algorithm/container.h"
14 #include "absl/memory/memory.h"
15 #include "rtc_base/checks.h"
16 #include "rtc_base/strings/string_builder.h"
21 ContentInfo
* FindContentInfoByName(ContentInfos
* contents
,
22 const std::string
& name
) {
24 for (ContentInfo
& content
: *contents
) {
25 if (content
.name
== name
) {
34 const ContentInfo
* FindContentInfoByName(const ContentInfos
& contents
,
35 const std::string
& name
) {
36 for (ContentInfos::const_iterator content
= contents
.begin();
37 content
!= contents
.end(); ++content
) {
38 if (content
->name
== name
) {
45 const ContentInfo
* FindContentInfoByType(const ContentInfos
& contents
,
46 MediaProtocolType type
) {
47 for (const auto& content
: contents
) {
48 if (content
.type
== type
) {
55 ContentGroup::ContentGroup(const std::string
& semantics
)
56 : semantics_(semantics
) {}
58 ContentGroup::ContentGroup(const ContentGroup
&) = default;
59 ContentGroup::ContentGroup(ContentGroup
&&) = default;
60 ContentGroup
& ContentGroup::operator=(const ContentGroup
&) = default;
61 ContentGroup
& ContentGroup::operator=(ContentGroup
&&) = default;
62 ContentGroup::~ContentGroup() = default;
64 const std::string
* ContentGroup::FirstContentName() const {
65 return (!content_names_
.empty()) ? &(*content_names_
.begin()) : NULL
;
68 bool ContentGroup::HasContentName(absl::string_view content_name
) const {
69 return absl::c_linear_search(content_names_
, content_name
);
72 void ContentGroup::AddContentName(absl::string_view content_name
) {
73 if (!HasContentName(content_name
)) {
74 content_names_
.emplace_back(content_name
);
78 bool ContentGroup::RemoveContentName(absl::string_view content_name
) {
79 ContentNames::iterator iter
= absl::c_find(content_names_
, content_name
);
80 if (iter
== content_names_
.end()) {
83 content_names_
.erase(iter
);
87 std::string
ContentGroup::ToString() const {
88 rtc::StringBuilder acc
;
89 acc
<< semantics_
<< "(";
90 if (!content_names_
.empty()) {
91 for (const auto& name
: content_names_
) {
99 SessionDescription::SessionDescription() = default;
100 SessionDescription::SessionDescription(const SessionDescription
&) = default;
102 SessionDescription::~SessionDescription() {}
104 std::unique_ptr
<SessionDescription
> SessionDescription::Clone() const {
105 // Copy using the private copy constructor.
106 // This will clone the descriptions using ContentInfo's copy constructor.
107 return absl::WrapUnique(new SessionDescription(*this));
110 const ContentInfo
* SessionDescription::GetContentByName(
111 const std::string
& name
) const {
112 return FindContentInfoByName(contents_
, name
);
115 ContentInfo
* SessionDescription::GetContentByName(const std::string
& name
) {
116 return FindContentInfoByName(&contents_
, name
);
119 const MediaContentDescription
* SessionDescription::GetContentDescriptionByName(
120 const std::string
& name
) const {
121 const ContentInfo
* cinfo
= FindContentInfoByName(contents_
, name
);
126 return cinfo
->media_description();
129 MediaContentDescription
* SessionDescription::GetContentDescriptionByName(
130 const std::string
& name
) {
131 ContentInfo
* cinfo
= FindContentInfoByName(&contents_
, name
);
136 return cinfo
->media_description();
139 const ContentInfo
* SessionDescription::FirstContentByType(
140 MediaProtocolType type
) const {
141 return FindContentInfoByType(contents_
, type
);
144 const ContentInfo
* SessionDescription::FirstContent() const {
145 return (contents_
.empty()) ? NULL
: &(*contents_
.begin());
148 void SessionDescription::AddContent(
149 const std::string
& name
,
150 MediaProtocolType type
,
151 std::unique_ptr
<MediaContentDescription
> description
) {
152 ContentInfo
content(type
);
154 content
.set_media_description(std::move(description
));
155 AddContent(std::move(content
));
158 void SessionDescription::AddContent(
159 const std::string
& name
,
160 MediaProtocolType type
,
162 std::unique_ptr
<MediaContentDescription
> description
) {
163 ContentInfo
content(type
);
165 content
.rejected
= rejected
;
166 content
.set_media_description(std::move(description
));
167 AddContent(std::move(content
));
170 void SessionDescription::AddContent(
171 const std::string
& name
,
172 MediaProtocolType type
,
175 std::unique_ptr
<MediaContentDescription
> description
) {
176 ContentInfo
content(type
);
178 content
.rejected
= rejected
;
179 content
.bundle_only
= bundle_only
;
180 content
.set_media_description(std::move(description
));
181 AddContent(std::move(content
));
184 void SessionDescription::AddContent(ContentInfo
&& content
) {
185 if (extmap_allow_mixed()) {
186 // Mixed support on session level overrides setting on media level.
187 content
.media_description()->set_extmap_allow_mixed_enum(
188 MediaContentDescription::kSession
);
190 contents_
.push_back(std::move(content
));
193 bool SessionDescription::RemoveContentByName(const std::string
& name
) {
194 for (ContentInfos::iterator content
= contents_
.begin();
195 content
!= contents_
.end(); ++content
) {
196 if (content
->name
== name
) {
197 contents_
.erase(content
);
205 void SessionDescription::AddTransportInfo(const TransportInfo
& transport_info
) {
206 transport_infos_
.push_back(transport_info
);
209 bool SessionDescription::RemoveTransportInfoByName(const std::string
& name
) {
210 for (TransportInfos::iterator transport_info
= transport_infos_
.begin();
211 transport_info
!= transport_infos_
.end(); ++transport_info
) {
212 if (transport_info
->content_name
== name
) {
213 transport_infos_
.erase(transport_info
);
220 const TransportInfo
* SessionDescription::GetTransportInfoByName(
221 const std::string
& name
) const {
222 for (TransportInfos::const_iterator iter
= transport_infos_
.begin();
223 iter
!= transport_infos_
.end(); ++iter
) {
224 if (iter
->content_name
== name
) {
231 TransportInfo
* SessionDescription::GetTransportInfoByName(
232 const std::string
& name
) {
233 for (TransportInfos::iterator iter
= transport_infos_
.begin();
234 iter
!= transport_infos_
.end(); ++iter
) {
235 if (iter
->content_name
== name
) {
242 void SessionDescription::RemoveGroupByName(const std::string
& name
) {
243 for (ContentGroups::iterator iter
= content_groups_
.begin();
244 iter
!= content_groups_
.end(); ++iter
) {
245 if (iter
->semantics() == name
) {
246 content_groups_
.erase(iter
);
252 bool SessionDescription::HasGroup(const std::string
& name
) const {
253 for (ContentGroups::const_iterator iter
= content_groups_
.begin();
254 iter
!= content_groups_
.end(); ++iter
) {
255 if (iter
->semantics() == name
) {
262 const ContentGroup
* SessionDescription::GetGroupByName(
263 const std::string
& name
) const {
264 for (ContentGroups::const_iterator iter
= content_groups_
.begin();
265 iter
!= content_groups_
.end(); ++iter
) {
266 if (iter
->semantics() == name
) {
273 std::vector
<const ContentGroup
*> SessionDescription::GetGroupsByName(
274 const std::string
& name
) const {
275 std::vector
<const ContentGroup
*> content_groups
;
276 for (const ContentGroup
& content_group
: content_groups_
) {
277 if (content_group
.semantics() == name
) {
278 content_groups
.push_back(&content_group
);
281 return content_groups
;
284 ContentInfo::~ContentInfo() {}
287 ContentInfo::ContentInfo(const ContentInfo
& o
)
290 rejected(o
.rejected
),
291 bundle_only(o
.bundle_only
),
292 description_(o
.description_
->Clone()) {}
294 ContentInfo
& ContentInfo::operator=(const ContentInfo
& o
) {
297 rejected
= o
.rejected
;
298 bundle_only
= o
.bundle_only
;
299 description_
= o
.description_
->Clone();
303 const MediaContentDescription
* ContentInfo::media_description() const {
304 return description_
.get();
307 MediaContentDescription
* ContentInfo::media_description() {
308 return description_
.get();
311 } // namespace cricket