All files / chunkers 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 22588x 22588x   22588x   22588x 4892x 733x 733x 733x 733x     17696x 2887x   2887x 2398x     14809x 14320x 14231x 822x 822x 733x 733x           22588x   22588x 733x 733x   733x   733x 733x 733x       101x 101x    
module.exports = {
  name: 'jsonObj',
  desc: 'chunks JSON objects (not arrays!) from streams and drops all characters in between.',
  func: ({verbose}) => (data, linesOffset) => {
    const chunks  = []
    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 chunk = text.slice(from, at + 1)
        
        chunks.push(chunk)
  
        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, chunks, lines, lastLine: lastLineWithoutRest, rest: text}
  }
}