From 0760d17d820c8cfd49bf2907b735295f5776e5c8 Mon Sep 17 00:00:00 2001 From: Paul Melnikow Date: Wed, 5 Apr 2017 22:40:47 -0400 Subject: [PATCH] Return data from svg2img via callback Given the chunks coming from imagemagick are getting stored memory and then tucked into a cache, this function could as easily return a buffer via callback. Streaming is just making it more complex. (And trickier to test!) --- gh-badge.js | 4 +++- lib/svg-to-img.js | 31 ++++++++----------------------- package.json | 1 - server.js | 4 +++- test/svg-to-img.spec.js | 18 ++++++------------ 5 files changed, 20 insertions(+), 38 deletions(-) diff --git a/gh-badge.js b/gh-badge.js index 95be6eb..92e8319 100755 --- a/gh-badge.js +++ b/gh-badge.js @@ -62,7 +62,9 @@ if (color[0] === ':') { badge(badgeData, function produceOutput(svg) { if (/png|jpg|gif/.test(format)) { - svg2img(svg, format, process.stdout); + svg2img(svg, format, function (data) { + process.stdout.write(data); + }); } else { console.log(svg); } diff --git a/lib/svg-to-img.js b/lib/svg-to-img.js index 266d86a..365a0fd 100644 --- a/lib/svg-to-img.js +++ b/lib/svg-to-img.js @@ -6,12 +6,12 @@ var imageMagick = gm.subClass({ imageMagick: true }); // The following is an arbitrary limit (~1.5MB, 1.5kB/image). var imgCache = new LruCache(1000); -module.exports = function (svg, format, out, cb) { +module.exports = function (svg, format, callback) { var cacheIndex = format + svg; if (imgCache.has(cacheIndex)) { // We own a cache for this svg conversion. - (new DataStream(imgCache.get(cacheIndex))).pipe(out); - cb && cb(); + var result = imgCache.get(cacheIndex); + callback(result); return; } @@ -24,28 +24,13 @@ module.exports = function (svg, format, out, cb) { if (err) { console.error(err); return; } var chunks = []; stdout.on('data', function(chunk) { chunks.push(chunk); }); - stdout.on('end', function() { imgCache.set(cacheIndex, chunks); }); - stdout.pipe(out); + stdout.on('finish', function() { + var result = Buffer.concat(chunks); + imgCache.set(cacheIndex, result); + callback(result); + }); }); }; // To simplify testing. module.exports._imgCache = imgCache; - -// Fake stream from the cache. -var Readable = require('stream').Readable; -var util = require('util'); -function DataStream(data) { - Readable.call(this); - this.data = data; - this.i = 0; -} -util.inherits(DataStream, Readable); -DataStream.prototype._read = function() { - while (this.i < this.data.length) { - var keepPushing = this.push(this.data[this.i]); - this.i++; - if (!keepPushing) { return; } - } - this.push(null); -}; diff --git a/package.json b/package.json index 72897b2..2774291 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "eslint": "^3.18.0", "is-png": "^1.0.0", "is-svg": "^2.1.0", - "memory-streams": "^0.1.2", "mocha": "^3.2.0", "sinon": "^2.1.0" } diff --git a/server.js b/server.js index b091fcf..271f4ba 100644 --- a/server.js +++ b/server.js @@ -6127,7 +6127,9 @@ function sendSVG(res, askres, end) { function sendOther(format, res, askres, end) { askres.setHeader('Content-Type', 'image/' + format); - svg2img(res, format, askres); + svg2img(res, format, function (data) { + end(null, {template: streamFromString(data)}); + }); } function sendJSON(res, askres, end) { diff --git a/test/svg-to-img.spec.js b/test/svg-to-img.spec.js index 3740518..2b19f92 100644 --- a/test/svg-to-img.spec.js +++ b/test/svg-to-img.spec.js @@ -1,6 +1,5 @@ const assert = require('assert'); const sinon = require('sinon'); -const WritableStream = require('memory-streams').WritableStream; const isPng = require('is-png'); const badge = require('../lib/badge'); @@ -13,10 +12,8 @@ describe('The rasterizer', function () { it('should produce PNG', function(done) { badge({ text: ['cactus', 'grown'], format: 'svg' }, svg => { - const out = new WritableStream(); - - svg2img(svg, 'png', out, () => { - assert.ok(isPng(out.toBuffer())); + svg2img(svg, 'png', data => { + assert.ok(isPng(data)); done(); }); }); @@ -24,15 +21,12 @@ describe('The rasterizer', function () { it('should cache its results', function(done) { badge({ text: ['will-this', 'be-cached?'], format: 'svg' }, svg => { - const out1 = new WritableStream(); - const out2 = new WritableStream(); - - svg2img(svg, 'png', out1, () => { - assert.ok(isPng(out1.toBuffer())); + svg2img(svg, 'png', data1 => { + assert.ok(isPng(data1)); assert.equal(cacheGet.called, false); - svg2img(svg, 'png', out2, () => { - assert.ok(isPng(out2.toBuffer())); + svg2img(svg, 'png', data2 => { + assert.ok(isPng(data2)); assert.ok(cacheGet.calledOnce); done();