Skip to content

Commit 382fb07

Browse files
authored
Merge pull request #740 from zbjornson/stream-polishing
Implement Readable instead of Stream
2 parents 48eb938 + 8b5dc05 commit 382fb07

File tree

5 files changed

+104
-46
lines changed

5 files changed

+104
-46
lines changed

lib/jpegstream.js

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
* Module dependencies.
1111
*/
1212

13-
var Stream = require('stream').Stream;
13+
var Readable = require('stream').Readable;
14+
var util = require('util');
1415

1516
/**
1617
* Initialize a `JPEGStream` with the given `canvas`.
@@ -30,33 +31,47 @@ var Stream = require('stream').Stream;
3031
*/
3132

3233
var JPEGStream = module.exports = function JPEGStream(canvas, options, sync) {
33-
var self = this
34-
, method = sync
34+
if (!(this instanceof JPEGStream)) {
35+
throw new TypeError("Class constructors cannot be invoked without 'new'");
36+
}
37+
38+
Readable.call(this);
39+
40+
var self = this;
41+
var method = sync
3542
? 'streamJPEGSync'
3643
: 'streamJPEG';
3744
this.options = options;
3845
this.sync = sync;
3946
this.canvas = canvas;
40-
this.readable = true;
47+
4148
// TODO: implement async
4249
if ('streamJPEG' == method) method = 'streamJPEGSync';
50+
this.method = method;
51+
};
52+
53+
util.inherits(JPEGStream, Readable);
54+
55+
function noop() {}
56+
57+
JPEGStream.prototype._read = function _read() {
58+
// For now we're not controlling the c++ code's data emission, so we only
59+
// call canvas.streamJPEGSync once and let it emit data at will.
60+
this._read = noop;
61+
var self = this;
62+
var method = this.method;
63+
var bufsize = this.options.bufsize;
64+
var quality = this.options.quality;
65+
var progressive = this.options.progressive;
4366
process.nextTick(function(){
44-
canvas[method](options.bufsize, options.quality, options.progressive, function(err, chunk){
67+
self.canvas[method](bufsize, quality, progressive, function(err, chunk){
4568
if (err) {
4669
self.emit('error', err);
47-
self.readable = false;
4870
} else if (chunk) {
49-
self.emit('data', chunk);
71+
self.push(chunk);
5072
} else {
51-
self.emit('end');
52-
self.readable = false;
73+
self.push(null);
5374
}
5475
});
5576
});
5677
};
57-
58-
/**
59-
* Inherit from `EventEmitter`.
60-
*/
61-
62-
JPEGStream.prototype.__proto__ = Stream.prototype;

lib/pdfstream.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
* Module dependencies.
99
*/
1010

11-
var Stream = require('stream').Stream;
11+
var Readable = require('stream').Readable;
12+
var util = require('util');
1213

1314
/**
1415
* Initialize a `PDFStream` with the given `canvas`.
@@ -28,32 +29,42 @@ var Stream = require('stream').Stream;
2829
*/
2930

3031
var PDFStream = module.exports = function PDFStream(canvas, sync) {
32+
if (!(this instanceof PDFStream)) {
33+
throw new TypeError("Class constructors cannot be invoked without 'new'");
34+
}
35+
36+
Readable.call(this);
37+
3138
var self = this
3239
, method = sync
3340
? 'streamPDFSync'
3441
: 'streamPDF';
3542
this.sync = sync;
3643
this.canvas = canvas;
37-
this.readable = true;
44+
3845
// TODO: implement async
3946
if ('streamPDF' == method) method = 'streamPDFSync';
47+
this.method = method;
48+
};
49+
50+
util.inherits(PDFStream, Readable);
51+
52+
function noop() {}
53+
54+
PDFStream.prototype._read = function _read() {
55+
// For now we're not controlling the c++ code's data emission, so we only
56+
// call canvas.streamPDFSync once and let it emit data at will.
57+
this._read = noop;
58+
var self = this;
4059
process.nextTick(function(){
41-
canvas[method](function(err, chunk, len){
60+
self.canvas[self.method](function(err, chunk, len){
4261
if (err) {
4362
self.emit('error', err);
44-
self.readable = false;
4563
} else if (len) {
46-
self.emit('data', chunk, len);
64+
self.push(chunk);
4765
} else {
48-
self.emit('end');
49-
self.readable = false;
66+
self.push(null);
5067
}
5168
});
5269
});
5370
};
54-
55-
/**
56-
* Inherit from `EventEmitter`.
57-
*/
58-
59-
PDFStream.prototype.__proto__ = Stream.prototype;

lib/pngstream.js

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
* Module dependencies.
1111
*/
1212

13-
var Stream = require('stream').Stream;
13+
var Readable = require('stream').Readable;
14+
var util = require('util');
1415

1516
/**
1617
* Initialize a `PNGStream` with the given `canvas`.
@@ -30,32 +31,59 @@ var Stream = require('stream').Stream;
3031
*/
3132

3233
var PNGStream = module.exports = function PNGStream(canvas, sync) {
33-
var self = this
34-
, method = sync
34+
if (!(this instanceof PNGStream)) {
35+
throw new TypeError("Class constructors cannot be invoked without 'new'");
36+
}
37+
38+
Readable.call(this);
39+
40+
var self = this;
41+
var method = sync
42+
? 'streamPNGSync'
43+
: 'streamPNG';
44+
this.sync = sync;
45+
this.canvas = canvas;
46+
47+
// TODO: implement async
48+
if ('streamPNG' === method) method = 'streamPNGSync';
49+
this.method = method;
50+
};
51+
52+
util.inherits(PNGStream, Readable);
53+
54+
var PNGStream = module.exports = function PNGStream(canvas, sync) {
55+
Readable.call(this);
56+
57+
var self = this;
58+
var method = sync
3559
? 'streamPNGSync'
3660
: 'streamPNG';
3761
this.sync = sync;
3862
this.canvas = canvas;
39-
this.readable = true;
63+
4064
// TODO: implement async
41-
if ('streamPNG' == method) method = 'streamPNGSync';
65+
if ('streamPNG' === method) method = 'streamPNGSync';
66+
this.method = method;
67+
};
68+
69+
util.inherits(PNGStream, Readable);
70+
71+
function noop() {}
72+
73+
PNGStream.prototype._read = function _read() {
74+
// For now we're not controlling the c++ code's data emission, so we only
75+
// call canvas.streamPNGSync once and let it emit data at will.
76+
this._read = noop;
77+
var self = this;
4278
process.nextTick(function(){
43-
canvas[method](function(err, chunk, len){
79+
self.canvas[self.method](function(err, chunk, len){
4480
if (err) {
4581
self.emit('error', err);
46-
self.readable = false;
4782
} else if (len) {
48-
self.emit('data', chunk, len);
83+
self.push(chunk);
4984
} else {
50-
self.emit('end');
51-
self.readable = false;
85+
self.push(null);
5286
}
5387
});
5488
});
5589
};
56-
57-
/**
58-
* Inherit from `EventEmitter`.
59-
*/
60-
61-
PNGStream.prototype.__proto__ = Stream.prototype;

src/Canvas.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ NAN_METHOD(Canvas::StreamPNGSync) {
456456
Nan::Null()
457457
, Nan::Null()
458458
, Nan::New<Uint32>(0) };
459-
Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local<v8::Function>)closure.fn, 1, argv);
459+
Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local<v8::Function>)closure.fn, 3, argv);
460460
}
461461
return;
462462
}

