Source: util/regex/ndn-regex-component-matcher.js

/**
 * Copyright (C) 2017-2018 Regents of the University of California.
 * @author: Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
 * @author: Jeff Thompson <[email protected]>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * A copy of the GNU Lesser General Public License is in the file COPYING.
 */

/** @ignore */
var NdnRegexMatcherBase = require('./ndn-regex-matcher-base.js').NdnRegexMatcherBase; /** @ignore */
var NdnRegexPseudoMatcher = require('./ndn-regex-pseudo-matcher.js').NdnRegexPseudoMatcher;

/**
 * Create a RegexComponent matcher from expr.
 * @param {string} expr The standard regular expression to match a component.
 * @param {NdnRegexBackrefManager} backrefManager The back-reference manager.
 * @param {boolean} isExactMatch (optional) The flag to provide exact match. If
 * omitted, use true.
 * @constructor
 */
var NdnRegexComponentMatcher = function NdnRegexComponentMatcher
  (expr, backrefManager, isExactMatch)
{
  // Call the base constructor.
  NdnRegexMatcherBase.call
    (this, expr, NdnRegexMatcherBase.NdnRegexExprType.COMPONENT, backrefManager);

  if (isExactMatch === undefined)
    isExactMatch = true;

  this.componentRegex_ = null;
  // Array of NdnRegexPseudoMatcher
  this.pseudoMatchers_ = [];

  this.isExactMatch_ = isExactMatch;

  this.compile_();
};

NdnRegexComponentMatcher.prototype = new NdnRegexMatcherBase();
NdnRegexComponentMatcher.prototype.name = "NdnRegexComponentMatcher";

exports.NdnRegexComponentMatcher = NdnRegexComponentMatcher;

/**
 * @param {Name} name
 * @param {number} offset
 * @param {number} len
 * @return {boolean}
 */
NdnRegexComponentMatcher.prototype.match = function(name, offset, len)
{
  this.matchResult_ = [];

  if (this.expr_ == "") {
    this.matchResult_.push(name.get(offset));
    return true;
  }

  if (this.isExactMatch_) {
    var targetStr = name.get(offset).toEscapedString();
    var subResult = targetStr.match(this.componentRegex_);
    if (subResult !== null) {
      for (var i = 1; i < subResult.length; ++i) {
        this.pseudoMatchers_[i].resetMatchResult();
        this.pseudoMatchers_[i].setMatchResult(subResult[i]);
      }

      this.matchResult_.push(name.get(offset));
      return true;
    }
  }
  else
    throw new NdnRegexMatcherBase.Error(new Error
      ("Non-exact component search is not supported yet"));

  return false;
};

NdnRegexComponentMatcher.prototype.compile_ = function()
{
  this.componentRegex_ = new RegExp(this.expr_);

  this.pseudoMatchers_ = [];
  this.pseudoMatchers_.push(new NdnRegexPseudoMatcher());

  // Imitate C++ mark_count by just counting the number of open parentheses.
  if (this.expr_.indexOf('\\(') >= 0)
    // We don't expect escaped parentheses, so don't try to handle them.
    throw new NdnRegexMatcherBase.Error(new Error
      ("Can't count subexpressions in regex with escaped parentheses: " + expr_));
  var markCount = 0;
  for (var i = 0; i < this.expr_.length; ++i) {
    if (this.expr_[i] === '(')
      ++markCount;
  }

  for (var i = 1; i <= markCount; ++i) {
    var pMatcher = new NdnRegexPseudoMatcher();
    this.pseudoMatchers_.push(pMatcher);
    this.backrefManager_.pushRef(pMatcher);
  }
};