All files basicDecoders.js

100% Statements 66/66
100% Branches 1/1
100% Functions 0/0
100% Lines 66/66

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 661x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x
export function assertChar (arr, regex) {
  if (!arr[arr.i].match(regex)) {
    throw new Error(`expected ${regex}. got ${arr[arr.i]} at i=${arr.i}`)
  }
  arr.i++
}
 
export function readValue (arr) {
  if (arr[arr.i].isValue) {
    return arr[arr.i++]
  }
}
 
export function readEscaped (arr) {
  assertChar(arr, /&/)
  if (readIf(arr, 'amp;')) {
    return '&'
  } else if (readIf(arr, 'apos;')) {
    return '\''
  } else if (readIf(arr, 'gt;')) {
    return '>'
  } else if (readIf(arr, 'lt;')) {
    return '<'
  } else if (readIf(arr, 'quot;')) {
    return '"'
  } else {
    throw new Error('unhandled escape sequence')
  }
}
 
export function readTo (arr, regex) {
  const ss = []
  while (arr.i < arr.length) {
    const c = arr[arr.i]
    if (c.isValue || c.match(regex)) {
      return ss.join('')
    } else if (c === '&') {
      ss.push(readEscaped(arr))
    } else {
      ss.push(c)
      arr.i++
    }
  }
  return ss.join('')
}
 
export function skipWhiteSpace (arr) {
  readTo(arr, /\S/)
}
 
export function readIf (arr, str) {
  if (!str.length) {
    str = [str]
  }
  const out = []
  for (let i = 0; i < str.length; i++) {
    const char = arr[arr.i + i]
    if (!char || !char.match || !char.match(str[i])) {
      return false
    }
    out.push(char)
  }
  arr.i += str.length
  return out.join('')
}