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.
5 #ifndef ReadableStreamImpl_h
6 #define ReadableStreamImpl_h
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"
22 // We define the default ChunkTypeTraits for frequently used types.
23 template<typename ChunkType>
24 class ReadableStreamChunkTypeTraits { };
27 class ReadableStreamChunkTypeTraits<String> {
29 typedef String HoldType;
30 typedef const String& PassType;
32 static size_t size(const String& value) { return value.length(); }
33 static ScriptValue toScriptValue(ScriptState* scriptState, const HoldType& value)
35 return ScriptValue(scriptState, v8String(scriptState->isolate(), value));
40 class ReadableStreamChunkTypeTraits<ArrayBuffer> {
42 typedef RefPtr<ArrayBuffer> HoldType;
43 typedef PassRefPtr<ArrayBuffer> PassType;
45 static size_t size(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)
49 return ScriptValue(scriptState, toV8NoInline(value.get(), scriptState->context()->Global(), scriptState->isolate()));
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 {
59 ReadableStreamImpl(ScriptState* scriptState, UnderlyingSource* source, ExceptionState* exceptionState)
60 : ReadableStream(scriptState, source, exceptionState)
61 , m_totalQueueSize(0) { }
62 virtual ~ReadableStreamImpl() { }
64 // ReadableStream methods
65 virtual ScriptValue read(ScriptState*, ExceptionState*) OVERRIDE;
67 bool enqueue(typename ChunkTypeTraits::PassType);
69 virtual void trace(Visitor* visitor) OVERRIDE
71 ReadableStream::trace(visitor);
75 // ReadableStream methods
76 virtual bool isQueueEmpty() const OVERRIDE { return m_queue.isEmpty(); }
77 virtual void clearQueue() OVERRIDE
83 Deque<typename ChunkTypeTraits::HoldType> m_queue;
84 size_t m_totalQueueSize;
87 template <typename ChunkTypeTraits>
88 bool ReadableStreamImpl<ChunkTypeTraits>::enqueue(typename ChunkTypeTraits::PassType chunk)
90 size_t size = ChunkTypeTraits::size(chunk);
91 if (!enqueuePreliminaryCheck(size))
93 m_queue.append(chunk);
94 m_totalQueueSize += size;
95 return enqueuePostAction(m_totalQueueSize);
98 template <typename ChunkTypeTraits>
99 ScriptValue ReadableStreamImpl<ChunkTypeTraits>::read(ScriptState* scriptState, ExceptionState* exceptionState)
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);
109 return ChunkTypeTraits::toScriptValue(scriptState, chunk);
114 #endif // ReadableStreamImpl_h