|
@@ -195,6 +195,31 @@ template <typename F> int wrap(F func) {
|
|
return RTC_ERR_SUCCESS; \
|
|
return RTC_ERR_SUCCESS; \
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+int copyAndReturn(string s, char *buffer, int size) {
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return int(s.size() + 1);
|
|
|
|
+
|
|
|
|
+ if (size < int(s.size()))
|
|
|
|
+ return RTC_ERR_TOO_SMALL;
|
|
|
|
+
|
|
|
|
+ std::copy(s.begin(), s.end(), buffer);
|
|
|
|
+ buffer[s.size()] = '\0';
|
|
|
|
+ return int(s.size() + 1);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int copyAndReturn(binary b, char *buffer, int size) {
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return int(b.size());
|
|
|
|
+
|
|
|
|
+ if (size < int(b.size()))
|
|
|
|
+ return RTC_ERR_TOO_SMALL;
|
|
|
|
+
|
|
|
|
+ auto data = reinterpret_cast<const char *>(b.data());
|
|
|
|
+ std::copy(data, data + b.size(), buffer);
|
|
|
|
+ buffer[b.size()] = '\0';
|
|
|
|
+ return int(b.size());
|
|
|
|
+}
|
|
|
|
+
|
|
class plogAppender : public plog::IAppender {
|
|
class plogAppender : public plog::IAppender {
|
|
public:
|
|
public:
|
|
plogAppender(rtcLogCallbackFunc cb = nullptr) { setCallback(cb); }
|
|
plogAppender(rtcLogCallbackFunc cb = nullptr) { setCallback(cb); }
|
|
@@ -280,43 +305,49 @@ int rtcDeletePeerConnection(int pc) {
|
|
}
|
|
}
|
|
|
|
|
|
int rtcAddDataChannel(int pc, const char *label) {
|
|
int rtcAddDataChannel(int pc, const char *label) {
|
|
- return rtcAddDataChannelExt(pc, label, nullptr, nullptr);
|
|
|
|
|
|
+ return rtcAddDataChannelExt(pc, label, nullptr);
|
|
}
|
|
}
|
|
|
|
|
|
-int rtcAddDataChannelExt(int pc, const char *label, const char *protocol,
|
|
|
|
- const rtcReliability *reliability) {
|
|
|
|
|
|
+int rtcAddDataChannelExt(int pc, const char *label, const rtcDataChannelInit *init) {
|
|
return WRAP({
|
|
return WRAP({
|
|
- Reliability r = {};
|
|
|
|
- if (reliability) {
|
|
|
|
- r.unordered = reliability->unordered;
|
|
|
|
|
|
+ DataChannelInit dci = {};
|
|
|
|
+ if (init) {
|
|
|
|
+ auto *reliability = &init->reliability;
|
|
|
|
+ dci.reliability.unordered = reliability->unordered;
|
|
if (reliability->unreliable) {
|
|
if (reliability->unreliable) {
|
|
if (reliability->maxPacketLifeTime > 0) {
|
|
if (reliability->maxPacketLifeTime > 0) {
|
|
- r.type = Reliability::Type::Timed;
|
|
|
|
- r.rexmit = milliseconds(reliability->maxPacketLifeTime);
|
|
|
|
|
|
+ dci.reliability.type = Reliability::Type::Timed;
|
|
|
|
+ dci.reliability.rexmit = milliseconds(reliability->maxPacketLifeTime);
|
|
} else {
|
|
} else {
|
|
- r.type = Reliability::Type::Rexmit;
|
|
|
|
- r.rexmit = int(reliability->maxRetransmits);
|
|
|
|
|
|
+ dci.reliability.type = Reliability::Type::Rexmit;
|
|
|
|
+ dci.reliability.rexmit = int(reliability->maxRetransmits);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- r.type = Reliability::Type::Reliable;
|
|
|
|
|
|
+ dci.reliability.type = Reliability::Type::Reliable;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ dci.negotiated = init->negotiated;
|
|
|
|
+ dci.id = init->manualStream ? std::make_optional(init->stream) : nullopt;
|
|
|
|
+ dci.protocol = init->protocol ? init->protocol : "";
|
|
}
|
|
}
|
|
|
|
+
|
|
auto peerConnection = getPeerConnection(pc);
|
|
auto peerConnection = getPeerConnection(pc);
|
|
- int dc = emplaceDataChannel(peerConnection->addDataChannel(
|
|
|
|
- string(label ? label : ""), string(protocol ? protocol : ""), r));
|
|
|
|
|
|
+ int dc = emplaceDataChannel(
|
|
|
|
+ peerConnection->addDataChannel(string(label ? label : ""), std::move(dci)));
|
|
|
|
+
|
|
if (auto ptr = getUserPointer(pc))
|
|
if (auto ptr = getUserPointer(pc))
|
|
rtcSetUserPointer(dc, *ptr);
|
|
rtcSetUserPointer(dc, *ptr);
|
|
|
|
+
|
|
return dc;
|
|
return dc;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
int rtcCreateDataChannel(int pc, const char *label) {
|
|
int rtcCreateDataChannel(int pc, const char *label) {
|
|
- return rtcCreateDataChannelExt(pc, label, nullptr, nullptr);
|
|
|
|
|
|
+ return rtcCreateDataChannelExt(pc, label, nullptr);
|
|
}
|
|
}
|
|
|
|
|
|
-int rtcCreateDataChannelExt(int pc, const char *label, const char *protocol,
|
|
|
|
- const rtcReliability *reliability) {
|
|
|
|
- int dc = rtcAddDataChannelExt(pc, label, protocol, reliability);
|
|
|
|
|
|
+int rtcCreateDataChannelExt(int pc, const char *label, const rtcDataChannelInit *init) {
|
|
|
|
+ int dc = rtcAddDataChannelExt(pc, label, init);
|
|
rtcSetLocalDescription(pc, NULL);
|
|
rtcSetLocalDescription(pc, NULL);
|
|
return dc;
|
|
return dc;
|
|
}
|
|
}
|
|
@@ -345,6 +376,7 @@ int rtcAddTrack(int pc, const char *mediaDescriptionSdp) {
|
|
int tr = emplaceTrack(peerConnection->addTrack(std::move(media)));
|
|
int tr = emplaceTrack(peerConnection->addTrack(std::move(media)));
|
|
if (auto ptr = getUserPointer(pc))
|
|
if (auto ptr = getUserPointer(pc))
|
|
rtcSetUserPointer(tr, *ptr);
|
|
rtcSetUserPointer(tr, *ptr);
|
|
|
|
+
|
|
return tr;
|
|
return tr;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
@@ -366,19 +398,7 @@ int rtcDeleteTrack(int tr) {
|
|
int rtcGetTrackDescription(int tr, char *buffer, int size) {
|
|
int rtcGetTrackDescription(int tr, char *buffer, int size) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto track = getTrack(tr);
|
|
auto track = getTrack(tr);
|
|
-
|
|
|
|
- if (size <= 0)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (!buffer)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- string description(track->description());
|
|
|
|
- const char *data = description.data();
|
|
|
|
- size = std::min(size - 1, int(description.size()));
|
|
|
|
- std::copy(data, data + size, buffer);
|
|
|
|
- buffer[size] = '\0';
|
|
|
|
- return int(size + 1);
|
|
|
|
|
|
+ return copyAndReturn(track->description(), buffer, size);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -528,7 +548,7 @@ int rtcSetRemoteDescription(int pc, const char *sdp, const char *type) {
|
|
if (!sdp)
|
|
if (!sdp)
|
|
throw std::invalid_argument("Unexpected null pointer for remote description");
|
|
throw std::invalid_argument("Unexpected null pointer for remote description");
|
|
|
|
|
|
- peerConnection->setRemoteDescription({string(sdp), type ? string(type) : "" });
|
|
|
|
|
|
+ peerConnection->setRemoteDescription({string(sdp), type ? string(type) : ""});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -547,22 +567,10 @@ int rtcGetLocalDescription(int pc, char *buffer, int size) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto peerConnection = getPeerConnection(pc);
|
|
auto peerConnection = getPeerConnection(pc);
|
|
|
|
|
|
- if (size <= 0)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (!buffer)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- if (auto desc = peerConnection->localDescription()) {
|
|
|
|
- auto sdp = string(*desc);
|
|
|
|
- const char *data = sdp.data();
|
|
|
|
- size = std::min(size - 1, int(sdp.size()));
|
|
|
|
- std::copy(data, data + size, buffer);
|
|
|
|
- buffer[size] = '\0';
|
|
|
|
- return size + 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return RTC_ERR_FAILURE;
|
|
|
|
|
|
+ if (auto desc = peerConnection->localDescription())
|
|
|
|
+ return copyAndReturn(string(*desc), buffer, size);
|
|
|
|
+ else
|
|
|
|
+ return RTC_ERR_NOT_AVAIL;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -570,22 +578,10 @@ int rtcGetRemoteDescription(int pc, char *buffer, int size) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto peerConnection = getPeerConnection(pc);
|
|
auto peerConnection = getPeerConnection(pc);
|
|
|
|
|
|
- if (size <= 0)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (!buffer)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- if (auto desc = peerConnection->remoteDescription()) {
|
|
|
|
- auto sdp = string(*desc);
|
|
|
|
- const char *data = sdp.data();
|
|
|
|
- size = std::min(size - 1, int(sdp.size()));
|
|
|
|
- std::copy(data, data + size, buffer);
|
|
|
|
- buffer[size] = '\0';
|
|
|
|
- return size + 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return RTC_ERR_FAILURE;
|
|
|
|
|
|
+ if (auto desc = peerConnection->remoteDescription())
|
|
|
|
+ return copyAndReturn(string(*desc), buffer, size);
|
|
|
|
+ else
|
|
|
|
+ return RTC_ERR_NOT_AVAIL;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -593,21 +589,10 @@ int rtcGetLocalAddress(int pc, char *buffer, int size) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto peerConnection = getPeerConnection(pc);
|
|
auto peerConnection = getPeerConnection(pc);
|
|
|
|
|
|
- if (size <= 0)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (!buffer)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- if (auto addr = peerConnection->localAddress()) {
|
|
|
|
- const char *data = addr->data();
|
|
|
|
- size = std::min(size - 1, int(addr->size()));
|
|
|
|
- std::copy(data, data + size, buffer);
|
|
|
|
- buffer[size] = '\0';
|
|
|
|
- return size + 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return RTC_ERR_FAILURE;
|
|
|
|
|
|
+ if (auto addr = peerConnection->localAddress())
|
|
|
|
+ return copyAndReturn(std::move(*addr), buffer, size);
|
|
|
|
+ else
|
|
|
|
+ return RTC_ERR_NOT_AVAIL;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -615,21 +600,10 @@ int rtcGetRemoteAddress(int pc, char *buffer, int size) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto peerConnection = getPeerConnection(pc);
|
|
auto peerConnection = getPeerConnection(pc);
|
|
|
|
|
|
- if (size <= 0)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (!buffer)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- if (auto addr = peerConnection->remoteAddress()) {
|
|
|
|
- const char *data = addr->data();
|
|
|
|
- size = std::min(size - 1, int(addr->size()));
|
|
|
|
- std::copy(data, data + size, buffer);
|
|
|
|
- buffer[size] = '\0';
|
|
|
|
- return int(size + 1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return RTC_ERR_FAILURE;
|
|
|
|
|
|
+ if (auto addr = peerConnection->remoteAddress())
|
|
|
|
+ return copyAndReturn(std::move(*addr), buffer, size);
|
|
|
|
+ else
|
|
|
|
+ return RTC_ERR_NOT_AVAIL;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -637,68 +611,41 @@ int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, char *remote
|
|
return WRAP({
|
|
return WRAP({
|
|
auto peerConnection = getPeerConnection(pc);
|
|
auto peerConnection = getPeerConnection(pc);
|
|
|
|
|
|
- if (!local)
|
|
|
|
- localSize = 0;
|
|
|
|
- if (!remote)
|
|
|
|
- remoteSize = 0;
|
|
|
|
-
|
|
|
|
Candidate localCand;
|
|
Candidate localCand;
|
|
Candidate remoteCand;
|
|
Candidate remoteCand;
|
|
- if (peerConnection->getSelectedCandidatePair(&localCand, &remoteCand)) {
|
|
|
|
- if (localSize > 0) {
|
|
|
|
- string localSdp = string(localCand);
|
|
|
|
- localSize = std::min(localSize - 1, int(localSdp.size()));
|
|
|
|
- std::copy(localSdp.begin(), localSdp.begin() + localSize, local);
|
|
|
|
- local[localSize] = '\0';
|
|
|
|
- }
|
|
|
|
- if (remoteSize > 0) {
|
|
|
|
- string remoteSdp = string(remoteCand);
|
|
|
|
- remoteSize = std::min(remoteSize - 1, int(remoteSdp.size()));
|
|
|
|
- std::copy(remoteSdp.begin(), remoteSdp.begin() + remoteSize, remote);
|
|
|
|
- remote[remoteSize] = '\0';
|
|
|
|
- }
|
|
|
|
- return localSize + remoteSize;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!peerConnection->getSelectedCandidatePair(&localCand, &remoteCand))
|
|
|
|
+ return RTC_ERR_NOT_AVAIL;
|
|
|
|
|
|
- return RTC_ERR_FAILURE;
|
|
|
|
|
|
+ int localRet = copyAndReturn(string(localCand), local, localSize);
|
|
|
|
+ if (localRet < 0)
|
|
|
|
+ return localRet;
|
|
|
|
+
|
|
|
|
+ int remoteRet = copyAndReturn(string(remoteCand), remote, remoteSize);
|
|
|
|
+ if (remoteRet < 0)
|
|
|
|
+ return remoteRet;
|
|
|
|
+
|
|
|
|
+ return std::max(localRet, remoteRet);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
-int rtcGetDataChannelLabel(int dc, char *buffer, int size) {
|
|
|
|
|
|
+int rtcGetDataChannelStream(int dc) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto dataChannel = getDataChannel(dc);
|
|
auto dataChannel = getDataChannel(dc);
|
|
|
|
+ return int(dataChannel->id());
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
|
|
- if (size <= 0)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (!buffer)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- string label = dataChannel->label();
|
|
|
|
- const char *data = label.data();
|
|
|
|
- size = std::min(size - 1, int(label.size()));
|
|
|
|
- std::copy(data, data + size, buffer);
|
|
|
|
- buffer[size] = '\0';
|
|
|
|
- return int(size + 1);
|
|
|
|
|
|
+int rtcGetDataChannelLabel(int dc, char *buffer, int size) {
|
|
|
|
+ return WRAP({
|
|
|
|
+ auto dataChannel = getDataChannel(dc);
|
|
|
|
+ return copyAndReturn(dataChannel->label(), buffer, size);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
int rtcGetDataChannelProtocol(int dc, char *buffer, int size) {
|
|
int rtcGetDataChannelProtocol(int dc, char *buffer, int size) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto dataChannel = getDataChannel(dc);
|
|
auto dataChannel = getDataChannel(dc);
|
|
-
|
|
|
|
- if (size <= 0)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (!buffer)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- string protocol = dataChannel->protocol();
|
|
|
|
- const char *data = protocol.data();
|
|
|
|
- size = std::min(size - 1, int(protocol.size()));
|
|
|
|
- std::copy(data, data + size, buffer);
|
|
|
|
- buffer[size] = '\0';
|
|
|
|
- return int(size + 1);
|
|
|
|
|
|
+ return copyAndReturn(dataChannel->protocol(), buffer, size);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -709,19 +656,19 @@ int rtcGetDataChannelReliability(int dc, rtcReliability *reliability) {
|
|
if (!reliability)
|
|
if (!reliability)
|
|
throw std::invalid_argument("Unexpected null pointer for reliability");
|
|
throw std::invalid_argument("Unexpected null pointer for reliability");
|
|
|
|
|
|
- Reliability r = dataChannel->reliability();
|
|
|
|
|
|
+ Reliability dcr = dataChannel->reliability();
|
|
std::memset(reliability, 0, sizeof(*reliability));
|
|
std::memset(reliability, 0, sizeof(*reliability));
|
|
- reliability->unordered = r.unordered;
|
|
|
|
- if (r.type == Reliability::Type::Timed) {
|
|
|
|
|
|
+ reliability->unordered = dcr.unordered;
|
|
|
|
+ if (dcr.type == Reliability::Type::Timed) {
|
|
reliability->unreliable = true;
|
|
reliability->unreliable = true;
|
|
- reliability->maxPacketLifeTime = unsigned(std::get<milliseconds>(r.rexmit).count());
|
|
|
|
- } else if (r.type == Reliability::Type::Rexmit) {
|
|
|
|
|
|
+ reliability->maxPacketLifeTime = unsigned(std::get<milliseconds>(dcr.rexmit).count());
|
|
|
|
+ } else if (dcr.type == Reliability::Type::Rexmit) {
|
|
reliability->unreliable = true;
|
|
reliability->unreliable = true;
|
|
- reliability->maxRetransmits = unsigned(std::get<int>(r.rexmit));
|
|
|
|
|
|
+ reliability->maxRetransmits = unsigned(std::get<int>(dcr.rexmit));
|
|
} else {
|
|
} else {
|
|
reliability->unreliable = false;
|
|
reliability->unreliable = false;
|
|
}
|
|
}
|
|
- return 0;
|
|
|
|
|
|
+ return RTC_ERR_SUCCESS;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -837,12 +784,12 @@ int rtcSetAvailableCallback(int id, rtcAvailableCallbackFunc cb) {
|
|
return WRAP({
|
|
return WRAP({
|
|
auto channel = getChannel(id);
|
|
auto channel = getChannel(id);
|
|
if (cb)
|
|
if (cb)
|
|
- channel->onOpen([id, cb]() {
|
|
|
|
|
|
+ channel->onAvailable([id, cb]() {
|
|
if (auto ptr = getUserPointer(id))
|
|
if (auto ptr = getUserPointer(id))
|
|
cb(id, *ptr);
|
|
cb(id, *ptr);
|
|
});
|
|
});
|
|
else
|
|
else
|
|
- channel->onOpen(nullptr);
|
|
|
|
|
|
+ channel->onAvailable(nullptr);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -853,34 +800,38 @@ int rtcReceiveMessage(int id, char *buffer, int *size) {
|
|
if (!size)
|
|
if (!size)
|
|
throw std::invalid_argument("Unexpected null pointer for size");
|
|
throw std::invalid_argument("Unexpected null pointer for size");
|
|
|
|
|
|
- if (!buffer && *size != 0)
|
|
|
|
- throw std::invalid_argument("Unexpected null pointer for buffer");
|
|
|
|
-
|
|
|
|
- if (auto message = channel->receive())
|
|
|
|
- return std::visit( //
|
|
|
|
- overloaded{ //
|
|
|
|
- [&](binary b) {
|
|
|
|
- if (*size > 0) {
|
|
|
|
- *size = std::min(*size, int(b.size()));
|
|
|
|
- auto data = reinterpret_cast<const char *>(b.data());
|
|
|
|
- std::copy(data, data + *size, buffer);
|
|
|
|
- }
|
|
|
|
- return 1;
|
|
|
|
- },
|
|
|
|
- [&](string s) {
|
|
|
|
- if (*size > 0) {
|
|
|
|
- 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;
|
|
|
|
|
|
+ *size = std::abs(*size);
|
|
|
|
+
|
|
|
|
+ auto message = channel->peek();
|
|
|
|
+ if (!message)
|
|
|
|
+ return RTC_ERR_NOT_AVAIL;
|
|
|
|
+
|
|
|
|
+ return std::visit( //
|
|
|
|
+ overloaded{
|
|
|
|
+ [&](binary b) {
|
|
|
|
+ int ret = copyAndReturn(std::move(b), buffer, *size);
|
|
|
|
+ if (ret >= 0) {
|
|
|
|
+ channel->receive(); // discard
|
|
|
|
+ *size = ret;
|
|
|
|
+ return RTC_ERR_SUCCESS;
|
|
|
|
+ } else {
|
|
|
|
+ *size = int(b.size());
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ [&](string s) {
|
|
|
|
+ int ret = copyAndReturn(std::move(s), buffer, *size);
|
|
|
|
+ if (ret >= 0) {
|
|
|
|
+ channel->receive(); // discard
|
|
|
|
+ *size = -ret;
|
|
|
|
+ return RTC_ERR_SUCCESS;
|
|
|
|
+ } else {
|
|
|
|
+ *size = -int(s.size() + 1);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ *message);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|