<commit_before>
/**
 * Module dependencies.
 */

var net = require('net')
  , Parser = require('../parser')
  , Message = require('../message')
  , codecs = require('../codecs')
  , Emitter = require('events').EventEmitter
  , debug = require('debug')('axon:sock')
  , url = require('url');

/**
 * Expose `Socket`.
 */

module.exports = Socket;

/**
 * Initialize a new `Socket`.
 *
 * A "Socket" encapsulates the ability of being
 * the "client" or the "server" depending on
 * whether `connect()` or `bind()` was called.
 *
 * Upon sending and recieving messages, the correct codec
 * set by `format` will be applied. Both sides must elect
 * the same codec, or all hell will break loose on the app.
 *
 * @api private
 */

function Socket() {
  var self = this;
  this.opts = {};
  this.server = null;
  this.socks = [];
  this.map = {};
  this.format('none');
  this.option('identity', '\u0000');
  this.option('retry timeout', 100);
  this.option('retry max timeout', 2000);
}

/**
 * Inherit from `Emitter.prototype`.
 */

Socket.prototype.__proto__ = Emitter.prototype;

/**
 * Use the given `plugin`.
 *
 * @param {Function} plugin
 * @api private
 */

Socket.prototype.use = function(plugin){
  plugin(this);
  return this;
};

/**
 * Set or get the option `key`.
 *
 * @param {String} key
 * @param {Mixed} value
 * @api public
 */

Socket.prototype.option = function(key, value){
  if (arguments.length == 1) {
    return this.opts[key];
  } else {
    this.opts[key] = value;
    return this;
  }
};

/**
 * Set format to `type`.
 *
 * @param {String} type
 * @return {Socket}
 * @api public
 */

Socket.prototype.format = function(type){
  var codec = codecs.byName(type);
  if (!codec) throw new Error('unknown format "' + type + '"');
  this.codec = codec;
  return this;
};


/**
 * Creates a new `Message` and writes `data` using the
 * `codec` set already by `format`.
 *
 * This will only work for single part messages or multi
 * part message that all use the same codec. If you need
 * otherwise, use the `Message` constructor to craft
 * your own message.
 *
 * @param {Mixed} data
 * @return {Buffer}
 * @api private
 */

Socket.prototype.pack = function(data){
  var msg = new Message();
  var codec = this.codec;

  if (Array.isArray(data)) {
    for (var i = 0; i < data.length; i++) {
      msg.write(codec.encode(data[i]), codec.id);
    }
  } else {
    msg.write(codec.encode(data), codec.id);
  }

  return msg.toBuffer();
};

/**
 * Close the socket.
 *
 * Delegates to the server or clients
 * based on the socket `type`.
 *
 * @api public
 */

Socket.prototype.close = function(){
  debug('close');
  this.closing = true;
  if ('server' == this.type) {
    this.server && this.server.close();
  } else {
    this.socks.forEach(function(sock){
      sock.destroy();
    });
  }
};

/**
 * Remove `sock`.
 *
 * @param {Socket} sock
 * @api private
 */

Socket.prototype.removeSocket = function(sock){
  var i = this.socks.indexOf(sock);
  this.socks.splice(i, 1);
  if (sock._axon_id) delete this.map[sock._axon_id];
};

/**
 * Add `sock`.
 *
 * TODO: Better ways to hook into the parsed
 * messages prior to the application receiving
 * them?
 *
 * @param {Socket} sock
 * @api private
 */

Socket.prototype.addSocket = function(sock){
  var self = this;
  var parser = new Parser;
  var n = this.socks.push(sock);

  // sent our greeting
  sock.write(this.pack(this.option('identity')));

  // parse incoming
  sock.on('data', parser.write.bind(parser));

  // accept greeting once, emit messages there on out
  parser.onmessage = ongreeting;

  function ongreeting(msg){
    var id = '' + msg;
    if ('0' === id) id = '' + Date.now() + process.pid + n;
    sock._axon_id = id;
    self.map[id] = sock;
    parser.onmessage = onmessage;
  }

  function onmessage(msg, multipart){
    if (multipart) {
      self.emit.apply(self, ['message'].concat(msg));
    } else {
      self.emit('message', msg);
    }
  }
};

/**
 * Connect to `port` at `host` and invoke `fn()`.
 *<commit_msg>style fixes<commit_after>
/**
 * Module dependencies.
 */

