diff --git a/include/rtc/rtc.h b/include/rtc/rtc.h index 0a94d5f..2237242 100644 --- a/include/rtc/rtc.h +++ b/include/rtc/rtc.h @@ -60,6 +60,10 @@ typedef enum { // Don't change, it must match plog severity RTC_LOG_VERBOSE = 6 } rtcLogLevel; +const int RTC_ERR_SUCCESS = 0; +const int RTC_ERR_INVALID = -1; // invalid argument +const int RTC_ERR_FAILURE = -2; // runtime error + typedef struct { const char **iceServers; int iceServersCount; @@ -129,7 +133,8 @@ int rtcGetAvailableAmount(int id); // total size available to receive int rtcSetAvailableCallback(int id, availableCallbackFunc cb); int rtcReceiveMessage(int id, char *buffer, int *size); -// Cleanup +// Optional preload and cleanup +void rtcPreload(); void rtcCleanup(); #ifdef __cplusplus diff --git a/src/certificate.cpp b/src/certificate.cpp index 24f03b1..37d566a 100644 --- a/src/certificate.cpp +++ b/src/certificate.cpp @@ -235,7 +235,7 @@ namespace { template std::future(std::decay_t...)>> thread_call(F &&f, Args &&... args) { - using R = std::result_of_t(std::decay_t...)>; + using R = std::invoke_result_t, std::decay_t...>; std::packaged_task task(std::bind(f, std::forward(args)...)); std::future future = task.get_future(); std::thread t(std::move(task)); diff --git a/src/peerconnection.cpp b/src/peerconnection.cpp index aed6933..4546595 100644 --- a/src/peerconnection.cpp +++ b/src/peerconnection.cpp @@ -42,6 +42,9 @@ PeerConnection::PeerConnection(const Configuration &config) : mConfig(config), mCertificate(make_certificate()), mState(State::New), mGatheringState(GatheringState::New) { PLOG_VERBOSE << "Creating PeerConnection"; + + if (config.portRangeEnd && config.portRangeBegin > config.portRangeEnd) + throw std::invalid_argument("Invalid port range"); } PeerConnection::~PeerConnection() { diff --git a/src/rtc.cpp b/src/rtc.cpp index 2f8a8b2..908c80a 100644 --- a/src/rtc.cpp +++ b/src/rtc.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -36,14 +37,6 @@ using namespace rtc; using std::shared_ptr; using std::string; -#define CATCH(statement) \ - try { \ - statement; \ - } catch (const std::exception &e) { \ - PLOG_ERROR << e.what(); \ - return -1; \ - } - namespace { std::unordered_map> peerConnectionMap; @@ -71,14 +64,18 @@ void setUserPointer(int i, void *ptr) { shared_ptr getPeerConnection(int id) { std::lock_guard lock(mutex); - auto it = peerConnectionMap.find(id); - return it != peerConnectionMap.end() ? it->second : nullptr; + if (auto it = peerConnectionMap.find(id); it != peerConnectionMap.end()) + return it->second; + else + throw std::invalid_argument("PeerConnection ID does not exist"); } shared_ptr getDataChannel(int id) { std::lock_guard lock(mutex); - auto it = dataChannelMap.find(id); - return it != dataChannelMap.end() ? it->second : nullptr; + if (auto it = dataChannelMap.find(id); it != dataChannelMap.end()) + return it->second; + else + throw std::invalid_argument("DataChannel ID does not exist"); } int emplacePeerConnection(shared_ptr ptr) { @@ -95,27 +92,27 @@ int emplaceDataChannel(shared_ptr ptr) { return dc; } -bool erasePeerConnection(int pc) { +void erasePeerConnection(int pc) { std::lock_guard lock(mutex); if (peerConnectionMap.erase(pc) == 0) - return false; + throw std::invalid_argument("PeerConnection ID does not exist"); userPointerMap.erase(pc); - return true; } -bool eraseDataChannel(int dc) { +void eraseDataChannel(int dc) { std::lock_guard lock(mutex); if (dataChannelMap.erase(dc) == 0) - return false; + throw std::invalid_argument("DataChannel ID does not exist"); userPointerMap.erase(dc); - return true; } #if RTC_ENABLE_WEBSOCKET shared_ptr getWebSocket(int id) { std::lock_guard lock(mutex); - auto it = webSocketMap.find(id); - return it != webSocketMap.end() ? it->second : nullptr; + if (auto it = webSocketMap.find(id); it != webSocketMap.end()) + return it->second; + else + throw std::invalid_argument("WebSocket ID does not exist"); } int emplaceWebSocket(shared_ptr ptr) { @@ -125,12 +122,11 @@ int emplaceWebSocket(shared_ptr ptr) { return ws; } -bool eraseWebSocket(int ws) { +void eraseWebSocket(int ws) { std::lock_guard lock(mutex); if (webSocketMap.erase(ws) == 0) - return false; + throw std::invalid_argument("WebSocket ID does not exist"); userPointerMap.erase(ws); - return true; } #endif @@ -142,9 +138,28 @@ shared_ptr getChannel(int id) { if (auto it = webSocketMap.find(id); it != webSocketMap.end()) return it->second; #endif - return nullptr; + throw std::invalid_argument("DataChannel or WebSocket ID does not exist"); } +template int wrap(F func) { + try { + return func(); + + } catch (const std::invalid_argument &e) { + PLOG_ERROR << e.what(); + return RTC_ERR_INVALID; + } catch (const std::exception &e) { + PLOG_ERROR << e.what(); + return RTC_ERR_FAILURE; + } +} + +#define WRAP(statement) \ + wrap([&]() { \ + statement; \ + return RTC_ERR_SUCCESS; \ + }) + } // namespace void rtcInitLogger(rtcLogLevel level) { InitLogger(static_cast(level)); } @@ -152,370 +167,349 @@ void rtcInitLogger(rtcLogLevel level) { InitLogger(static_cast(level)) void rtcSetUserPointer(int i, void *ptr) { setUserPointer(i, ptr); } int rtcCreatePeerConnection(const rtcConfiguration *config) { - Configuration c; - for (int i = 0; i < config->iceServersCount; ++i) - c.iceServers.emplace_back(string(config->iceServers[i])); + return WRAP({ + Configuration c; + for (int i = 0; i < config->iceServersCount; ++i) + c.iceServers.emplace_back(string(config->iceServers[i])); - if (config->portRangeBegin || config->portRangeEnd) { - c.portRangeBegin = config->portRangeBegin; - c.portRangeEnd = config->portRangeEnd; - } + if (config->portRangeBegin || config->portRangeEnd) { + c.portRangeBegin = config->portRangeBegin; + c.portRangeEnd = config->portRangeEnd; + } - return emplacePeerConnection(std::make_shared(c)); + return emplacePeerConnection(std::make_shared(c)); + }); } int rtcDeletePeerConnection(int pc) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; + return WRAP({ + auto peerConnection = getPeerConnection(pc); + peerConnection->onDataChannel(nullptr); + peerConnection->onLocalDescription(nullptr); + peerConnection->onLocalCandidate(nullptr); + peerConnection->onStateChange(nullptr); + peerConnection->onGatheringStateChange(nullptr); - peerConnection->onDataChannel(nullptr); - peerConnection->onLocalDescription(nullptr); - peerConnection->onLocalCandidate(nullptr); - peerConnection->onStateChange(nullptr); - peerConnection->onGatheringStateChange(nullptr); - - erasePeerConnection(pc); - return 0; + erasePeerConnection(pc); + }); } int rtcCreateDataChannel(int pc, const char *label) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - int dc = emplaceDataChannel(peerConnection->createDataChannel(string(label))); - void *ptr = getUserPointer(pc); - rtcSetUserPointer(dc, ptr); - return dc; + return WRAP({ + auto peerConnection = getPeerConnection(pc); + int dc = emplaceDataChannel(peerConnection->createDataChannel(string(label))); + rtcSetUserPointer(dc, getUserPointer(pc)); + return dc; + }); } int rtcDeleteDataChannel(int dc) { - auto dataChannel = getDataChannel(dc); - if (!dataChannel) - return -1; + return WRAP({ + auto dataChannel = getDataChannel(dc); + dataChannel->onOpen(nullptr); + dataChannel->onClosed(nullptr); + dataChannel->onError(nullptr); + dataChannel->onMessage(nullptr); + dataChannel->onBufferedAmountLow(nullptr); + dataChannel->onAvailable(nullptr); - dataChannel->onOpen(nullptr); - dataChannel->onClosed(nullptr); - dataChannel->onError(nullptr); - dataChannel->onMessage(nullptr); - dataChannel->onBufferedAmountLow(nullptr); - dataChannel->onAvailable(nullptr); - - eraseDataChannel(dc); - return 0; + eraseDataChannel(dc); + }); } #if RTC_ENABLE_WEBSOCKET int rtcCreateWebSocket(const char *url) { - auto ws = std::make_shared(); - ws->open(url); - return emplaceWebSocket(ws); -} - -int rtcDeleteWebsocket(int ws) { - auto webSocket = getWebSocket(ws); - if (!webSocket) - return -1; - - webSocket->onOpen(nullptr); - webSocket->onClosed(nullptr); - webSocket->onError(nullptr); - webSocket->onMessage(nullptr); - webSocket->onBufferedAmountLow(nullptr); - webSocket->onAvailable(nullptr); - - eraseWebSocket(ws); - return 0; -} - -#endif - -int rtcSetDataChannelCallback(int pc, dataChannelCallbackFunc cb) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - if (cb) - peerConnection->onDataChannel([pc, cb](std::shared_ptr dataChannel) { - int dc = emplaceDataChannel(dataChannel); - void *ptr = getUserPointer(pc); - rtcSetUserPointer(dc, ptr); - cb(dc, ptr); - }); - else - peerConnection->onDataChannel(nullptr); - return 0; -} - -int rtcSetLocalDescriptionCallback(int pc, descriptionCallbackFunc cb) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - if (cb) - peerConnection->onLocalDescription([pc, cb](const Description &desc) { - cb(string(desc).c_str(), desc.typeString().c_str(), getUserPointer(pc)); - }); - else - peerConnection->onLocalDescription(nullptr); - return 0; -} - -int rtcSetLocalCandidateCallback(int pc, candidateCallbackFunc cb) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - if (cb) - peerConnection->onLocalCandidate([pc, cb](const Candidate &cand) { - cb(cand.candidate().c_str(), cand.mid().c_str(), getUserPointer(pc)); - }); - else - peerConnection->onLocalCandidate(nullptr); - return 0; -} - -int rtcSetStateChangeCallback(int pc, stateChangeCallbackFunc cb) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - if (cb) - peerConnection->onStateChange([pc, cb](PeerConnection::State state) { - cb(static_cast(state), getUserPointer(pc)); - }); - else - peerConnection->onStateChange(nullptr); - return 0; -} - -int rtcSetGatheringStateChangeCallback(int pc, gatheringStateCallbackFunc cb) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - if (cb) - peerConnection->onGatheringStateChange([pc, cb](PeerConnection::GatheringState state) { - cb(static_cast(state), getUserPointer(pc)); - }); - else - peerConnection->onGatheringStateChange(nullptr); - return 0; -} - -int rtcSetRemoteDescription(int pc, const char *sdp, const char *type) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - CATCH(peerConnection->setRemoteDescription({string(sdp), type ? string(type) : ""})); - return 0; -} - -int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - CATCH(peerConnection->addRemoteCandidate({string(cand), mid ? string(mid) : ""})) - return 0; -} - -int rtcGetLocalAddress(int pc, char *buffer, int size) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - if (auto addr = peerConnection->localAddress()) { - size = std::min(size_t(size - 1), addr->size()); - std::copy(addr->data(), addr->data() + size, buffer); - buffer[size] = '\0'; - return size + 1; - } - return -1; -} - -int rtcGetRemoteAddress(int pc, char *buffer, int size) { - auto peerConnection = getPeerConnection(pc); - if (!peerConnection) - return -1; - - if (auto addr = peerConnection->remoteAddress()) { - size = std::min(size_t(size - 1), addr->size()); - std::copy(addr->data(), addr->data() + size, buffer); - buffer[size] = '\0'; - return size + 1; - } - return -1; -} - -int rtcGetDataChannelLabel(int dc, char *buffer, int size) { - auto dataChannel = getDataChannel(dc); - if (!dataChannel) - return -1; - - if (!size) - return 0; - - string label = dataChannel->label(); - size = std::min(size_t(size - 1), label.size()); - std::copy(label.data(), label.data() + size, buffer); - buffer[size] = '\0'; - return size + 1; -} - -int rtcSetOpenCallback(int id, openCallbackFunc cb) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (cb) - channel->onOpen([id, cb]() { cb(getUserPointer(id)); }); - else - channel->onOpen(nullptr); - return 0; -} - -int rtcSetClosedCallback(int id, closedCallbackFunc cb) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (cb) - channel->onClosed([id, cb]() { cb(getUserPointer(id)); }); - else - channel->onClosed(nullptr); - return 0; -} - -int rtcSetErrorCallback(int id, errorCallbackFunc cb) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (cb) - channel->onError([id, cb](const string &error) { cb(error.c_str(), getUserPointer(id)); }); - else - channel->onError(nullptr); - return 0; -} - -int rtcSetMessageCallback(int id, messageCallbackFunc cb) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (cb) - channel->onMessage( - [id, cb](const binary &b) { - cb(reinterpret_cast(b.data()), b.size(), getUserPointer(id)); - }, - [id, cb](const string &s) { cb(s.c_str(), -1, getUserPointer(id)); }); - else - channel->onMessage(nullptr); - - return 0; -} - -int rtcSendMessage(int id, const char *data, int size) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (size >= 0) { - auto b = reinterpret_cast(data); - CATCH(channel->send(binary(b, b + size))); - return size; - } else { - string str(data); - int len = str.size(); - CATCH(channel->send(std::move(str))); - return len; - } -} - -int rtcGetBufferedAmount(int id) { - auto channel = getChannel(id); - if (!channel) - return -1; - - CATCH(return int(channel->bufferedAmount())); -} - -int rtcSetBufferedAmountLowThreshold(int id, int amount) { - auto channel = getChannel(id); - if (!channel) - return -1; - - CATCH(channel->setBufferedAmountLowThreshold(size_t(amount))); - return 0; -} - -int rtcSetBufferedAmountLowCallback(int id, bufferedAmountLowCallbackFunc cb) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (cb) - channel->onBufferedAmountLow([id, cb]() { cb(getUserPointer(id)); }); - else - channel->onBufferedAmountLow(nullptr); - return 0; -} - -int rtcGetAvailableAmount(int id) { - auto channel = getChannel(id); - if (!channel) - return -1; - - CATCH(return int(channel->availableAmount())); -} - -int rtcSetAvailableCallback(int id, availableCallbackFunc cb) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (cb) - channel->onOpen([id, cb]() { cb(getUserPointer(id)); }); - else - channel->onOpen(nullptr); - return 0; -} - -int rtcReceiveMessage(int id, char *buffer, int *size) { - auto channel = getChannel(id); - if (!channel) - return -1; - - if (!size) - return -1; - - CATCH({ - auto message = channel->receive(); - if (!message) - return 0; - - return std::visit( // - overloaded{ // - [&](const binary &b) { - *size = std::min(*size, int(b.size())); - auto data = reinterpret_cast(b.data()); - std::copy(data, data + *size, buffer); - return *size; - }, - [&](const string &s) { - int len = std::min(*size - 1, int(s.size())); - if (len >= 0) { - std::copy(s.data(), s.data() + len, buffer); - buffer[len] = '\0'; - } - *size = -(len + 1); - return len + 1; - }}, - *message); + return WRAP({ + auto ws = std::make_shared(); + ws->open(url); + return emplaceWebSocket(ws); }); } +int rtcDeleteWebsocket(int ws) { + return WRAP({ + auto webSocket = getWebSocket(ws); + webSocket->onOpen(nullptr); + webSocket->onClosed(nullptr); + webSocket->onError(nullptr); + webSocket->onMessage(nullptr); + webSocket->onBufferedAmountLow(nullptr); + webSocket->onAvailable(nullptr); + + eraseWebSocket(ws); + }); +} +#endif + +int rtcSetDataChannelCallback(int pc, dataChannelCallbackFunc cb) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + if (cb) + peerConnection->onDataChannel([pc, cb](std::shared_ptr dataChannel) { + int dc = emplaceDataChannel(dataChannel); + void *ptr = getUserPointer(pc); + rtcSetUserPointer(dc, ptr); + cb(dc, ptr); + }); + else + peerConnection->onDataChannel(nullptr); + }); +} + +int rtcSetLocalDescriptionCallback(int pc, descriptionCallbackFunc cb) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + if (cb) + peerConnection->onLocalDescription([pc, cb](const Description &desc) { + cb(string(desc).c_str(), desc.typeString().c_str(), getUserPointer(pc)); + }); + else + peerConnection->onLocalDescription(nullptr); + }); +} + +int rtcSetLocalCandidateCallback(int pc, candidateCallbackFunc cb) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + if (cb) + peerConnection->onLocalCandidate([pc, cb](const Candidate &cand) { + cb(cand.candidate().c_str(), cand.mid().c_str(), getUserPointer(pc)); + }); + else + peerConnection->onLocalCandidate(nullptr); + }); +} + +int rtcSetStateChangeCallback(int pc, stateChangeCallbackFunc cb) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + if (cb) + peerConnection->onStateChange([pc, cb](PeerConnection::State state) { + cb(static_cast(state), getUserPointer(pc)); + }); + else + peerConnection->onStateChange(nullptr); + }); +} + +int rtcSetGatheringStateChangeCallback(int pc, gatheringStateCallbackFunc cb) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + if (cb) + peerConnection->onGatheringStateChange([pc, cb](PeerConnection::GatheringState state) { + cb(static_cast(state), getUserPointer(pc)); + }); + else + peerConnection->onGatheringStateChange(nullptr); + }); +} + +int rtcSetRemoteDescription(int pc, const char *sdp, const char *type) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + + if (!sdp) + throw std::invalid_argument("Unexpected null pointer"); + + peerConnection->setRemoteDescription({string(sdp), type ? string(type) : ""}); + }); +} + +int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + + if (!cand) + throw std::invalid_argument("Unexpected null pointer"); + + peerConnection->addRemoteCandidate({string(cand), mid ? string(mid) : ""}); + }); +} + +int rtcGetLocalAddress(int pc, char *buffer, int size) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + + if (!buffer) + throw std::invalid_argument("Unexpected null pointer"); + + if (auto addr = peerConnection->localAddress()) { + size = std::min(size_t(size - 1), addr->size()); + std::copy(addr->data(), addr->data() + size, buffer); + buffer[size] = '\0'; + return size + 1; + } + }); +} + +int rtcGetRemoteAddress(int pc, char *buffer, int size) { + return WRAP({ + auto peerConnection = getPeerConnection(pc); + + if (!buffer) + throw std::invalid_argument("Unexpected null pointer"); + + if (auto addr = peerConnection->remoteAddress()) { + size = std::min(size_t(size - 1), addr->size()); + std::copy(addr->data(), addr->data() + size, buffer); + buffer[size] = '\0'; + return size + 1; + } + }); +} + +int rtcGetDataChannelLabel(int dc, char *buffer, int size) { + return WRAP({ + auto dataChannel = getDataChannel(dc); + + if (!buffer) + throw std::invalid_argument("Unexpected null pointer"); + + if (size >= 0) { + string label = dataChannel->label(); + size = std::min(size_t(size - 1), label.size()); + std::copy(label.data(), label.data() + size, buffer); + buffer[size] = '\0'; + return size + 1; + } else { + return 0; + } + }); +} + +int rtcSetOpenCallback(int id, openCallbackFunc cb) { + return WRAP({ + auto channel = getChannel(id); + if (cb) + channel->onOpen([id, cb]() { cb(getUserPointer(id)); }); + else + channel->onOpen(nullptr); + }); +} + +int rtcSetClosedCallback(int id, closedCallbackFunc cb) { + return WRAP({ + auto channel = getChannel(id); + if (cb) + channel->onClosed([id, cb]() { cb(getUserPointer(id)); }); + else + channel->onClosed(nullptr); + }); +} + +int rtcSetErrorCallback(int id, errorCallbackFunc cb) { + return WRAP({ + auto channel = getChannel(id); + if (cb) + channel->onError( + [id, cb](const string &error) { cb(error.c_str(), getUserPointer(id)); }); + else + channel->onError(nullptr); + }); +} + +int rtcSetMessageCallback(int id, messageCallbackFunc cb) { + return WRAP({ + auto channel = getChannel(id); + if (cb) + channel->onMessage( + [id, cb](const binary &b) { + cb(reinterpret_cast(b.data()), b.size(), getUserPointer(id)); + }, + [id, cb](const string &s) { cb(s.c_str(), -1, getUserPointer(id)); }); + else + channel->onMessage(nullptr); + }); +} + +int rtcSendMessage(int id, const char *data, int size) { + return WRAP({ + auto channel = getChannel(id); + + if (!data) + throw std::invalid_argument("Unexpected null pointer"); + + if (size >= 0) { + auto b = reinterpret_cast(data); + channel->send(binary(b, b + size)); + return size; + } else { + string str(data); + int len = str.size(); + channel->send(std::move(str)); + return len; + } + }); +} + +int rtcGetBufferedAmount(int id) { + return WRAP({ + auto channel = getChannel(id); + return int(channel->bufferedAmount()); + }); +} + +int rtcSetBufferedAmountLowThreshold(int id, int amount) { + return WRAP({ + auto channel = getChannel(id); + channel->setBufferedAmountLowThreshold(size_t(amount)); + }); +} + +int rtcSetBufferedAmountLowCallback(int id, bufferedAmountLowCallbackFunc cb) { + return WRAP({ + auto channel = getChannel(id); + if (cb) + channel->onBufferedAmountLow([id, cb]() { cb(getUserPointer(id)); }); + else + channel->onBufferedAmountLow(nullptr); + }); +} + +int rtcGetAvailableAmount(int id) { + return WRAP({ return int(getChannel(id)->availableAmount()); }); +} + +int rtcSetAvailableCallback(int id, availableCallbackFunc cb) { + return WRAP({ + auto channel = getChannel(id); + if (cb) + channel->onOpen([id, cb]() { cb(getUserPointer(id)); }); + else + channel->onOpen(nullptr); + }); +} + +int rtcReceiveMessage(int id, char *buffer, int *size) { + return WRAP({ + auto channel = getChannel(id); + + if (!buffer || !size) + throw std::invalid_argument("Unexpected null pointer"); + + if (auto message = channel->receive()) + return std::visit( // + overloaded{ // + [&](const binary &b) { + *size = std::min(*size, int(b.size())); + auto data = reinterpret_cast(b.data()); + std::copy(data, data + *size, buffer); + return 1; + }, + [&](const string &s) { + int len = std::min(*size - 1, int(s.size())); + if (len >= 0) { + std::copy(s.data(), s.data() + len, buffer); + buffer[len] = '\0'; + } + *size = -(len + 1); + return 1; + }}, + *message); + else + return 0; + }); +} + +void rtcPreload() { rtc::Preload(); } void rtcCleanup() { rtc::Cleanup(); } diff --git a/test/benchmark.cpp b/test/benchmark.cpp index 326aa67..b163b5d 100644 --- a/test/benchmark.cpp +++ b/test/benchmark.cpp @@ -35,7 +35,8 @@ using chrono::steady_clock; template weak_ptr make_weak_ptr(shared_ptr ptr) { return ptr; } size_t benchmark(milliseconds duration) { - InitLogger(LogLevel::Warning); + rtc::InitLogger(LogLevel::Warning); + rtc::Preload(); Configuration config1; // config1.iceServers.emplace_back("stun:stun.l.google.com:19302"); @@ -177,19 +178,17 @@ size_t benchmark(milliseconds duration) { pc2->close(); this_thread::sleep_for(1s); + rtc::Cleanup(); return goodput; } #ifdef BENCHMARK_MAIN int main(int argc, char **argv) { try { - rtc::Preload(); - size_t goodput = benchmark(30s); if (goodput == 0) throw runtime_error("No data received"); - rtc::Cleanup(); return 0; } catch (const std::exception &e) {