Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1842)

Unified Diff: Source/modules/mediastream/RTCDataChannel.cpp

Issue 268923002: Add support of sending blob data for RTCDataChannel Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/mediastream/RTCDataChannel.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/mediastream/RTCDataChannel.cpp
diff --git a/Source/modules/mediastream/RTCDataChannel.cpp b/Source/modules/mediastream/RTCDataChannel.cpp
index 43e24e8ff655fb5f953b15db69d7cea026a0f45d..69ae692b043ac185e869831b0696919ed837481c 100644
--- a/Source/modules/mediastream/RTCDataChannel.cpp
+++ b/Source/modules/mediastream/RTCDataChannel.cpp
@@ -31,9 +31,11 @@
#include "core/events/Event.h"
#include "core/events/MessageEvent.h"
#include "core/fileapi/Blob.h"
+#include "core/fileapi/FileReaderLoader.h"
#include "public/platform/WebRTCPeerConnectionHandler.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/ArrayBufferView.h"
+#include "wtf/OwnPtr.h"
namespace WebCore {
@@ -47,11 +49,6 @@ static void throwCouldNotSendDataException(ExceptionState& exceptionState)
exceptionState.throwDOMException(NetworkError, "Could not send data");
}
-static void throwNoBlobSupportException(ExceptionState& exceptionState)
-{
- exceptionState.throwDOMException(NotSupportedError, "Blob support not implemented yet");
-}
-
PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, PassOwnPtr<blink::WebRTCDataChannelHandler> handler)
{
ASSERT(handler);
@@ -73,7 +70,8 @@ RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<blink::WebR
, m_handler(handler)
, m_stopped(false)
, m_readyState(ReadyStateConnecting)
- , m_binaryType(BinaryTypeArrayBuffer)
+ , m_binaryType(BinaryTypeBlob)
+ , m_blobLoaderStatus(BlobLoaderNotStarted)
, m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired)
{
ScriptWrappable::init(this);
@@ -161,7 +159,7 @@ String RTCDataChannel::binaryType() const
void RTCDataChannel::setBinaryType(const String& binaryType, ExceptionState& exceptionState)
{
if (binaryType == "blob")
- throwNoBlobSupportException(exceptionState);
+ m_binaryType = BinaryTypeBlob;
else if (binaryType == "arraybuffer")
m_binaryType = BinaryTypeArrayBuffer;
else
@@ -209,8 +207,12 @@ void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionState& exce
void RTCDataChannel::send(PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& exceptionState)
{
- // FIXME: implement
- throwNoBlobSupportException(exceptionState);
+ if (m_readyState != ReadyStateOpen) {
+ throwNotOpenException(exceptionState);
+ return;
+ }
+ m_outgoingBlobQueue.append(data->blobDataHandle());
+ processOutgoingBlobQueue();
}
void RTCDataChannel::close()
@@ -254,7 +256,14 @@ void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength)
return;
if (m_binaryType == BinaryTypeBlob) {
- // FIXME: Implement.
+ OwnPtr<BlobData> blobData = BlobData::create();
+ RefPtr<RawData> rawData = RawData::create();
+ OwnPtr<Vector<char> > binaryData = adoptPtr(new Vector<char>(dataLength));
michaeln 2014/05/06 02:36:49 this also probably won't work well with large blob
Li Yin 2014/05/06 07:09:37 When blob is large, it needs much memory, do you m
+ memcpy(binaryData->data(), data, dataLength);
+ binaryData->swap(*rawData->mutableData());
+ blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile);
+ RefPtrWillBeRawPtr<Blob> blob = Blob::create(BlobDataHandle::create(blobData.release(), dataLength));
+ scheduleDispatchEvent(MessageEvent::create(blob.release()));
return;
}
if (m_binaryType == BinaryTypeArrayBuffer) {
@@ -314,4 +323,68 @@ void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*)
events.clear();
}
+void RTCDataChannel::didStartLoading()
+{
+ ASSERT(m_blobLoader);
+ ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
+}
+
+void RTCDataChannel::didReceiveData()
+{
+ ASSERT(m_blobLoader);
+ ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
+}
+
+void RTCDataChannel::didFinishLoading()
+{
+ ASSERT(m_blobLoader);
+ ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
+ m_blobLoaderStatus = BlobLoaderFinished;
+ processOutgoingBlobQueue();
+ deref();
+}
+
+void RTCDataChannel::didFail(FileError::ErrorCode errorCode)
+{
+ ASSERT(m_blobLoader);
+ ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
+ m_blobLoader.clear();
+ m_blobLoaderStatus = BlobLoaderFailed;
+ close();
+ deref();
+}
+
+void RTCDataChannel::processOutgoingBlobQueue()
+{
+ while (!m_outgoingBlobQueue.isEmpty()) {
+ RefPtr<BlobDataHandle> blobDataHandle = m_outgoingBlobQueue.takeFirst();
+ switch (m_blobLoaderStatus) {
+ case BlobLoaderNotStarted:
+ ref(); // Will be derefed after didFinishLoading() or didFail().
+ ASSERT(!m_blobLoader);
+ m_blobLoader = adoptPtr(new FileReaderLoader(FileReaderLoader::ReadAsArrayBuffer, this));
+ m_blobLoaderStatus = BlobLoaderStarted;
+ m_blobLoader->start(m_executionContext, blobDataHandle.get());
+ m_outgoingBlobQueue.prepend(blobDataHandle.release());
+ return;
+
+ case BlobLoaderStarted:
+ case BlobLoaderFailed:
+ m_outgoingBlobQueue.prepend(blobDataHandle.release());
+ return;
+
+ case BlobLoaderFinished: {
+ RefPtr<ArrayBuffer> result = m_blobLoader->arrayBufferResult();
michaeln 2014/05/06 02:36:49 this probably won't work well with large blobs, ha
Li Yin 2014/05/06 07:09:37 Yeah, your concern looks reasonable, but unfortuna
+ m_blobLoader.clear();
+ m_blobLoaderStatus = BlobLoaderNotStarted;
+ if (!m_handler->sendRawData(static_cast<const char*>(result->data()), result->byteLength())) {
+ // FIXME: This should forcefully close the data channel.
+ return;
+ }
+ break;
+ }
+ }
+ }
+}
+
} // namespace WebCore
« no previous file with comments | « Source/modules/mediastream/RTCDataChannel.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698