1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ReadableStreamImpl_h 6 #define ReadableStreamImpl_h 7 8 #include "bindings/core/v8/ExceptionState.h" 9 #include "bindings/core/v8/ScriptState.h" 10 #include "bindings/core/v8/ScriptValue.h" 11 #include "bindings/core/v8/V8Binding.h" 12 #include "core/streams/ReadableStream.h" 13 #include "wtf/ArrayBuffer.h" 14 #include "wtf/Deque.h" 15 #include "wtf/Forward.h" 16 #include "wtf/OwnPtr.h" 17 #include "wtf/RefPtr.h" 18 #include "wtf/text/WTFString.h" 19 20 namespace blink { 21 22 // We define the default ChunkTypeTraits for frequently used types. 23 template<typename ChunkType> 24 class ReadableStreamChunkTypeTraits { }; 25 26 template<> 27 class ReadableStreamChunkTypeTraits<String> { 28 public: 29 typedef String HoldType; 30 typedef const String& PassType; 31 32 static size_t size(const String& value) { return value.length(); } 33 static ScriptValue toScriptValue(ScriptState* scriptState, const HoldType& value) 34 { 35 return ScriptValue(scriptState, v8String(scriptState->isolate(), value)); 36 } 37 }; 38 39 template<> 40 class ReadableStreamChunkTypeTraits<ArrayBuffer> { 41 public: 42 typedef RefPtr<ArrayBuffer> HoldType; 43 typedef PassRefPtr<ArrayBuffer> PassType; 44 45 static size_t size(const PassType& value) { return value->byteLength(); } 46 static size_t size(const HoldType& value) { return value->byteLength(); } 47 static ScriptValue toScriptValue(ScriptState* scriptState, const HoldType& value) 48 { 49 return ScriptValue(scriptState, toV8NoInline(value.get(), scriptState->context()->Global(), scriptState->isolate())); 50 } 51 }; 52 53 // ReadableStreamImpl<ChunkTypeTraits> is a ReadableStream subtype. It has a 54 // queue whose type depends on ChunkTypeTraits and it implements queue-related 55 // ReadableStream pure virtual methods. 56 template <typename ChunkTypeTraits> 57 class ReadableStreamImpl : public ReadableStream { 58 public: 59 ReadableStreamImpl(ExecutionContext* executionContext, UnderlyingSource* source) 60 : ReadableStream(executionContext, source) 61 , m_totalQueueSize(0) { } 62 virtual ~ReadableStreamImpl() { } 63 64 // ReadableStream methods 65 virtual ScriptValue read(ScriptState*, ExceptionState&) OVERRIDE; 66 67 bool enqueue(typename ChunkTypeTraits::PassType); 68 69 virtual void trace(Visitor* visitor) OVERRIDE 70 { 71 ReadableStream::trace(visitor); 72 } 73 74 private: 75 // ReadableStream methods 76 virtual bool isQueueEmpty() const OVERRIDE { return m_queue.isEmpty(); } 77 virtual void clearQueue() OVERRIDE 78 { 79 m_queue.clear(); 80 m_totalQueueSize = 0; 81 } 82 83 Deque<typename ChunkTypeTraits::HoldType> m_queue; 84 size_t m_totalQueueSize; 85 }; 86 87 template <typename ChunkTypeTraits> 88 bool ReadableStreamImpl<ChunkTypeTraits>::enqueue(typename ChunkTypeTraits::PassType chunk) 89 { 90 size_t size = ChunkTypeTraits::size(chunk); 91 if (!enqueuePreliminaryCheck(size)) 92 return false; 93 m_queue.append(chunk); 94 m_totalQueueSize += size; 95 return enqueuePostAction(m_totalQueueSize); 96 } 97 98 template <typename ChunkTypeTraits> 99 ScriptValue ReadableStreamImpl<ChunkTypeTraits>::read(ScriptState* scriptState, ExceptionState& exceptionState) 100 { 101 readPreliminaryCheck(exceptionState); 102 if (exceptionState.hadException()) 103 return ScriptValue(); 104 ASSERT(state() == Readable); 105 ASSERT(!m_queue.isEmpty()); 106 typename ChunkTypeTraits::HoldType chunk = m_queue.takeFirst(); 107 m_totalQueueSize -= ChunkTypeTraits::size(chunk); 108 readPostAction(); 109 return ChunkTypeTraits::toScriptValue(scriptState, chunk); 110 } 111 112 } // namespace blink 113 114 #endif // ReadableStreamImpl_h 115 116