Example #1
0
function parseHead(buffer) {
  // Parses and returns the first type on the buffer and the total bytes consumed
  var type = bops.readUInt8(buffer, 0);
  // Nullary
  if (~nullaryTypes.indexOf(type)) return [ decode(bops.from([ type ])), 1 ];
  // Fixed
  var size = fixedTypes[type];
  if (size++) return [ decode(bops.subarray(buffer, 0, size)), size ];
  // Flat
  var index;
  var end;
  if (~flatTypes.indexOf(type)) {
    // Find end byte
    for (index = 1, end = buffer.length; index < end; ++index) {
      if (bops.readUInt8(buffer, index) === 0x00) break;
    }
    if (index >= buffer.length) throw new Error('No ending byte found for list');
    var chunk = flatUnescape(bops.subarray(buffer, 0, index));
    // Add 1 to index to skip over end byte
    return [ decode(chunk), index + 1 ];
  }
  // Nested, recurse for each item
  var list = [];
  index = 1;
  var next;

  while ((next = bops.readUInt8(buffer, index)) !== 0) {
    var result = parseHead(bops.subarray(buffer, index));
    list.push(bops.readUInt8(result, 0));
    index += bops.readUInt8(result, 1);
    if (index >= buffer.length) throw new Error('No ending byte found for nested list');
  }
  return [ structure(type, list), index + 1 ];
}
Example #2
0
// TODO expose in public API
function flatUnescape(buffer) {
  var b, bytes = [];
  // Don't escape last byte
  for (var i = 0, end = buffer.length; i < end; ++i) {
    b = bops.readUInt8(buffer, i);
    // If low-byte escape tag use the following byte minus 1
    if (b === 0x01) bytes.push(bops.readUInt8(buffer, ++i) - 1);
    // If high-byte escape tag use the following byte plus 1
    else if (b === 0xfe) bytes.push(bops.readUInt8(buffer, ++i) + 1);
    // Otherwise no unescapement needed
    else bytes.push(b);
  }
  return bops.from(bytes);
}
Example #3
0
function invert(buffer) {
  var bytes = [];
  for (var i = 0, end = buffer.length; i < end; ++i) {
    bytes.push(~bops.readUInt8(buffer, i));
  }
  return bops.from(bytes);
}
Example #4
0
parser.header = function(buf, packet) {
  var zero = bops.readUInt8(buf, 0);
  packet.cmd = protocol.types[zero >> protocol.CMD_SHIFT];
  packet.retain = (zero & protocol.RETAIN_MASK) !== 0;
  packet.qos = (zero >> protocol.QOS_SHIFT) & protocol.QOS_MASK;
  packet.dup = (zero & protocol.DUP_MASK) !== 0;
  return packet;
};
Example #5
0
function decode(buffer) {

  var type = bops.readUInt8(buffer, 0);

  // Nullary types
  if (~nullaryTypes.indexOf(type)) {
    if (buffer.length !== 1) throw new Error('Invalid encoding in buffer: ' + buffer);

    if (type === UNDEFINED) return;
    if (type === NULL) return null;
    if (type === FALSE) return false;
    if (type === TRUE) return true;
    if (type === NEGATIVE_INFINITY) return Number.NEGATIVE_INFINITY;
    if (type === POSITIVE_INFINITY) return Number.POSITIVE_INFINITY;
  }

  // Fixed size types
  var chunk = bops.subarray(buffer, 1);
  var chunkSize = fixedTypes[type];
  if (chunkSize) {
    if (chunk.length !== chunkSize) throw new Error('Invalid size for buffer: ' + buffer);

    if (type === NEGATIVE_NUMBER || type === POSITIVE_NUMBER) {
      return decodeNumber(chunk, type === NEGATIVE_NUMBER);
    }
    if (type === DATE_PRE_EPOCH || type === DATE_POST_EPOCH) {
      return new Date(decodeNumber(chunk, type === DATE_PRE_EPOCH));
    }
  }

  // Flat types
  if (type === BUFFER) return chunk;
  if (type === STRING) return bops.to(chunk, 'utf8');

  // Structured types
  if (~structuredTypes.indexOf(type)) {
    var result = parseHead(buffer);
    if (bops.readUInt8(result, 1) !== buffer.length) {
      throw new Error('List deserialization fail: ' + bops.readUInt8(result, 1) + '!=' + bops.length(buffer));
    }
    return bops.readUInt8(result, 0);
  }

}
test('from array works', function(assert) {
  var arr = [1, 2, 3]
    , buf = bops.from(arr)

  assert.equal(buf.length, arr.length)
  for(var i = 0, len = arr.length; i < len; ++i) {
    assert.equal(bops.readUInt8(buf, i), arr[i])
  }
  assert.end()
})
test('from base64 works as expected', function(assert) {
  var buf = bops.from('aGVsbG8gd29ybGTGkgAKCAk=', 'base64')
    , expect

  expect = [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 198, 146, 0, 10, 8, 9]

  assert.equal(buf.length, expect.length)
  for(var i = 0, len = buf.length; i < len; ++i) {
    assert.equal(bops.readUInt8(buf, i), expect[i])
  }

  assert.end()
})
test('from hex works as expected', function(assert) {
  var buf = bops.from('68656c6c6f20776f726c64c692000a0809', 'hex')
    , expect

  expect = [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 198, 146, 0, 10, 8, 9]

  assert.equal(buf.length, expect.length)
  for(var i = 0, len = buf.length; i < len; ++i) {
    assert.equal(bops.readUInt8(buf, i), expect[i])
  }

  assert.end()
})
test('from utf8 works as expected', function(assert) {
  var buf = bops.from('ƒello 淾淾淾 hello world 淾淾 yep ƒuu 淾 \ud83d\ude04', 'utf8')
    , expect

  expect = [198,146,101,108,108,111,32,230,183,190,230,183,190,230,183,190,32,104,101,108,108,111,32,119,111,114,108,100,32,230,183,190,230,183,190,32,121,101,112,32,198,146,117,117,32,230,183,190,32,0xF0,0x9F,0x98,0x84]

  assert.equal(buf.length, expect.length)
  for(var i = 0, len = buf.length; i < len; ++i) {
    assert.equal(bops.readUInt8(buf, i), expect[i])
  }

  assert.end()
})
Example #10
0
Connection.prototype._parseLength = function() {
  var result = true, data = this.data, readByte;

  if (this.packet.length === undefined) {

    if (data.length <= this.index) {
      result = false;
    } else {

      readByte = bops.readUInt8(data, this.index++);

      while (this.tmp.pos++ < 4) {
        this.tmp.length += 
          this.tmp.mul * (readByte & protocol.LENGTH_MASK);
        this.tmp.mul *= 0x80;

        if ((readByte & protocol.LENGTH_FIN_MASK) === 0) {
          break;
        }

        if (data.length <= this.index) {
          result = false;
          break;
        }

        readByte = bops.readUInt8(data, this.index++);
      }

      if (result) {
        this.packet.length = this.tmp.length;
      }
    }
  }

  return result;
};
Example #11
0
function encodeList(items) {
  // TODO pass around a map of references already encoded to detect cycles
  var buffers = [];
  var chunk;
  for (var i = 0, end = items.length; i < end; ++i) {
    chunk = encode(items[i]);
    var type = bops.readUInt8(chunk, 0);
    // We need to escape a few bytes in string and buffer types to prevent confusion with the end byte
    if (~flatTypes.indexOf(type)) chunk = flatEscape(chunk);
    buffers.push(chunk);
  }
  // Close the list with an end byte
  buffers.push(bops.create([ 0 ]));
  return bops.join(buffers);
}
Example #12
0
parser.connect = function(buf, packet) {
  parser._pos = 0;
  parser._len = buf.length;

  var protocolId // Protocol id
    , clientId // Client id
    , topic // Will topic
    , payload // Will payload
    , password // Password
    , username // Username
    , flags = {};
  
  // Parse protocol id
  protocolId = parser.parse_string(buf);
  if (protocolId === null) return new Error('Parse error - cannot parse protocol id');
  packet.protocolId = protocolId;

  // Parse protocol version number
  if(parser._pos > parser._len) return null;
  packet.protocolVersion = bops.readUInt8(buf, parser._pos);
  parser._pos += 1;
  
  // Parse connect flags
  flags.username = (bops.readUInt8(buf, parser._pos) & protocol.USERNAME_MASK);
  flags.password = (bops.readUInt8(buf, parser._pos) & protocol.PASSWORD_MASK);
  flags.will = (bops.readUInt8(buf, parser._pos) & protocol.WILL_FLAG_MASK);
  
  if(flags.will) {
    packet.will = {};
    packet.will.retain = (bops.readUInt8(buf, parser._pos) & protocol.WILL_RETAIN_MASK) !== 0;
    packet.will.qos = (bops.readUInt8(buf, parser._pos) & protocol.WILL_QOS_MASK) >> protocol.WILL_QOS_SHIFT;
  }
  
  packet.clean = (bops.readUInt8(buf, parser._pos) & protocol.CLEAN_SESSION_MASK) !== 0;
  parser._pos += 1;
  
  // Parse keepalive
  packet.keepalive = this.parse_num(buf);
  if(packet.keepalive === null) return null;
  
  // Parse client ID
  clientId = this.parse_string(buf);
  if(clientId === null) return new Error('Parse error - cannot parse client id');
  packet.clientId = clientId;

  if(flags.will) {
    // Parse will topic
    topic = this.parse_string(buf);
    if(topic === null) return new Error('Parse error - cannot parse will topic');
    packet.will.topic = topic;

    // Parse will payload
    payload = this.parse_string(buf);
    if(payload === null) return new Error('Parse error - cannot parse will payload');
    packet.will.payload = payload;
  }
  
  // Parse username
  if(flags.username) {
    username = this.parse_string(buf);
    if(username === null) return new Error('Parse error - cannot parse username');
    packet.username = username;
  }
  
  // Parse password
  if(flags.password) {
    password = this.parse_string(buf);
    if(password === null) return ;
    packet.password = password;
  }
  
  return packet;
};
Example #13
0
Decoder.prototype.parse = function () {
  var type = this.buffer[this.offset];
  var value, length, extType;
  // Positive FixInt
  if ((type & 0x80) === 0x00) {
    this.offset++;
    return type;
  }
  // FixMap
  if ((type & 0xf0) === 0x80) {
    length = type & 0x0f;
    this.offset++;
    return this.map(length);
  }
  // FixArray
  if ((type & 0xf0) === 0x90) {
    length = type & 0x0f;
    this.offset++;
    return this.array(length);
  }
  // FixStr
  if ((type & 0xe0) === 0xa0) {
    length = type & 0x1f;
    this.offset++;
    return this.str(length);
  }
  // Negative FixInt
  if ((type & 0xe0) === 0xe0) {
    value = bops.readInt8(this.buffer, this.offset);
    this.offset++;
    return value;
  }
  switch (type) {
  // nil
  case 0xc0:
    this.offset++;
    return null;
  // 0xc1: (never used)
  // false
  case 0xc2:
    this.offset++;
    return false;
  // true
  case 0xc3:
    this.offset++;
    return true;
  // bin 8
  case 0xc4:
    length = bops.readUInt8(this.buffer, this.offset + 1);
    this.offset += 2;
    return this.bin(length);
  // bin 16
  case 0xc5:
    length = bops.readUInt16BE(this.buffer, this.offset + 1);
    this.offset += 3;
    return this.bin(length);
  // bin 32
  case 0xc6:
    length = bops.readUInt32BE(this.buffer, this.offset + 1);
    this.offset += 5;
    return this.bin(length);
  // ext 8
  case 0xc7:
    length = bops.readUInt8(this.buffer, this.offset + 1);
    extType = bops.readUInt8(this.buffer, this.offset + 2);
    this.offset += 3;
    return [extType, this.bin(length)];
  // ext 16
  case 0xc8:
    length = bops.readUInt16BE(this.buffer, this.offset + 1);
    extType = bops.readUInt8(this.buffer, this.offset + 3);
    this.offset += 4;
    return [extType, this.bin(length)];
  // ext 32
  case 0xc9:
    length = bops.readUInt32BE(this.buffer, this.offset + 1);
    extType = bops.readUInt8(this.buffer, this.offset + 5);
    this.offset += 6;
    return [extType, this.bin(length)];
  // float 32
  case 0xca:
    value = bops.readFloatBE(this.buffer, this.offset + 1);
    this.offset += 5;
    return value;
  // float 64 / double
  case 0xcb:
    value = bops.readDoubleBE(this.buffer, this.offset + 1);
    this.offset += 9;
    return value;
  // uint8
  case 0xcc:
    value = this.buffer[this.offset + 1];
    this.offset += 2;
    return value;
  // uint 16
  case 0xcd:
    value = bops.readUInt16BE(this.buffer, this.offset + 1);
    this.offset += 3;
    return value;
  // uint 32
  case 0xce:
    value = bops.readUInt32BE(this.buffer, this.offset + 1);
    this.offset += 5;
    return value;
  // uint64
  case 0xcf:
    value = bops.readUInt64BE(this.buffer, this.offset + 1);
    this.offset += 9;
    return value;
  // int 8
  case 0xd0:
    value = bops.readInt8(this.buffer, this.offset + 1);
    this.offset += 2;
    return value;
  // int 16
  case 0xd1:
    value = bops.readInt16BE(this.buffer, this.offset + 1);
    this.offset += 3;
    return value;
  // int 32
  case 0xd2:
    value = bops.readInt32BE(this.buffer, this.offset + 1);
    this.offset += 5;
    return value;
  // int 64
  case 0xd3:
    value = bops.readInt64BE(this.buffer, this.offset + 1);
    this.offset += 9;
    return value;

  // fixext 1 / undefined
  case 0xd4:
    extType = bops.readUInt8(this.buffer, this.offset + 1);
    value = bops.readUInt8(this.buffer, this.offset + 2);
    this.offset += 3;
    return (extType === 0 && value === 0) ? undefined : [extType, value];
  // fixext 2
  case 0xd5:
    extType = bops.readUInt8(this.buffer, this.offset + 1);
    this.offset += 2;
    return [extType, this.bin(2)];
  // fixext 4
  case 0xd6:
    extType = bops.readUInt8(this.buffer, this.offset + 1);
    this.offset += 2;
    return [extType, this.bin(4)];
  // fixext 8
  case 0xd7:
    extType = bops.readUInt8(this.buffer, this.offset + 1);
    this.offset += 2;
    return [extType, this.bin(8)];
  // fixext 16
  case 0xd8:
    extType = bops.readUInt8(this.buffer, this.offset + 1);
    this.offset += 2;
    return [extType, this.bin(16)];
  // str 8
  case 0xd9:
    length = bops.readUInt8(this.buffer, this.offset + 1);
    this.offset += 2;
    return this.str(length);
  // str 16
  case 0xda:
    length = bops.readUInt16BE(this.buffer, this.offset + 1);
    this.offset += 3;
    return this.str(length);
  // str 32
  case 0xdb:
    length = bops.readUInt32BE(this.buffer, this.offset + 1);
    this.offset += 5;
    return this.str(length);
  // array 16
  case 0xdc:
    length = bops.readUInt16BE(this.buffer, this.offset + 1);
    this.offset += 3;
    return this.array(length);
  // array 32
  case 0xdd:
    length = bops.readUInt32BE(this.buffer, this.offset + 1);
    this.offset += 5;
    return this.array(length);
  // map 16:
  case 0xde:
    length = bops.readUInt16BE(this.buffer, this.offset + 1);
    this.offset += 3;
    return this.map(length);
  // map 32
  case 0xdf:
    length = bops.readUInt32BE(this.buffer, this.offset + 1);
    this.offset += 5;
    return this.map(length);
  // buffer 16
  case 0xd8:
    length = bops.readUInt16BE(this.buffer, this.offset + 1);
    this.offset += 3;
    return this.buf(length);
  // buffer 32
  case 0xd9:
    length = bops.readUInt32BE(this.buffer, this.offset + 1);
    this.offset += 5;
    return this.buf(length);
  }

  throw new Error("Unknown type 0x" + type.toString(16));
};
Example #14
0
File: zip.js Project: Ivshti/zip
var bytesToNumberBE = function (bytes) {
    var acc = 0;
    for (var i = 0; i < bytes.length; i++)
        acc = (acc << 8) + bops.readUInt8(bytes, i);
    return acc;
};
Example #15
0
File: zip.js Project: Ivshti/zip
var bytesToNumberLE = function (bytes) {
    var acc = 0;
    for (var i = 0; i < bytes.length; i++)
        acc += bops.readUInt8(bytes, i) << (8*i);
    return acc;
};