tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Response.js (3112B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 var {
      8  findPlaceholders,
      9  getPath,
     10 } = require("resource://devtools/shared/protocol/utils.js");
     11 var { types } = require("resource://devtools/shared/protocol/types.js");
     12 
     13 /**
     14 * Manages a response template.
     15 */
     16 class Response {
     17  /**
     18   * @param {object} template
     19   *    The response template.
     20   */
     21  constructor(template = {}) {
     22    this.template = template;
     23    if (this.template instanceof RetVal && this.template.isArrayType()) {
     24      throw Error("Arrays should be wrapped in objects");
     25    }
     26 
     27    const placeholders = findPlaceholders(template, RetVal);
     28    if (placeholders.length > 1) {
     29      throw Error("More than one RetVal specified in response");
     30    }
     31    const placeholder = placeholders.shift();
     32    if (placeholder) {
     33      this.retVal = placeholder.placeholder;
     34      this.path = placeholder.path;
     35    }
     36  }
     37  /**
     38   * Write a response for the given return value.
     39   *
     40   * @param val ret
     41   *    The return value.
     42   * @param {object} ctx
     43   *    The object writing the response.
     44   */
     45  write(ret, ctx) {
     46    // Consider that `template` is either directly a `RetVal`,
     47    // or a dictionary with may be one `RetVal`.
     48    if (this.template instanceof RetVal) {
     49      return this.template.write(ret, ctx);
     50    }
     51    const result = {};
     52    for (const key in this.template) {
     53      const value = this.template[key];
     54      if (value instanceof RetVal) {
     55        result[key] = value.write(ret, ctx);
     56      } else {
     57        throw new Error(
     58          "Response can only be a `RetVal` instance or an object " +
     59            "with one property being a `RetVal` instance."
     60        );
     61      }
     62    }
     63    return result;
     64  }
     65 
     66  /**
     67   * Read a return value from the given response.
     68   *
     69   * @param {object} packet
     70   *    The response packet.
     71   * @param {object} ctx
     72   *    The object reading the response.
     73   */
     74  read(packet, ctx) {
     75    if (!this.retVal) {
     76      return undefined;
     77    }
     78    const v = getPath(packet, this.path);
     79    return this.retVal.read(v, ctx);
     80  }
     81 }
     82 
     83 exports.Response = Response;
     84 
     85 /**
     86 * Placeholder for return values in a response template.
     87 */
     88 class RetVal {
     89  /**
     90   * @param type type
     91   *    The return value should be marshalled as this type.
     92   */
     93  constructor(type) {
     94    this._type = type;
     95    // Prevent force loading all RetVal types by accessing it only when needed
     96    loader.lazyGetter(this, "type", function () {
     97      return types.getType(type);
     98    });
     99  }
    100  write(v, ctx) {
    101    return this.type.write(v, ctx);
    102  }
    103 
    104  read(v, ctx) {
    105    return this.type.read(v, ctx);
    106  }
    107 
    108  isArrayType() {
    109    // `_type` should always be a string, but a few incorrect RetVal calls
    110    // pass `0`. See Bug 1677703.
    111    return typeof this._type === "string" && this._type.startsWith("array:");
    112  }
    113 }
    114 
    115 // Outside of protocol.js, RetVal is called as factory method, without the new keyword.
    116 exports.RetVal = function (type) {
    117  return new RetVal(type);
    118 };