blob: 86e06706a55caea3ad7d7cb4911bc0bd431d301c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cast/common/channel/virtual_connection_manager.h"
#include <type_traits>
namespace openscreen {
namespace cast {
VirtualConnectionManager::VirtualConnectionManager() = default;
VirtualConnectionManager::~VirtualConnectionManager() = default;
void VirtualConnectionManager::AddConnection(
VirtualConnection virtual_connection,
VirtualConnection::AssociatedData associated_data) {
auto& socket_map = connections_[virtual_connection.socket_id];
auto local_entries = socket_map.equal_range(virtual_connection.local_id);
auto it = std::find_if(
local_entries.first, local_entries.second,
[&virtual_connection](const std::pair<std::string, VCTail>& entry) {
return entry.second.peer_id == virtual_connection.peer_id;
});
if (it == socket_map.end()) {
socket_map.emplace(std::move(virtual_connection.local_id),
VCTail{std::move(virtual_connection.peer_id),
std::move(associated_data)});
}
}
bool VirtualConnectionManager::RemoveConnection(
const VirtualConnection& virtual_connection,
VirtualConnection::CloseReason reason) {
auto socket_entry = connections_.find(virtual_connection.socket_id);
if (socket_entry == connections_.end()) {
return false;
}
auto& socket_map = socket_entry->second;
auto local_entries = socket_map.equal_range(virtual_connection.local_id);
if (local_entries.first == socket_map.end()) {
return false;
}
for (auto it = local_entries.first; it != local_entries.second; ++it) {
if (it->second.peer_id == virtual_connection.peer_id) {
socket_map.erase(it);
if (socket_map.empty()) {
connections_.erase(socket_entry);
}
return true;
}
}
return false;
}
size_t VirtualConnectionManager::RemoveConnectionsByLocalId(
const std::string& local_id,
VirtualConnection::CloseReason reason) {
size_t removed_count = 0;
for (auto socket_entry = connections_.begin();
socket_entry != connections_.end();) {
auto& socket_map = socket_entry->second;
auto local_entries = socket_map.equal_range(local_id);
if (local_entries.first != socket_map.end()) {
size_t current_count =
std::distance(local_entries.first, local_entries.second);
removed_count += current_count;
socket_map.erase(local_entries.first, local_entries.second);
if (socket_map.empty()) {
socket_entry = connections_.erase(socket_entry);
} else {
++socket_entry;
}
} else {
++socket_entry;
}
}
return removed_count;
}
size_t VirtualConnectionManager::RemoveConnectionsBySocketId(
int socket_id,
VirtualConnection::CloseReason reason) {
auto entry = connections_.find(socket_id);
if (entry == connections_.end()) {
return 0;
}
size_t removed_count = entry->second.size();
connections_.erase(entry);
return removed_count;
}
absl::optional<const VirtualConnection::AssociatedData*>
VirtualConnectionManager::GetConnectionData(
const VirtualConnection& virtual_connection) const {
auto socket_entry = connections_.find(virtual_connection.socket_id);
if (socket_entry == connections_.end()) {
return absl::nullopt;
}
auto& socket_map = socket_entry->second;
auto local_entries = socket_map.equal_range(virtual_connection.local_id);
if (local_entries.first == socket_map.end()) {
return absl::nullopt;
}
for (auto it = local_entries.first; it != local_entries.second; ++it) {
if (it->second.peer_id == virtual_connection.peer_id) {
return &it->second.data;
}
}
return absl::nullopt;
}
} // namespace cast
} // namespace openscreen
|