var net = require('net')
  , Parser = require('../parser')
  , Message = require('../message')
  , codecs = require('../codecs')
  , Emitter = require('events').EventEmitter
  , debug = require('debug')('axon:sock')
  , url = require('url');

/**
 * Expose `Socket`.
 */

module.exports = Socket;

/**
 * Initialize a new `Socket`.
 *
 * A "Socket" encapsulates the ability of being
 * the "client" or the "server" depending on
 * whether `connect()` or `bind()` was called.
 *
 * Upon sending and recieving messages, the correct codec
 * set by `format` will be applied. Both sides must elect
 * the same codec, or all hell will break loose on the app.
 *
 * @api private
 */

function Socket() {
  var self = this;
  this.opts = {};
  this.server = null;
  this.socks = [];
  this.map = {};
  this.format('none');
  this.option('identity', '\u0000');
  this.option('retry timeout', 100);
  this.option('retry max timeout', 2000);
}

/**
 * Inherit from `Emitter.prototype`.
 */

Socket.prototype.__proto__ = Emitter.prototype;

/**
 * Use the given `plugin`.
 *
 * @param {Function} plugin
 * @api private
 */

Socket.prototype.use = function(plugin){
  plugin(this);
  return this;
};

/**
 * Set or get the option `key`.
 *
 * @param {String} key
 * @param {Mixed} value
 * @api public
 */

Socket.prototype.option = function(key, value){
  if (arguments.length == 1) {
    return this.opts[key];
  } else {
    this.opts[key] = value;
    return this;
  }
};

/**
 * Set format to `type`.
 *
 * @param {String} type
 * @return {Socket}
 * @api public
 */

Socket.prototype.format = function(type){
  var codec = codecs.byName(type);
  if (!codec) throw new Error('unknown format "' + type + '"');
  this.codec = codec;
  return this;
};


/**
 * Creates a new `Message` and writes `data` using the
 * `codec` set already by `format`.
 *
 * This will only work for single part messages or multi
 * part message that all use the same codec. If you need
 * otherwise, use the `Message` constructor to craft
 * your own message.
 *
 * @param {Mixed} data
 * @return {Buffer}
 * @api private
 */

Socket.prototype.pack = function(data){
  var msg = new Message();
  var codec = this.codec;

  if (Array.isArray(data)) {
    for (var i = 0; i < data.length; i++) {
      msg.write(codec.encode(data[i]), codec.id);
    }
  } else {
    msg.write(codec.encode(data), codec.id);
  }

  return msg.toBuffer();
};

/**
 * Close the socket.
 *
 * Delegates to the server or clients
 * based on the socket `type`.
 *
 * @api public
 */

Socket.prototype.close = function(){
  debug('close');
  this.closing = true;
  if ('server' == this.type) {
    this.server && this.server.close();
  } else {
    this.socks.forEach(function(sock){
      sock.destroy();
    });
  }
};

/**
 * Remove `sock`.
 *
 * @param {Socket} sock
 * @api private
 */

Socket.prototype.removeSocket = function(sock){
  var i = this.socks.indexOf(sock);
  this.socks.splice(i, 1);
  if (sock._axon_id) delete this.map[sock._axon_id];
};

/**
 * Add `sock`.
 *
 * TODO: Better ways to hook into the parsed
 * messages prior to the application receiving
 * them?
 *
 * @param {Socket} sock
 * @api private
 */

Socket.prototype.addSocket = function(sock){
  var self = this
    , pid = String(process.pid)
    , parser = new Parser
    , n = this.socks.push(sock);

  // send our greeting
  sock.write(this.pack(this.option('identity')));

  // parse incoming
  sock.on('data', parser.write.bind(parser));

  // accept greeting once, emit messages there on out
  parser.onmessage = ongreeting;

  function ongreeting(msg){
    var id = String(msg);
    if ('0' === id) id = pid + Date.now() + n;
    sock._axon_id = id;
    self.map[id] = sock;
    parser.onmessage = onmessage;
  }

  function onmessage(msg, multipart){
    if (multipart) {
      self.emit.apply(self, ['message'].concat(msg));
    } else {
      self.emit('message', msg);
    }
  }
};

/**
 * Connect to `port` at `host` and invoke `fn()`.
 *
{'fraction_non_alphanumeric': 0.16782522343594836, 'fraction_numerical': 0.003723932472691162, 'mean_word_length': 3.065085771947528, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1505421', 'n_tokens_mistral': 2740, 'n_tokens_neox': 2670, 'n_words': 767}