jsep_ice_candidate.cc (3351B)
1 /* 2 * Copyright 2018 The WebRTC project authors. All Rights Reserved. 3 * 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. 9 */ 10 11 #include "api/jsep_ice_candidate.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <limits> 16 #include <memory> 17 #include <string> 18 #include <utility> 19 20 #include "absl/algorithm/container.h" 21 #include "absl/memory/memory.h" 22 #include "absl/strings/string_view.h" 23 #include "api/candidate.h" 24 #include "api/jsep.h" 25 #include "rtc_base/checks.h" 26 #include "rtc_base/logging.h" 27 28 namespace webrtc { 29 namespace { 30 // The sdpMLineIndex property is an unsigned short, a zero based index of the 31 // m-line associated with the candidate. This function ensures we consistently 32 // set the property to -1 for out-of-bounds values, to make candidate 33 // comparisons more robust. 34 int EnsureValidMLineIndex(int sdp_mline_index) { 35 if (sdp_mline_index < 0 || 36 sdp_mline_index > std::numeric_limits<uint16_t>::max()) 37 return -1; 38 return sdp_mline_index; 39 } 40 } // namespace 41 42 IceCandidate::IceCandidate(absl::string_view sdp_mid, 43 int sdp_mline_index, 44 const Candidate& candidate) 45 : sdp_mid_(sdp_mid), 46 sdp_mline_index_(EnsureValidMLineIndex(sdp_mline_index)), 47 candidate_(candidate) { 48 if (sdp_mid_.empty() && sdp_mline_index_ < 0) { 49 RTC_LOG(LS_ERROR) << "Neither mid nor index supplied for IceCandidate."; 50 } 51 } 52 53 void IceCandidateCollection::add(std::unique_ptr<IceCandidate> candidate) { 54 candidates_.push_back(std::move(candidate)); 55 } 56 57 void IceCandidateCollection::add(IceCandidate* candidate) { 58 candidates_.push_back(absl::WrapUnique(candidate)); 59 } 60 61 void IceCandidateCollection::Append(IceCandidateCollection collection) { 62 candidates_.insert(candidates_.end(), 63 std::make_move_iterator(collection.candidates_.begin()), 64 std::make_move_iterator(collection.candidates_.end())); 65 } 66 67 const IceCandidate* IceCandidateCollection::at(size_t index) const { 68 return candidates_[index].get(); 69 } 70 71 bool IceCandidateCollection::HasCandidate(const IceCandidate* candidate) const { 72 const auto sdp_mid = candidate->sdp_mid(); // avoid string copy per entry. 73 return absl::c_any_of( 74 candidates_, [&](const std::unique_ptr<IceCandidate>& entry) { 75 if (!entry->candidate().IsEquivalent(candidate->candidate())) { 76 return false; 77 } 78 if (!sdp_mid.empty()) { 79 // In this case, we ignore the `sdp_mline_index()` property. 80 return sdp_mid == entry->sdp_mid(); 81 } 82 RTC_DCHECK_NE(candidate->sdp_mline_index(), -1); 83 return candidate->sdp_mline_index() == entry->sdp_mline_index(); 84 }); 85 } 86 87 size_t JsepCandidateCollection::remove(const IceCandidate* candidate) { 88 RTC_DCHECK(candidate); 89 auto iter = 90 absl::c_find_if(candidates_, [&](const std::unique_ptr<IceCandidate>& c) { 91 return c->candidate().MatchesForRemoval(candidate->candidate()); 92 }); 93 if (iter != candidates_.end()) { 94 candidates_.erase(iter); 95 return 1u; 96 } 97 return 0u; 98 } 99 100 } // namespace webrtc