• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
size(const String & value)32     static size_t size(const String& value) { return value.length(); }
toScriptValue(ScriptState * scriptState,const HoldType & value)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 
size(const PassType & value)45     static size_t size(const PassType& value) { return value->byteLength(); }
size(const HoldType & value)46     static size_t size(const HoldType& value) { return value->byteLength(); }
toScriptValue(ScriptState * scriptState,const HoldType & value)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:
ReadableStreamImpl(ExecutionContext * executionContext,UnderlyingSource * source)59     ReadableStreamImpl(ExecutionContext* executionContext, UnderlyingSource* source)
60         : ReadableStream(executionContext, source)
61         , m_totalQueueSize(0) { }
~ReadableStreamImpl()62     virtual ~ReadableStreamImpl() { }
63 
64     // ReadableStream methods
65     virtual ScriptValue read(ScriptState*, ExceptionState&) OVERRIDE;
66 
67     bool enqueue(typename ChunkTypeTraits::PassType);
68 
trace(Visitor * visitor)69     virtual void trace(Visitor* visitor) OVERRIDE
70     {
71         ReadableStream::trace(visitor);
72     }
73 
74 private:
75     // ReadableStream methods
isQueueEmpty()76     virtual bool isQueueEmpty() const OVERRIDE { return m_queue.isEmpty(); }
clearQueue()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>
enqueue(typename ChunkTypeTraits::PassType chunk)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>
read(ScriptState * scriptState,ExceptionState & exceptionState)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