249865c47cd5160e539191b1287f366ec371f3b3
[WebKit-https.git] / LayoutTests / streams / reference-implementation / resources / streams-utils.js
1 var standardTimeout = 100;
2
3 function RandomPushSource(toPush) {
4     this.pushed = 0;
5     this.toPush = toPush;
6     this.started = false;
7     this.paused = false;
8     this.closed = false;
9
10     this._intervalHandle = null;
11 }
12
13 RandomPushSource.prototype = {
14
15     readStart: function() {
16         if (this.closed) {
17             return;
18         }
19
20         if (!this.started) {
21             this._intervalHandle = setInterval(writeChunk, 23);
22             this.started = true;
23         }
24
25         if (this.paused) {
26             this._intervalHandle = setInterval(writeChunk, 23);
27             this.paused = false;
28         }
29
30         var stream = this;
31         function writeChunk() {
32             if (stream.paused) {
33                 return;
34             }
35
36             stream.pushed++;
37
38             if (stream.toPush > 0 && stream.pushed > stream.toPush) {
39                 if (stream._intervalHandle) {
40                     clearInterval(stream._intervalHandle);
41                     stream._intervalHandle = undefined;
42                 }
43                 stream.closed = true;
44                 stream.onend();
45             }
46             else {
47                 stream.ondata(randomChunk(128));
48             }
49         }
50     },
51
52     readStop: function() {
53         if (this.paused) {
54             return;
55         }
56
57         if (this.started) {
58             this.paused = true;
59             clearInterval(this._intervalHandle);
60             this._intervalHandle = undefined;
61         } else {
62             throw new Error('Can\'t pause reading an unstarted source.');
63         }
64     },
65 }
66
67 function randomChunk(size) {
68     var chunk = '';
69
70     for (var i = 0; i < size; i++) {
71         // Add a random character from the basic printable ASCII set.
72         chunk += String.fromCharCode(Math.round(Math.random() * 84) + 32)
73     }
74
75     return chunk;
76 }
77
78 function readableStreamToArray(readable, reader) {
79     var chunks = [];
80
81     if (reader == undefined) {
82         reader = readable.getReader();
83     }
84
85     return pump();
86
87     function pump() {
88         return reader.read().then(function({ value, done }) {
89             if (done) {
90                 return chunks;
91             }
92
93             chunks.push(value);
94             return pump();
95         });
96     }
97 }
98
99 function SequentialPullSource(limit, async) {
100     this.current = 0;
101     this.limit = limit;
102     this.opened = false;
103     this.closed = false;
104
105     this._exec = function(f) {
106         f();
107     };
108     if (async)
109         this._exec = function(f) {
110             setTimeout(f, 0);
111         };
112 }
113
114 SequentialPullSource.prototype = {
115
116     open: function(cb) {
117         var myFunction = function() {
118             this.opened = true
119             cb();
120         };
121         this._exec(myFunction.bind(this));
122     },
123
124     read: function(cb) {
125         var myFunction = function() {
126             if (++this.current <= this.limit) {
127                 cb(null, false, this.current);
128             } else {
129                 cb(null, true, null);
130             }
131         };
132         this._exec(myFunction.bind(this));
133     },
134
135     close: function(cb) {
136         var myFunction = function() {
137             this.closed = true;
138             cb();
139         };
140         this._exec(myFunction.bind(this));
141     },
142 }
143
144 function sequentialReadableStream(limit, options) {
145     var sequentialSource = new SequentialPullSource(limit, options);
146
147     var stream = new ReadableStream({
148         start: function() {
149             return new Promise(function(resolve, reject) {
150                 sequentialSource.open(function(err) {
151                     if (err) {
152                         reject(err);
153                     }
154                     resolve();
155                 });
156             });
157         },
158
159         pull: function(enqueue, finish, error) {
160             sequentialSource.read(function(err, done, chunk) {
161                 if (err) {
162                     error(err);
163                 } else if (done) {
164                     sequentialSource.close(function(err) {
165                         if (err) {
166                             error(err);
167                         }
168                         finish();
169                     });
170                 } else {
171                     enqueue(chunk);
172                 }
173             });
174         },
175     });
176
177     stream.source = sequentialSource;
178
179     return stream;
180 };