binutils64 0.2.0 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,15 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.0] - 2026-07-04
9
+
10
+ ### Added
11
+
12
+ - `BinaryReader.ReadString(count)` and `BinaryWriter.WriteString(value)`: read and
13
+ write strings using the instance's `Encoding` (`'ascii'` by default). Reading
14
+ past the end returns an empty string without advancing; writing a non-string
15
+ throws.
16
+
8
17
  ## [0.2.0] - 2026-07-02
9
18
 
10
19
  ### Added
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
  make it easy to parse and produce binary data sequentially, with an API modelled on
15
15
  the corresponding .NET classes. Both classes let you choose the byte order
16
16
  (`big`- or `little`-endian) and support 8-, 16-, 32- and 64-bit integers, floats,
17
- doubles, and raw byte runs.
17
+ doubles, raw byte runs, and encoded strings.
18
18
 
19
19
  ## Table of contents
20
20
 
@@ -36,7 +36,8 @@ doubles, and raw byte runs.
36
36
  - Sequential `Read*` / `Write*` methods for every common fixed-width type.
37
37
  - Per-instance endianness (`big` by default, or `little`).
38
38
  - 64-bit integers via JavaScript `BigInt`.
39
- - Signed and unsigned integers, IEEE-754 `float` and `double`, and raw byte runs.
39
+ - Signed and unsigned integers, IEEE-754 `float` and `double`, raw byte runs, and
40
+ strings in any `Buffer` encoding.
40
41
  - Zero runtime dependencies.
41
42
  - Bundled TypeScript type definitions.
42
43
 
@@ -90,7 +91,7 @@ you read.
90
91
  | ------------ | ----------------------------- | ------- | ------------------------------------------------------------------ |
91
92
  | `input` | `Buffer` \| `number[]` \| `string` | — | The data to read. A `Buffer` is **copied** so the source is never mutated. |
92
93
  | `endianness` | `'big'` \| `'little'` | `'big'` | Byte order used by all multi-byte reads. |
93
- | `encoding` | `string` | `'ascii'` | Used only when `input` is a `string`, to turn it into bytes. |
94
+ | `encoding` | `string` | `'ascii'` | Used to turn a `string` input into bytes, and by `ReadString`. |
94
95
 
95
96
  Throws `Error` if `input` is not a `Buffer`, array, or string.
96
97
 
@@ -109,10 +110,11 @@ Throws `Error` if `input` is not a `Buffer`, array, or string.
109
110
  | `ReadFloat()` | 4 | `number` | IEEE-754 single precision. |
110
111
  | `ReadDouble()` | 8 | `number` | IEEE-754 double precision. |
111
112
  | `ReadBytes(count)`| `count` | `Buffer`| Copies `count` bytes into a new `Buffer`. |
113
+ | `ReadString(count)`| `count` | `string`| Decodes `count` bytes using the instance's `Encoding`. |
112
114
 
113
115
  If fewer than the required number of bytes remain, integer/float reads return `0`
114
- (or `0.0`), and `ReadBytes` returns an empty `Buffer` — **without** throwing or
115
- advancing the position. See [Behavior and best practices](#behavior-and-best-practices).
116
+ (or `0.0`), and `ReadBytes`/`ReadString` return an empty `Buffer`/`string` — **without**
117
+ throwing or advancing the position. See [Behavior and best practices](#behavior-and-best-practices).
116
118
 
117
119
  #### Reader properties
118
120
 
@@ -133,7 +135,7 @@ A writer accumulates bytes in an internal buffer that grows with every write.
133
135
  | Parameter | Type | Default | Description |
134
136
  | ------------ | --------------------- | --------- | ---------------------------------------- |
135
137
  | `endianness` | `'big'` \| `'little'` | `'big'` | Byte order used by all multi-byte writes.|
136
- | `encoding` | `string` | `'ascii'` | Stored on the instance; reserved. |
138
+ | `encoding` | `string` | `'ascii'` | Used by `WriteString` to encode strings. |
137
139
 
138
140
  #### Write methods
139
141
 
@@ -150,6 +152,7 @@ A writer accumulates bytes in an internal buffer that grows with every write.
150
152
  | `WriteFloat(value)` | 4 | `number` | IEEE-754 single precision. |
151
153
  | `WriteDouble(value)` | 8 | `number` | IEEE-754 double precision. |
152
154
  | `WriteBytes(value)` | varies| `Buffer` \| `number[]` \| `string` | Strings are written as one byte per character code. Throws on any other type. |
155
+ | `WriteString(value)` | varies| `string` | Encodes the string using the instance's `Encoding`. Throws on any other type. |
153
156
 
154
157
  Writing a value outside the target type's range throws a `RangeError` (the standard
155
158
  Node.js `Buffer` write behavior) — e.g. `WriteUInt8(256)`.
@@ -191,6 +194,11 @@ Node.js `Buffer` write behavior) — e.g. `WriteUInt8(256)`.
191
194
  - **Constructing a reader from a string?** Pass the encoding explicitly
192
195
  (e.g. `new BinaryReader(text, 'big', 'utf8')`) so the bytes are interpreted the
193
196
  way you expect.
