/
rpp-transform.mjs
95 lines (89 loc) · 2.6 KB
/
rpp-transform.mjs
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
'use strict'
import stream from 'stream'
import string_decoder from 'string_decoder'
import { RppCore } from './rpp-core.mjs'
import { RppError } from './rpp-util.mjs'
// class RpptError extends Error {
// constructor(m) {
// super(m)
// }
// }
class RppTransform extends stream.Transform {
constructor(rppInstOrDefines, secondArg, thirdArg) {
let rpp, streamOptions
if (rppInstOrDefines instanceof RppCore) {
rpp = rppInstOrDefines
streamOptions = secondArg
} else {
rpp = new RppCore(rppInstOrDefines, secondArg)
streamOptions = thirdArg
}
super(streamOptions)
this.rpp = rpp
this.decoder = new string_decoder.StringDecoder('utf8')
this.remChunk = null
this.reNonWS = RegExp("[^ \\t]")
this.reEOL = RegExp('\\n')
}
_assert(cond, msg) {
if (!cond)
throw new RppError(msg ? msg : 'assert fail')
}
rppLine(line, wsOff) {
// testing
//this.push("[[" + line.slice(0,wsOff) + "]]")
//this.push(line.slice(wsOff) + "<<EOL>>\n")
// TODO add functionality to rpp so that wsOff is used; (optimize)
// eslint-disable-next-line no-unused-vars
let [err, _] = this.rpp.line(line, this.push.bind(this), null, wsOff)
return err
}
_transform(chunk, enc, callback) {
if (enc === 'buffer') {
chunk = this.decoder.write(chunk)
}
if (this.remChunk) {
chunk = this.remChunk + chunk
this.remChunk = null
}
let idx0 = 0
let err
// eslint-disable-next-line no-constant-condition
while (true) {
let wsOff = chunk.slice(idx0).search(this.reNonWS)
if (wsOff === -1) {
// no EOL, odd end of chunk, set remainder and break
this.remChunk = chunk.slice(idx0)
break
}
let len = chunk.slice(idx0 + wsOff).search(this.reEOL)
if (len === -1) {
// no EOL, odd end of chunk, set remainder and break
this.remChunk = chunk.slice(idx0)
break
} else {
let next = idx0 + wsOff + len + 1
if (len > 0 && chunk.slice(idx0 + wsOff)[len - 1] === '\r')
len--
err = this.rppLine(chunk.slice(idx0, idx0 + wsOff + len), wsOff)
if (err)
break
idx0 = next
}
}
callback(err, null)
}
_flush(callback) {
let err = null
if (this.remChunk) {
let wsOff = this.remChunk.search(this.reNonWS)
err = this.rppLine(this.remChunk, wsOff)
}
callback(err, null)
}
}
export { RppTransform }
// the following alias class should eventually be deleted
// export default class ReversiblePreproc extends RppCore {
// constructor(...args) { super(...args) }
// }