test/canvas.test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ var Canvas = require('../')
66
, assert = require('assert')
77
, parseFont = Canvas.Context2d.parseFont
88
, fs = require('fs')
9-
, os = require('os');
9+
, os = require('os')
10+
, Readable = require('stream').Readable;
1011

1112
console.log();
1213
console.log(' canvas: %s', Canvas.version);
@@ -886,6 +887,7 @@ describe('Canvas', function () {
886887
it('Canvas#createSyncPNGStream()', function (done) {
887888
var canvas = new Canvas(20, 20);
888889
var stream = canvas.createSyncPNGStream();
890+
assert(stream instanceof Readable);
889891
var firstChunk = true;
890892
stream.on('data', function(chunk){
891893
if (firstChunk) {
@@ -904,6 +906,7 @@ describe('Canvas', function () {
904906
it('Canvas#createSyncPDFStream()', function (done) {
905907
var canvas = new Canvas(20, 20, 'pdf');
906908
var stream = canvas.createSyncPDFStream();
909+
assert(stream instanceof Readable);
907910
var firstChunk = true;
908911
stream.on('data', function (chunk) {
909912
if (firstChunk) {
@@ -922,6 +925,7 @@ describe('Canvas', function () {
922925
it('Canvas#jpegStream()', function (done) {
923926
var canvas = new Canvas(640, 480);
924927
var stream = canvas.jpegStream();
928+
assert(stream instanceof Readable);
925929
var firstChunk = true;
926930
var bytes = 0;
927931
stream.on('data', function(chunk){

0 commit comments

Comments
 (0)