Skip to content

Commit af7ccc7

Browse files
committed
Fixed nested pausing
1 parent 575b3a5 commit af7ccc7

17 files changed

+388
-150
lines changed

compiled/download.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiled/upload-download.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiled/upload.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/lib/appendable-stream.d.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import AppendableBuffer from './appendable';
1111
export default class AppendableStream implements AppendableBuffer {
1212
private readonly outStream;
1313
private writtenBytes;
14+
private pauseCount;
1415
private paused;
1516
/**
1617
* @param outStream The underlying writable stream
@@ -43,7 +44,22 @@ export default class AppendableStream implements AppendableBuffer {
4344
* [[resume]] is next called and
4445
* can be cancelled from being written
4546
* by calling [[reset]].
46-
* @throws If paused earlier and never resumed
47+
*
48+
* If called multiple times, [[resume]]
49+
* and [[reset]] only act on bytes added
50+
* since the most recent pause. Example:
51+
* ````javascript
52+
* let gb = new GrowableBuffer
53+
* gb
54+
* .pause()
55+
* .add(1).add(2).add(3)
56+
* .pause()
57+
* .add(4).add(5).add(6)
58+
* .reset() //cancels [4, 5, 6]
59+
* .resume()
60+
* .resume() //resumes [1, 2, 3]
61+
* console.log(new Uint8Array(gb.toBuffer())) //Uint8Array [ 1, 2, 3 ]
62+
* ````
4763
*/
4864
pause(): this;
4965
/**

dist/lib/appendable-stream.js

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class AppendableStream {
2020
assert_1.default.instanceOf(outStream, WRITABLE_STREAMS);
2121
this.outStream = outStream;
2222
this.writtenBytes = 0;
23-
this.paused = null;
23+
this.pauseCount = 0;
24+
this.paused = new growable_buffer_1.default;
2425
}
2526
/**
2627
* Appends a byte to the end
@@ -39,7 +40,7 @@ class AppendableStream {
3940
*/
4041
addAll(buffer) {
4142
assert_1.default.instanceOf(buffer, ArrayBuffer);
42-
if (this.paused)
43+
if (this.pauseCount)
4344
this.paused.addAll(buffer);
4445
else
4546
this.outStream.write(Buffer.from(buffer));
@@ -65,11 +66,26 @@ class AppendableStream {
6566
* [[resume]] is next called and
6667
* can be cancelled from being written
6768
* by calling [[reset]].
68-
* @throws If paused earlier and never resumed
69+
*
70+
* If called multiple times, [[resume]]
71+
* and [[reset]] only act on bytes added
72+
* since the most recent pause. Example:
73+
* ````javascript
74+
* let gb = new GrowableBuffer
75+
* gb
76+
* .pause()
77+
* .add(1).add(2).add(3)
78+
* .pause()
79+
* .add(4).add(5).add(6)
80+
* .reset() //cancels [4, 5, 6]
81+
* .resume()
82+
* .resume() //resumes [1, 2, 3]
83+
* console.log(new Uint8Array(gb.toBuffer())) //Uint8Array [ 1, 2, 3 ]
84+
* ````
6985
*/
7086
pause() {
71-
assert_1.default(this.paused === null, 'Already paused');
72-
this.paused = new growable_buffer_1.default;
87+
this.paused.pause();
88+
this.pauseCount++;
7389
return this;
7490
}
7591
/**
@@ -79,11 +95,15 @@ class AppendableStream {
7995
* @throws If not currently paused
8096
*/
8197
resume() {
82-
if (!this.paused)
98+
if (!this.pauseCount)
8399
throw new Error('Was not paused');
84-
const { length } = this.paused;
85-
this.outStream.write(Buffer.from(this.paused.rawBuffer, 0, length));
86-
this.paused = null;
100+
this.pauseCount--;
101+
if (this.pauseCount)
102+
this.paused.resume(); //still in pause stack
103+
else {
104+
this.outStream.write(Buffer.from(this.paused.rawBuffer, 0, this.paused.length));
105+
this.paused = new growable_buffer_1.default; //must use a new buffer to avoid overwriting data sent to outStream
106+
}
87107
return this;
88108
}
89109
/**
@@ -95,10 +115,12 @@ class AppendableStream {
95115
* @throws If not currently paused
96116
*/
97117
reset() {
98-
if (!this.paused)
118+
if (!this.pauseCount)
99119
throw new Error('Was not paused');
100-
this.writtenBytes -= this.paused.length;
101-
this.paused = new growable_buffer_1.default;
120+
const lengthBeforeReset = this.paused.length;
121+
this.paused.reset();
122+
const lengthAfterReset = this.paused.length;
123+
this.writtenBytes -= lengthBeforeReset - lengthAfterReset;
102124
return this;
103125
}
104126
}

dist/lib/appendable.d.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
* .add(1).add(2)
1111
* .addAll(new Uint8Array([3, 4, 5]).buffer)
1212
* .pause()
13-
* .add(0)
14-
* .reset()
13+
* .add(0)
14+
* .reset()
1515
* .resume()
1616
* console.log(new Uint8Array(gb.toBuffer())) //Uint8Array [ 1, 2, 3, 4, 5 ]
1717
* ````
@@ -42,7 +42,22 @@ export default interface AppendableBuffer {
4242
* [[resume]] is next called and
4343
* can be cancelled from being written
4444
* by calling [[reset]].
45-
* @throws If paused earlier and never resumed
45+
*
46+
* If called multiple times, [[resume]]
47+
* and [[reset]] only act on bytes added
48+
* since the most recent pause. Example:
49+
* ````javascript
50+
* let gb = new GrowableBuffer
51+
* gb
52+
* .pause()
53+
* .add(1).add(2).add(3)
54+
* .pause()
55+
* .add(4).add(5).add(6)
56+
* .reset() //cancels [4, 5, 6]
57+
* .resume()
58+
* .resume() //resumes [1, 2, 3]
59+
* console.log(new Uint8Array(gb.toBuffer())) //Uint8Array [ 1, 2, 3 ]
60+
* ````
4661
*/
4762
pause(): this;
4863
/**

dist/lib/growable-buffer.d.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ import AppendableBuffer from './appendable';
99
export default class GrowableBuffer implements AppendableBuffer {
1010
private buffer;
1111
private size;
12-
/**
13-
* The length of the buffer before the current pause,
14-
* or `null` if not currently paused
15-
*/
16-
private commitedSize;
12+
private readonly pausePoints;
1713
/**
1814
* @param initialLength
1915
* The number of bytes in the internal buffer at start
@@ -70,7 +66,22 @@ export default class GrowableBuffer implements AppendableBuffer {
7066
* [[resume]] is next called and
7167
* can be cancelled from being written
7268
* by calling [[reset]].
73-
* @throws If paused earlier and never resumed
69+
*
70+
* If called multiple times, [[resume]]
71+
* and [[reset]] only act on bytes added
72+
* since the most recent pause. Example:
73+
* ````javascript
74+
* let gb = new GrowableBuffer
75+
* gb
76+
* .pause()
77+
* .add(1).add(2).add(3)
78+
* .pause()
79+
* .add(4).add(5).add(6)
80+
* .reset() //cancels [4, 5, 6]
81+
* .resume()
82+
* .resume() //resumes [1, 2, 3]
83+
* console.log(new Uint8Array(gb.toBuffer())) //Uint8Array [ 1, 2, 3 ]
84+
* ````
7485
*/
7586
pause(): this;
7687
/**

dist/lib/growable-buffer.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class GrowableBuffer {
2525
}
2626
this.buffer = new ArrayBuffer(initialLength);
2727
this.size = 0;
28-
this.commitedSize = null;
28+
this.pausePoints = [];
2929
}
3030
/**
3131
* The current number of bytes being occupied.
@@ -95,10 +95,10 @@ class GrowableBuffer {
9595
*/
9696
toBuffer() {
9797
let length;
98-
if (this.commitedSize === null)
99-
length = this.size;
98+
if (this.pausePoints.length)
99+
[length] = this.pausePoints; //go up to first pause point
100100
else
101-
length = this.commitedSize;
101+
length = this.size;
102102
return this.buffer.slice(0, length);
103103
}
104104
/**
@@ -108,11 +108,25 @@ class GrowableBuffer {
108108
* [[resume]] is next called and
109109
* can be cancelled from being written
110110
* by calling [[reset]].
111-
* @throws If paused earlier and never resumed
111+
*
112+
* If called multiple times, [[resume]]
113+
* and [[reset]] only act on bytes added
114+
* since the most recent pause. Example:
115+
* ````javascript
116+
* let gb = new GrowableBuffer
117+
* gb
118+
* .pause()
119+
* .add(1).add(2).add(3)
120+
* .pause()
121+
* .add(4).add(5).add(6)
122+
* .reset() //cancels [4, 5, 6]
123+
* .resume()
124+
* .resume() //resumes [1, 2, 3]
125+
* console.log(new Uint8Array(gb.toBuffer())) //Uint8Array [ 1, 2, 3 ]
126+
* ````
112127
*/
113128
pause() {
114-
assert_1.default(this.commitedSize === null, 'Already paused');
115-
this.commitedSize = this.size;
129+
this.pausePoints.push(this.size);
116130
return this;
117131
}
118132
/**
@@ -122,8 +136,9 @@ class GrowableBuffer {
122136
* @throws If not currently paused
123137
*/
124138
resume() {
125-
assert_1.default(this.commitedSize !== null, 'Was not paused');
126-
this.commitedSize = null;
139+
const pausePoint = this.pausePoints.pop();
140+
if (pausePoint === undefined)
141+
throw new Error('Was not paused');
127142
return this;
128143
}
129144
/**
@@ -135,9 +150,10 @@ class GrowableBuffer {
135150
* @throws If not currently paused
136151
*/
137152
reset() {
138-
if (this.commitedSize === null)
153+
if (!this.pausePoints.length)
139154
throw new Error('Was not paused');
140-
this.size = this.commitedSize;
155+
const pausePoint = this.pausePoints[this.pausePoints.length - 1];
156+
this.size = pausePoint;
141157
return this;
142158
}
143159
}

0 commit comments

Comments
 (0)