-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinfinite-buffer.js
More file actions
78 lines (76 loc) · 1.9 KB
/
infinite-buffer.js
File metadata and controls
78 lines (76 loc) · 1.9 KB
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
// node-reliable-udp
// Karol Walasek
// https://github.com/WalasPrime/node-reliable-udp
/**
* A Buffer that can be unshifted and pushed to. Lookup of the first partition is also possible.
* @class
*/
class InfiniteBuffer {
constructor(){
this.partitions = [];
this.size = 0;
}
/**
* Add data to the buffer.
* @param {Buffer} data Data to be added to the buffer
*/
append(data){
this.partitions.push(data);
this.size += data.length;
}
/**
* Removes and returns a portion of the buffer from the begining.
* @param {Number} length
* @returns {Buffer}
*/
splice(length){
const buf = Buffer.allocUnsafe(Math.min(length, this.size));
let partition = 0, at = 0, splice = 0, splice_length = 0;
while(partition < this.partitions.length && at < length){
const p = this.partitions[partition];
p.copy(buf, at, 0, Math.min(length-at, p.length));
if(length >= p.length){
// Whole partition will be removed
splice++;
splice_length += p.length;
}else{
// Only a part of this partition should be removed
this.partitions[partition] = p.slice(length);
splice_length += length;
}
at += p.length;
partition++;
}
this.partitions.splice(0, splice);
this.size -= splice_length;
return buf;
}
/**
* Lookup the first partition buffer. Allows to decide if proper decoding of a larger chunk is possible.
* @returns {Buffer}
*/
lookup(){
return this.partitions[0];
}
/**
* Return the n-th byte of the buffer.
* @param {Number} index
*/
get(index){
let at = 0;
for(let partition = 0; partition < this.partitions.length; partition++){
if(at+this.partitions[partition].length > index)
return this.partitions[partition][index-at];
at += this.partitions[partition].length;
}
return null;
}
/**
* Returns the total size of the data in the buffer.
* @returns {Number}
*/
getLength(){
return this.size;
}
}
module.exports = InfiniteBuffer;