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