npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

split-frames

v2.5.1

Published

Split Buffer frames from streams

Downloads

186

Readme

split-frames

Split Buffer frames from streams

Build Status Coverage Status Dependency Status Dev dependency Status Issues Pull requests

Installation

$ npm install split-frames

Doc

Works very well with, for example, serialport for industrial protocols like Concert

/!\ this version only split frames properly, and does not remove start & end tags or escape bits anymore.

Methods

  • inherited from stream.Transform
  • constructor ([ options: object ]): split-frames instance

Options

All these options are optionnal

type ControlBits = "none" | "end+1" | "end+2";
type Tag: number | Buffer | Array< number | Buffer >
  • javascript "startWith": Tag
  • javascript "startTimeout": integer (default: 200)
  • javascript "endWith": Tag
  • javascript "escapeWith": number
  • javascript "escaped": Array<number>
  • javascript "specifics": object
  • javascript "controlBits": ControlBits (default: "none")

"startTimeout" is a timeout (in milliseconds) which end frame in "start only" mode, if no second "start" bit is encountered after the first one

"specifics" is a [ key: string => value: Tag ] object which fire a "key" event when a "value" tag is found out of the message and not escaped ex : { "specifics": { "nak": 0x25 } } will fire an "nak" event when 0x25 bit is encountered

Examples

In the following exemples, "Splitter" and "Readable" classes are defined like that :

// typescript
import Splitter = require("split-frames");
import { Readable } from "stream";
// javascript
const Splitter = require("split-frames");
const { Readable } = require("stream");

The "createReadStream" function is defined like that :

function createReadStream () {
	return new Readable({
		read () { }
	});
}

And the "STX", "DLE" and "ETX" constants are defined like that :

const STX = 0x02, ETX = 0x03, DLE = 0x10, ACK = 0x06, NAK = 0x15, WAK = 0x13;

want to split frames content on a start bit ?

const stream = createReadStream();

stream.pipe(new Splitter({
	"startWith": STX
})).on("data", (chunk) => {
	// Buffer([ STX, 0x24, 0x25, 0x26 ])
	// Buffer([ STX, 0x24, 0x25 ])
});

stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, STX, 0x24 ]));
stream.push(Buffer.from([ 0x25, STX ]));

prefere an end bit ?

const stream = createReadStream();

stream.pipe(new Splitter({
	"endWith": ETX
})).on("data", (chunk) => {
	// Buffer([ 0x24, 0x25, 0x26, ETX ])
	// Buffer([ 0x24, 0x25, ETX ])
});

stream.push(Buffer.from([ 0x24, 0x25, 0x26, ETX, 0x24, 0x25 ]));
stream.push(Buffer.from([ ETX ]));

want both ?

const stream = createReadStream();

stream.pipe(new Splitter({
	"startWith": STX, "endWith": ETX
})).on("data", (chunk) => {
	// Buffer([ STX, 0x24, 0x25, 0x26, ETX ])
	// Buffer([ STX, 0x24, 0x25, ETX ])
});

stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, ETX, 0x24, 0x25, STX ]));
stream.push(Buffer.from([ 0x24, 0x25, ETX ]));

what about two end bits (works with start one as well) ?

const stream = createReadStream();

stream.pipe(new Splitter({
	"startWith": STX, "endWith": Buffer.from([ DLE, ETX ])
})).on("data", (chunk) => {
	// Buffer([ STX, 0x24, 0x25, 0x26, DLE, ETX ])
});

stream.push(Buffer.from([ 0x20, STX, 0x24, 0x25, 0x26, DLE, ETX, STX, 0x24, 0x25 ]));

Do you need to parse escaped bits ?

const stream = createReadStream();

stream.pipe(new Splitter({
	"startWith": STX, "endWith": ETX,
	"escapeWith": DLE, "escaped": [ DLE, STX, ETX ]
})).on("data", (chunk) => {
	// Buffer([ STX, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
});

stream.push(Buffer.from([ 0x20, STX, 0x24, DLE, STX, 0x25, 0x26 ]));
stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, STX, 0x24, 0x25 ]));

And what do you think about multiple start (or end !) bits possibilities ?

For even parity in seriaport, for example

const STX2 = 0x82;
const stream = createReadStream();

stream.pipe(new Splitter({
	"startWith": [ STX, STX2 ], "endWith": ETX,
	"escapeWith": DLE, "escaped": [ DLE, STX, ETX ]
})).on("data", (chunk) => {
	// Buffer([ STX, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
	// Buffer([ STX2, 0x24, DLE, STX, 0x25, 0x26, DLE, DLE, 0x27, DLE, ETX, 0x28, ETX ])
});

stream.push(Buffer.from([ 0x24, STX, 0x24, DLE, STX, 0x25, ACK ]));
stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, ACK, 0x24, 0x25 ]));
stream.push(Buffer.from([ STX2, 0x24, DLE, STX, 0x25, ACK ]));
stream.push(Buffer.from([ DLE, DLE, 0x27, DLE, ETX, 0x28, ETX, ACK, 0x24, 0x25 ]));

Want to extract specific tags ?

positive acknowledgement, negative acknowledgement, waiting for acknowledgement, whatever... only with no tags || start AND end tags || end tags (for firsts bits)

const stream = createReadStream();

stream.pipe(new Splitter({
	"startWith": STX, "endWith": ETX,
	"specifics": {
		"ack": ACK, "nak": NAK, "wak": WAK, "whatever": 0x51
	},
	"escapeWith": DLE, "escaped": [ DLE, ACK, NAK, WAK ]
})).on("ack", () => {
	console.log("ack received"); // (only 1x) -> good, escaped, in data
}).on("nak", () => {
	console.log("nak received"); // (only 1x) -> in data, good, escaped
}).on("wak", () => {
	console.log("wak received"); // (only 1x) -> in data, good, escaped
}).on("whatever", () => {
	console.log("whatever received"); // (only 1x)
}).on("data", (chunk) => {
	// Buffer([ STX, 0x20, 0x21, 0x22, ACK, NAK, WAK, 0x23, ETX ]) (x1)
});

stream.push(Buffer.from([ 0x51, 0x24, ACK, DLE, ACK, STX, 0x20, 0x21, 0x22, ACK, NAK, WAK ]));
stream.push(Buffer.from([ 0x23, ETX, NAK, DLE, NAK, WAK, DLE, WAK, 0x20, 0x21 ]));

Want to use control bits ?

used to compute LRC, MSB, LSB, etc... this example is for a structure like STX ETX LRC, where LRC compute all bits


function _computeLRC (frame) {

	let lrc = 0x00;

		for (let i = 0; i < frame.length; ++i) {
			lrc ^= frame[i];
		}

	return lrc;

}

const stream = createReadStream();

stream.pipe(new Splitter({
	"startWith": STX, "endWith": ETX,
	"controlBits": "end+1"
})).on("data", (chunk) => {

	// Buffer([ STX, 0x20, 0x21, 0x22, 0x24, ETX, 0x07 ]) (x1)

	const data = chunk.slice(1, chunk.length - 2); // Buffer([ 0x20, 0x21, 0x22, 0x24 ])
	const LRC = chunk[chunk.length - 1];

	if (_computeLRC(data) === LRC) {
		console.log("OK");
	}
	else {
		console.error(new Error("not well-computed data :" + data.toString("hex") + "|" + Buffer.from([ LRC ]).toString("hex")));
	}

});

stream.push(Buffer.from([ 0x51, 0x24, STX, 0x20, 0x21, 0x22, 0x24, ETX, 0x07, 0x24 ]));

Tests

$ npm run-script tests

License

ISC