123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- "use strict";
- var bodec = require('bodec');
- var PACK = bodec.fromRaw("PACK");
- module.exports = {
- deframer: deframer,
- framer: framer
- };
- function deframer(emit) {
- var state = 0;
- var offset = 4;
- var length = 0;
- var data;
- var more = true;
- return function (item) {
- // Forward the EOS marker
- if (item === undefined) return emit();
- // Once we're in pack mode, everything goes straight through
- if (state === 3) return emit(item);
- // Otherwise parse the data using a state machine.
- for (var i = 0, l = item.length; i < l; i++) {
- var byte = item[i];
- if (state === 0) {
- var val = fromHexChar(byte);
- if (val === -1) {
- if (byte === PACK[0]) {
- offset = 1;
- state = 2;
- continue;
- }
- state = -1;
- throw new SyntaxError("Not a hex char: " + String.fromCharCode(byte));
- }
- length |= val << ((--offset) * 4);
- if (offset === 0) {
- if (length === 4) {
- offset = 4;
- more = emit("");
- }
- else if (length === 0) {
- offset = 4;
- more = emit(null);
- }
- else if (length > 4) {
- length -= 4;
- data = bodec.create(length);
- state = 1;
- }
- else {
- state = -1;
- throw new SyntaxError("Invalid length: " + length);
- }
- }
- }
- else if (state === 1) {
- data[offset++] = byte;
- if (offset === length) {
- offset = 4;
- state = 0;
- length = 0;
- if (data[0] === 1) {
- more = emit(bodec.slice(data, 1));
- }
- else if (data[0] === 2) {
- more = emit({progress: bodec.toUnicode(data, 1)});
- }
- else if (data[0] === 3) {
- more = emit({error: bodec.toUnicode(data, 1)});
- }
- else {
- more = emit(bodec.toUnicode(data).trim());
- }
- }
- }
- else if (state === 2) {
- if (offset < 4 && byte === PACK[offset++]) {
- continue;
- }
- state = 3;
- more = emit(bodec.join([PACK, bodec.subarray(item, i)]));
- break;
- }
- else {
- throw new Error("pkt-line decoder in invalid state");
- }
- }
- return more;
- };
- }
- function framer(emit) {
- return function (item) {
- if (item === undefined) return emit();
- if (item === null) {
- return emit(bodec.fromRaw("0000"));
- }
- if (typeof item === "string") {
- item = bodec.fromUnicode(item);
- }
- return emit(bodec.join([frameHead(item.length + 4), item]));
- };
- }
- function frameHead(length) {
- var buffer = bodec.create(4);
- buffer[0] = toHexChar(length >>> 12);
- buffer[1] = toHexChar((length >>> 8) & 0xf);
- buffer[2] = toHexChar((length >>> 4) & 0xf);
- buffer[3] = toHexChar(length & 0xf);
- return buffer;
- }
- function fromHexChar(val) {
- return (val >= 0x30 && val < 0x40) ? val - 0x30 :
- ((val > 0x60 && val <= 0x66) ? val - 0x57 : -1);
- }
- function toHexChar(val) {
- return val < 0x0a ? val + 0x30 : val + 0x57;
- }
|