diff --git a/parsers/cbor/70-cbor.html b/parsers/cbor/70-cbor.html new file mode 100644 index 00000000..8367e80e --- /dev/null +++ b/parsers/cbor/70-cbor.html @@ -0,0 +1,44 @@ + + + + + + diff --git a/parsers/cbor/70-cbor.js b/parsers/cbor/70-cbor.js new file mode 100644 index 00000000..abed6dbf --- /dev/null +++ b/parsers/cbor/70-cbor.js @@ -0,0 +1,38 @@ + +module.exports = function(RED) { + "use strict"; + var cbor = require('cbor-x'); + + function CborNode(n) { + RED.nodes.createNode(this,n); + this.property = n.property||"payload"; + var node = this; + this.on("input", function(msg) { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + if (Buffer.isBuffer(value)) { + var l = value.length; + try { + value = cbor.decode(value); + RED.util.setMessageProperty(msg,node.property,value); + node.send(msg); + node.status({text:l +" b->o "+ JSON.stringify(value).length}); + } + catch (e) { + node.error("Bad decode",msg); + node.status({text:"not a cbor buffer"}); + } + } + else { + var le = JSON.stringify(value).length; + value = cbor.encode(value); + RED.util.setMessageProperty(msg,node.property,value); + node.send(msg); + node.status({text:le +" o->b "+ value.length}); + } + } + else { node.warn("No payload found to process"); } + }); + } + RED.nodes.registerType("cbor",CborNode); +} diff --git a/parsers/cbor/LICENSE b/parsers/cbor/LICENSE new file mode 100644 index 00000000..f5b60114 --- /dev/null +++ b/parsers/cbor/LICENSE @@ -0,0 +1,14 @@ +Copyright 2016 JS Foundation and other contributors, https://js.foundation/ +Copyright 2013-2016 IBM Corp. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/parsers/cbor/README.md b/parsers/cbor/README.md new file mode 100644 index 00000000..d0c7fbf9 --- /dev/null +++ b/parsers/cbor/README.md @@ -0,0 +1,27 @@ +node-red-node-cbor +================== + +A Node-RED node to pack and unpack objects to cbor format buffers. + +Install +------- + +Run the following command in your Node-RED user directory - typically `~/.node-red` + + npm install node-red-node-cbor + +Changes +------- + +Version 1.0.0 - move to cbor-x library (more supported and faster). +Usage +----- + +Uses the cbor-x npm to pack and unpack msg.payload objects to cbor format buffers. + +**Note**: this node does not currently encode raw buffer types. +It will automatically try to *decode* any buffer received, and may not cause an error. + +If the input is NOT a buffer it converts it into a msgpack buffer. + +If the input is a msgpack buffer it converts it back to the original type. diff --git a/parsers/cbor/icons/parser-cbor.png b/parsers/cbor/icons/parser-cbor.png new file mode 100644 index 00000000..02b5ddc0 Binary files /dev/null and b/parsers/cbor/icons/parser-cbor.png differ diff --git a/parsers/cbor/package.json b/parsers/cbor/package.json new file mode 100644 index 00000000..eb0534c2 --- /dev/null +++ b/parsers/cbor/package.json @@ -0,0 +1,28 @@ +{ + "name" : "node-red-node-cbor", + "version" : "1.0.0", + "description" : "A Node-RED node to pack and unpack objects to cbor format", + "dependencies" : { + "cbor-x" : "^1.3.2" + }, + "bundledDependencies": [ + "cbor-x" + ], + "repository" : { + "type":"git", + "url":"https://github.com/node-red/node-red-nodes.git", + "directory": "tree/master/parsers/cbor" + }, + "license": "Apache-2.0", + "keywords": [ "node-red", "cbor" ], + "node-red" : { + "nodes" : { + "cbor": "70-cbor.js" + } + }, + "author": { + "name": "Dave Conway-Jones", + "email": "dceejay@gmail.com", + "url": "http://nodered.org" + } +} diff --git a/test/parsers/cbor/70-cbor_spec.js b/test/parsers/cbor/70-cbor_spec.js new file mode 100644 index 00000000..bcebe91c --- /dev/null +++ b/test/parsers/cbor/70-cbor_spec.js @@ -0,0 +1,101 @@ + +var should = require("should"); +var helper = require("node-red-node-test-helper"); +var testNode = require('../../../parsers/cbor/70-cbor.js'); + +describe('cbor node', function() { + "use strict"; + + beforeEach(function(done) { + helper.startServer(done); + }); + + afterEach(function(done) { + helper.unload().then(function() { + helper.stopServer(done); + }); + }); + + it("should be loaded with correct defaults", function(done) { + var flow = [{"id":"n1", "type":"cbor", "name":"cbor1", "wires":[[]]}]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property("name", "cbor1"); + done(); + }); + }); + + var buf; + + it('should pack an object', function(done) { + var flow = [{"id":"n1", "type":"cbor", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.a.property("payload"); + msg.payload.should.be.a.Object; + msg.payload.should.have.length(47); + buf = msg.payload; + done(); + }); + n1.emit("input", {payload:{A:1, B:"string", C:true, D:[1,true,"string"], E:{Y:9,Z:"string"}}}); + }); + }); + + it('should unpack a Buffer', function(done) { + var flow = [{"id":"n1", "type":"cbor", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.a.property("payload"); + msg.payload.should.have.a.property("A",1); + msg.payload.should.have.a.property("B",'string'); + msg.payload.should.have.a.property("C",true); + msg.payload.should.have.a.property("D",[1,true,"string"]); + msg.payload.should.have.a.property("E"); + msg.payload.E.should.have.a.property("Y",9); + msg.payload.E.should.have.a.property("Z","string"); + done(); + }); + n1.emit("input", {payload:buf}); + }); + }); + + it('should error if the buffer fails to decode', function(done) { + buf[0] = 0x87; + var flow = [{"id":"n1", "type":"cbor", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + done("should not get here if there is an error."); + }); + setTimeout(function() { + done(); + }, 25); + n1.emit("input", {payload:buf}); + }); + }); + + it('ignore msg with no payload', function(done) { + var flow = [{"id":"n1", "type":"cbor", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + done("should not get here with no payload."); + }); + setTimeout(function() { + done(); + }, 25); + n1.emit("input", {topic:1}); + }); + }); + +});