-
Notifications
You must be signed in to change notification settings - Fork 0
/
read.js
113 lines (94 loc) · 2.28 KB
/
read.js
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const duplexer = require('duplexer2')
const split = require('split2')
const through = require('through2')
const idRe = /^\d+$/
const posRe = /^(\d\d):(\d\d):(\d\d),(\d\d\d)$/
module.exports = function (onInvalid) {
if (onInvalid && typeof onInvalid !== 'function') {
throw new Error('argument must be a function')
}
var id = 0
var time = {
startTime: null,
endTime: null
}
var body = []
var state = 'new'
const s = split()
const t = through.obj(onLine, onEnd)
s.pipe(t)
return duplexer({readableObjectMode: true}, s, t)
function onLine (line, enc, cb) {
if (line === '') {
if (state !== 'new') {
pushSub.call(this)
id = 0
time = {
startTime: null,
endTime: null
}
body = []
state = 'new'
}
return cb()
} else if (line !== '' && state === 'new') state = 'id'
if (state === 'id') {
let match = idRe.exec(line)
if (!match) {
id = 0
} else id = Number(match[0])
state = 'time'
return cb()
}
if (state === 'time') {
let pos = line.split(' --> ')
if (pos.length !== 2) {
state = 'body'
return cb()
}
let startTime = posRe.exec(pos[0])
let endTime = posRe.exec(pos[1])
if (startTime) {
time.startTime = {
hours: Number(startTime[1]),
minutes: Number(startTime[2]),
seconds: Number(startTime[3]),
ms: Number(startTime[4])
}
}
if (endTime) {
time.endTime = {
hours: Number(endTime[1]),
minutes: Number(endTime[2]),
seconds: Number(endTime[3]),
ms: Number(endTime[4])
}
}
state = 'body'
return cb()
}
if (state === 'body') {
body.push(line)
return cb()
}
}
function onEnd (cb) {
if (state !== 'new') pushSub.call(this)
cb()
}
function pushSub () {
let valid = id && time.startTime && time.endTime && body.length > 0
if (onInvalid && !valid) {
var newSub = onInvalid(getSubObj())
if (newSub) this.push(newSub)
} else if (valid) this.push(getSubObj())
}
function getSubObj () {
return {
id,
startTime: time.startTime,
endTime: time.endTime,
body
}
}
}