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));