strtok3 5.0.2 → 6.0.3

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/README.md CHANGED
@@ -48,7 +48,7 @@ All of the strtok3 methods return a [*tokenizer*](#tokenizer), either directly o
48
48
  |-----------|-----------------------|----------------------------|
49
49
  | path | Path to file (string) | Path to file to read from |
50
50
 
51
- Note that [file-information](#IFileInfo) is automatically added.
51
+ Note that [file-information](#file-information) is automatically added.
52
52
 
53
53
  Returns, via a promise, a [*tokenizer*](#tokenizer) which can be used to parse a file.
54
54
 
@@ -118,7 +118,7 @@ What is the difference with Nodejs.js stream?
118
118
  * The *tokenizer-stream* supports jumping / seeking in a the *tokenizer-stream* using [`tokenizer.ignore()`](#method-tokenizerignore)
119
119
  * In addition to *read* methods, it has *peek* methods, to read a ahead and check what is coming.
120
120
 
121
- The [tokenizer.position](#attribute-tokenizerposition) keeps tracks of
121
+ The [tokenizer.position](#attribute-tokenizerposition) keeps tracks of the read position.
122
122
 
123
123
  ### strtok3 attributes
124
124
 
@@ -139,62 +139,54 @@ There are to groups of methods
139
139
  #### Method `tokenizer.readBuffer()`
140
140
 
141
141
  Read buffer from stream.
142
- `readBuffer(buffer, offset?, length?, position?, maybeless?)`
142
+ `readBuffer(buffer, options?)`
143
143
 
144
- | Parameter | Type | Description |
145
- |------------|----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
146
- | buffer | [Buffer](https://nodejs.org/api/buffer.html) | Uint8Array | Target buffer to write the data read to |
147
- | offset? | number | The offset in the buffer to start writing at; if not provided, start at 0 |
148
- | length? | number | An integer specifying the number of bytes to read |
149
- | position? | number | An integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position. |
150
- | maybeless? | boolean | If set, will not throw an EOF error if the less then the requested length could be read |
144
+ | Parameter | Type | Description |
145
+ |------------|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
146
+ | buffer | [Buffer](https://nodejs.org/api/buffer.html) | Uint8Array | Target buffer to write the data read to |
147
+ | options | [IReadChunkOptions](#ireadchunkoptions) | An integer specifying the number of bytes to read |
151
148
 
152
- Return value `Promise<number>` Promise with number of bytes read
149
+ Return value `Promise<number>` Promise with number of bytes read. The number of bytes read maybe if less, *mayBeLess* flag was set.
153
150
 
154
151
  #### Method `tokenizer.peekBuffer()`
155
152
 
156
153
  Peek (read ahead) buffer from [*tokenizer*](#tokenizer)
157
- `peekBuffer(buffer, offset?, length?, position?, maybeless?)`
154
+ `peekBuffer(buffer, options?)`
158
155
 
159
- | Parameter | Type | Description |
160
- |------------|--------------------------|-----------------------------------------------------------------------------------------------------------------------|
161
- | buffer | Buffer &#124; Uint8Array | Target buffer to write the data read (peeked) to |
162
- | offset? | number | The offset in the buffer to start writing at; if not provided, start at 0 |
163
- | length? | number | The number of bytes to read. |
164
- | position? | number | Offset where to begin reading within the file. If position is null, data will be read from the current file position. |
165
- | maybeless? | boolean | If set, will not throw an EOF error if the less then the requested length could be read |
156
+ | Parameter | Type | Description |
157
+ |------------|-----------------------------------------|-----------------------------------------------------|
158
+ | buffer | Buffer &#124; Uint8Array | Target buffer to write the data read (peeked) to. |
159
+ | options | [IReadChunkOptions](#ireadchunkoptions) | An integer specifying the number of bytes to read. | |
166
160
 
167
- Return value `Promise<number>` Promise with number of bytes read
161
+ Return value `Promise<number>` Promise with number of bytes read. The number of bytes read maybe if less, *mayBeLess* flag was set.
168
162
 
169
163
  #### Method `tokenizer.readToken()`
170
164
 
171
165
  Read a *token* from the tokenizer-stream.
172
- `readToken(token, position?, maybeless?)`
166
+ `readToken(token, position?)`
173
167
 
174
- | Parameter | Type | Description |
175
- |------------|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
176
- | token | [IGetToken](#IGetToken) | Token to read from the tokenizer-stream. |
177
- | position? | number | Offset where to begin reading within the file. If position is null, data will be read from the current file position. |
178
- | maybeless? | boolean | If set, will not throw an EOF error if the less then the requested length could be read. |
168
+ | Parameter | Type | Description |
169
+ |------------|-------------------------|---------------------------------------------------------------------------------------------------------------------- |
170
+ | token | [IGetToken](#IGetToken) | Token to read from the tokenizer-stream. |
171
+ | position? | number | Offset where to begin reading within the file. If position is null, data will be read from the current file position. |
179
172
 
180
- Return value `Promise<T>`. Promise with token value read from the *tokenizer-stream*.
173
+ Return value `Promise<number>`. Promise with number of bytes read. The number of bytes read maybe if less, *mayBeLess* flag was set.
181
174
 
182
175
  #### Method `tokenizer.peekToken()`
183
176
 
184
- Peek a *token* from the tokenizer-stream.
185
- `peekToken(token, position?, maybeless?)`
177
+ Peek a *token* from the [*tokenizer*](#tokenizer).
178
+ `peekToken(token, position?)`
186
179
 
187
180
  | Parameter | Type | Description |
188
181
  |------------|----------------------------|-------------------------------------------------------------------------------------------------------------------------|
189
182
  | token | [IGetToken<T>](#IGetToken) | Token to read from the tokenizer-stream. |
190
183
  | position? | number | Offset where to begin reading within the file. If position is null, data will be read from the current file position. |
191
- | maybeless? | boolean | If set, will not throw an EOF error if the less then the requested length could be read |
192
184
 
193
- Return value `Promise<T>` Promise with token value peeked from the *tokenizer-stream*.
185
+ Return value `Promise<T>` Promise with token value peeked from the [*tokenizer*](#tokenizer).
194
186
 
195
187
  #### Method `tokenizer.readNumber()`
196
188
 
197
- Peek a numeric [*token*](#token) from the *tokenizer-stream*.
189
+ Peek a numeric [*token*](#token) from the [*tokenizer*](#tokenizer).
198
190
  `readNumber(token)`
199
191
 
200
192
  | Parameter | Type | Description |
@@ -217,33 +209,33 @@ Return value `Promise<number>` Promise with number peeked from the *tokenizer-st
217
209
  #### Method `tokenizer.close()`
218
210
  Clean up resources, such as closing a file pointer if applicable.
219
211
 
220
- ## IFileInfo
212
+ ### IReadChunkOptions
221
213
 
222
- File information interface which describes the underlying file:
214
+ Each attribute is optional:
223
215
 
224
- ```ts
225
- export interface IFileInfo {
226
- /**
227
- * File size in bytes
228
- */
229
- size?: number;
230
- /**
231
- * MIME-type of file
232
- */
233
- mimeType?: string;
234
-
235
- /**
236
- * File path
237
- */
238
- path?: string;
216
+ | Attribute | Type | Description |
217
+ |-----------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
218
+ | offset | number | The offset in the buffer to start writing at; if not provided, start at 0 |
219
+ | length | number | Requested number of bytes to read. |
220
+ | position | number | Position where to peek from the file. If position is null, data will be read from the [current file position](#attribute-tokenizerposition). Position may not be less then [tokenizer.position](#attribute-tokenizerposition) |
221
+ | mayBeLess | boolean | If and only if set, will not throw an EOF error if less then the requested *mayBeLess* could be read. |
239
222
 
240
- /**
241
- * File URL
242
- */
243
- url?: string;
244
- }
223
+ Example:
224
+ ```js
225
+ tokenizer.peekBuffer(buffer, {mayBeLess: true});
245
226
  ```
246
227
 
228
+ ## IFileInfo
229
+
230
+ File information interface which describes the underlying file, each attribute is optional.
231
+
232
+ | Attribute | Type | Description |
233
+ |-----------|---------|---------------------------------------------------------------------------------------------------|
234
+ | size | number | File size in bytes |
235
+ | mimeType | number | [MIME-type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) of file. |
236
+ | path | number | File path |
237
+ | url | boolean | File URL |
238
+
247
239
  ## Token
248
240
 
249
241
  The *token* is basically a description what to read form the [*tokenizer-stream*](#tokenizer).
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { ITokenizer, IFileInfo } from './types';
2
+ import { ITokenizer, IFileInfo, IReadChunkOptions } from './types';
3
3
  import { IGetToken, IToken } from '@tokenizer/token';
4
4
  /**
5
5
  * Core tokenizer
@@ -15,39 +15,31 @@ export declare abstract class AbstractTokenizer implements ITokenizer {
15
15
  /**
16
16
  * Read buffer from tokenizer
17
17
  * @param buffer - Target buffer to fill with data read from the tokenizer-stream
18
- * @param offset - Offset in the buffer to start writing at; if not provided, start at 0
19
- * @param length - The number of bytes to read
20
- * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
21
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
18
+ * @param options - Additional read options
22
19
  * @returns Promise with number of bytes read
23
20
  */
24
- abstract readBuffer(buffer: Buffer | Uint8Array, offset?: number, length?: number, position?: number, maybeless?: boolean): Promise<number>;
21
+ abstract readBuffer(buffer: Buffer | Uint8Array, options?: IReadChunkOptions): Promise<number>;
25
22
  /**
26
23
  * Peek (read ahead) buffer from tokenizer
27
24
  * @param buffer - Target buffer to fill with data peek from the tokenizer-stream
28
- * @param offset - The offset in the buffer to start writing at; if not provided, start at 0
29
- * @param length - The number of bytes to read
30
- * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
31
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
25
+ * @param options - Peek behaviour options
32
26
  * @returns Promise with number of bytes read
33
27
  */
34
- abstract peekBuffer(buffer: Buffer | Uint8Array, offset?: number, length?: number, position?: number, maybeless?: boolean): Promise<number>;
28
+ abstract peekBuffer(buffer: Buffer | Uint8Array, options?: IReadChunkOptions): Promise<number>;
35
29
  /**
36
30
  * Read a token from the tokenizer-stream
37
31
  * @param token - The token to read
38
32
  * @param position - If provided, the desired position in the tokenizer-stream
39
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
40
33
  * @returns Promise with token data
41
34
  */
42
- readToken<T>(token: IGetToken<T>, position?: number | null, maybeless?: boolean): Promise<T>;
35
+ readToken<T>(token: IGetToken<T>, position?: number): Promise<T>;
43
36
  /**
44
37
  * Peek a token from the tokenizer-stream.
45
38
  * @param token - Token to peek from the tokenizer-stream.
46
39
  * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
47
- * @param maybeless - If set, will not throw an EOF error if the less then the requested length could be read.
48
40
  * @returns Promise with token data
49
41
  */
50
- peekToken<T>(token: IGetToken<T>, position?: number, maybeless?: boolean): Promise<T>;
42
+ peekToken<T>(token: IGetToken<T>, position?: number): Promise<T>;
51
43
  /**
52
44
  * Read a numeric token from the stream
53
45
  * @param token - Numeric token
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractTokenizer = void 0;
3
4
  const peek_readable_1 = require("peek-readable");
4
5
  /**
5
6
  * Core tokenizer
@@ -17,13 +18,12 @@ class AbstractTokenizer {
17
18
  * Read a token from the tokenizer-stream
18
19
  * @param token - The token to read
19
20
  * @param position - If provided, the desired position in the tokenizer-stream
20
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
21
21
  * @returns Promise with token data
22
22
  */
23
- async readToken(token, position = null, maybeless) {
23
+ async readToken(token, position) {
24
24
  const buffer = Buffer.alloc(token.len);
25
- const len = await this.readBuffer(buffer, 0, token.len, position);
26
- if (!maybeless && len < token.len)
25
+ const len = await this.readBuffer(buffer, { position });
26
+ if (len < token.len)
27
27
  throw new peek_readable_1.EndOfStreamError();
28
28
  return token.get(buffer, 0);
29
29
  }
@@ -31,13 +31,12 @@ class AbstractTokenizer {
31
31
  * Peek a token from the tokenizer-stream.
32
32
  * @param token - Token to peek from the tokenizer-stream.
33
33
  * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
34
- * @param maybeless - If set, will not throw an EOF error if the less then the requested length could be read.
35
34
  * @returns Promise with token data
36
35
  */
37
- async peekToken(token, position = this.position, maybeless) {
36
+ async peekToken(token, position = this.position) {
38
37
  const buffer = Buffer.alloc(token.len);
39
- const len = await this.peekBuffer(buffer, 0, token.len, position);
40
- if (!maybeless && len < token.len)
38
+ const len = await this.peekBuffer(buffer, { position });
39
+ if (len < token.len)
41
40
  throw new peek_readable_1.EndOfStreamError();
42
41
  return token.get(buffer, 0);
43
42
  }
@@ -47,7 +46,7 @@ class AbstractTokenizer {
47
46
  * @returns Promise with number
48
47
  */
49
48
  async readNumber(token) {
50
- const len = await this.readBuffer(this.numBuffer, 0, token.len, null);
49
+ const len = await this.readBuffer(this.numBuffer, { length: token.len });
51
50
  if (len < token.len)
52
51
  throw new peek_readable_1.EndOfStreamError();
53
52
  return token.get(this.numBuffer, 0);
@@ -58,7 +57,7 @@ class AbstractTokenizer {
58
57
  * @returns Promise with number
59
58
  */
60
59
  async peekNumber(token) {
61
- const len = await this.peekBuffer(this.numBuffer, 0, token.len);
60
+ const len = await this.peekBuffer(this.numBuffer, { length: token.len });
62
61
  if (len < token.len)
63
62
  throw new peek_readable_1.EndOfStreamError();
64
63
  return token.get(this.numBuffer, 0);
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { IFileInfo, ITokenizer } from './types';
2
+ import { IFileInfo, IReadChunkOptions, ITokenizer } from './types';
3
3
  import { IGetToken, IToken } from '@tokenizer/token';
4
4
  export declare class BufferTokenizer implements ITokenizer {
5
5
  private buffer;
@@ -14,22 +14,17 @@ export declare class BufferTokenizer implements ITokenizer {
14
14
  /**
15
15
  * Read buffer from tokenizer
16
16
  * @param buffer
17
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
18
- * @param length is an integer specifying the number of bytes to read
19
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
20
- * @returns {Promise<TResult|number>}
17
+ * @param options - Read behaviour options
18
+ * @returns {Promise<number>}
21
19
  */
22
- readBuffer(buffer: Buffer | Uint8Array, offset?: number, length?: number, position?: number): Promise<number>;
20
+ readBuffer(buffer: Buffer | Uint8Array, options?: IReadChunkOptions): Promise<number>;
23
21
  /**
24
22
  * Peek (read ahead) buffer from tokenizer
25
23
  * @param buffer
26
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
27
- * @param length is an integer specifying the number of bytes to read
28
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
29
- * @param maybeLess If true, will return the bytes available if available bytes is less then length.
30
- * @returns {Promise<TResult|number>}
24
+ * @param options - Read behaviour options
25
+ * @returns {Promise<number>}
31
26
  */
32
- peekBuffer(buffer: Buffer | Uint8Array, offset?: number, length?: number, position?: number, maybeLess?: boolean): Promise<number>;
27
+ peekBuffer(buffer: Buffer | Uint8Array, options?: IReadChunkOptions): Promise<number>;
33
28
  readToken<T>(token: IGetToken<T>, position?: number): Promise<T>;
34
29
  peekToken<T>(token: IGetToken<T>, position?: number): Promise<T>;
35
30
  readNumber(token: IToken<number>): Promise<number>;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BufferTokenizer = void 0;
3
4
  const peek_readable_1 = require("peek-readable");
4
5
  class BufferTokenizer {
5
6
  /**
@@ -16,14 +17,17 @@ class BufferTokenizer {
16
17
  /**
17
18
  * Read buffer from tokenizer
18
19
  * @param buffer
19
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
20
- * @param length is an integer specifying the number of bytes to read
21
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
22
- * @returns {Promise<TResult|number>}
20
+ * @param options - Read behaviour options
21
+ * @returns {Promise<number>}
23
22
  */
24
- async readBuffer(buffer, offset, length, position) {
25
- this.position = position || this.position;
26
- return this.peekBuffer(buffer, offset, length, this.position).then(bytesRead => {
23
+ async readBuffer(buffer, options) {
24
+ if (options && options.position) {
25
+ if (options.position < this.position) {
26
+ throw new Error('`options.position` must be equal or greater than `tokenizer.position`');
27
+ }
28
+ this.position = options.position;
29
+ }
30
+ return this.peekBuffer(buffer, options).then(bytesRead => {
27
31
  this.position += bytesRead;
28
32
  return bytesRead;
29
33
  });
@@ -31,19 +35,39 @@ class BufferTokenizer {
31
35
  /**
32
36
  * Peek (read ahead) buffer from tokenizer
33
37
  * @param buffer
34
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
35
- * @param length is an integer specifying the number of bytes to read
36
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
37
- * @param maybeLess If true, will return the bytes available if available bytes is less then length.
38
- * @returns {Promise<TResult|number>}
38
+ * @param options - Read behaviour options
39
+ * @returns {Promise<number>}
39
40
  */
40
- async peekBuffer(buffer, offset, length, position, maybeLess = false) {
41
+ async peekBuffer(buffer, options) {
42
+ let offset = 0;
43
+ let length = buffer.length;
44
+ let position = this.position;
45
+ if (options) {
46
+ if (options.position) {
47
+ if (options.position < this.position) {
48
+ throw new Error('`options.position` can be less than `tokenizer.position`');
49
+ }
50
+ position = options.position;
51
+ }
52
+ if (Number.isInteger(options.length)) {
53
+ length = options.length;
54
+ }
55
+ else {
56
+ length -= options.offset || 0;
57
+ }
58
+ if (options.offset) {
59
+ offset = options.offset;
60
+ }
61
+ }
62
+ if (length === 0) {
63
+ return Promise.resolve(0);
64
+ }
41
65
  position = position || this.position;
42
66
  if (!length) {
43
67
  length = buffer.length;
44
68
  }
45
69
  const bytes2read = Math.min(this.buffer.length - position, length);
46
- if (!maybeLess && bytes2read < length) {
70
+ if ((!options || !options.mayBeLess) && bytes2read < length) {
47
71
  throw new peek_readable_1.EndOfStreamError();
48
72
  }
49
73
  else {
@@ -1,28 +1,23 @@
1
1
  /// <reference types="node" />
2
2
  import { AbstractTokenizer } from './AbstractTokenizer';
3
- import { IFileInfo } from './types';
3
+ import { IFileInfo, IReadChunkOptions } from './types';
4
4
  export declare class FileTokenizer extends AbstractTokenizer {
5
5
  private fd;
6
6
  constructor(fd: number, fileInfo: IFileInfo);
7
7
  /**
8
8
  * Read buffer from file
9
9
  * @param buffer
10
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
11
- * @param length is an integer specifying the number of bytes to read, of not provided the buffer length will be used
12
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
10
+ * @param options - Read behaviour options
13
11
  * @returns Promise number of bytes read
14
12
  */
15
- readBuffer(buffer: Buffer, offset?: number, length?: number, position?: number): Promise<number>;
13
+ readBuffer(buffer: Buffer, options?: IReadChunkOptions): Promise<number>;
16
14
  /**
17
15
  * Peek buffer from file
18
16
  * @param buffer
19
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
20
- * @param length is an integer specifying the number of bytes to read, of not provided the buffer length will be used
21
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
22
- * @param maybeless If set, will not throw an EOF error if the less then the requested length could be read
17
+ * @param options - Read behaviour options
23
18
  * @returns Promise number of bytes read
24
19
  */
25
- peekBuffer(buffer: Buffer, offset?: number, length?: number, position?: number, maybeless?: boolean): Promise<number>;
20
+ peekBuffer(buffer: Buffer, options?: IReadChunkOptions): Promise<number>;
26
21
  /**
27
22
  * @param length - Number of bytes to ignore
28
23
  * @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fromFile = exports.FileTokenizer = void 0;
3
4
  const AbstractTokenizer_1 = require("./AbstractTokenizer");
4
5
  const peek_readable_1 = require("peek-readable");
5
6
  const fs = require("./FsPromise");
@@ -11,26 +12,35 @@ class FileTokenizer extends AbstractTokenizer_1.AbstractTokenizer {
11
12
  /**
12
13
  * Read buffer from file
13
14
  * @param buffer
14
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
15
- * @param length is an integer specifying the number of bytes to read, of not provided the buffer length will be used
16
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
15
+ * @param options - Read behaviour options
17
16
  * @returns Promise number of bytes read
18
17
  */
19
- async readBuffer(buffer, offset = 0, length = buffer.length, position) {
20
- if (position) {
21
- this.position = position;
18
+ async readBuffer(buffer, options) {
19
+ let offset = 0;
20
+ let length = buffer.length;
21
+ if (options) {
22
+ if (options.position) {
23
+ if (options.position < this.position) {
24
+ throw new Error('`options.position` must be equal or greater than `tokenizer.position`');
25
+ }
26
+ this.position = options.position;
27
+ }
28
+ if (Number.isInteger(options.length)) {
29
+ length = options.length;
30
+ }
31
+ else {
32
+ length -= options.offset || 0;
33
+ }
34
+ if (options.offset) {
35
+ offset = options.offset;
36
+ }
22
37
  }
23
38
  if (length === 0) {
24
39
  return Promise.resolve(0);
25
40
  }
26
- if (!length) {
27
- length = buffer.length;
28
- }
29
41
  const res = await fs.read(this.fd, buffer, offset, length, this.position);
30
- if (res.bytesRead < length)
31
- throw new peek_readable_1.EndOfStreamError();
32
42
  this.position += res.bytesRead;
33
- if (res.bytesRead < length) {
43
+ if (res.bytesRead < length && (!options || !options.mayBeLess)) {
34
44
  throw new peek_readable_1.EndOfStreamError();
35
45
  }
36
46
  return res.bytesRead;
@@ -38,15 +48,35 @@ class FileTokenizer extends AbstractTokenizer_1.AbstractTokenizer {
38
48
  /**
39
49
  * Peek buffer from file
40
50
  * @param buffer
41
- * @param offset is the offset in the buffer to start writing at; if not provided, start at 0
42
- * @param length is an integer specifying the number of bytes to read, of not provided the buffer length will be used
43
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
44
- * @param maybeless If set, will not throw an EOF error if the less then the requested length could be read
51
+ * @param options - Read behaviour options
45
52
  * @returns Promise number of bytes read
46
53
  */
47
- async peekBuffer(buffer, offset = 0, length = buffer.length, position = this.position, maybeless = false) {
54
+ async peekBuffer(buffer, options) {
55
+ let offset = 0;
56
+ let length = buffer.length;
57
+ let position = this.position;
58
+ if (options) {
59
+ if (options.position) {
60
+ if (options.position < this.position) {
61
+ throw new Error('`options.position` must be equal or greater than `tokenizer.position`');
62
+ }
63
+ position = options.position;
64
+ }
65
+ if (Number.isInteger(options.length)) {
66
+ length = options.length;
67
+ }
68
+ else {
69
+ length -= options.offset || 0;
70
+ }
71
+ if (options.offset) {
72
+ offset = options.offset;
73
+ }
74
+ }
75
+ if (length === 0) {
76
+ return Promise.resolve(0);
77
+ }
48
78
  const res = await fs.read(this.fd, buffer, offset, length, position);
49
- if (!maybeless && res.bytesRead < length) {
79
+ if ((!options || !options.mayBeLess) && res.bytesRead < length) {
50
80
  throw new peek_readable_1.EndOfStreamError();
51
81
  }
52
82
  return res.bytesRead;
package/lib/FsPromise.js CHANGED
@@ -3,6 +3,7 @@
3
3
  * Module convert fs functions to promise based functions
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readFile = exports.writeFileSync = exports.writeFile = exports.read = exports.open = exports.close = exports.stat = exports.createReadStream = exports.pathExists = void 0;
6
7
  const fs = require("fs");
7
8
  exports.pathExists = fs.existsSync;
8
9
  exports.createReadStream = fs.createReadStream;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { AbstractTokenizer } from './AbstractTokenizer';
3
3
  import * as Stream from 'stream';
4
- import { IFileInfo } from './types';
4
+ import { IFileInfo, IReadChunkOptions } from './types';
5
5
  export declare class ReadStreamTokenizer extends AbstractTokenizer {
6
6
  private streamReader;
7
7
  constructor(stream: Stream.Readable, fileInfo?: IFileInfo);
@@ -13,22 +13,16 @@ export declare class ReadStreamTokenizer extends AbstractTokenizer {
13
13
  /**
14
14
  * Read buffer from tokenizer
15
15
  * @param buffer - Target buffer to fill with data read from the tokenizer-stream
16
- * @param offset - Offset in the buffer to start writing at; if not provided, start at 0
17
- * @param length - The number of bytes to read
18
- * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
19
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
16
+ * @param options - Read behaviour options
20
17
  * @returns Promise with number of bytes read
21
18
  */
22
- readBuffer(buffer: Buffer | Uint8Array, offset?: number, length?: number, position?: number, maybeless?: boolean): Promise<number>;
19
+ readBuffer(buffer: Buffer | Uint8Array, options?: IReadChunkOptions): Promise<number>;
23
20
  /**
24
21
  * Peek (read ahead) buffer from tokenizer
25
22
  * @param buffer - Target buffer to write the data read to
26
- * @param offset - The offset in the buffer to start writing at; if not provided, start at 0
27
- * @param length - The number of bytes to read
28
- * @param position - Specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
29
- * @param maybeless - If set, will not throw an EOF error if the less then the requested length could be read
23
+ * @param options - Read behaviour options
30
24
  * @returns Promise with number of bytes peeked
31
25
  */
32
- peekBuffer(buffer: Buffer | Uint8Array, offset?: number, length?: number, position?: number, maybeless?: boolean): Promise<number>;
26
+ peekBuffer(buffer: Buffer | Uint8Array, options?: IReadChunkOptions): Promise<number>;
33
27
  ignore(length: number): Promise<number>;
34
28
  }
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReadStreamTokenizer = void 0;
3
4
  const AbstractTokenizer_1 = require("./AbstractTokenizer");
4
5
  const peek_readable_1 = require("peek-readable");
5
6
  const _debug = require("debug");
6
7
  const debug = _debug('strtok3:ReadStreamTokenizer');
7
- const maxBufferSize = 1 * 1000 * 1000;
8
+ const maxBufferSize = 256000;
8
9
  class ReadStreamTokenizer extends AbstractTokenizer_1.AbstractTokenizer {
9
10
  constructor(stream, fileInfo) {
10
11
  super(fileInfo);
@@ -20,31 +21,41 @@ class ReadStreamTokenizer extends AbstractTokenizer_1.AbstractTokenizer {
20
21
  /**
21
22
  * Read buffer from tokenizer
22
23
  * @param buffer - Target buffer to fill with data read from the tokenizer-stream
23
- * @param offset - Offset in the buffer to start writing at; if not provided, start at 0
24
- * @param length - The number of bytes to read
25
- * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
26
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
24
+ * @param options - Read behaviour options
27
25
  * @returns Promise with number of bytes read
28
26
  */
29
- async readBuffer(buffer, offset = 0, length = buffer.length, position, maybeless) {
27
+ async readBuffer(buffer, options) {
30
28
  // const _offset = position ? position : this.position;
31
29
  // debug(`readBuffer ${_offset}...${_offset + length - 1}`);
32
- if (length === 0) {
33
- return 0;
34
- }
35
- if (position) {
36
- const skipBytes = position - this.position;
37
- if (skipBytes > 0) {
38
- await this.ignore(position - this.position);
39
- return this.readBuffer(buffer, offset, length);
30
+ let offset = 0;
31
+ let length = buffer.length;
32
+ if (options) {
33
+ if (Number.isInteger(options.length)) {
34
+ length = options.length;
35
+ }
36
+ else {
37
+ length -= options.offset || 0;
40
38
  }
41
- else if (skipBytes < 0) {
42
- throw new Error('Cannot read from a negative offset in a stream');
39
+ if (options.position) {
40
+ const skipBytes = options.position - this.position;
41
+ if (skipBytes > 0) {
42
+ await this.ignore(skipBytes);
43
+ return this.readBuffer(buffer, options);
44
+ }
45
+ else if (skipBytes < 0) {
46
+ throw new Error('`options.position` must be equal or greater than `tokenizer.position`');
47
+ }
48
+ }
49
+ if (options.offset) {
50
+ offset = options.offset;
43
51
  }
44
52
  }
53
+ if (length === 0) {
54
+ return 0;
55
+ }
45
56
  const bytesRead = await this.streamReader.read(buffer, offset, length);
46
57
  this.position += bytesRead;
47
- if (!maybeless && bytesRead < length) {
58
+ if ((!options || !options.mayBeLess) && bytesRead < length) {
48
59
  throw new peek_readable_1.EndOfStreamError();
49
60
  }
50
61
  return bytesRead;
@@ -52,30 +63,48 @@ class ReadStreamTokenizer extends AbstractTokenizer_1.AbstractTokenizer {
52
63
  /**
53
64
  * Peek (read ahead) buffer from tokenizer
54
65
  * @param buffer - Target buffer to write the data read to
55
- * @param offset - The offset in the buffer to start writing at; if not provided, start at 0
56
- * @param length - The number of bytes to read
57
- * @param position - Specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
58
- * @param maybeless - If set, will not throw an EOF error if the less then the requested length could be read
66
+ * @param options - Read behaviour options
59
67
  * @returns Promise with number of bytes peeked
60
68
  */
61
- async peekBuffer(buffer, offset = 0, length = buffer.length, position, maybeless) {
69
+ async peekBuffer(buffer, options) {
62
70
  // const _offset = position ? position : this.position;
63
71
  // debug(`peek ${_offset}...${_offset + length - 1}`);
72
+ let offset = 0;
64
73
  let bytesRead;
65
- if (position) {
66
- const skipBytes = position - this.position;
67
- if (skipBytes > 0) {
68
- const skipBuffer = Buffer.alloc(length + skipBytes);
69
- bytesRead = await this.peekBuffer(skipBuffer, 0, skipBytes + length, undefined, maybeless);
70
- skipBuffer.copy(buffer, offset, skipBytes);
71
- return bytesRead - skipBytes;
74
+ let length = buffer.length;
75
+ if (options) {
76
+ if (options.offset) {
77
+ offset = options.offset;
78
+ }
79
+ if (Number.isInteger(options.length)) {
80
+ length = options.length;
81
+ }
82
+ else {
83
+ length -= options.offset || 0;
72
84
  }
73
- else if (skipBytes < 0) {
74
- throw new Error('Cannot peek from a negative offset in a stream');
85
+ if (options.position) {
86
+ const skipBytes = options.position - this.position;
87
+ if (skipBytes > 0) {
88
+ const skipBuffer = Buffer.alloc(length + skipBytes);
89
+ bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: options.mayBeLess });
90
+ skipBuffer.copy(buffer, offset, skipBytes);
91
+ return bytesRead - skipBytes;
92
+ }
93
+ else if (skipBytes < 0) {
94
+ throw new Error('Cannot peek from a negative offset in a stream');
95
+ }
96
+ }
97
+ }
98
+ try {
99
+ bytesRead = await this.streamReader.peek(buffer, offset, length);
100
+ }
101
+ catch (err) {
102
+ if (options && options.mayBeLess && err instanceof peek_readable_1.EndOfStreamError) {
103
+ return 0;
75
104
  }
105
+ throw err;
76
106
  }
77
- bytesRead = await this.streamReader.peek(buffer, offset, length);
78
- if (!maybeless && bytesRead < length) {
107
+ if ((!options || !options.mayBeLess) && bytesRead < length) {
79
108
  throw new peek_readable_1.EndOfStreamError();
80
109
  }
81
110
  return bytesRead;
@@ -87,7 +116,7 @@ class ReadStreamTokenizer extends AbstractTokenizer_1.AbstractTokenizer {
87
116
  let totBytesRead = 0;
88
117
  while (totBytesRead < length) {
89
118
  const remaining = length - totBytesRead;
90
- const bytesRead = await this.readBuffer(buf, 0, Math.min(bufSize, remaining));
119
+ const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) });
91
120
  if (bytesRead < 0) {
92
121
  return bytesRead;
93
122
  }
package/lib/core.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fromBuffer = exports.fromStream = void 0;
3
4
  const ReadStreamTokenizer_1 = require("./ReadStreamTokenizer");
4
5
  const BufferTokenizer_1 = require("./BufferTokenizer");
5
6
  var peek_readable_1 = require("peek-readable");
6
- exports.EndOfStreamError = peek_readable_1.EndOfStreamError;
7
+ Object.defineProperty(exports, "EndOfStreamError", { enumerable: true, get: function () { return peek_readable_1.EndOfStreamError; } });
7
8
  /**
8
9
  * Construct ReadStreamTokenizer from given Stream.
9
10
  * Will set fileSize, if provided given Stream has set the .path property/
package/lib/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fromStream = void 0;
3
4
  const fs = require("./FsPromise");
4
5
  const core = require("./core");
5
6
  var FileTokenizer_1 = require("./FileTokenizer");
6
- exports.fromFile = FileTokenizer_1.fromFile;
7
+ Object.defineProperty(exports, "fromFile", { enumerable: true, get: function () { return FileTokenizer_1.fromFile; } });
7
8
  var core_1 = require("./core");
8
- exports.EndOfStreamError = core_1.EndOfStreamError;
9
- exports.fromBuffer = core_1.fromBuffer;
9
+ Object.defineProperty(exports, "EndOfStreamError", { enumerable: true, get: function () { return core_1.EndOfStreamError; } });
10
+ Object.defineProperty(exports, "fromBuffer", { enumerable: true, get: function () { return core_1.fromBuffer; } });
10
11
  /**
11
12
  * Construct ReadStreamTokenizer from given Stream.
12
13
  * Will set fileSize, if provided given Stream has set the .path property.
package/lib/types.d.ts CHANGED
@@ -18,6 +18,26 @@ export interface IFileInfo {
18
18
  */
19
19
  url?: string;
20
20
  }
21
+ export interface IReadChunkOptions {
22
+ /**
23
+ * The offset in the buffer to start writing at; default is 0
24
+ */
25
+ offset?: number;
26
+ /**
27
+ * Number of bytes to read.
28
+ */
29
+ length?: number;
30
+ /**
31
+ * Position where to begin reading from the file.
32
+ * Default it is `tokenizer.position`.
33
+ * Position may not be less then `tokenizer.position`.
34
+ */
35
+ position?: number;
36
+ /**
37
+ * If set, will not throw an EOF error if not all of the requested data could be read
38
+ */
39
+ mayBeLess?: boolean;
40
+ }
21
41
  /**
22
42
  * The tokenizer allows us to read or peek from the tokenizer-stream.
23
43
  * The tokenizer-stream is an abstraction of a stream, file or Buffer.
@@ -34,23 +54,17 @@ export interface ITokenizer {
34
54
  /**
35
55
  * Peek (read ahead) buffer from tokenizer
36
56
  * @param buffer - Target buffer to fill with data peek from the tokenizer-stream
37
- * @param offset - The offset in the buffer to start writing at; if not provided, start at 0
38
- * @param length - is an integer specifying the number of bytes to read
39
- * @param position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
40
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
57
+ * @param options - Read behaviour options
41
58
  * @returns Promise with number of bytes read
42
59
  */
43
- peekBuffer(buffer: Buffer, offset?: number, length?: number, position?: number, maybeless?: boolean): Promise<number>;
60
+ peekBuffer(buffer: Buffer, options?: IReadChunkOptions): Promise<number>;
44
61
  /**
45
62
  * Peek (read ahead) buffer from tokenizer
46
63
  * @param buffer - Target buffer to fill with data peeked from the tokenizer-stream
47
- * @param offset - Offset in the buffer to start writing at; if not provided, start at 0
48
- * @param length - The number of bytes to read
49
- * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
50
- * @param maybeless - If set, will not throw an EOF error if not all of the requested data could be read
64
+ * @param options - Additional read options
51
65
  * @returns Promise with number of bytes read
52
66
  */
53
- readBuffer(buffer: Buffer, offset?: number, length?: number, position?: number, maybeless?: boolean): Promise<number>;
67
+ readBuffer(buffer: Buffer, options?: IReadChunkOptions): Promise<number>;
54
68
  /**
55
69
  * Peek a token from the tokenizer-stream.
56
70
  * @param token - Token to peek from the tokenizer-stream.
@@ -62,9 +76,8 @@ export interface ITokenizer {
62
76
  * Read a token from the tokenizer-stream.
63
77
  * @param token - Token to peek from the tokenizer-stream.
64
78
  * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
65
- * @param maybeless - If set, will not throw an EOF error if the less then the requested length could be read.
66
79
  */
67
- readToken<T>(token: IGetToken<T>, position?: number | null, maybeless?: boolean): Promise<T>;
80
+ readToken<T>(token: IGetToken<T>, position?: number): Promise<T>;
68
81
  /**
69
82
  * Peek a numeric token from the stream
70
83
  * @param token - Numeric token
@@ -79,9 +92,9 @@ export interface ITokenizer {
79
92
  readNumber(token: IGetToken<number>): Promise<number>;
80
93
  /**
81
94
  * Ignore given number of bytes
82
- * @param actual number of bytes ignored
95
+ * @param length - Number of bytes ignored
83
96
  */
84
- ignore(length: number): any;
97
+ ignore(length: number): Promise<number>;
85
98
  /**
86
99
  * Clean up resources.
87
100
  * It does not close the stream for StreamReader, but is does close the file-descriptor.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strtok3",
3
- "version": "5.0.2",
3
+ "version": "6.0.3",
4
4
  "description": "A promise based streaming tokenizer",
5
5
  "author": {
6
6
  "name": "Borewit",
@@ -15,7 +15,6 @@
15
15
  "eslint": "eslint lib test --ext .ts --ignore-pattern *.d.ts",
16
16
  "lint-md": "remark -u preset-lint-recommended .",
17
17
  "lint": "npm run lint-md && npm run eslint",
18
- "lint-fix": "tslint --fix 'lib/**/*.ts' 'test/**/*.ts'",
19
18
  "test": "mocha --require ts-node/register --require source-map-support/register --full-trace test/test.ts",
20
19
  "test-coverage": "nyc npm run test",
21
20
  "coveralls": "npm run test-coverage && nyc report --reporter=text-lcov | coveralls",
@@ -39,26 +38,31 @@
39
38
  "url": "https://github.com/Borewit/strtok3/issues"
40
39
  },
41
40
  "devDependencies": {
42
- "@types/chai": "^4.2.5",
43
- "@types/mocha": "^5.2.7",
44
- "@types/node": "^13.1.7",
45
- "@typescript-eslint/eslint-plugin": "^2.16.0",
46
- "@typescript-eslint/parser": "^2.16.0",
41
+ "@types/chai": "^4.2.11",
42
+ "@types/mocha": "^7.0.2",
43
+ "@types/node": "^14.0.13",
44
+ "@typescript-eslint/eslint-plugin": "^2.31.0",
45
+ "@typescript-eslint/eslint-plugin-tslint": "^2.31.0",
46
+ "@typescript-eslint/parser": "^2.31.0",
47
47
  "chai": "^4.2.0",
48
- "coveralls": "^3.0.7",
48
+ "coveralls": "^3.1.0",
49
49
  "del-cli": "^3.0.0",
50
50
  "eslint": "^6.8.0",
51
- "mocha": "^7.0.0",
52
- "nyc": "^15.0.0",
53
- "remark-cli": "^7.0.1",
54
- "remark-preset-lint-recommended": "^3.0.3",
51
+ "eslint-plugin-import": "^2.21.2",
52
+ "eslint-plugin-prefer-arrow": "^1.2.1",
53
+ "mocha": "^7.2.0",
54
+ "nyc": "^15.1.0",
55
+ "remark-cli": "^8.0.0",
56
+ "remark-preset-lint-recommended": "^4.0.0",
55
57
  "source-map-support": "^0.5.16",
56
58
  "token-types": "^2.0.0",
57
- "ts-node": "^8.6.2",
58
- "typescript": "^3.7.5"
59
+ "ts-node": "^8.10.2",
60
+ "tslint": "^6.1.2",
61
+ "typescript": "^3.9.5"
59
62
  },
60
63
  "dependencies": {
61
64
  "@tokenizer/token": "^0.1.1",
65
+ "@types/debug": "^4.1.5",
62
66
  "debug": "^4.1.1",
63
67
  "peek-readable": "^3.1.0"
64
68
  },