Skip to content

Commit 652fbee

Browse files
committed
Add writing capabilities and rename package to binary-io
1 parent db7d148 commit 652fbee

File tree

9 files changed

+169
-19
lines changed

9 files changed

+169
-19
lines changed

README.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
1-
# stream-reader
1+
# binary-io
22

3-
Streaming binary data and bitstream reader. Extracted from [aurora.js](https://github.com/audiocogs/aurora.js).
3+
Streaming byte and bit stream reader and writer. Extracted from [aurora.js](https://github.com/audiocogs/aurora.js).
44

55
## BufferList
66

77
A `BufferList` is represents a linked list of byte buffers. It manages the current total length of the list and is used by the `Stream` class internally.
88

9-
## Stream
9+
## StreamReader
1010

11-
The `Stream` class represents a stream of binary data backed by a `BufferList`. Streams handle the complexity of reading various types of values from a binary data stream for you, including issues regarding the native endianness of the platform.
11+
The `StreamReader` class reads a stream of binary data backed by a `BufferList`. `StreamReader` handles the complexity of reading various types of values from a binary data stream for you, including issues regarding the native endianness of the platform.
1212

13-
## Bitstream
13+
## BitstreamReader
1414

15-
The `Bitstream` class wraps a `Stream` and adds methods to read data on an individual bit level.
15+
The `BitstreamReader` class wraps a `StreamReader` and adds methods to read data on an individual bit level.
16+
17+
## StreamWriter
18+
19+
The `StreamWriter` class writes various binary data types to a writable stream.
20+
21+
## BitstreamWriter
22+
23+
The `BitstreamWriter` class wraps a `StreamWriter`, and adds methods to write data on an individual bit level.
1624

1725
## License
1826

index.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
export {default as BufferList} from './src/bufferlist';
2-
export {default as Stream} from './src/stream';
3-
export {default as Bitstream} from './src/bitstream';
4-
export {default as UnderflowError} from './src/underflow';
1+
export {default as BufferList} from './src/BufferList';
2+
export {default as StreamReader} from './src/StreamReader';
3+
export {default as StreamWriter} from './src/StreamWriter';
4+
export {default as BitstreamReader} from './src/BitstreamReader';
5+
export {default as BitstreamWriter} from './src/BitstreamWriter';
6+
export {default as UnderflowError} from './src/UnderflowError';

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "stream-reader",
2+
"name": "binary-io",
33
"version": "1.0.0",
4-
"description": "Streaming binary data and bitstream reader",
4+
"description": "Streaming byte and bit stream reader and writer",
55
"keywords": ["stream", "binary", "byte", "bit", "bitstream"],
66
"main": "index.js",
77
"scripts": {

src/bitstream.js renamed to src/BitstreamReader.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
import Stream from './stream';
1+
import StreamReader from './StreamReader';
22

3-
export default class Bitstream {
3+
export default class BitstreamReader {
44
constructor(stream) {
55
this.stream = stream;
66
this.bitPosition = 0;
77
}
88

99
static fromBuffer(buffer) {
10-
return new Bitstream(Stream.fromBuffer(buffer));
10+
return new BitstreamReader(StreamReader.fromBuffer(buffer));
1111
}
1212

1313
copy() {
14-
let result = new Bitstream(this.stream.copy());
14+
let result = new BitstreamReader(this.stream.copy());
1515
result.bitPosition = this.bitPosition;
1616
return result;
1717
}

src/BitstreamWriter.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// TODO
2+
export default class BitstreamWriter {}
File renamed without changes.

src/stream.js renamed to src/StreamReader.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const float64 = new Float64Array(buf);
1515
// 0x3412 is little endian, 0x1234 is big endian
1616
const nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;
1717

18-
export default class Stream {
18+
export default class StreamReader {
1919
constructor(list) {
2020
this.list = list;
2121
this.localOffset = 0;
@@ -25,11 +25,11 @@ export default class Stream {
2525
static fromBuffer(buffer) {
2626
let list = new BufferList;
2727
list.append(buffer);
28-
return new Stream(list);
28+
return new StreamReader(list);
2929
}
3030

3131
copy() {
32-
let result = new Stream(this.list.copy());
32+
let result = new StreamReader(this.list.copy());
3333
result.localOffset = this.localOffset;
3434
result.offset = this.offset;
3535
return result;

src/StreamWriter.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import {Writable} from 'stream';
2+
3+
const BUFFER_SIZE = 65536;
4+
5+
export default class StreamWriter extends Writable {
6+
constructor(stream) {
7+
super();
8+
this.stream = stream || this;
9+
this.buffer = new Uint8Array(BUFFER_SIZE);
10+
this.view = new DataView(this.buffer.buffer);
11+
this.queue = [];
12+
this.bufferOffset = 0;
13+
this.offset = 0;
14+
}
15+
16+
flush() {
17+
if (this.bufferOffset > 0) {
18+
this.stream.write(new Buffer(this.buffer.subarray(0, this.bufferOffset)));
19+
this.bufferOffset = 0;
20+
}
21+
}
22+
23+
end() {
24+
this.flush();
25+
this.stream.end();
26+
}
27+
28+
ensure(bytes) {
29+
if (this.bufferOffset + bytes > this.buffer.length) {
30+
this.flush();
31+
}
32+
}
33+
34+
advance(bytes) {
35+
// ??? fill with 0?
36+
}
37+
38+
seek(offset) {
39+
if (typeof this.stream.seek === 'function') {
40+
this.flush();
41+
this.stream.seek(offset);
42+
} else {
43+
throw new Error('Stream is not seekable');
44+
}
45+
}
46+
47+
writeUInt8(val) {
48+
this.ensure(1);
49+
this.buffer[this.bufferOffset++] = val;
50+
this.offset++;
51+
}
52+
53+
writeInt8(val) {
54+
this.ensure(1);
55+
this.view.setInt8(this.bufferOffset++, val);
56+
this.offset++;
57+
}
58+
59+
writeUInt16(val, littleEndian) {
60+
this.ensure(2);
61+
this.view.setUint16(this.bufferOffset, val, littleEndian);
62+
this.bufferOffset += 2;
63+
this.offset += 2;
64+
}
65+
66+
writeInt16(val, littleEndian) {
67+
this.ensure(2);
68+
this.view.setInt16(this.bufferOffset, val, littleEndian);
69+
this.bufferOffset += 2;
70+
this.offset += 2;
71+
}
72+
73+
writeUInt24(val, littleEndian) {
74+
if (littleEndian) {
75+
this.writeUInt8(val & 0xff);
76+
this.writeUInt8(val >>> 8 & 0xff);
77+
this.writeUInt8(val >>> 16 & 0xff);
78+
} else {
79+
this.writeUInt8(val >>> 16 & 0xff);
80+
this.writeUInt8(val >>> 8 & 0xff);
81+
this.writeUInt8(val & 0xff);
82+
}
83+
}
84+
85+
writeInt24(val, littleEndian) {
86+
this.writeUInt24(val >= 0 ? val : val + 0xffffff + 1, littleEndian);
87+
}
88+
89+
writeUInt32(val, littleEndian) {
90+
this.ensure(4);
91+
this.view.setUint32(this.bufferOffset, val, littleEndian);
92+
this.bufferOffset += 4;
93+
this.offset += 4;
94+
}
95+
96+
writeInt32(val, littleEndian) {
97+
this.ensure(4);
98+
this.view.setInt32(this.bufferOffset, val, littleEndian);
99+
this.bufferOffset += 4;
100+
this.offset += 4;
101+
}
102+
103+
writeFloat32(val, littleEndian) {
104+
this.ensure(4);
105+
this.view.setFloat32(this.bufferOffset, val, littleEndian);
106+
this.bufferOffset += 4;
107+
this.offset += 4;
108+
}
109+
110+
writeFloat64(val, littleEndian) {
111+
this.ensure(8);
112+
this.view.setFloat64(this.bufferOffset, val, littleEndian);
113+
this.bufferOffset += 8;
114+
this.offset += 8;
115+
}
116+
117+
writeFloat80(val, littleEndian) {
118+
// TODO
119+
}
120+
121+
writeBuffer(buffer) {
122+
this.flush();
123+
this.stream.push(buffer);
124+
this.offset += buffer.length;
125+
}
126+
127+
writeString(string, encoding, nullTerminated) {
128+
let buf = new Buffer(string, encoding);
129+
if (buf.length < this.buffer.length) {
130+
this.ensure(buf.length);
131+
this.buffer.set(buf, this.bufferOffset);
132+
this.bufferOffset += buf.length;
133+
this.offset += buf.length;
134+
} else {
135+
this.writeBuffer(buf);
136+
}
137+
}
138+
}
File renamed without changes.

0 commit comments

Comments
 (0)