koffi 2.7.0 → 2.7.2

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
@@ -4,6 +4,17 @@
4
4
 
5
5
  ### Koffi 2.7
6
6
 
7
+ #### Koffi 2.7.2 (2024-01-15)
8
+
9
+ - Add missing TypeScript declaration for `koffi.free()`
10
+ - Fix TypeScript declaration of `koffi.encode()`
11
+ - Try to improve compatibility with webpack
12
+
13
+ #### Koffi 2.7.1 (2024-01-02)
14
+
15
+ - Support C-like `int[3]` syntax for [fixed array types](input.md#fixed-size-c-arrays)
16
+ - Refuse type specifiers with invalid tokens at the end (previously ignored)
17
+
7
18
  #### Koffi 2.7.0 (2023-12-21)
8
19
 
9
20
  - Support alternative [callback calling convention](callbacks.md#callback-types) in classic syntax
package/README.md CHANGED
@@ -25,9 +25,9 @@ Go to the web site for more information: https://koffi.dev/
25
25
 
26
26
  # Project history
27
27
 
28
- You can consult the [changelog](https://koffi.dev/changes) on the official website.
28
+ You can consult the [changelog](https://koffi.dev/changelog) on the official website.
29
29
 
30
- Major version increments can include breaking API changes, use the [migration guide](https://koffi.dev/changes#migration-guide) for more information.
30
+ Major version increments can include breaking API changes, use the [migration guide](https://koffi.dev/changelog#migration-guide) for more information.
31
31
 
32
32
  # License
33
33
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/doc/functions.md CHANGED
@@ -9,7 +9,7 @@ To declare functions, start by loading the shared library with `koffi.load(filen
9
9
  const koffi = require('koffi');
10
10
 
11
11
  const lib = koffi.load('/path/to/shared/library'); // File extension depends on platforms: .so, .dll, .dylib, etc.
12
- ````
12
+ ```
13
13
 
14
14
  This library will be automatically unloaded once all references to it are gone (including all the functions that use it, as described below).
15
15
 
package/doc/input.md CHANGED
@@ -336,6 +336,8 @@ try {
336
336
 
337
337
  ### Fixed-size C arrays
338
338
 
339
+ *Changed in Koffi 2.7.1*
340
+
339
341
  Fixed-size arrays are declared with `koffi.array(type, length)`. Just like in C, they cannot be passed as functions parameters (they degenerate to pointers), or returned by value. You can however embed them in struct types.
340
342
 
341
343
  Koffi applies the following conversion rules when passing arrays to/from C:
@@ -350,13 +352,13 @@ See the example below:
350
352
  const koffi = require('koffi');
351
353
 
352
354
  // Those two structs are exactly the same, only the array conversion hint is different
353
- const Foo1 = koffi.struct('Foo', {
355
+ const Foo1 = koffi.struct('Foo1', {
354
356
  i: 'int',
355
- a16: koffi.array('int16_t', 8)
357
+ a16: koffi.array('int16_t', 2)
356
358
  });
357
- const Foo2 = koffi.struct('Foo', {
359
+ const Foo2 = koffi.struct('Foo2', {
358
360
  i: 'int',
359
- a16: koffi.array('int16_t', 8, 'Array')
361
+ a16: koffi.array('int16_t', 2, 'Array')
360
362
  });
361
363
 
362
364
  // Uses an hypothetical C function that just returns the struct passed as a parameter
@@ -367,6 +369,19 @@ console.log(ReturnFoo1({ i: 5, a16: [6, 8] })) // Prints { i: 5, a16: Int16Array
367
369
  console.log(ReturnFoo2({ i: 5, a16: [6, 8] })) // Prints { i: 5, a16: [6, 8] }
368
370
  ```
369
371
 
372
+ You can also declare arrays with the C-like short syntax in type declarations, as shown below:
373
+
374
+ ```js
375
+ const StructType = koffi.struct('StructType', {
376
+ f8: 'float [8]',
377
+ self4: 'StructType *[4]'
378
+ });
379
+ ```
380
+
381
+ ```{note}
382
+ The short C-like syntax was introduced in Koffi 2.7.1, use `koffi.array()` for older versions.
383
+ ```
384
+
370
385
  ### Fixed-size string buffers
371
386
 
372
387
  Koffi can also convert JS strings to fixed-sized arrays in the following cases:
package/doc/unions.md CHANGED
@@ -49,8 +49,8 @@ const U = koffi.union('U', { i: 'int', str: 'char *' });
49
49
 
50
50
  const DoSomething = lib.func('void DoSomething(const char *type, U u)');
51
51
 
52
- DoSomething('int', { .i = 42 });
53
- DoSomething('string', { .str = 'Hello!' });
52
+ DoSomething('int', { i: 42 });
53
+ DoSomething('string', { str: 'Hello!' });
54
54
  ```
55
55
 
56
56
  ### Win32 example
package/index.d.ts CHANGED
@@ -104,8 +104,8 @@ declare module 'koffi' {
104
104
  /** @deprecated */ export function handle(): IKoffiCType;
105
105
 
106
106
  export function pointer(ref: TypeSpec): IKoffiCType;
107
- export function pointer(ref: TypeSpec, asteriskCount: number): IKoffiCType;
108
- export function pointer(name: string, ref: TypeSpec, asteriskCount: number): IKoffiCType;
107
+ export function pointer(ref: TypeSpec, asteriskCount?: number): IKoffiCType;
108
+ export function pointer(name: string, ref: TypeSpec, asteriskCount?: number): IKoffiCType;
109
109
 
110
110
  export function out(type: TypeSpec): IKoffiCType;
111
111
  export function inout(type: TypeSpec): IKoffiCType;
@@ -131,7 +131,7 @@ declare module 'koffi' {
131
131
  export function decode(value: any, offset: number, type: TypeSpec): any;
132
132
  export function decode(value: any, offset: number, type: TypeSpec, len: number): any;
133
133
  export function address(value: any): bigint;
134
- export function encode(ref: any, type: TypeSpec): void;
134
+ export function call(value: any, type: TypeSpec, ...args: any[]): any;
135
135
  export function encode(ref: any, type: TypeSpec, value: any): void;
136
136
  export function encode(ref: any, type: TypeSpec, value: any, len: number): void;
137
137
  export function encode(ref: any, offset: number, type: TypeSpec): void;
@@ -150,6 +150,8 @@ declare module 'koffi' {
150
150
  export function config(cfg: Record<string, unknown>): Record<string, unknown>;
151
151
  export function stats(): Record<string, unknown>;
152
152
 
153
+ export function free(value: any): void;
154
+
153
155
  export function errno(): number;
154
156
  export function errno(value: number): number;
155
157
 
package/index.js CHANGED
@@ -69,17 +69,17 @@ var require_tools = __commonJS({
69
69
  try {
70
70
  crypto.randomFillSync(buf);
71
71
  let suffix = buf.toString("hex").padStart(8, "0");
72
- let filename = `${prefix}.${suffix}`;
73
- let file = fs2.createWriteStream(filename, { flags: "wx", mode: 420 });
74
- return [filename, file];
72
+ let filename2 = `${prefix}.${suffix}`;
73
+ let file = fs2.createWriteStream(filename2, { flags: "wx", mode: 420 });
74
+ return [filename2, file];
75
75
  } catch (err) {
76
76
  if (err.code != "EEXIST")
77
77
  throw err;
78
78
  }
79
79
  }
80
80
  }
81
- function extract_targz(filename, dest_dir, strip = 0) {
82
- let reader = fs2.createReadStream(filename).pipe(zlib.createGunzip());
81
+ function extract_targz(filename2, dest_dir, strip = 0) {
82
+ let reader = fs2.createReadStream(filename2).pipe(zlib.createGunzip());
83
83
  return new Promise((resolve, reject) => {
84
84
  let header = null;
85
85
  let extended = {};
@@ -119,13 +119,13 @@ var require_tools = __commonJS({
119
119
  }
120
120
  data = data.subarray(0, header.size);
121
121
  if (header.type == "0" || header.type == "7") {
122
- let filename2 = dest_dir + "/" + header.filename;
123
- let dirname = path.dirname(filename2);
122
+ let filename3 = dest_dir + "/" + header.filename;
123
+ let dirname = path.dirname(filename3);
124
124
  fs2.mkdirSync(dirname, { recursive: true, mode: 493 });
125
- fs2.writeFileSync(filename2, data, { mode: header.mode });
125
+ fs2.writeFileSync(filename3, data, { mode: header.mode });
126
126
  } else if (header.type == "5") {
127
- let filename2 = dest_dir + "/" + header.filename;
128
- fs2.mkdirSync(filename2, { recursive: true, mode: header.mode });
127
+ let filename3 = dest_dir + "/" + header.filename;
128
+ fs2.mkdirSync(filename3, { recursive: true, mode: header.mode });
129
129
  } else if (header.type == "L") {
130
130
  extended.filename = data.toString("utf-8").replace(/\0/g, "");
131
131
  } else if (header.type == "x") {
@@ -233,10 +233,10 @@ var require_tools = __commonJS({
233
233
  }
234
234
  return arch2;
235
235
  }
236
- function read_file_header(filename, read) {
236
+ function read_file_header(filename2, read) {
237
237
  let fd = null;
238
238
  try {
239
- let fd2 = fs2.openSync(filename);
239
+ let fd2 = fs2.openSync(filename2);
240
240
  let buf = Buffer.allocUnsafe(read);
241
241
  let len = fs2.readSync(fd2, buf);
242
242
  return buf.subarray(0, len);
@@ -378,8 +378,8 @@ var require_package = __commonJS({
378
378
  "build/dist/src/koffi/package.json"(exports2, module2) {
379
379
  module2.exports = {
380
380
  name: "koffi",
381
- version: "2.7.0",
382
- stable: "2.7.0",
381
+ version: "2.7.2",
382
+ stable: "2.7.2",
383
383
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
384
384
  keywords: [
385
385
  "foreign",
@@ -527,24 +527,24 @@ try {
527
527
  } catch (err) {
528
528
  }
529
529
  if (native == null) {
530
+ let roots = [__dirname];
531
+ if (process.resourcesPath != null)
532
+ roots.push(process.resourcesPath);
530
533
  let names = [
531
534
  `/build/koffi/${process.platform}_${arch}/koffi.node`,
532
535
  `/koffi/${process.platform}_${arch}/koffi.node`,
533
536
  `/node_modules/koffi/build/koffi/${process.platform}_${arch}/koffi.node`
534
537
  ];
535
- for (let name of names) {
536
- if (fs.existsSync(__dirname + name)) {
537
- native = require(__dirname + name);
538
- break;
539
- }
540
- }
541
- if (native == null && process.resourcesPath != null) {
538
+ for (let root of roots) {
542
539
  for (let name of names) {
543
- if (fs.existsSync(process.resourcesPath + name)) {
544
- native = require(process.resourcesPath + name);
540
+ let filename = root + name;
541
+ if (fs.existsSync(filename)) {
542
+ native = eval("require")(filename);
545
543
  break;
546
544
  }
547
545
  }
546
+ if (native != null)
547
+ break;
548
548
  }
549
549
  }
550
550
  if (native == null)
package/indirect.js CHANGED
@@ -69,17 +69,17 @@ var require_tools = __commonJS({
69
69
  try {
70
70
  crypto.randomFillSync(buf);
71
71
  let suffix = buf.toString("hex").padStart(8, "0");
72
- let filename = `${prefix}.${suffix}`;
73
- let file = fs2.createWriteStream(filename, { flags: "wx", mode: 420 });
74
- return [filename, file];
72
+ let filename2 = `${prefix}.${suffix}`;
73
+ let file = fs2.createWriteStream(filename2, { flags: "wx", mode: 420 });
74
+ return [filename2, file];
75
75
  } catch (err) {
76
76
  if (err.code != "EEXIST")
77
77
  throw err;
78
78
  }
79
79
  }
80
80
  }
81
- function extract_targz(filename, dest_dir, strip = 0) {
82
- let reader = fs2.createReadStream(filename).pipe(zlib.createGunzip());
81
+ function extract_targz(filename2, dest_dir, strip = 0) {
82
+ let reader = fs2.createReadStream(filename2).pipe(zlib.createGunzip());
83
83
  return new Promise((resolve, reject) => {
84
84
  let header = null;
85
85
  let extended = {};
@@ -119,13 +119,13 @@ var require_tools = __commonJS({
119
119
  }
120
120
  data = data.subarray(0, header.size);
121
121
  if (header.type == "0" || header.type == "7") {
122
- let filename2 = dest_dir + "/" + header.filename;
123
- let dirname = path.dirname(filename2);
122
+ let filename3 = dest_dir + "/" + header.filename;
123
+ let dirname = path.dirname(filename3);
124
124
  fs2.mkdirSync(dirname, { recursive: true, mode: 493 });
125
- fs2.writeFileSync(filename2, data, { mode: header.mode });
125
+ fs2.writeFileSync(filename3, data, { mode: header.mode });
126
126
  } else if (header.type == "5") {
127
- let filename2 = dest_dir + "/" + header.filename;
128
- fs2.mkdirSync(filename2, { recursive: true, mode: header.mode });
127
+ let filename3 = dest_dir + "/" + header.filename;
128
+ fs2.mkdirSync(filename3, { recursive: true, mode: header.mode });
129
129
  } else if (header.type == "L") {
130
130
  extended.filename = data.toString("utf-8").replace(/\0/g, "");
131
131
  } else if (header.type == "x") {
@@ -233,10 +233,10 @@ var require_tools = __commonJS({
233
233
  }
234
234
  return arch2;
235
235
  }
236
- function read_file_header(filename, read) {
236
+ function read_file_header(filename2, read) {
237
237
  let fd = null;
238
238
  try {
239
- let fd2 = fs2.openSync(filename);
239
+ let fd2 = fs2.openSync(filename2);
240
240
  let buf = Buffer.allocUnsafe(read);
241
241
  let len = fs2.readSync(fd2, buf);
242
242
  return buf.subarray(0, len);
@@ -378,8 +378,8 @@ var require_package = __commonJS({
378
378
  "build/dist/src/koffi/package.json"(exports2, module2) {
379
379
  module2.exports = {
380
380
  name: "koffi",
381
- version: "2.7.0",
382
- stable: "2.7.0",
381
+ version: "2.7.2",
382
+ stable: "2.7.2",
383
383
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
384
384
  keywords: [
385
385
  "foreign",
@@ -447,24 +447,24 @@ var arch = determine_arch();
447
447
  var triplet = `${process.platform}_${arch}`;
448
448
  var native = null;
449
449
  {
450
+ let roots = [__dirname];
451
+ if (process.resourcesPath != null)
452
+ roots.push(process.resourcesPath);
450
453
  let names = [
451
454
  `/build/koffi/${process.platform}_${arch}/koffi.node`,
452
455
  `/koffi/${process.platform}_${arch}/koffi.node`,
453
456
  `/node_modules/koffi/build/koffi/${process.platform}_${arch}/koffi.node`
454
457
  ];
455
- for (let name of names) {
456
- if (fs.existsSync(__dirname + name)) {
457
- native = require(__dirname + name);
458
- break;
459
- }
460
- }
461
- if (native == null && process.resourcesPath != null) {
458
+ for (let root of roots) {
462
459
  for (let name of names) {
463
- if (fs.existsSync(process.resourcesPath + name)) {
464
- native = require(process.resourcesPath + name);
460
+ let filename = root + name;
461
+ if (fs.existsSync(filename)) {
462
+ native = eval("require")(filename);
465
463
  break;
466
464
  }
467
465
  }
466
+ if (native != null)
467
+ break;
468
468
  }
469
469
  }
470
470
  if (native == null)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.7.0",
4
- "stable": "2.7.0",
3
+ "version": "2.7.2",
4
+ "stable": "2.7.2",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
7
7
  "foreign",
@@ -26,7 +26,7 @@
26
26
 
27
27
  namespace RG {
28
28
 
29
- class BrotliDecompressor: public StreamDecompressor {
29
+ class BrotliDecompressor: public StreamDecoder {
30
30
  BrotliDecoderState *state = nullptr;
31
31
  bool done = false;
32
32
 
@@ -37,27 +37,23 @@ class BrotliDecompressor: public StreamDecompressor {
37
37
  Size out_len = 0;
38
38
 
39
39
  public:
40
- BrotliDecompressor(StreamReader *reader) : StreamDecompressor(reader) {}
40
+ BrotliDecompressor(StreamReader *reader, CompressionType type);
41
41
  ~BrotliDecompressor();
42
42
 
43
- bool Init(CompressionType type) override;
44
43
  Size Read(Size max_len, void *out_buf) override;
45
44
  };
46
45
 
47
- BrotliDecompressor::~BrotliDecompressor()
48
- {
49
- if (state) {
50
- BrotliDecoderDestroyInstance(state);
51
- }
52
- }
53
-
54
- bool BrotliDecompressor::Init(CompressionType)
46
+ BrotliDecompressor::BrotliDecompressor(StreamReader *reader, CompressionType)
47
+ : StreamDecoder(reader)
55
48
  {
56
49
  state = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
57
50
  if (!state)
58
51
  throw std::bad_alloc();
52
+ }
59
53
 
60
- return true;
54
+ BrotliDecompressor::~BrotliDecompressor()
55
+ {
56
+ BrotliDecoderDestroyInstance(state);
61
57
  }
62
58
 
63
59
  Size BrotliDecompressor::Read(Size max_len, void *user_buf)
@@ -105,26 +101,19 @@ Size BrotliDecompressor::Read(Size max_len, void *user_buf)
105
101
  RG_UNREACHABLE();
106
102
  }
107
103
 
108
- class BrotliCompressor: public StreamCompressor {
104
+ class BrotliCompressor: public StreamEncoder {
109
105
  BrotliEncoderStateStruct *state = nullptr;
110
106
 
111
107
  public:
112
- BrotliCompressor(StreamWriter *writer) : StreamCompressor(writer) {}
108
+ BrotliCompressor(StreamWriter *writer, CompressionType type, CompressionSpeed speed);
113
109
  ~BrotliCompressor();
114
110
 
115
- bool Init(CompressionType type, CompressionSpeed speed) override;
116
111
  bool Write(Span<const uint8_t> buf) override;
117
112
  bool Finalize() override;
118
113
  };
119
114
 
120
- BrotliCompressor::~BrotliCompressor()
121
- {
122
- if (state) {
123
- BrotliEncoderDestroyInstance(state);
124
- }
125
- }
126
-
127
- bool BrotliCompressor::Init(CompressionType, CompressionSpeed speed)
115
+ BrotliCompressor::BrotliCompressor(StreamWriter *writer, CompressionType, CompressionSpeed speed)
116
+ : StreamEncoder(writer)
128
117
  {
129
118
  state = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
130
119
  if (!state)
@@ -137,8 +126,11 @@ bool BrotliCompressor::Init(CompressionType, CompressionSpeed speed)
137
126
  case CompressionSpeed::Slow: { BrotliEncoderSetParameter(state, BROTLI_PARAM_QUALITY, 11); } break;
138
127
  case CompressionSpeed::Fast: { BrotliEncoderSetParameter(state, BROTLI_PARAM_QUALITY, 0); } break;
139
128
  }
129
+ }
140
130
 
141
- return true;
131
+ BrotliCompressor::~BrotliCompressor()
132
+ {
133
+ BrotliEncoderDestroyInstance(state);
142
134
  }
143
135
 
144
136
  bool BrotliCompressor::Write(Span<const uint8_t> buf)