# All files / src/utils attr-list.js

100% Statements 48/48
90% Branches 18/20
100% Functions 9/9
100% Lines 47/47

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
    901x
    1x

    1x

    66x
    61x

    66x
    147x
    147x

    1x
    46x
    46x
    1x

    45x

    1x
    5x
    3x
    3x

    3x
    3x
    19x

    3x

    2x

    1x
    8x
    8x
    1x

    7x

    1x
    8x

    1x
    12x

    1x
    28x
    28x
    8x

    20x

    1x
    61x
    61x
    61x
    146x

    146x

    50x

    146x

    61x

    1x

    1x
     const DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/; // eslint-disable-line no-useless-escape
    const ATTR_LIST_REGEX = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; // eslint-disable-line no-useless-escape

    // adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
    class AttrList {
      constructor (attrs) {
        if (typeof attrs === 'string') {
          attrs = AttrList.parseAttrList(attrs);
        }

        for (let attr in attrs) {
          Eif (attrs.hasOwnProperty(attr)) {
            this[attr] = attrs[attr];
          }
        }
      }

      decimalInteger (attrName) {
        const intValue = parseInt(this[attrName], 10);
        if (intValue > Number.MAX_SAFE_INTEGER) {
          return Infinity;
        }

        return intValue;
      }

      hexadecimalInteger (attrName) {
        if (this[attrName]) {
          let stringValue = (this[attrName] || '0x').slice(2);
          stringValue = ((stringValue.length & 1) ? '0' : '') + stringValue;

          const value = new Uint8Array(stringValue.length / 2);
          for (let i = 0; i < stringValue.length / 2; i++) {
            value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16);
          }

          return value;
        } else {
          return null;
        }
      }

      hexadecimalIntegerAsNumber (attrName) {
        const intValue = parseInt(this[attrName], 16);
        if (intValue > Number.MAX_SAFE_INTEGER) {
          return Infinity;
        }

        return intValue;
      }

      decimalFloatingPoint (attrName) {
        return parseFloat(this[attrName]);
      }

      enumeratedString (attrName) {
        return this[attrName];
      }

      decimalResolution (attrName) {
        const res = DECIMAL_RESOLUTION_REGEX.exec(this[attrName]);
        if (res === null) {
          return undefined;
        }

        return {
          width: parseInt(res[1], 10),
          height: parseInt(res[2], 10)
        };
      }

      static parseAttrList (input) {
        let match, attrs = {};
        ATTR_LIST_REGEX.lastIndex = 0;
        while ((match = ATTR_LIST_REGEX.exec(input)) !== null) {
          let value = match[2], quote = '"';

          if (value.indexOf(quote) === 0 &&
              value.lastIndexOf(quote) === (value.length - 1)) {
            value = value.slice(1, -1);
          }

          attrs[match[1]] = value;
        }
        return attrs;
      }
    }

    export default AttrList;