-
Notifications
You must be signed in to change notification settings - Fork 0
/
buffered-reader.js
75 lines (69 loc) · 2.15 KB
/
buffered-reader.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
/**
* A helper object to read line by line in a buffered fashion.
*/
const BufferedReader = {
/**
* [reads file internally chunk by chunk, and notifies client code about every line
* detected along the way and the amount of filed consumed so far (pogress) for every chunk]
* @param {[FILE]} file
* @param {[float]} chunkSize
* @param {[function]} lineDetectedcallback [(line, error, eof)]
* @param {[function]} progressCallback [(lengthSoFar, totalLength)]
*/
readLineByLine: (file, chunkSize, lineDetectedCallback, progressCallback, interrupter) => {
const fr = new FileReader();
let offset = 0;
let line = '';
// function called in every successful read
fr.onload = () => {
// first check for interruptions
if (interrupter.stop) {
lineDetectedCallback(null, interrupter.reason, false);
return;
}
const result = fr.result;
let start = 0;
let end;
while (true) {
end = -1;
for (let i = start; i < result.length; ++i) {
const char = result[i];
if (char === '\n' || char === '\r') {
end = i;
break;
}
}
if (end === -1) {
line += result.substring(start);
offset += result.length;
break;
} else {
line += result.substring(start, end);
if (line !== '') lineDetectedCallback(line, null, false); // line found
line = ''; // reset line
start = end + 1;
}
}
progressCallback(offset, file.size); // notify progress
readNextChunk();
};
// function called when an error is raised
fr.onerror = (err) => {
lineDetectedCallback(null, err, false);
};
// function to read by chunks
function readNextChunk() {
// check we are still within the limits
if (offset >= file.size) {
lineDetectedCallback(null, null, true); // EOF detected
return;
}
// read next slice
const slice = file.slice(offset, offset + chunkSize);
fr.readAsText(slice);
}
// start reading
readNextChunk();
},
};
export default BufferedReader;