197
+ - **The default `'ascii'` encoding is 7-bit only.** Node.js clears the high bit of
198
+ every byte when decoding `'ascii'`, so text containing characters above `0x7F`
199
+ does **not** round-trip through `WriteString`/`ReadString` with the default
200
+ encoding. Pass `'utf8'` (or `'latin1'`) to both constructors when handling
201
+ non-ASCII text.
194
202
 
195
203
  ## Examples
196
204
 
@@ -220,6 +228,21 @@ const reader = new BinaryReader(writer.ByteBuffer, 'little');
220
228
  console.log(reader.ReadUInt32().toString(16)); // "1020304"
221
229
  ```
222
230
 
231
+ ### Writing and reading strings
232
+
233
+ ```javascript
234
+ const { BinaryReader, BinaryWriter } = require('binutils64');
235
+
236
+ const text = 'héllo';
237
+ const writer = new BinaryWriter('big', 'utf8');
238
+ writer.WriteUInt8(Buffer.byteLength(text, 'utf8')); // length prefix: 6
239
+ writer.WriteString(text);
240
+
241
+ const reader = new BinaryReader(writer.ByteBuffer, 'big', 'utf8');
242
+ const length = reader.ReadUInt8(); // 6
243
+ console.log(reader.ReadString(length)); // "héllo"
244
+ ```
245
+
223
246
  ### Parsing a structured record
224
247
 
225
248
  ```javascript
package/binutils.d.ts CHANGED
@@ -21,7 +21,7 @@ declare namespace binutils {
21
21
  ByteBuffer: Buffer;
22
22
  /** Byte order used by all multi-byte reads. */
23
23
  Endianness: Endianness;
24
- /** Encoding used to turn a string input into bytes. */
24
+ /** Encoding used to turn a string input into bytes and to decode `ReadString`. */
25
25
  Encoding: BufferEncoding;
26
26
  /** Length of the original input in bytes. Never changes as you read. */
27
27
  Length: number;
@@ -50,6 +50,8 @@ declare namespace binutils {
50
50
  ReadDouble(): number;
51
51
  /** Copies `count` bytes into a new Buffer. Returns an empty Buffer (without advancing) if fewer than `count` bytes remain. */
52
52
  ReadBytes(count: number): Buffer;
53
+ /** Decodes `count` bytes as a string using the instance's `Encoding`. Returns an empty string (without advancing) if fewer than `count` bytes remain. */
54
+ ReadString(count: number): string;
53
55
  }
54
56
 
55
57
  class BinaryWriter {
@@ -60,7 +62,7 @@ declare namespace binutils {
60
62
  ByteBuffer: Buffer;
61
63
  /** Byte order used by all multi-byte writes. */
62
64
  Endianness: Endianness;
63
- /** Stored on the instance; reserved. */
65
+ /** Encoding used by `WriteString`. */
64
66
  Encoding: BufferEncoding;
65
67
  /** The current length of `ByteBuffer`. */
66
68
  Length: number;
@@ -79,5 +81,7 @@ declare namespace binutils {
79
81
  WriteDouble(value: number): void;
80
82
  /** Strings are written as one byte per character code. Throws on any other input type. */
81
83
  WriteBytes(value: Buffer | ReadonlyArray<number> | string): void;
84
+ /** Encodes the string using the instance's `Encoding`. Throws on any other input type. */
85
+ WriteString(value: string): void;
82
86
  }
83
87
  }
package/binutils.js CHANGED
@@ -142,6 +142,17 @@ BinaryReader.prototype = {
142
142
 
143
143
  this.ByteBuffer = this.ByteBuffer.slice(p_Count);
144
144
 
145
+ this.Position += p_Count;
146
+ return s_Val;
147
+ },
148
+
149
+ ReadString: function(p_Count) {
150
+ if (p_Count <= 0 || p_Count > this.ByteBuffer.length) {
151
+ return '';
152
+ }
153
+
154
+ var s_Val = this.ByteBuffer.toString(this.Encoding, 0, p_Count);
155
+ this.ByteBuffer = this.ByteBuffer.slice(p_Count);
145
156
  this.Position += p_Count;
146
157
  return s_Val;
147
158
  }
@@ -287,6 +298,16 @@ BinaryWriter.prototype = {
287
298
 
288
299
  var s_TempBuffer = (p_Value instanceof Buffer) ? p_Value : Buffer.from(p_Value);
289
300
 
301
+ this.Length += s_TempBuffer.length;
302
+ this.ByteBuffer = Buffer.concat([this.ByteBuffer, s_TempBuffer], this.Length);
303
+ },
304
+
305
+ WriteString: function(p_Value) {
306
+ if (typeof p_Value != 'string') {
307
+ throw new Error("Invalid string provided.");
308
+ }
309
+
310
+ var s_TempBuffer = Buffer.from(p_Value, this.Encoding);
290
311
  this.Length += s_TempBuffer.length;
291
312
  this.ByteBuffer = Buffer.concat([this.ByteBuffer, s_TempBuffer], this.Length);
292
313
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "binutils64",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "author": "Mihail Shumilov <mschumilow@gmail.com>",
5
5
  "description": "A .NET-like BinaryReader and BinaryWriter with endianness support.",
6
6
  "license": "MIT",