strtok3 8.0.2 → 8.0.4
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/lib/AbstractTokenizer.d.ts +75 -0
- package/lib/AbstractTokenizer.js +108 -0
- package/lib/BufferTokenizer.d.ts +26 -0
- package/lib/BufferTokenizer.js +49 -0
- package/lib/FileTokenizer.d.ts +23 -0
- package/lib/FileTokenizer.js +50 -0
- package/lib/ReadStreamTokenizer.d.ts +27 -0
- package/lib/ReadStreamTokenizer.js +92 -0
- package/lib/core.d.ts +33 -0
- package/lib/core.js +34 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.js +22 -0
- package/lib/types.d.ts +113 -0
- package/lib/types.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ITokenizer, IFileInfo, IReadChunkOptions, ITokenizerOptions } from './types.js';
|
|
2
|
+
import type { IGetToken, IToken } from '@tokenizer/token';
|
|
3
|
+
interface INormalizedReadChunkOptions extends IReadChunkOptions {
|
|
4
|
+
offset: number;
|
|
5
|
+
length: number;
|
|
6
|
+
position: number;
|
|
7
|
+
mayBeLess?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Core tokenizer
|
|
11
|
+
*/
|
|
12
|
+
export declare abstract class AbstractTokenizer implements ITokenizer {
|
|
13
|
+
fileInfo: IFileInfo;
|
|
14
|
+
private onClose?;
|
|
15
|
+
/**
|
|
16
|
+
* Constructor
|
|
17
|
+
* @param options Tokenizer options
|
|
18
|
+
* @protected
|
|
19
|
+
*/
|
|
20
|
+
protected constructor(options?: ITokenizerOptions);
|
|
21
|
+
/**
|
|
22
|
+
* Tokenizer-stream position
|
|
23
|
+
*/
|
|
24
|
+
position: number;
|
|
25
|
+
private numBuffer;
|
|
26
|
+
/**
|
|
27
|
+
* Read buffer from tokenizer
|
|
28
|
+
* @param buffer - Target buffer to fill with data read from the tokenizer-stream
|
|
29
|
+
* @param options - Additional read options
|
|
30
|
+
* @returns Promise with number of bytes read
|
|
31
|
+
*/
|
|
32
|
+
abstract readBuffer(buffer: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
33
|
+
/**
|
|
34
|
+
* Peek (read ahead) buffer from tokenizer
|
|
35
|
+
* @param uint8Array - Target buffer to fill with data peeked from the tokenizer-stream
|
|
36
|
+
* @param options - Peek behaviour options
|
|
37
|
+
* @returns Promise with number of bytes read
|
|
38
|
+
*/
|
|
39
|
+
abstract peekBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Read a token from the tokenizer-stream
|
|
42
|
+
* @param token - The token to read
|
|
43
|
+
* @param position - If provided, the desired position in the tokenizer-stream
|
|
44
|
+
* @returns Promise with token data
|
|
45
|
+
*/
|
|
46
|
+
readToken<Value>(token: IGetToken<Value>, position?: number): Promise<Value>;
|
|
47
|
+
/**
|
|
48
|
+
* Peek a token from the tokenizer-stream.
|
|
49
|
+
* @param token - Token to peek from the tokenizer-stream.
|
|
50
|
+
* @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
|
|
51
|
+
* @returns Promise with token data
|
|
52
|
+
*/
|
|
53
|
+
peekToken<Value>(token: IGetToken<Value>, position?: number): Promise<Value>;
|
|
54
|
+
/**
|
|
55
|
+
* Read a numeric token from the stream
|
|
56
|
+
* @param token - Numeric token
|
|
57
|
+
* @returns Promise with number
|
|
58
|
+
*/
|
|
59
|
+
readNumber(token: IToken<number>): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* Read a numeric token from the stream
|
|
62
|
+
* @param token - Numeric token
|
|
63
|
+
* @returns Promise with number
|
|
64
|
+
*/
|
|
65
|
+
peekNumber(token: IToken<number>): Promise<number>;
|
|
66
|
+
/**
|
|
67
|
+
* Ignore number of bytes, advances the pointer in under tokenizer-stream.
|
|
68
|
+
* @param length - Number of bytes to ignore
|
|
69
|
+
* @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
|
|
70
|
+
*/
|
|
71
|
+
ignore(length: number): Promise<number>;
|
|
72
|
+
close(): Promise<void>;
|
|
73
|
+
protected normalizeOptions(uint8Array: Uint8Array, options?: IReadChunkOptions): INormalizedReadChunkOptions;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { EndOfStreamError } from 'peek-readable';
|
|
2
|
+
/**
|
|
3
|
+
* Core tokenizer
|
|
4
|
+
*/
|
|
5
|
+
export class AbstractTokenizer {
|
|
6
|
+
/**
|
|
7
|
+
* Constructor
|
|
8
|
+
* @param options Tokenizer options
|
|
9
|
+
* @protected
|
|
10
|
+
*/
|
|
11
|
+
constructor(options) {
|
|
12
|
+
var _a;
|
|
13
|
+
/**
|
|
14
|
+
* Tokenizer-stream position
|
|
15
|
+
*/
|
|
16
|
+
this.position = 0;
|
|
17
|
+
this.numBuffer = new Uint8Array(8);
|
|
18
|
+
this.fileInfo = (_a = options === null || options === void 0 ? void 0 : options.fileInfo) !== null && _a !== void 0 ? _a : {};
|
|
19
|
+
this.onClose = options === null || options === void 0 ? void 0 : options.onClose;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read a token from the tokenizer-stream
|
|
23
|
+
* @param token - The token to read
|
|
24
|
+
* @param position - If provided, the desired position in the tokenizer-stream
|
|
25
|
+
* @returns Promise with token data
|
|
26
|
+
*/
|
|
27
|
+
async readToken(token, position = this.position) {
|
|
28
|
+
const uint8Array = new Uint8Array(token.len);
|
|
29
|
+
const len = await this.readBuffer(uint8Array, { position });
|
|
30
|
+
if (len < token.len)
|
|
31
|
+
throw new EndOfStreamError();
|
|
32
|
+
return token.get(uint8Array, 0);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Peek a token from the tokenizer-stream.
|
|
36
|
+
* @param token - Token to peek from the tokenizer-stream.
|
|
37
|
+
* @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
|
|
38
|
+
* @returns Promise with token data
|
|
39
|
+
*/
|
|
40
|
+
async peekToken(token, position = this.position) {
|
|
41
|
+
const uint8Array = new Uint8Array(token.len);
|
|
42
|
+
const len = await this.peekBuffer(uint8Array, { position });
|
|
43
|
+
if (len < token.len)
|
|
44
|
+
throw new EndOfStreamError();
|
|
45
|
+
return token.get(uint8Array, 0);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Read a numeric token from the stream
|
|
49
|
+
* @param token - Numeric token
|
|
50
|
+
* @returns Promise with number
|
|
51
|
+
*/
|
|
52
|
+
async readNumber(token) {
|
|
53
|
+
const len = await this.readBuffer(this.numBuffer, { length: token.len });
|
|
54
|
+
if (len < token.len)
|
|
55
|
+
throw new EndOfStreamError();
|
|
56
|
+
return token.get(this.numBuffer, 0);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Read a numeric token from the stream
|
|
60
|
+
* @param token - Numeric token
|
|
61
|
+
* @returns Promise with number
|
|
62
|
+
*/
|
|
63
|
+
async peekNumber(token) {
|
|
64
|
+
const len = await this.peekBuffer(this.numBuffer, { length: token.len });
|
|
65
|
+
if (len < token.len)
|
|
66
|
+
throw new EndOfStreamError();
|
|
67
|
+
return token.get(this.numBuffer, 0);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Ignore number of bytes, advances the pointer in under tokenizer-stream.
|
|
71
|
+
* @param length - Number of bytes to ignore
|
|
72
|
+
* @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
|
|
73
|
+
*/
|
|
74
|
+
async ignore(length) {
|
|
75
|
+
if (this.fileInfo.size !== undefined) {
|
|
76
|
+
const bytesLeft = this.fileInfo.size - this.position;
|
|
77
|
+
if (length > bytesLeft) {
|
|
78
|
+
this.position += bytesLeft;
|
|
79
|
+
return bytesLeft;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.position += length;
|
|
83
|
+
return length;
|
|
84
|
+
}
|
|
85
|
+
async close() {
|
|
86
|
+
var _a;
|
|
87
|
+
await ((_a = this.onClose) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
88
|
+
}
|
|
89
|
+
normalizeOptions(uint8Array, options) {
|
|
90
|
+
if (options && options.position !== undefined && options.position < this.position) {
|
|
91
|
+
throw new Error('`options.position` must be equal or greater than `tokenizer.position`');
|
|
92
|
+
}
|
|
93
|
+
if (options) {
|
|
94
|
+
return {
|
|
95
|
+
mayBeLess: options.mayBeLess === true,
|
|
96
|
+
offset: options.offset ? options.offset : 0,
|
|
97
|
+
length: options.length ? options.length : (uint8Array.length - (options.offset ? options.offset : 0)),
|
|
98
|
+
position: options.position ? options.position : this.position
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
mayBeLess: false,
|
|
103
|
+
offset: 0,
|
|
104
|
+
length: uint8Array.length,
|
|
105
|
+
position: this.position
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ITokenizerOptions, IReadChunkOptions } from './types.js';
|
|
2
|
+
import { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
3
|
+
export declare class BufferTokenizer extends AbstractTokenizer {
|
|
4
|
+
private uint8Array;
|
|
5
|
+
/**
|
|
6
|
+
* Construct BufferTokenizer
|
|
7
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
8
|
+
* @param options Tokenizer options
|
|
9
|
+
*/
|
|
10
|
+
constructor(uint8Array: Uint8Array, options?: ITokenizerOptions);
|
|
11
|
+
/**
|
|
12
|
+
* Read buffer from tokenizer
|
|
13
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
14
|
+
* @param options - Read behaviour options
|
|
15
|
+
* @returns {Promise<number>}
|
|
16
|
+
*/
|
|
17
|
+
readBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
18
|
+
/**
|
|
19
|
+
* Peek (read ahead) buffer from tokenizer
|
|
20
|
+
* @param uint8Array
|
|
21
|
+
* @param options - Read behaviour options
|
|
22
|
+
* @returns {Promise<number>}
|
|
23
|
+
*/
|
|
24
|
+
peekBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { EndOfStreamError } from 'peek-readable';
|
|
2
|
+
import { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
3
|
+
export class BufferTokenizer extends AbstractTokenizer {
|
|
4
|
+
/**
|
|
5
|
+
* Construct BufferTokenizer
|
|
6
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
7
|
+
* @param options Tokenizer options
|
|
8
|
+
*/
|
|
9
|
+
constructor(uint8Array, options) {
|
|
10
|
+
super(options);
|
|
11
|
+
this.uint8Array = uint8Array;
|
|
12
|
+
this.fileInfo.size = this.fileInfo.size ? this.fileInfo.size : uint8Array.length;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read buffer from tokenizer
|
|
16
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
17
|
+
* @param options - Read behaviour options
|
|
18
|
+
* @returns {Promise<number>}
|
|
19
|
+
*/
|
|
20
|
+
async readBuffer(uint8Array, options) {
|
|
21
|
+
if (options === null || options === void 0 ? void 0 : options.position) {
|
|
22
|
+
if (options.position < this.position) {
|
|
23
|
+
throw new Error('`options.position` must be equal or greater than `tokenizer.position`');
|
|
24
|
+
}
|
|
25
|
+
this.position = options.position;
|
|
26
|
+
}
|
|
27
|
+
const bytesRead = await this.peekBuffer(uint8Array, options);
|
|
28
|
+
this.position += bytesRead;
|
|
29
|
+
return bytesRead;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Peek (read ahead) buffer from tokenizer
|
|
33
|
+
* @param uint8Array
|
|
34
|
+
* @param options - Read behaviour options
|
|
35
|
+
* @returns {Promise<number>}
|
|
36
|
+
*/
|
|
37
|
+
async peekBuffer(uint8Array, options) {
|
|
38
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
39
|
+
const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length);
|
|
40
|
+
if ((!normOptions.mayBeLess) && bytes2read < normOptions.length) {
|
|
41
|
+
throw new EndOfStreamError();
|
|
42
|
+
}
|
|
43
|
+
uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read), normOptions.offset);
|
|
44
|
+
return bytes2read;
|
|
45
|
+
}
|
|
46
|
+
close() {
|
|
47
|
+
return super.close();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
2
|
+
import type { IReadChunkOptions, ITokenizerOptions } from './types.js';
|
|
3
|
+
import { type FileHandle } from 'node:fs/promises';
|
|
4
|
+
export declare class FileTokenizer extends AbstractTokenizer {
|
|
5
|
+
private fileHandle;
|
|
6
|
+
constructor(fileHandle: FileHandle, options: ITokenizerOptions);
|
|
7
|
+
/**
|
|
8
|
+
* Read buffer from file
|
|
9
|
+
* @param uint8Array - Uint8Array to write result to
|
|
10
|
+
* @param options - Read behaviour options
|
|
11
|
+
* @returns Promise number of bytes read
|
|
12
|
+
*/
|
|
13
|
+
readBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
14
|
+
/**
|
|
15
|
+
* Peek buffer from file
|
|
16
|
+
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
17
|
+
* @param options - Read behaviour options
|
|
18
|
+
* @returns Promise number of bytes read
|
|
19
|
+
*/
|
|
20
|
+
peekBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare function fromFile(sourceFilePath: string): Promise<FileTokenizer>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
2
|
+
import { EndOfStreamError } from 'peek-readable';
|
|
3
|
+
import { open as fsOpen } from 'node:fs/promises';
|
|
4
|
+
export class FileTokenizer extends AbstractTokenizer {
|
|
5
|
+
constructor(fileHandle, options) {
|
|
6
|
+
super(options);
|
|
7
|
+
this.fileHandle = fileHandle;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Read buffer from file
|
|
11
|
+
* @param uint8Array - Uint8Array to write result to
|
|
12
|
+
* @param options - Read behaviour options
|
|
13
|
+
* @returns Promise number of bytes read
|
|
14
|
+
*/
|
|
15
|
+
async readBuffer(uint8Array, options) {
|
|
16
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
17
|
+
this.position = normOptions.position;
|
|
18
|
+
if (normOptions.length === 0)
|
|
19
|
+
return 0;
|
|
20
|
+
const res = await this.fileHandle.read(uint8Array, normOptions.offset, normOptions.length, normOptions.position);
|
|
21
|
+
this.position += res.bytesRead;
|
|
22
|
+
if (res.bytesRead < normOptions.length && (!options || !options.mayBeLess)) {
|
|
23
|
+
throw new EndOfStreamError();
|
|
24
|
+
}
|
|
25
|
+
return res.bytesRead;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Peek buffer from file
|
|
29
|
+
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
30
|
+
* @param options - Read behaviour options
|
|
31
|
+
* @returns Promise number of bytes read
|
|
32
|
+
*/
|
|
33
|
+
async peekBuffer(uint8Array, options) {
|
|
34
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
35
|
+
const res = await this.fileHandle.read(uint8Array, normOptions.offset, normOptions.length, normOptions.position);
|
|
36
|
+
if ((!normOptions.mayBeLess) && res.bytesRead < normOptions.length) {
|
|
37
|
+
throw new EndOfStreamError();
|
|
38
|
+
}
|
|
39
|
+
return res.bytesRead;
|
|
40
|
+
}
|
|
41
|
+
async close() {
|
|
42
|
+
await this.fileHandle.close();
|
|
43
|
+
return super.close();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export async function fromFile(sourceFilePath) {
|
|
47
|
+
const fileHandle = await fsOpen(sourceFilePath, 'r');
|
|
48
|
+
const stat = await fileHandle.stat();
|
|
49
|
+
return new FileTokenizer(fileHandle, { fileInfo: { path: sourceFilePath, size: stat.size } });
|
|
50
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
2
|
+
import { type IStreamReader } from 'peek-readable';
|
|
3
|
+
import type { IReadChunkOptions, ITokenizerOptions } from './types.js';
|
|
4
|
+
export declare class ReadStreamTokenizer extends AbstractTokenizer {
|
|
5
|
+
private streamReader;
|
|
6
|
+
/**
|
|
7
|
+
* Constructor
|
|
8
|
+
* @param streamReader stream-reader to read from
|
|
9
|
+
* @param options Tokenizer options
|
|
10
|
+
*/
|
|
11
|
+
constructor(streamReader: IStreamReader, options?: ITokenizerOptions);
|
|
12
|
+
/**
|
|
13
|
+
* Read buffer from tokenizer
|
|
14
|
+
* @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream
|
|
15
|
+
* @param options - Read behaviour options
|
|
16
|
+
* @returns Promise with number of bytes read
|
|
17
|
+
*/
|
|
18
|
+
readBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
19
|
+
/**
|
|
20
|
+
* Peek (read ahead) buffer from tokenizer
|
|
21
|
+
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
22
|
+
* @param options - Read behaviour options
|
|
23
|
+
* @returns Promise with number of bytes peeked
|
|
24
|
+
*/
|
|
25
|
+
peekBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
26
|
+
ignore(length: number): Promise<number>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
2
|
+
import { EndOfStreamError } from 'peek-readable';
|
|
3
|
+
const maxBufferSize = 256000;
|
|
4
|
+
export class ReadStreamTokenizer extends AbstractTokenizer {
|
|
5
|
+
/**
|
|
6
|
+
* Constructor
|
|
7
|
+
* @param streamReader stream-reader to read from
|
|
8
|
+
* @param options Tokenizer options
|
|
9
|
+
*/
|
|
10
|
+
constructor(streamReader, options) {
|
|
11
|
+
super(options);
|
|
12
|
+
this.streamReader = streamReader;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read buffer from tokenizer
|
|
16
|
+
* @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream
|
|
17
|
+
* @param options - Read behaviour options
|
|
18
|
+
* @returns Promise with number of bytes read
|
|
19
|
+
*/
|
|
20
|
+
async readBuffer(uint8Array, options) {
|
|
21
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
22
|
+
const skipBytes = normOptions.position - this.position;
|
|
23
|
+
if (skipBytes > 0) {
|
|
24
|
+
await this.ignore(skipBytes);
|
|
25
|
+
return this.readBuffer(uint8Array, options);
|
|
26
|
+
}
|
|
27
|
+
if (skipBytes < 0) {
|
|
28
|
+
throw new Error('`options.position` must be equal or greater than `tokenizer.position`');
|
|
29
|
+
}
|
|
30
|
+
if (normOptions.length === 0) {
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
const bytesRead = await this.streamReader.read(uint8Array, normOptions.offset, normOptions.length);
|
|
34
|
+
this.position += bytesRead;
|
|
35
|
+
if ((!options || !options.mayBeLess) && bytesRead < normOptions.length) {
|
|
36
|
+
throw new EndOfStreamError();
|
|
37
|
+
}
|
|
38
|
+
return bytesRead;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Peek (read ahead) buffer from tokenizer
|
|
42
|
+
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
43
|
+
* @param options - Read behaviour options
|
|
44
|
+
* @returns Promise with number of bytes peeked
|
|
45
|
+
*/
|
|
46
|
+
async peekBuffer(uint8Array, options) {
|
|
47
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
48
|
+
let bytesRead = 0;
|
|
49
|
+
if (normOptions.position) {
|
|
50
|
+
const skipBytes = normOptions.position - this.position;
|
|
51
|
+
if (skipBytes > 0) {
|
|
52
|
+
const skipBuffer = new Uint8Array(normOptions.length + skipBytes);
|
|
53
|
+
bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: normOptions.mayBeLess });
|
|
54
|
+
uint8Array.set(skipBuffer.subarray(skipBytes), normOptions.offset);
|
|
55
|
+
return bytesRead - skipBytes;
|
|
56
|
+
}
|
|
57
|
+
if (skipBytes < 0) {
|
|
58
|
+
throw new Error('Cannot peek from a negative offset in a stream');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (normOptions.length > 0) {
|
|
62
|
+
try {
|
|
63
|
+
bytesRead = await this.streamReader.peek(uint8Array, normOptions.offset, normOptions.length);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if ((options === null || options === void 0 ? void 0 : options.mayBeLess) && err instanceof EndOfStreamError) {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
if ((!normOptions.mayBeLess) && bytesRead < normOptions.length) {
|
|
72
|
+
throw new EndOfStreamError();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return bytesRead;
|
|
76
|
+
}
|
|
77
|
+
async ignore(length) {
|
|
78
|
+
// debug(`ignore ${this.position}...${this.position + length - 1}`);
|
|
79
|
+
const bufSize = Math.min(maxBufferSize, length);
|
|
80
|
+
const buf = new Uint8Array(bufSize);
|
|
81
|
+
let totBytesRead = 0;
|
|
82
|
+
while (totBytesRead < length) {
|
|
83
|
+
const remaining = length - totBytesRead;
|
|
84
|
+
const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) });
|
|
85
|
+
if (bytesRead < 0) {
|
|
86
|
+
return bytesRead;
|
|
87
|
+
}
|
|
88
|
+
totBytesRead += bytesRead;
|
|
89
|
+
}
|
|
90
|
+
return totBytesRead;
|
|
91
|
+
}
|
|
92
|
+
}
|
package/lib/core.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ReadStreamTokenizer } from './ReadStreamTokenizer.js';
|
|
2
|
+
import { BufferTokenizer } from './BufferTokenizer.js';
|
|
3
|
+
import type { ITokenizerOptions } from './types.js';
|
|
4
|
+
import type { ReadableStream as NodeReadableStream, ReadableStream } from 'node:stream/web';
|
|
5
|
+
import type { Readable } from 'node:stream';
|
|
6
|
+
export { EndOfStreamError } from 'peek-readable';
|
|
7
|
+
export type { ITokenizer, IFileInfo, ITokenizerOptions, IReadChunkOptions, OnClose } from './types.js';
|
|
8
|
+
export type { IToken, IGetToken } from '@tokenizer/token';
|
|
9
|
+
export { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
10
|
+
export type AnyWebByteStream = NodeReadableStream<Uint8Array> | ReadableStream<Uint8Array>;
|
|
11
|
+
/**
|
|
12
|
+
* Construct ReadStreamTokenizer from given Stream.
|
|
13
|
+
* Will set fileSize, if provided given Stream has set the .path property/
|
|
14
|
+
* @param stream - Read from Node.js Stream.Readable
|
|
15
|
+
* @param options - Tokenizer options
|
|
16
|
+
* @returns ReadStreamTokenizer
|
|
17
|
+
*/
|
|
18
|
+
export declare function fromStream(stream: Readable, options?: ITokenizerOptions): ReadStreamTokenizer;
|
|
19
|
+
/**
|
|
20
|
+
* Construct ReadStreamTokenizer from given ReadableStream (WebStream API).
|
|
21
|
+
* Will set fileSize, if provided given Stream has set the .path property/
|
|
22
|
+
* @param webStream - Read from Node.js Stream.Readable (must be a byte stream)
|
|
23
|
+
* @param options - Tokenizer options
|
|
24
|
+
* @returns ReadStreamTokenizer
|
|
25
|
+
*/
|
|
26
|
+
export declare function fromWebStream(webStream: AnyWebByteStream, options?: ITokenizerOptions): ReadStreamTokenizer;
|
|
27
|
+
/**
|
|
28
|
+
* Construct ReadStreamTokenizer from given Buffer.
|
|
29
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
30
|
+
* @param options - Tokenizer options
|
|
31
|
+
* @returns BufferTokenizer
|
|
32
|
+
*/
|
|
33
|
+
export declare function fromBuffer(uint8Array: Uint8Array, options?: ITokenizerOptions): BufferTokenizer;
|
package/lib/core.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ReadStreamTokenizer } from './ReadStreamTokenizer.js';
|
|
2
|
+
import { BufferTokenizer } from './BufferTokenizer.js';
|
|
3
|
+
import { StreamReader, WebStreamReader } from 'peek-readable';
|
|
4
|
+
export { EndOfStreamError } from 'peek-readable';
|
|
5
|
+
export { AbstractTokenizer } from './AbstractTokenizer.js';
|
|
6
|
+
/**
|
|
7
|
+
* Construct ReadStreamTokenizer from given Stream.
|
|
8
|
+
* Will set fileSize, if provided given Stream has set the .path property/
|
|
9
|
+
* @param stream - Read from Node.js Stream.Readable
|
|
10
|
+
* @param options - Tokenizer options
|
|
11
|
+
* @returns ReadStreamTokenizer
|
|
12
|
+
*/
|
|
13
|
+
export function fromStream(stream, options) {
|
|
14
|
+
return new ReadStreamTokenizer(new StreamReader(stream), options);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Construct ReadStreamTokenizer from given ReadableStream (WebStream API).
|
|
18
|
+
* Will set fileSize, if provided given Stream has set the .path property/
|
|
19
|
+
* @param webStream - Read from Node.js Stream.Readable (must be a byte stream)
|
|
20
|
+
* @param options - Tokenizer options
|
|
21
|
+
* @returns ReadStreamTokenizer
|
|
22
|
+
*/
|
|
23
|
+
export function fromWebStream(webStream, options) {
|
|
24
|
+
return new ReadStreamTokenizer(new WebStreamReader(webStream), options);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Construct ReadStreamTokenizer from given Buffer.
|
|
28
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
29
|
+
* @param options - Tokenizer options
|
|
30
|
+
* @returns BufferTokenizer
|
|
31
|
+
*/
|
|
32
|
+
export function fromBuffer(uint8Array, options) {
|
|
33
|
+
return new BufferTokenizer(uint8Array, options);
|
|
34
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
import type { ReadStreamTokenizer } from './ReadStreamTokenizer.js';
|
|
3
|
+
import { type ITokenizerOptions } from './core.js';
|
|
4
|
+
export { fromFile } from './FileTokenizer.js';
|
|
5
|
+
export { EndOfStreamError, fromBuffer, fromWebStream, AbstractTokenizer } from './core.js';
|
|
6
|
+
export type { ITokenizer, IFileInfo, ITokenizerOptions, IReadChunkOptions, OnClose, AnyWebByteStream } from './core.js';
|
|
7
|
+
export type { IToken, IGetToken } from '@tokenizer/token';
|
|
8
|
+
/**
|
|
9
|
+
* Construct ReadStreamTokenizer from given Stream.
|
|
10
|
+
* Will set fileSize, if provided given Stream has set the .path property.
|
|
11
|
+
* @param stream - Node.js Stream.Readable
|
|
12
|
+
* @param options - Pass additional file information to the tokenizer
|
|
13
|
+
* @returns Tokenizer
|
|
14
|
+
*/
|
|
15
|
+
export declare function fromStream(stream: Readable, options?: ITokenizerOptions): Promise<ReadStreamTokenizer>;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { stat as fsStat } from 'node:fs/promises';
|
|
2
|
+
import { fromStream as coreFromStream } from './core.js';
|
|
3
|
+
export { fromFile } from './FileTokenizer.js';
|
|
4
|
+
export { EndOfStreamError, fromBuffer, fromWebStream, AbstractTokenizer } from './core.js';
|
|
5
|
+
/**
|
|
6
|
+
* Construct ReadStreamTokenizer from given Stream.
|
|
7
|
+
* Will set fileSize, if provided given Stream has set the .path property.
|
|
8
|
+
* @param stream - Node.js Stream.Readable
|
|
9
|
+
* @param options - Pass additional file information to the tokenizer
|
|
10
|
+
* @returns Tokenizer
|
|
11
|
+
*/
|
|
12
|
+
export async function fromStream(stream, options) {
|
|
13
|
+
var _a;
|
|
14
|
+
const augmentedOptions = options !== null && options !== void 0 ? options : {};
|
|
15
|
+
augmentedOptions.fileInfo = (_a = augmentedOptions.fileInfo) !== null && _a !== void 0 ? _a : {};
|
|
16
|
+
if (stream.path) {
|
|
17
|
+
const stat = await fsStat(stream.path);
|
|
18
|
+
augmentedOptions.fileInfo.path = stream.path;
|
|
19
|
+
augmentedOptions.fileInfo.size = stat.size;
|
|
20
|
+
}
|
|
21
|
+
return coreFromStream(stream, augmentedOptions);
|
|
22
|
+
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { IGetToken } from '@tokenizer/token';
|
|
2
|
+
export interface IFileInfo {
|
|
3
|
+
/**
|
|
4
|
+
* File size in bytes
|
|
5
|
+
*/
|
|
6
|
+
size?: number;
|
|
7
|
+
/**
|
|
8
|
+
* MIME-type of file
|
|
9
|
+
*/
|
|
10
|
+
mimeType?: string;
|
|
11
|
+
/**
|
|
12
|
+
* File path
|
|
13
|
+
*/
|
|
14
|
+
path?: string;
|
|
15
|
+
/**
|
|
16
|
+
* File URL
|
|
17
|
+
*/
|
|
18
|
+
url?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface IReadChunkOptions {
|
|
21
|
+
/**
|
|
22
|
+
* The offset in the buffer to start writing at; default is 0
|
|
23
|
+
*/
|
|
24
|
+
offset?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Number of bytes to read.
|
|
27
|
+
*/
|
|
28
|
+
length?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Position where to begin reading from the file.
|
|
31
|
+
* Default it is `tokenizer.position`.
|
|
32
|
+
* Position may not be less then `tokenizer.position`.
|
|
33
|
+
*/
|
|
34
|
+
position?: number;
|
|
35
|
+
/**
|
|
36
|
+
* If set, will not throw an EOF error if not all of the requested data could be read
|
|
37
|
+
*/
|
|
38
|
+
mayBeLess?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The tokenizer allows us to read or peek from the tokenizer-stream.
|
|
42
|
+
* The tokenizer-stream is an abstraction of a stream, file or Buffer.
|
|
43
|
+
*/
|
|
44
|
+
export interface ITokenizer {
|
|
45
|
+
/**
|
|
46
|
+
* Provide access to information of the underlying information stream or file.
|
|
47
|
+
*/
|
|
48
|
+
fileInfo: IFileInfo;
|
|
49
|
+
/**
|
|
50
|
+
* Offset in bytes (= number of bytes read) since beginning of file or stream
|
|
51
|
+
*/
|
|
52
|
+
position: number;
|
|
53
|
+
/**
|
|
54
|
+
* Peek (read ahead) buffer from tokenizer
|
|
55
|
+
* @param buffer - Target buffer to fill with data peek from the tokenizer-stream
|
|
56
|
+
* @param options - Read behaviour options
|
|
57
|
+
* @returns Promise with number of bytes read
|
|
58
|
+
*/
|
|
59
|
+
peekBuffer(buffer: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* Peek (read ahead) buffer from tokenizer
|
|
62
|
+
* @param buffer - Target buffer to fill with data peeked from the tokenizer-stream
|
|
63
|
+
* @param options - Additional read options
|
|
64
|
+
* @returns Promise with number of bytes read
|
|
65
|
+
*/
|
|
66
|
+
readBuffer(buffer: Uint8Array, options?: IReadChunkOptions): Promise<number>;
|
|
67
|
+
/**
|
|
68
|
+
* Peek a token from the tokenizer-stream.
|
|
69
|
+
* @param token - Token to peek from the tokenizer-stream.
|
|
70
|
+
* @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
|
|
71
|
+
* @param maybeless - If set, will not throw an EOF error if the less then the requested length could be read.
|
|
72
|
+
*/
|
|
73
|
+
peekToken<T>(token: IGetToken<T>, position?: number | null, maybeless?: boolean): Promise<T>;
|
|
74
|
+
/**
|
|
75
|
+
* Read a token from the tokenizer-stream.
|
|
76
|
+
* @param token - Token to peek from the tokenizer-stream.
|
|
77
|
+
* @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
|
|
78
|
+
*/
|
|
79
|
+
readToken<T>(token: IGetToken<T>, position?: number): Promise<T>;
|
|
80
|
+
/**
|
|
81
|
+
* Peek a numeric token from the stream
|
|
82
|
+
* @param token - Numeric token
|
|
83
|
+
* @returns Promise with number
|
|
84
|
+
*/
|
|
85
|
+
peekNumber(token: IGetToken<number>): Promise<number>;
|
|
86
|
+
/**
|
|
87
|
+
* Read a numeric token from the stream
|
|
88
|
+
* @param token - Numeric token
|
|
89
|
+
* @returns Promise with number
|
|
90
|
+
*/
|
|
91
|
+
readNumber(token: IGetToken<number>): Promise<number>;
|
|
92
|
+
/**
|
|
93
|
+
* Ignore given number of bytes
|
|
94
|
+
* @param length - Number of bytes ignored
|
|
95
|
+
*/
|
|
96
|
+
ignore(length: number): Promise<number>;
|
|
97
|
+
/**
|
|
98
|
+
* Clean up resources.
|
|
99
|
+
* It does not close the stream for StreamReader, but is does close the file-descriptor.
|
|
100
|
+
*/
|
|
101
|
+
close(): Promise<void>;
|
|
102
|
+
}
|
|
103
|
+
export type OnClose = () => Promise<void>;
|
|
104
|
+
export interface ITokenizerOptions {
|
|
105
|
+
/**
|
|
106
|
+
* Pass additional file information to the tokenizer
|
|
107
|
+
*/
|
|
108
|
+
fileInfo?: IFileInfo;
|
|
109
|
+
/**
|
|
110
|
+
* On tokenizer close handler
|
|
111
|
+
*/
|
|
112
|
+
onClose?: OnClose;
|
|
113
|
+
}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|