All files / lexers jsonObj.js

96.36% Statements 53/55
93.75% Branches 30/32
100% Functions 2/2
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 761x     101x 101x 101x 101x   101x 101x   101x 101x   101x 101x 101x   101x 101x   101x 101x     101x 21859x 21859x   21859x   21859x 5116x 776x 776x 776x 776x     16743x 2584x   2584x 2154x     14159x 13729x 13638x 867x 867x 776x 776x           21859x   21859x 776x 776x   776x   776x 776x 776x       101x 101x    
module.exports = {
  name: 'jsonObj',
  desc: 'lexes streams of JSON objects (not arrays!) and drops all characters in between.',
  func: ({verbose}) => (data, linesOffset) => {
    const tokens  = []
    const lines   = []
    const err     = []
  
    let text      = data
    let len       = text.length
  
    let at        = -1
    let lastLine  = linesOffset
    
    let isEscaped = false
    let inString  = false
    let inObj     = false
  
    let objFound  = false
    let brackets  = 0
  
    let isDone    = false
    let from      = 0
    let ch
    
    do {
      at++
      ch = text.charAt(at)
  
      if (verbose > 0 && ch === '\n') lastLine++
  
      if (!inObj) {
        if (ch === '{') {
          from = at
          brackets = 1
          inObj = true
          if (verbose > 0) lines.push(lastLine)
        }
      } else {
        if (inString) {
          Iif (isEscaped) isEscaped = false
          else {
            if (ch === '"') inString = false
            else Iif (ch === '\\') isEscaped = true
          }
        } else {
          if (ch === '"') inString = true
          else if (ch === '{') brackets++
          else if (ch === '}') {
            brackets--
            if (brackets === 0) {
              inObj    = false
              objFound = true
            }
          }
        }
      }
      
      if (at === len) isDone = true
  
      if (objFound) {
        objFound    = false
        const token = text.slice(from, at + 1)
        
        tokens.push(token)
  
        text = text.slice(at + 1, len)
        len  = text.length
        at   = -1
      }
    } while (!isDone)
  
    const lastLineWithoutRest = lines.length === 0 ? linesOffset : lines[lines.length - 1]
    return {err, tokens, lines, lastLine: lastLineWithoutRest, rest: text}
  }
}