OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 /** | |
6 * Default implementation of [ListInputStream]. | |
7 */ | |
8 class _ListInputStream extends _BaseDataInputStream implements ListInputStream { | |
9 _ListInputStream() : _bufferList = new _BufferList(); | |
10 | |
11 void write(List<int> data) { | |
12 if (_streamMarkedClosed) { | |
13 throw new StreamException.streamClosed(); | |
14 } | |
15 _bufferList.add(data); | |
16 _checkScheduleCallbacks(); | |
17 } | |
18 | |
19 void markEndOfStream() { | |
20 _streamMarkedClosed = true; | |
21 _checkScheduleCallbacks(); | |
22 } | |
23 | |
24 int available() => _bufferList.length; | |
25 | |
26 List<int> _read(int bytesToRead) { | |
27 return _bufferList.readBytes(bytesToRead); | |
28 } | |
29 | |
30 int _readInto(List<int> buffer, int offset, int bytesToRead) { | |
31 List<int> tmp = _bufferList.readBytes(bytesToRead); | |
32 buffer.setRange(offset, bytesToRead, tmp, 0); | |
33 return bytesToRead; | |
34 } | |
35 | |
36 void _close() { | |
37 _streamMarkedClosed = true; | |
38 _bufferList.clear(); | |
39 } | |
40 | |
41 _BufferList _bufferList; | |
42 } | |
43 | |
44 | |
45 class _ListOutputStream extends _BaseOutputStream implements ListOutputStream { | |
46 _ListOutputStream() : _bufferList = new _BufferList(); | |
47 | |
48 List<int> read() => _bufferList.readBytes(_bufferList.length); | |
49 | |
50 bool write(List<int> buffer, [bool copyBuffer = true]) { | |
51 if (_streamMarkedClosed) throw new StreamException.streamClosed(); | |
52 if (copyBuffer) { | |
53 _bufferList.add(buffer.getRange(0, buffer.length)); | |
54 } else { | |
55 _bufferList.add(buffer); | |
56 } | |
57 _checkScheduleCallbacks(); | |
58 return true; | |
59 } | |
60 | |
61 bool writeFrom(List<int> buffer, [int offset = 0, int len]) { | |
62 return write( | |
63 buffer.getRange(offset, (len == null) ? buffer.length - offset : len), | |
64 false); | |
65 } | |
66 | |
67 void flush() { | |
68 // Nothing to do on a list output stream. | |
69 } | |
70 | |
71 void close() { | |
72 if (_streamMarkedClosed) throw new StreamException.streamClosed(); | |
73 _streamMarkedClosed = true; | |
74 _checkScheduleCallbacks(); | |
75 } | |
76 | |
77 void destroy() { | |
78 close(); | |
79 } | |
80 | |
81 void set onData(void callback()) { | |
82 _clientDataHandler = callback; | |
83 _checkScheduleCallbacks(); | |
84 } | |
85 | |
86 void set onNoPendingWrites(void callback()) { | |
87 _clientNoPendingWriteHandler = callback; | |
88 _checkScheduleCallbacks(); | |
89 } | |
90 | |
91 void set onClosed(void callback()) { | |
92 _clientCloseHandler = callback; | |
93 } | |
94 | |
95 void set onError(void callback(e)) { | |
96 // No errors emitted. | |
97 } | |
98 | |
99 void _checkScheduleCallbacks() { | |
100 void issueDataCallback(Timer timer) { | |
101 _scheduledDataCallback = null; | |
102 if (_clientDataHandler != null) { | |
103 _clientDataHandler(); | |
104 _checkScheduleCallbacks(); | |
105 } | |
106 } | |
107 | |
108 void issueNoPendingWriteCallback(Timer timer) { | |
109 _scheduledNoPendingWriteCallback = null; | |
110 if (_clientNoPendingWriteHandler != null && | |
111 !_streamMarkedClosed) { | |
112 _clientNoPendingWriteHandler(); | |
113 _checkScheduleCallbacks(); | |
114 } | |
115 } | |
116 | |
117 void issueCloseCallback(Timer timer) { | |
118 _scheduledCloseCallback = null; | |
119 if (_clientCloseHandler !== null) _clientCloseHandler(); | |
120 } | |
121 | |
122 // Schedule no pending callback if there is a callback set as this | |
123 // output stream does not wait for any transmission. Schedule | |
124 // close callback once when the stream is closed. Only schedule a | |
125 // new callback if the previous one has actually been called. | |
126 if (_closeCallbackCalled) return; | |
127 | |
128 if (!_streamMarkedClosed) { | |
129 if (!_bufferList.isEmpty && | |
130 _clientDataHandler != null && | |
131 _scheduledDataCallback == null) { | |
132 _scheduledDataCallback = new Timer(0, issueDataCallback); | |
133 } | |
134 | |
135 if (_clientNoPendingWriteHandler != null && | |
136 _scheduledNoPendingWriteCallback == null && | |
137 _scheduledDataCallback == null) { | |
138 _scheduledNoPendingWriteCallback = | |
139 new Timer(0, issueNoPendingWriteCallback); | |
140 } | |
141 | |
142 } else if (_clientCloseHandler != null) { | |
143 _scheduledCloseCallback = new Timer(0, issueCloseCallback); | |
144 _closeCallbackCalled = true; | |
145 } | |
146 } | |
147 | |
148 bool get closed => _streamMarkedClosed; | |
149 | |
150 _BufferList _bufferList; | |
151 bool _streamMarkedClosed = false; | |
152 bool _closeCallbackCalled = false; | |
153 Timer _scheduledDataCallback; | |
154 Timer _scheduledNoPendingWriteCallback; | |
155 Timer _scheduledCloseCallback; | |
156 Function _clientDataHandler; | |
157 Function _clientNoPendingWriteHandler; | |
158 Function _clientCloseHandler; | |
159 } | |
OLD | NEW |