API Docs for: 0.0.1
Show:

File: lib/parser.js

/*
 * niViz -- snow profiles visualization
 * Copyright (C) 2015 WSL/SLF - Fluelastrasse 11 - 7260 Davos Dorf - Switzerland.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

(function (niviz) {
  'use strict';

  // --- Module Dependencies ---
  var properties = Object.defineProperties;

  var EventEmitter   = niviz.EventEmitter;
  var synchronizable = niviz.synchronizable;

  var util           = niviz.util;
  var delay          = util.delay;
  var inherits       = util.inherits;


  /** @module niviz */

  /**
   * Abstract parser interface.
   *
   * @class Parser
   * @constructor
   *
   * @extends EventEmitter
   * @extends Synchronizable
   *
   * @param {Object} data The data to parse.
   */
  function Parser(data) {
    EventEmitter.call(this);
    synchronizable(this);

    /**
     * @property data
     * @type Object
     */
    this.data = data;

    /**
     * @property result
     * @type Object
     */
    this.result;
  }

  inherits(Parser, EventEmitter);

  /**
   * Registry of parser implementations.
   *
   * @property format
   * @type Object
   * @static
   */
  Parser.format = {};

  properties(Parser, {
    /**
     * The list of supported formats.
     *
     * @property formats
     * @type Array<String>
     * @static
     */
    formats: {
      get: function () { return Object.keys(this.format); }
    }

  });

  /**
   * Makes the passed-in constructor inherit from
   * Parser and registers it for the given format.
   *
   * @method implement
   * @static
   *
   * @param {Function} C The constructor.
   * @param {String} format The name of the format.
   * @param {String} [base] The format from which to inherit.
   *
   * @returns {Function} The extended constructor.
   */
  Parser.implement = function (C, format, base) {
    inherits(C, base && Parser.format[base] || Parser);
    Parser.format[format] = C;

    return C;
  };

  /**
   * Parses data using a suitable parser.
   * See `.formats` for a list of supported formats.
   *
   * @method parse
   * @static
   *
   * @param {String} data The input data.
   * @param {String} fmt The format.
   * @param {Function} [callback] The callback function.
   *
   * @returns {Object} The parse result.
   */
  Parser.parse = function (data, fmt, callback) {
    var P = Parser.format[fmt];

    if (!P && !callback) throw new Error('no parser found for: ' + fmt);
    else if (!P) callback(new Error('no parser found for: ' + fmt), null);

    return (new P(data)).parse(callback);
  };

  /**
   * Starts the parsing process; in sync mode this
   * method blocks until the parsing has finished,
   * otherwise it should return immediately!
   *
   * If given a callback, it must be bound to the `end`
   * and `error` events.
   *
   * @method parse
   *
   * @param {Function} [callback]
   * @returns {Object} The parse result.
   */
  Parser.prototype.parse = function (callback) {
    if (typeof callback === 'function')
      this.nodeback(callback);

    this.emit('parse', this);

    if (this.synchronous)
      return this._parse();

    delay(this._parse.bind(this));

    return this.result;
  };

  /**
   * @method parse
   * @abstract
   */
  Parser.prototype._parse = function () {
    throw new Error('not implemented');
  };

  /**
   * Verify that all syntactic and semantic requirements are met
   * by the parsed entity.
   *
   * @method verify
   * @chainable
   */
  Parser.prototype.verify = function () {
    return this;
  };

  /**
   * This method must be called by the parsing methods
   * when the parsing has finished.
   *
   * @method end
   * @chainable
   */
  Parser.prototype.end = function () {
    this.emit('end', this.result);
    return this;
  };

  // --- Module Exports ---
  niviz.Parser = Parser;
  niviz.parse  = Parser.parse;

}(niviz));