mirror of
https://github.com/mii443/libdatachannel.git
synced 2025-08-23 07:35:30 +00:00
Added sendBuffer() methods to DataChannel
This commit is contained in:
@ -28,6 +28,7 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
@ -48,6 +49,9 @@ public:
|
|||||||
void send(const byte *data, size_t size);
|
void send(const byte *data, size_t size);
|
||||||
std::optional<std::variant<binary, string>> receive();
|
std::optional<std::variant<binary, string>> receive();
|
||||||
|
|
||||||
|
template <typename Buffer> void sendBuffer(const Buffer &buf);
|
||||||
|
template <typename Iterator> void sendBuffer(Iterator first, Iterator last);
|
||||||
|
|
||||||
size_t available() const;
|
size_t available() const;
|
||||||
size_t availableSize() const;
|
size_t availableSize() const;
|
||||||
|
|
||||||
@ -61,6 +65,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void open(std::shared_ptr<SctpTransport> sctpTransport);
|
void open(std::shared_ptr<SctpTransport> sctpTransport);
|
||||||
|
void outgoing(mutable_message_ptr message);
|
||||||
void incoming(message_ptr message);
|
void incoming(message_ptr message);
|
||||||
void processOpenMessage(message_ptr message);
|
void processOpenMessage(message_ptr message);
|
||||||
|
|
||||||
@ -81,6 +86,34 @@ private:
|
|||||||
friend class PeerConnection;
|
friend class PeerConnection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Buffer> std::pair<const byte *, size_t> to_bytes(const Buffer &buf) {
|
||||||
|
using T = typename std::remove_pointer<decltype(buf.data())>::type;
|
||||||
|
using E = typename std::conditional<std::is_void<T>::value, byte, T>::type;
|
||||||
|
return std::make_pair(static_cast<const byte *>(static_cast<const void *>(buf.data())),
|
||||||
|
buf.size() * sizeof(E));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Buffer> void DataChannel::sendBuffer(const Buffer &buf) {
|
||||||
|
auto [bytes, size] = to_bytes(buf);
|
||||||
|
auto message = std::make_shared<Message>(size);
|
||||||
|
std::copy(bytes, bytes + size, message->data());
|
||||||
|
outgoing(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator> void DataChannel::sendBuffer(Iterator first, Iterator last) {
|
||||||
|
size_t size = 0;
|
||||||
|
for (Iterator it = first; it != last; ++it)
|
||||||
|
size += it->size();
|
||||||
|
|
||||||
|
auto message = std::make_shared<Message>(size);
|
||||||
|
auto pos = message->begin();
|
||||||
|
for (Iterator it = first; it != last; ++it) {
|
||||||
|
auto [bytes, size] = to_bytes(*it);
|
||||||
|
pos = std::copy(bytes, bytes + size, pos);
|
||||||
|
}
|
||||||
|
outgoing(message);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,24 +30,29 @@ namespace rtc {
|
|||||||
struct Message : binary {
|
struct Message : binary {
|
||||||
enum Type { Binary, String, Control };
|
enum Type { Binary, String, Control };
|
||||||
|
|
||||||
|
Message(size_t size) : binary(size), type(Binary) {}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
Message(Iterator begin_, Iterator end_, Type type_ = Binary, unsigned int stream_ = 0,
|
Message(Iterator begin_, Iterator end_, Type type_ = Binary)
|
||||||
std::shared_ptr<Reliability> reliability_ = nullptr)
|
: binary(begin_, end_), type(type_) {}
|
||||||
: binary(begin_, end_), type(type_), stream(stream_), reliability(reliability_) {}
|
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
unsigned int stream;
|
unsigned int stream = 0;
|
||||||
std::shared_ptr<Reliability> reliability;
|
std::shared_ptr<Reliability> reliability;
|
||||||
};
|
};
|
||||||
|
|
||||||
using message_ptr = std::shared_ptr<const Message>;
|
using message_ptr = std::shared_ptr<const Message>;
|
||||||
|
using mutable_message_ptr = std::shared_ptr<Message>;
|
||||||
using message_callback = std::function<void(message_ptr message)>;
|
using message_callback = std::function<void(message_ptr message)>;
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
message_ptr make_message(Iterator begin, Iterator end, Message::Type type = Message::Binary,
|
message_ptr make_message(Iterator begin, Iterator end, Message::Type type = Message::Binary,
|
||||||
unsigned int stream = 0,
|
unsigned int stream = 0,
|
||||||
std::shared_ptr<Reliability> reliability = nullptr) {
|
std::shared_ptr<Reliability> reliability = nullptr) {
|
||||||
return std::make_shared<Message>(begin, end, type, stream, reliability);
|
auto message = std::make_shared<Message>(begin, end, type);
|
||||||
|
message->stream = stream;
|
||||||
|
message->reliability = reliability;
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
@ -80,29 +80,18 @@ void DataChannel::close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::send(const std::variant<binary, string> &data) {
|
void DataChannel::send(const std::variant<binary, string> &data) {
|
||||||
if (mIsClosed || !mSctpTransport)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::visit(
|
std::visit(
|
||||||
[this](const auto &d) {
|
[&](const auto &d) {
|
||||||
using T = std::decay_t<decltype(d)>;
|
using T = std::decay_t<decltype(d)>;
|
||||||
constexpr auto type = std::is_same_v<T, string> ? Message::String : Message::Binary;
|
constexpr auto type = std::is_same_v<T, string> ? Message::String : Message::Binary;
|
||||||
auto *b = reinterpret_cast<const byte *>(d.data());
|
auto *b = reinterpret_cast<const byte *>(d.data());
|
||||||
// Before the ACK has been received on a DataChannel, all messages must be sent ordered
|
outgoing(std::make_shared<Message>(b, b + d.size(), type));
|
||||||
auto reliability = mIsOpen ? mReliability : nullptr;
|
|
||||||
auto message = make_message(b, b + d.size(), type, mStream, reliability);
|
|
||||||
mSctpTransport->send(message);
|
|
||||||
},
|
},
|
||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::send(const byte *data, size_t size) {
|
void DataChannel::send(const byte *data, size_t size) {
|
||||||
if (mIsClosed || !mSctpTransport)
|
outgoing(std::make_shared<Message>(data, data + size, Message::Binary));
|
||||||
return;
|
|
||||||
|
|
||||||
auto reliability = mIsOpen ? mReliability : nullptr;
|
|
||||||
auto message = make_message(data, data + size, Message::Binary, mStream, reliability);
|
|
||||||
mSctpTransport->send(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::variant<binary, string>> DataChannel::receive() {
|
std::optional<std::variant<binary, string>> DataChannel::receive() {
|
||||||
@ -179,6 +168,15 @@ void DataChannel::open(shared_ptr<SctpTransport> sctpTransport) {
|
|||||||
mSctpTransport->send(make_message(buffer.begin(), buffer.end(), Message::Control, mStream));
|
mSctpTransport->send(make_message(buffer.begin(), buffer.end(), Message::Control, mStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataChannel::outgoing(mutable_message_ptr message) {
|
||||||
|
if (mIsClosed || !mSctpTransport)
|
||||||
|
return;
|
||||||
|
// Before the ACK has been received on a DataChannel, all messages must be sent ordered
|
||||||
|
message->reliability = mIsOpen ? mReliability : nullptr;
|
||||||
|
message->stream = mStream;
|
||||||
|
mSctpTransport->send(message);
|
||||||
|
}
|
||||||
|
|
||||||
void DataChannel::incoming(message_ptr message) {
|
void DataChannel::incoming(message_ptr message) {
|
||||||
switch (message->type) {
|
switch (message->type) {
|
||||||
case Message::Control: {
|
case Message::Control: {
|
||||||
|
Reference in New Issue
Block a user