All files StructuredData.js

75.75% Statements 25/33
50% Branches 6/12
66.66% Functions 4/6
75.75% Lines 25/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106      21x 21x                               1x   1x                 1x 1x 1x     1x     1x 1x   1x   1x                                                     1x           12x 10x     2x 2x 2x 2x 2x   2x   2x         2x         2x       2x    
import { SyslogStmt } from "./SyslogStmt.js";
 
export class StructuredData {
  #elements = new Map(); // Map<SDID, Map<Key, Value>>
  #currentSdId = null;
 
  /**
   * 構造化データにキーと値のペアを追加する。
   * arg1はSD-ID、arg2はPARAM-NAME、arg3はPARAM-VALUEとして扱う。
   * arg3に値が指定されなかった場合は、arg1をPARAM-NAME、arg2をPARAM-VALUEとして扱う。
   * また、use(arg1)と同じ効果を持つ。
   * SD-PARAM(PARAM-VALUE)
   * @param {string} arg1
   * @param {string} arg2
   * @param {string} arg3
   * @returns {StructuredData}
   */
  add(arg1, arg2, arg3) {
    let sdId, key, value;
 
    if (arg3 !== undefined) {
      // 3つ引数がある場合: add(sdId, key, value)
      [sdId, key, value] = [arg1, arg2, arg3];
    } else E{
      // 2つ引数がある場合: add(key, value) -> 直前のSDIDを使用
      if (!this.#currentSdId) {
        throw new Error("No previous SDID found");
      }
      [sdId, key, value] = [this.#currentSdId, arg1, arg2];
    }
 
    this.#validateSDName(sdId);
    this.#validateSDName(key);
    value = SyslogStmt.escapeControlChars(this.#escape(value));
 
    // 状態の更新
    this.#currentSdId = sdId;
 
    // 以下、Mapへの追加処理...
    Eif (!this.#elements.has(sdId)) {
      this.#elements.set(sdId, new Map());
    }
    this.#elements.get(sdId).set(key, value);
 
    return this;
  }
 
  /**
   * addを呼び出すだけです。addという語がしっくり来ない時にどうぞ。
   * @param {string} arg1 
   * @param {string} arg2 
   * @param {string} arg3 
   * @returns {StructuredData}
   * @see {@link add} addメソッドを参照
   */
  set(arg1, arg2, arg3) {
    return this.add(arg1, arg2, arg3);
  }
 
  /**
   * 指定したSDIDを現在の編集対象にする。
   * @param {*} sdId 
   * @returns {StructuredData}
   */
  use(sdId) {
    this.#currentSdId = sdId;
    return this;
  }
 
  #escape(val) {
    // ], ", \ をエスケープする処理
    return String(val).replace(/\\/g, '\\\\')
      .replace(/"/g, '\\"')
      .replace(/]/g, '\\]');
  }
 
  toString() {
    if (this.#elements.size === 0) {
      return SyslogStmt.NILVALUE;
    }
 
    let res = "";
    for (const [sdId, params] of this.#elements) {
      res += `[${sdId}`;
      for (const [k, v] of params) {
        res += ` ${k}="${v}"`;
      }
      res += "]";
    }
    return res;
  }
 
  #validateSDName(name) {
    // 長さのチェック
    Iif (!/^[\x21-\x7E]{1,32}$/.test(name)) {
      throw new Error("SD-NAMEは1〜32文字の範囲で指定してください。");
    }
 
    // 禁止文字のチェック
    Iif (/[=\]"\s]/.test(name)) {
      throw new Error('SD-NAMEに不正な文字(=, 空白, ], ")が含まれています。');
    }
 
    return true;
  }
}