@fuman/io 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +8 -0
- package/_utils.cjs +23 -0
- package/_utils.d.ts +2 -0
- package/_utils.js +23 -0
- package/bits/index.d.ts +2 -0
- package/bits/reader.cjs +122 -0
- package/bits/reader.d.ts +15 -0
- package/bits/reader.js +122 -0
- package/bits/utils.cjs +49 -0
- package/bits/utils.d.ts +12 -0
- package/bits/utils.js +49 -0
- package/buf-reader.cjs +60 -0
- package/buf-reader.d.ts +9 -0
- package/buf-reader.js +60 -0
- package/bytes.cjs +114 -0
- package/bytes.d.ts +24 -0
- package/bytes.js +114 -0
- package/codec/delimiter.cjs +38 -0
- package/codec/delimiter.d.ts +22 -0
- package/codec/delimiter.js +38 -0
- package/codec/index.d.ts +6 -0
- package/codec/length-delimited.cjs +42 -0
- package/codec/length-delimited.d.ts +14 -0
- package/codec/length-delimited.js +42 -0
- package/codec/reader.cjs +51 -0
- package/codec/reader.d.ts +12 -0
- package/codec/reader.js +51 -0
- package/codec/text-delimiter.cjs +24 -0
- package/codec/text-delimiter.d.ts +11 -0
- package/codec/text-delimiter.js +24 -0
- package/codec/types.d.ts +16 -0
- package/codec/writer.cjs +24 -0
- package/codec/writer.d.ts +10 -0
- package/codec/writer.js +24 -0
- package/errors.cjs +9 -0
- package/errors.d.ts +9 -0
- package/errors.js +9 -0
- package/index.cjs +39 -0
- package/index.d.ts +12 -0
- package/index.js +39 -0
- package/package.json +29 -0
- package/read/adapters.cjs +90 -0
- package/read/adapters.d.ts +4 -0
- package/read/adapters.js +90 -0
- package/read/async/index.cjs +5 -0
- package/read/async/index.d.ts +1 -0
- package/read/async/index.js +5 -0
- package/read/async/strings.cjs +40 -0
- package/read/async/strings.d.ts +3 -0
- package/read/async/strings.js +40 -0
- package/read/index.cjs +40 -0
- package/read/index.d.ts +4 -0
- package/read/index.js +40 -0
- package/read/numbers.cjs +181 -0
- package/read/numbers.d.ts +27 -0
- package/read/numbers.js +181 -0
- package/read/strings.cjs +67 -0
- package/read/strings.d.ts +9 -0
- package/read/strings.js +67 -0
- package/reader-with-final.cjs +69 -0
- package/reader-with-final.d.ts +13 -0
- package/reader-with-final.js +69 -0
- package/streams.cjs +15 -0
- package/streams.d.ts +1 -0
- package/streams.js +15 -0
- package/types.d.ts +66 -0
- package/write/adapters.cjs +38 -0
- package/write/adapters.d.ts +4 -0
- package/write/adapters.js +38 -0
- package/write/index.cjs +37 -0
- package/write/index.d.ts +3 -0
- package/write/index.js +37 -0
- package/write/numbers.cjs +311 -0
- package/write/numbers.d.ts +27 -0
- package/write/numbers.js +311 -0
- package/write/pipe.cjs +11 -0
- package/write/pipe.d.ts +2 -0
- package/write/pipe.js +11 -0
- package/write/strings.cjs +38 -0
- package/write/strings.d.ts +6 -0
- package/write/strings.js +38 -0
package/read/numbers.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { getDv } from "../_utils.js";
|
|
2
|
+
import { PartialReadError } from "../errors.js";
|
|
3
|
+
import { exactly } from "./strings.js";
|
|
4
|
+
function uint8(readable) {
|
|
5
|
+
return exactly(readable, 1)[0];
|
|
6
|
+
}
|
|
7
|
+
function _maybeRead(readable, size) {
|
|
8
|
+
if (ArrayBuffer.isView(readable)) {
|
|
9
|
+
if (readable.byteLength < size) {
|
|
10
|
+
throw new PartialReadError(readable, size);
|
|
11
|
+
}
|
|
12
|
+
return readable;
|
|
13
|
+
}
|
|
14
|
+
return exactly(readable, size);
|
|
15
|
+
}
|
|
16
|
+
function int8(readable) {
|
|
17
|
+
const val = _maybeRead(readable, 1)[0];
|
|
18
|
+
if (!(val & 128)) return val;
|
|
19
|
+
return -(255 - val + 1);
|
|
20
|
+
}
|
|
21
|
+
function uint16le(readable) {
|
|
22
|
+
const buffer = _maybeRead(readable, 2);
|
|
23
|
+
return buffer[0] | buffer[1] << 8;
|
|
24
|
+
}
|
|
25
|
+
function uint16be(readable) {
|
|
26
|
+
const buffer = _maybeRead(readable, 2);
|
|
27
|
+
return buffer[0] << 8 | buffer[1];
|
|
28
|
+
}
|
|
29
|
+
function uint24le(readable) {
|
|
30
|
+
const buffer = _maybeRead(readable, 3);
|
|
31
|
+
return buffer[0] | buffer[1] << 8 | buffer[2] << 16;
|
|
32
|
+
}
|
|
33
|
+
function uint24be(readable) {
|
|
34
|
+
const buffer = _maybeRead(readable, 3);
|
|
35
|
+
return buffer[0] << 16 | buffer[1] << 8 | buffer[2];
|
|
36
|
+
}
|
|
37
|
+
function uint32le(readable) {
|
|
38
|
+
const buffer = _maybeRead(readable, 4);
|
|
39
|
+
return (buffer[0] | buffer[1] << 8 | buffer[2] << 16) + buffer[3] * 16777216;
|
|
40
|
+
}
|
|
41
|
+
function uint32be(readable) {
|
|
42
|
+
const buffer = _maybeRead(readable, 4);
|
|
43
|
+
return buffer[0] * 16777216 + (buffer[1] << 16 | buffer[2] << 8 | buffer[3]);
|
|
44
|
+
}
|
|
45
|
+
function uint64le(readable) {
|
|
46
|
+
const buffer = _maybeRead(readable, 8);
|
|
47
|
+
const lo = (buffer[0] | buffer[1] << 8 | buffer[2] << 16) + buffer[3] * 16777216;
|
|
48
|
+
const hi = (buffer[4] | buffer[5] << 8 | buffer[6] << 16) + buffer[7] * 16777216;
|
|
49
|
+
return BigInt(lo) | BigInt(hi) << 32n;
|
|
50
|
+
}
|
|
51
|
+
function uint64be(readable) {
|
|
52
|
+
const buffer = _maybeRead(readable, 8);
|
|
53
|
+
const lo = buffer[0] * 16777216 + (buffer[1] << 16 | buffer[2] << 8 | buffer[3]);
|
|
54
|
+
const hi = buffer[4] * 16777216 + (buffer[5] << 16 | buffer[6] << 8 | buffer[7]);
|
|
55
|
+
return BigInt(lo) << 32n | BigInt(hi);
|
|
56
|
+
}
|
|
57
|
+
function int16le(readable) {
|
|
58
|
+
const buffer = _maybeRead(readable, 2);
|
|
59
|
+
const val = buffer[0] | buffer[1] << 8;
|
|
60
|
+
return val & 32768 ? val | 4294901760 : val;
|
|
61
|
+
}
|
|
62
|
+
function int16be(readable) {
|
|
63
|
+
const buffer = _maybeRead(readable, 2);
|
|
64
|
+
const val = buffer[0] << 8 | buffer[1];
|
|
65
|
+
return val & 32768 ? val | 4294901760 : val;
|
|
66
|
+
}
|
|
67
|
+
function int24le(readable) {
|
|
68
|
+
const buffer = _maybeRead(readable, 3);
|
|
69
|
+
const val = buffer[0] | buffer[1] << 8 | buffer[2] << 16;
|
|
70
|
+
return val & 8388608 ? val | 4278190080 : val;
|
|
71
|
+
}
|
|
72
|
+
function int24be(readable) {
|
|
73
|
+
const buffer = _maybeRead(readable, 3);
|
|
74
|
+
const val = buffer[0] << 16 | buffer[1] << 8 | buffer[2];
|
|
75
|
+
return val & 8388608 ? val | 4278190080 : val;
|
|
76
|
+
}
|
|
77
|
+
function int32le(readable) {
|
|
78
|
+
const buffer = _maybeRead(readable, 4);
|
|
79
|
+
return buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] << 24;
|
|
80
|
+
}
|
|
81
|
+
function int32be(readable) {
|
|
82
|
+
const buffer = _maybeRead(readable, 4);
|
|
83
|
+
return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
|
|
84
|
+
}
|
|
85
|
+
function int64le(readable) {
|
|
86
|
+
const buffer = _maybeRead(readable, 8);
|
|
87
|
+
const val = buffer[4] + buffer[5] * 2 ** 8 + buffer[6] * 2 ** 16 + (buffer[7] << 24);
|
|
88
|
+
return (BigInt(val) << 32n) + BigInt(buffer[0] + buffer[1] * 2 ** 8 + buffer[2] * 2 ** 16 + buffer[3] * 2 ** 24);
|
|
89
|
+
}
|
|
90
|
+
function int64be(readable) {
|
|
91
|
+
const buffer = _maybeRead(readable, 8);
|
|
92
|
+
const val = (buffer[0] << 24) + buffer[1] * 2 ** 16 + buffer[2] * 2 ** 8 + buffer[3];
|
|
93
|
+
return (BigInt(val) << 32n) + BigInt(buffer[4] * 2 ** 24 + buffer[5] * 2 ** 16 + buffer[6] * 2 ** 8 + buffer[7]);
|
|
94
|
+
}
|
|
95
|
+
function uintle(readable, size) {
|
|
96
|
+
const buffer = _maybeRead(readable, size);
|
|
97
|
+
let val = BigInt(buffer[0]);
|
|
98
|
+
let mul = 1;
|
|
99
|
+
let i = 0;
|
|
100
|
+
while (++i < size && (mul *= 256)) {
|
|
101
|
+
val |= BigInt(buffer[i] * mul);
|
|
102
|
+
}
|
|
103
|
+
return val;
|
|
104
|
+
}
|
|
105
|
+
function uintbe(readable, size) {
|
|
106
|
+
const buffer = _maybeRead(readable, size);
|
|
107
|
+
let val = BigInt(buffer[--size]);
|
|
108
|
+
let mul = 1;
|
|
109
|
+
while (size > 0 && (mul *= 256)) {
|
|
110
|
+
val |= BigInt(buffer[--size] * mul);
|
|
111
|
+
}
|
|
112
|
+
return val;
|
|
113
|
+
}
|
|
114
|
+
function intbe(readable, size) {
|
|
115
|
+
const buffer = _maybeRead(readable, size);
|
|
116
|
+
let i = size - 1;
|
|
117
|
+
let mul = 1;
|
|
118
|
+
let val = BigInt(buffer[i]);
|
|
119
|
+
while (i > 0 && (mul *= 256)) {
|
|
120
|
+
val |= BigInt(buffer[--i] * mul);
|
|
121
|
+
}
|
|
122
|
+
mul *= 128;
|
|
123
|
+
if (val >= mul) val -= 2n ** BigInt(8 * size);
|
|
124
|
+
return val;
|
|
125
|
+
}
|
|
126
|
+
function intle(readable, size) {
|
|
127
|
+
const buffer = _maybeRead(readable, size);
|
|
128
|
+
let val = BigInt(buffer[0]);
|
|
129
|
+
let mul = 1;
|
|
130
|
+
let i = 0;
|
|
131
|
+
while (++i < size && (mul *= 256)) {
|
|
132
|
+
val |= BigInt(buffer[i] * mul);
|
|
133
|
+
}
|
|
134
|
+
mul *= 128;
|
|
135
|
+
if (val >= mul) val -= 2n ** BigInt(8 * size);
|
|
136
|
+
return val;
|
|
137
|
+
}
|
|
138
|
+
function float32le(readable) {
|
|
139
|
+
const buffer = _maybeRead(readable, 4);
|
|
140
|
+
return getDv(buffer).getFloat32(buffer.byteOffset, true);
|
|
141
|
+
}
|
|
142
|
+
function float32be(readable) {
|
|
143
|
+
const buffer = _maybeRead(readable, 4);
|
|
144
|
+
return getDv(buffer).getFloat32(buffer.byteOffset, false);
|
|
145
|
+
}
|
|
146
|
+
function float64le(readable) {
|
|
147
|
+
const buffer = _maybeRead(readable, 8);
|
|
148
|
+
return getDv(buffer).getFloat64(buffer.byteOffset, true);
|
|
149
|
+
}
|
|
150
|
+
function float64be(readable) {
|
|
151
|
+
const buffer = _maybeRead(readable, 8);
|
|
152
|
+
return getDv(buffer).getFloat64(buffer.byteOffset, false);
|
|
153
|
+
}
|
|
154
|
+
export {
|
|
155
|
+
float32be,
|
|
156
|
+
float32le,
|
|
157
|
+
float64be,
|
|
158
|
+
float64le,
|
|
159
|
+
int16be,
|
|
160
|
+
int16le,
|
|
161
|
+
int24be,
|
|
162
|
+
int24le,
|
|
163
|
+
int32be,
|
|
164
|
+
int32le,
|
|
165
|
+
int64be,
|
|
166
|
+
int64le,
|
|
167
|
+
int8,
|
|
168
|
+
intbe,
|
|
169
|
+
intle,
|
|
170
|
+
uint16be,
|
|
171
|
+
uint16le,
|
|
172
|
+
uint24be,
|
|
173
|
+
uint24le,
|
|
174
|
+
uint32be,
|
|
175
|
+
uint32le,
|
|
176
|
+
uint64be,
|
|
177
|
+
uint64le,
|
|
178
|
+
uint8,
|
|
179
|
+
uintbe,
|
|
180
|
+
uintle
|
|
181
|
+
};
|
package/read/strings.cjs
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const utils = require("@fuman/utils");
|
|
4
|
+
const bytes = require("../bytes.cjs");
|
|
5
|
+
const errors = require("../errors.cjs");
|
|
6
|
+
function exactly(readable, length) {
|
|
7
|
+
const buf = readable.readSync(length);
|
|
8
|
+
if (buf.length < length) {
|
|
9
|
+
throw new errors.PartialReadError(buf, length);
|
|
10
|
+
}
|
|
11
|
+
return buf;
|
|
12
|
+
}
|
|
13
|
+
function rawString(readable, length) {
|
|
14
|
+
const buf = exactly(readable, length);
|
|
15
|
+
let result = "";
|
|
16
|
+
for (let i = 0; i < length; i++) {
|
|
17
|
+
result += String.fromCharCode(buf[i]);
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
function utf8String(readable, length) {
|
|
22
|
+
return utils.utf8.decoder.decode(exactly(readable, length));
|
|
23
|
+
}
|
|
24
|
+
function untilCondition(readable, condition) {
|
|
25
|
+
const buf = bytes.Bytes.alloc();
|
|
26
|
+
while (true) {
|
|
27
|
+
const byte = readable.readSync(1);
|
|
28
|
+
if (byte.length === 0) {
|
|
29
|
+
throw new errors.PartialReadError(buf.result(), buf.available + 1);
|
|
30
|
+
}
|
|
31
|
+
buf.writeSync(1)[0] = byte[0];
|
|
32
|
+
if (condition(byte[0])) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return buf.result();
|
|
37
|
+
}
|
|
38
|
+
function untilEnd(readable, chunkSize = 1024) {
|
|
39
|
+
const buf = bytes.Bytes.alloc(chunkSize);
|
|
40
|
+
while (true) {
|
|
41
|
+
const chunk = readable.readSync(chunkSize);
|
|
42
|
+
if (chunk.length === 0) {
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
buf.writeSync(chunk.length).set(chunk);
|
|
46
|
+
}
|
|
47
|
+
return buf.result();
|
|
48
|
+
}
|
|
49
|
+
function untilZero(readable) {
|
|
50
|
+
return untilCondition(readable, (byte) => byte === 0);
|
|
51
|
+
}
|
|
52
|
+
function cUtf8String(readable) {
|
|
53
|
+
const buf = untilZero(readable);
|
|
54
|
+
return utils.utf8.decoder.decode(buf.subarray(0, buf.length - 1));
|
|
55
|
+
}
|
|
56
|
+
function lengthPrefixed(readLength, readable) {
|
|
57
|
+
const length = readLength(readable);
|
|
58
|
+
return exactly(readable, length);
|
|
59
|
+
}
|
|
60
|
+
exports.cUtf8String = cUtf8String;
|
|
61
|
+
exports.exactly = exactly;
|
|
62
|
+
exports.lengthPrefixed = lengthPrefixed;
|
|
63
|
+
exports.rawString = rawString;
|
|
64
|
+
exports.untilCondition = untilCondition;
|
|
65
|
+
exports.untilEnd = untilEnd;
|
|
66
|
+
exports.untilZero = untilZero;
|
|
67
|
+
exports.utf8String = utf8String;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ISyncReadable } from '../types.js';
|
|
2
|
+
export declare function exactly(readable: ISyncReadable, length: number): Uint8Array;
|
|
3
|
+
export declare function rawString(readable: ISyncReadable, length: number): string;
|
|
4
|
+
export declare function utf8String(readable: ISyncReadable, length: number): string;
|
|
5
|
+
export declare function untilCondition(readable: ISyncReadable, condition: (byte: number) => boolean): Uint8Array;
|
|
6
|
+
export declare function untilEnd(readable: ISyncReadable, chunkSize?: number): Uint8Array;
|
|
7
|
+
export declare function untilZero(readable: ISyncReadable): Uint8Array;
|
|
8
|
+
export declare function cUtf8String(readable: ISyncReadable): string;
|
|
9
|
+
export declare function lengthPrefixed(readLength: (readable: ISyncReadable) => number, readable: ISyncReadable): Uint8Array;
|
package/read/strings.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { utf8 } from "@fuman/utils";
|
|
2
|
+
import { Bytes } from "../bytes.js";
|
|
3
|
+
import { PartialReadError } from "../errors.js";
|
|
4
|
+
function exactly(readable, length) {
|
|
5
|
+
const buf = readable.readSync(length);
|
|
6
|
+
if (buf.length < length) {
|
|
7
|
+
throw new PartialReadError(buf, length);
|
|
8
|
+
}
|
|
9
|
+
return buf;
|
|
10
|
+
}
|
|
11
|
+
function rawString(readable, length) {
|
|
12
|
+
const buf = exactly(readable, length);
|
|
13
|
+
let result = "";
|
|
14
|
+
for (let i = 0; i < length; i++) {
|
|
15
|
+
result += String.fromCharCode(buf[i]);
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
function utf8String(readable, length) {
|
|
20
|
+
return utf8.decoder.decode(exactly(readable, length));
|
|
21
|
+
}
|
|
22
|
+
function untilCondition(readable, condition) {
|
|
23
|
+
const buf = Bytes.alloc();
|
|
24
|
+
while (true) {
|
|
25
|
+
const byte = readable.readSync(1);
|
|
26
|
+
if (byte.length === 0) {
|
|
27
|
+
throw new PartialReadError(buf.result(), buf.available + 1);
|
|
28
|
+
}
|
|
29
|
+
buf.writeSync(1)[0] = byte[0];
|
|
30
|
+
if (condition(byte[0])) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return buf.result();
|
|
35
|
+
}
|
|
36
|
+
function untilEnd(readable, chunkSize = 1024) {
|
|
37
|
+
const buf = Bytes.alloc(chunkSize);
|
|
38
|
+
while (true) {
|
|
39
|
+
const chunk = readable.readSync(chunkSize);
|
|
40
|
+
if (chunk.length === 0) {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
buf.writeSync(chunk.length).set(chunk);
|
|
44
|
+
}
|
|
45
|
+
return buf.result();
|
|
46
|
+
}
|
|
47
|
+
function untilZero(readable) {
|
|
48
|
+
return untilCondition(readable, (byte) => byte === 0);
|
|
49
|
+
}
|
|
50
|
+
function cUtf8String(readable) {
|
|
51
|
+
const buf = untilZero(readable);
|
|
52
|
+
return utf8.decoder.decode(buf.subarray(0, buf.length - 1));
|
|
53
|
+
}
|
|
54
|
+
function lengthPrefixed(readLength, readable) {
|
|
55
|
+
const length = readLength(readable);
|
|
56
|
+
return exactly(readable, length);
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
cUtf8String,
|
|
60
|
+
exactly,
|
|
61
|
+
lengthPrefixed,
|
|
62
|
+
rawString,
|
|
63
|
+
untilCondition,
|
|
64
|
+
untilEnd,
|
|
65
|
+
untilZero,
|
|
66
|
+
utf8String
|
|
67
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
class ReaderWithFinal {
|
|
4
|
+
#buf1;
|
|
5
|
+
#buf2;
|
|
6
|
+
#readable;
|
|
7
|
+
#prev = null;
|
|
8
|
+
#ended = false;
|
|
9
|
+
constructor(readable, params) {
|
|
10
|
+
this.#readable = readable;
|
|
11
|
+
const bufSize = params?.internalBufferSize ?? 1024 * 32;
|
|
12
|
+
this.#buf1 = new Uint8Array(bufSize);
|
|
13
|
+
this.#buf2 = new Uint8Array(bufSize);
|
|
14
|
+
}
|
|
15
|
+
#swapBufs() {
|
|
16
|
+
const tmp = this.#buf1;
|
|
17
|
+
this.#buf1 = this.#buf2;
|
|
18
|
+
this.#buf2 = tmp;
|
|
19
|
+
}
|
|
20
|
+
async readWithFinal(into) {
|
|
21
|
+
if (this.#ended) {
|
|
22
|
+
return {
|
|
23
|
+
nread: 0,
|
|
24
|
+
final: true
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (!this.#prev) {
|
|
28
|
+
const nread2 = await this.#readable.read(this.#buf1);
|
|
29
|
+
if (nread2 === 0) {
|
|
30
|
+
return {
|
|
31
|
+
nread: 0,
|
|
32
|
+
final: true
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
this.#prev = this.#buf1.subarray(0, nread2);
|
|
36
|
+
this.#swapBufs();
|
|
37
|
+
}
|
|
38
|
+
if (this.#prev.length > into.length) {
|
|
39
|
+
into.set(this.#prev.subarray(0, into.length));
|
|
40
|
+
this.#prev = this.#prev.subarray(into.length);
|
|
41
|
+
return {
|
|
42
|
+
nread: into.length,
|
|
43
|
+
final: false
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const nread = await this.#readable.read(this.#buf1);
|
|
47
|
+
if (nread === 0) {
|
|
48
|
+
into.set(this.#prev);
|
|
49
|
+
this.#ended = true;
|
|
50
|
+
return {
|
|
51
|
+
nread: this.#prev.length,
|
|
52
|
+
final: true
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
into.set(this.#prev);
|
|
56
|
+
const nwritten = this.#prev.length;
|
|
57
|
+
this.#prev = this.#buf1.subarray(0, nread);
|
|
58
|
+
this.#swapBufs();
|
|
59
|
+
return {
|
|
60
|
+
nread: nwritten,
|
|
61
|
+
final: false
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async read(into) {
|
|
65
|
+
const res = await this.readWithFinal(into);
|
|
66
|
+
return res.nread;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.ReaderWithFinal = ReaderWithFinal;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IReadable } from './types.js';
|
|
2
|
+
export interface ReaderWithFinalResult {
|
|
3
|
+
readonly nread: number;
|
|
4
|
+
readonly final: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare class ReaderWithFinal implements IReadable {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(readable: IReadable, params?: {
|
|
9
|
+
internalBufferSize?: number;
|
|
10
|
+
});
|
|
11
|
+
readWithFinal(into: Uint8Array): Promise<ReaderWithFinalResult>;
|
|
12
|
+
read(into: Uint8Array): Promise<number>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
class ReaderWithFinal {
|
|
2
|
+
#buf1;
|
|
3
|
+
#buf2;
|
|
4
|
+
#readable;
|
|
5
|
+
#prev = null;
|
|
6
|
+
#ended = false;
|
|
7
|
+
constructor(readable, params) {
|
|
8
|
+
this.#readable = readable;
|
|
9
|
+
const bufSize = params?.internalBufferSize ?? 1024 * 32;
|
|
10
|
+
this.#buf1 = new Uint8Array(bufSize);
|
|
11
|
+
this.#buf2 = new Uint8Array(bufSize);
|
|
12
|
+
}
|
|
13
|
+
#swapBufs() {
|
|
14
|
+
const tmp = this.#buf1;
|
|
15
|
+
this.#buf1 = this.#buf2;
|
|
16
|
+
this.#buf2 = tmp;
|
|
17
|
+
}
|
|
18
|
+
async readWithFinal(into) {
|
|
19
|
+
if (this.#ended) {
|
|
20
|
+
return {
|
|
21
|
+
nread: 0,
|
|
22
|
+
final: true
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (!this.#prev) {
|
|
26
|
+
const nread2 = await this.#readable.read(this.#buf1);
|
|
27
|
+
if (nread2 === 0) {
|
|
28
|
+
return {
|
|
29
|
+
nread: 0,
|
|
30
|
+
final: true
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
this.#prev = this.#buf1.subarray(0, nread2);
|
|
34
|
+
this.#swapBufs();
|
|
35
|
+
}
|
|
36
|
+
if (this.#prev.length > into.length) {
|
|
37
|
+
into.set(this.#prev.subarray(0, into.length));
|
|
38
|
+
this.#prev = this.#prev.subarray(into.length);
|
|
39
|
+
return {
|
|
40
|
+
nread: into.length,
|
|
41
|
+
final: false
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const nread = await this.#readable.read(this.#buf1);
|
|
45
|
+
if (nread === 0) {
|
|
46
|
+
into.set(this.#prev);
|
|
47
|
+
this.#ended = true;
|
|
48
|
+
return {
|
|
49
|
+
nread: this.#prev.length,
|
|
50
|
+
final: true
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
into.set(this.#prev);
|
|
54
|
+
const nwritten = this.#prev.length;
|
|
55
|
+
this.#prev = this.#buf1.subarray(0, nread);
|
|
56
|
+
this.#swapBufs();
|
|
57
|
+
return {
|
|
58
|
+
nread: nwritten,
|
|
59
|
+
final: false
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async read(into) {
|
|
63
|
+
const res = await this.readWithFinal(into);
|
|
64
|
+
return res.nread;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
ReaderWithFinal
|
|
69
|
+
};
|
package/streams.cjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function isByobCapableStream(stream) {
|
|
4
|
+
try {
|
|
5
|
+
const reader = stream.getReader({ mode: "byob" });
|
|
6
|
+
reader.releaseLock();
|
|
7
|
+
return true;
|
|
8
|
+
} catch (e) {
|
|
9
|
+
if (e instanceof TypeError) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
throw e;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.isByobCapableStream = isByobCapableStream;
|
package/streams.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isByobCapableStream(stream: ReadableStream<Uint8Array>): boolean;
|
package/streams.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function isByobCapableStream(stream) {
|
|
2
|
+
try {
|
|
3
|
+
const reader = stream.getReader({ mode: "byob" });
|
|
4
|
+
reader.releaseLock();
|
|
5
|
+
return true;
|
|
6
|
+
} catch (e) {
|
|
7
|
+
if (e instanceof TypeError) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
throw e;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
isByobCapableStream
|
|
15
|
+
};
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An interface for reading bytes synchronously from somewhere.
|
|
3
|
+
*/
|
|
4
|
+
export interface ISyncReadable {
|
|
5
|
+
/**
|
|
6
|
+
* Read the specified number of bytes from the source
|
|
7
|
+
* and return them as a Uint8Array.
|
|
8
|
+
*
|
|
9
|
+
* **The returned Uint8Array**:
|
|
10
|
+
* - *may* be a view into a larger buffer
|
|
11
|
+
* - is only valid until the next call to `readSync`
|
|
12
|
+
* - may be smaller than the requested number of bytes if the end of the source is reached.
|
|
13
|
+
* > these constraints allow for more efficient zero-copy implementations in many cases
|
|
14
|
+
*
|
|
15
|
+
* @param bytes The number of bytes to read
|
|
16
|
+
* @returns Uint8Array containing the bytes that were read.
|
|
17
|
+
*/
|
|
18
|
+
readSync: (bytes: number) => Uint8Array;
|
|
19
|
+
}
|
|
20
|
+
export interface IReadable {
|
|
21
|
+
/**
|
|
22
|
+
* Read data from the underlying source into the provided Uint8Array,
|
|
23
|
+
* up to the length of the array, and return the number of bytes read.
|
|
24
|
+
*
|
|
25
|
+
* If there are no bytes available currently, the implementation is supposed to wait
|
|
26
|
+
* until at least one byte is available, and only then resolve the promise.
|
|
27
|
+
* Resolving the promise with a zero-length Uint8Array is marking the end of the source.
|
|
28
|
+
*
|
|
29
|
+
* @param bytes The number of bytes to read
|
|
30
|
+
* @returns Uint8Array containing the bytes that were read.
|
|
31
|
+
*/
|
|
32
|
+
read: (into: Uint8Array) => Promise<number>;
|
|
33
|
+
}
|
|
34
|
+
export interface IClosable {
|
|
35
|
+
/**
|
|
36
|
+
* Close the underlying source.
|
|
37
|
+
*/
|
|
38
|
+
close: () => void;
|
|
39
|
+
}
|
|
40
|
+
export interface ISyncWritable {
|
|
41
|
+
/**
|
|
42
|
+
* Write the specified number of bytes to the underlying source.
|
|
43
|
+
*
|
|
44
|
+
* The implementation is supposed to make sure there are at least `bytes` bytes
|
|
45
|
+
* available in the underlying source and return a Uint8Array that can be written to.
|
|
46
|
+
* The returned Uint8Array must be valid at least until the next call to `writeSync`
|
|
47
|
+
* or `disposeWriteSync`.
|
|
48
|
+
*
|
|
49
|
+
* If the caller writes less than `bytes` bytes to the returned Uint8Array,
|
|
50
|
+
* `disposeWriteSync` must be called with the number of bytes that were actually written.
|
|
51
|
+
*
|
|
52
|
+
* @param bytes The number of bytes to write
|
|
53
|
+
* @returns Uint8Array of length `bytes` that can be written to
|
|
54
|
+
*/
|
|
55
|
+
writeSync: (bytes: number) => Uint8Array;
|
|
56
|
+
/**
|
|
57
|
+
* Explicitly dispose of the buffer that was returned by the last call to `writeSync`.
|
|
58
|
+
*
|
|
59
|
+
* If less than `bytes` bytes were written to the buffer, the number of bytes that were
|
|
60
|
+
* written must be passed as the `written` argument.
|
|
61
|
+
*/
|
|
62
|
+
disposeWriteSync: (written?: number) => void;
|
|
63
|
+
}
|
|
64
|
+
export interface IWritable {
|
|
65
|
+
write: (bytes: Uint8Array) => Promise<void>;
|
|
66
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function fumanSyncWritableToAsync(sync) {
|
|
4
|
+
return {
|
|
5
|
+
async write(bytes) {
|
|
6
|
+
const buf = sync.writeSync(bytes.length);
|
|
7
|
+
buf.set(bytes);
|
|
8
|
+
sync.disposeWriteSync();
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function webWritableToFuman(writable) {
|
|
13
|
+
const writer = writable.getWriter();
|
|
14
|
+
return {
|
|
15
|
+
async write(bytes) {
|
|
16
|
+
await writer.write(bytes);
|
|
17
|
+
},
|
|
18
|
+
close() {
|
|
19
|
+
writer.close().catch(() => {
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function fumanWritableToWeb(writable) {
|
|
25
|
+
return new WritableStream({
|
|
26
|
+
async write(chunk) {
|
|
27
|
+
await writable.write(chunk);
|
|
28
|
+
},
|
|
29
|
+
close() {
|
|
30
|
+
if ("close" in writable) {
|
|
31
|
+
writable.close();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
exports.fumanSyncWritableToAsync = fumanSyncWritableToAsync;
|
|
37
|
+
exports.fumanWritableToWeb = fumanWritableToWeb;
|
|
38
|
+
exports.webWritableToFuman = webWritableToFuman;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { IClosable, ISyncWritable, IWritable } from '../types.js';
|
|
2
|
+
export declare function fumanSyncWritableToAsync(sync: ISyncWritable): IWritable;
|
|
3
|
+
export declare function webWritableToFuman(writable: WritableStream<Uint8Array>): IWritable & IClosable;
|
|
4
|
+
export declare function fumanWritableToWeb(writable: IWritable): WritableStream<Uint8Array>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function fumanSyncWritableToAsync(sync) {
|
|
2
|
+
return {
|
|
3
|
+
async write(bytes) {
|
|
4
|
+
const buf = sync.writeSync(bytes.length);
|
|
5
|
+
buf.set(bytes);
|
|
6
|
+
sync.disposeWriteSync();
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function webWritableToFuman(writable) {
|
|
11
|
+
const writer = writable.getWriter();
|
|
12
|
+
return {
|
|
13
|
+
async write(bytes) {
|
|
14
|
+
await writer.write(bytes);
|
|
15
|
+
},
|
|
16
|
+
close() {
|
|
17
|
+
writer.close().catch(() => {
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function fumanWritableToWeb(writable) {
|
|
23
|
+
return new WritableStream({
|
|
24
|
+
async write(chunk) {
|
|
25
|
+
await writable.write(chunk);
|
|
26
|
+
},
|
|
27
|
+
close() {
|
|
28
|
+
if ("close" in writable) {
|
|
29
|
+
writable.close();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
fumanSyncWritableToAsync,
|
|
36
|
+
fumanWritableToWeb,
|
|
37
|
+
webWritableToFuman
|
|
38
|
+
};
|