index.js 1.88 KB
var assert = require('assert')
var bl = require('bl')
var streams = require('./lib/streams')
var buildDecode = require('./lib/decoder')
var buildEncode = require('./lib/encoder')

function msgpack (options) {
  var encodingTypes = []
  var decodingTypes = []

  options = options || {
    forceFloat64: false,
    compatibilityMode: false
  }

  function registerEncoder (check, encode) {
    assert(check, 'must have an encode function')
    assert(encode, 'must have an encode function')

    encodingTypes.push({
      check: check, encode: encode
    })

    return this
  }

  function registerDecoder (type, decode) {
    assert(type >= 0, 'must have a non-negative type')
    assert(decode, 'must have a decode function')

    decodingTypes.push({
      type: type, decode: decode
    })

    return this
  }

  function register (type, constructor, encode, decode) {
    assert(constructor, 'must have a constructor')
    assert(encode, 'must have an encode function')
    assert(type >= 0, 'must have a non-negative type')
    assert(decode, 'must have a decode function')

    function check (obj) {
      return (obj instanceof constructor)
    }

    function reEncode (obj) {
      var buf = bl()
      var header = new Buffer(1)

      header.writeInt8(type, 0)

      buf.append(header)
      buf.append(encode(obj))

      return buf
    }

    this.registerEncoder(check, reEncode)
    this.registerDecoder(type, decode)

    return this
  }

  return {
    encode: buildEncode(encodingTypes, options.forceFloat64, options.compatibilityMode),
    decode: buildDecode(decodingTypes),
    register: register,
    registerEncoder: registerEncoder,
    registerDecoder: registerDecoder,
    encoder: streams.encoder,
    decoder: streams.decoder,
    // needed for levelup support
    buffer: true,
    type: 'msgpack5',
    IncompleteBufferError: buildDecode.IncompleteBufferError
  }
}

module.exports = msgpack