koffi 2.3.10-beta.3 → 2.3.10

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/build/2.3.10/koffi_darwin_arm64/koffi.node +0 -0
  3. package/build/2.3.10/koffi_darwin_x64/koffi.node +0 -0
  4. package/build/2.3.10/koffi_freebsd_arm64/koffi.node +0 -0
  5. package/build/2.3.10/koffi_freebsd_ia32/koffi.node +0 -0
  6. package/build/2.3.10/koffi_freebsd_x64/koffi.node +0 -0
  7. package/build/2.3.10/koffi_linux_arm32hf/koffi.node +0 -0
  8. package/build/2.3.10/koffi_linux_arm64/koffi.node +0 -0
  9. package/build/2.3.10/koffi_linux_ia32/koffi.node +0 -0
  10. package/build/2.3.10/koffi_linux_riscv64hf64/koffi.node +0 -0
  11. package/build/2.3.10/koffi_linux_x64/koffi.node +0 -0
  12. package/build/2.3.10/koffi_openbsd_ia32/koffi.node +0 -0
  13. package/build/2.3.10/koffi_openbsd_x64/koffi.node +0 -0
  14. package/build/2.3.10/koffi_win32_arm64/koffi.node +0 -0
  15. package/build/2.3.10/koffi_win32_ia32/koffi.node +0 -0
  16. package/build/2.3.10/koffi_win32_x64/koffi.node +0 -0
  17. package/package.json +2 -2
  18. package/src/cnoke/package.json +2 -8
  19. package/src/core/libcc/brotli.cc +194 -0
  20. package/src/core/libcc/libcc.cc +111 -615
  21. package/src/core/libcc/libcc.hh +102 -28
  22. package/src/core/libcc/lz4.cc +204 -0
  23. package/src/core/libcc/miniz.cc +361 -0
  24. package/src/koffi/CMakeLists.txt +1 -1
  25. package/src/koffi/src/call.cc +18 -0
  26. package/build/2.3.10-beta.3/koffi_darwin_arm64/koffi.node +0 -0
  27. package/build/2.3.10-beta.3/koffi_darwin_x64/koffi.node +0 -0
  28. package/build/2.3.10-beta.3/koffi_freebsd_arm64/koffi.node +0 -0
  29. package/build/2.3.10-beta.3/koffi_freebsd_ia32/koffi.node +0 -0
  30. package/build/2.3.10-beta.3/koffi_freebsd_x64/koffi.node +0 -0
  31. package/build/2.3.10-beta.3/koffi_linux_arm32hf/koffi.node +0 -0
  32. package/build/2.3.10-beta.3/koffi_linux_arm64/koffi.node +0 -0
  33. package/build/2.3.10-beta.3/koffi_linux_ia32/koffi.node +0 -0
  34. package/build/2.3.10-beta.3/koffi_linux_riscv64hf64/koffi.node +0 -0
  35. package/build/2.3.10-beta.3/koffi_linux_x64/koffi.node +0 -0
  36. package/build/2.3.10-beta.3/koffi_openbsd_ia32/koffi.node +0 -0
  37. package/build/2.3.10-beta.3/koffi_openbsd_x64/koffi.node +0 -0
  38. package/build/2.3.10-beta.3/koffi_win32_arm64/koffi.node +0 -0
  39. package/build/2.3.10-beta.3/koffi_win32_ia32/koffi.node +0 -0
  40. package/build/2.3.10-beta.3/koffi_win32_x64/koffi.node +0 -0
  41. /package/build/{2.3.10-beta.3 → 2.3.10}/koffi_win32_arm64/koffi.exp +0 -0
  42. /package/build/{2.3.10-beta.3 → 2.3.10}/koffi_win32_arm64/koffi.lib +0 -0
  43. /package/build/{2.3.10-beta.3 → 2.3.10}/koffi_win32_ia32/koffi.exp +0 -0
  44. /package/build/{2.3.10-beta.3 → 2.3.10}/koffi_win32_ia32/koffi.lib +0 -0
  45. /package/build/{2.3.10-beta.3 → 2.3.10}/koffi_win32_x64/koffi.exp +0 -0
  46. /package/build/{2.3.10-beta.3 → 2.3.10}/koffi_win32_x64/koffi.lib +0 -0
@@ -136,7 +136,7 @@ static_assert(sizeof(double) == 8, "This code base is not designed to support si
136
136
  #define RG_STRINGIFY(a) RG_STRINGIFY_(a)
137
137
  #define RG_CONCAT_(a, b) a ## b
138
138
  #define RG_CONCAT(a, b) RG_CONCAT_(a, b)
139
- #define RG_UNIQUE_NAME(prefix) RG_CONCAT(prefix, __COUNTER__)
139
+ #define RG_UNIQUE_NAME(prefix) RG_CONCAT(prefix, __LINE__)
140
140
  #define RG_FORCE_EXPAND(x) x
141
141
  #define RG_IGNORE (void)!
142
142
 
@@ -597,7 +597,7 @@ public:
597
597
  }; \
598
598
  static ClassName RG_UNIQUE_NAME(init); \
599
599
  ClassName::ClassName()
600
- #define RG_INIT(Name) RG_INIT_(RG_UNIQUE_NAME(InitHelper))
600
+ #define RG_INIT(Name) RG_INIT_(RG_CONCAT(RG_UNIQUE_NAME(InitHelper), Name))
601
601
 
602
602
  #define RG_EXIT_(ClassName) \
603
603
  class ClassName { \
@@ -606,7 +606,7 @@ public:
606
606
  }; \
607
607
  static ClassName RG_UNIQUE_NAME(exit); \
608
608
  ClassName::~ClassName()
609
- #define RG_EXIT(Name) RG_EXIT_(RG_UNIQUE_NAME(ExitHelper))
609
+ #define RG_EXIT(Name) RG_EXIT_(RG_CONCAT(RG_UNIQUE_NAME(ExitHelper), Name))
610
610
 
611
611
  template <typename T>
612
612
  T MultiCmp()
@@ -3791,13 +3791,22 @@ enum class CompressionType {
3791
3791
  None,
3792
3792
  Zlib,
3793
3793
  Gzip,
3794
- Brotli
3794
+ Brotli,
3795
+ LZ4
3795
3796
  };
3796
3797
  static const char *const CompressionTypeNames[] = {
3797
3798
  "None",
3798
3799
  "Zlib",
3799
3800
  "Gzip",
3800
- "Brotli"
3801
+ "Brotli",
3802
+ "LZ4"
3803
+ };
3804
+ static const char *const CompressionTypeExtensions[] = {
3805
+ nullptr,
3806
+ nullptr,
3807
+ ".gz",
3808
+ ".br",
3809
+ ".lz4"
3801
3810
  };
3802
3811
 
3803
3812
  Span<const char> GetPathDirectory(Span<const char> filename);
@@ -3842,6 +3851,9 @@ struct FileInfo {
3842
3851
  int64_t mtime;
3843
3852
  int64_t btime;
3844
3853
  unsigned int mode;
3854
+
3855
+ uint32_t uid;
3856
+ uint32_t gid;
3845
3857
  };
3846
3858
 
3847
3859
  enum class StatResult {
@@ -4202,6 +4214,9 @@ enum class CompressionSpeed {
4202
4214
  Fast
4203
4215
  };
4204
4216
 
4217
+ class StreamDecompressor;
4218
+ class StreamCompressor;
4219
+
4205
4220
  class StreamReader {
4206
4221
  RG_DELETE_COPY(StreamReader)
4207
4222
 
@@ -4235,13 +4250,8 @@ class StreamReader {
4235
4250
  bool eof = false;
4236
4251
  } source;
4237
4252
 
4238
- struct {
4239
- CompressionType type = CompressionType::None;
4240
- union {
4241
- struct MinizInflateContext *miniz;
4242
- struct BrotliDecompressContext *brotli;
4243
- } u;
4244
- } compression;
4253
+ CompressionType compression_type = CompressionType::None;
4254
+ StreamDecompressor *decompressor = nullptr;
4245
4255
 
4246
4256
  int64_t raw_len = -1;
4247
4257
  Size raw_read = 0;
@@ -4278,7 +4288,7 @@ public:
4278
4288
  bool Rewind();
4279
4289
 
4280
4290
  const char *GetFileName() const { return filename; }
4281
- CompressionType GetCompressionType() const { return compression.type; }
4291
+ CompressionType GetCompressionType() const { return compression_type; }
4282
4292
  bool IsValid() const { return filename && !error; }
4283
4293
  bool IsEOF() const { return eof; }
4284
4294
 
@@ -4301,10 +4311,9 @@ private:
4301
4311
 
4302
4312
  bool InitDecompressor(CompressionType type);
4303
4313
 
4304
- Size ReadInflate(Size max_len, void *out_buf);
4305
- Size ReadBrotli(Size max_len, void *out_buf);
4306
-
4307
4314
  Size ReadRaw(Size max_len, void *out_buf);
4315
+
4316
+ friend class StreamDecompressor;
4308
4317
  };
4309
4318
 
4310
4319
  static inline Size ReadFile(const char *filename, CompressionType compression_type, Span<uint8_t> out_buf)
@@ -4351,6 +4360,42 @@ static inline Size ReadFile(const char *filename, Size max_len, HeapArray<char>
4351
4360
  return st.ReadAll(max_len, out_buf);
4352
4361
  }
4353
4362
 
4363
+ class StreamDecompressor {
4364
+ protected:
4365
+ StreamReader *reader;
4366
+
4367
+ public:
4368
+ StreamDecompressor(StreamReader *reader) : reader(reader) {}
4369
+ virtual ~StreamDecompressor() {}
4370
+
4371
+ virtual bool Init(CompressionType type) = 0;
4372
+ virtual Size Read(Size max_len, void *out_buf) = 0;
4373
+
4374
+ protected:
4375
+ const char *GetFileName() const { return reader->filename; }
4376
+ bool IsValid() const { return reader->IsValid(); }
4377
+ bool IsSourceEOF() const { return reader->source.eof; }
4378
+
4379
+ Size ReadRaw(Size max_len, void *out_buf) { return reader->ReadRaw(max_len, out_buf); }
4380
+
4381
+ void SetEOF(bool eof) { reader->eof = eof; }
4382
+ };
4383
+
4384
+ typedef StreamDecompressor *CreateDecompressorFunc(StreamReader *reader);
4385
+
4386
+ class StreamDecompressorHelper {
4387
+ public:
4388
+ StreamDecompressorHelper(CompressionType type, CreateDecompressorFunc *func);
4389
+ };
4390
+
4391
+ #define RG_REGISTER_DECOMPRESSOR(Type, Cls) \
4392
+ static StreamDecompressor *RG_UNIQUE_NAME(CreateDecompressor)(StreamReader *reader) \
4393
+ { \
4394
+ StreamDecompressor *decompressor = new Cls(reader); \
4395
+ return decompressor; \
4396
+ } \
4397
+ static StreamDecompressorHelper RG_UNIQUE_NAME(CreateDecompressorHelper)((Type), RG_UNIQUE_NAME(CreateDecompressor))
4398
+
4354
4399
  class LineReader {
4355
4400
  RG_DELETE_COPY(LineReader)
4356
4401
 
@@ -4420,14 +4465,9 @@ class StreamWriter {
4420
4465
  bool vt100;
4421
4466
  } dest;
4422
4467
 
4423
- struct {
4424
- CompressionType type = CompressionType::None;
4425
- CompressionSpeed speed = CompressionSpeed::Default;
4426
- union {
4427
- struct MinizDeflateContext *miniz;
4428
- struct BrotliEncoderStateStruct *brotli;
4429
- } u;
4430
- } compression;
4468
+ CompressionType compression_type = CompressionType::None;
4469
+ CompressionSpeed compression_speed = CompressionSpeed::Default;
4470
+ StreamCompressor *compressor = nullptr;
4431
4471
 
4432
4472
  int64_t raw_written = 0;
4433
4473
 
@@ -4471,7 +4511,8 @@ public:
4471
4511
  bool Flush();
4472
4512
 
4473
4513
  const char *GetFileName() const { return filename; }
4474
- CompressionType GetCompressionType() const { return compression.type; }
4514
+ CompressionType GetCompressionType() const { return compression_type; }
4515
+ CompressionSpeed GetCompressionSpeed() const { return compression_speed; }
4475
4516
  bool IsVt100() const { return dest.vt100; }
4476
4517
  bool IsValid() const { return filename && !error; }
4477
4518
 
@@ -4490,10 +4531,9 @@ private:
4490
4531
 
4491
4532
  bool InitCompressor(CompressionType type, CompressionSpeed speed);
4492
4533
 
4493
- bool WriteDeflate(Span<const uint8_t> buf);
4494
- bool WriteBrotli(Span<const uint8_t> buf);
4495
-
4496
4534
  bool WriteRaw(Span<const uint8_t> buf);
4535
+
4536
+ friend class StreamCompressor;
4497
4537
  };
4498
4538
 
4499
4539
  static inline bool WriteFile(Span<const uint8_t> buf, const char *filename, unsigned int flags = 0,
@@ -4511,6 +4551,40 @@ static inline bool WriteFile(Span<const char> buf, const char *filename, unsigne
4511
4551
  return st.Close();
4512
4552
  }
4513
4553
 
4554
+ class StreamCompressor {
4555
+ protected:
4556
+ StreamWriter *writer;
4557
+
4558
+ public:
4559
+ StreamCompressor(StreamWriter *writer) : writer(writer) {}
4560
+ virtual ~StreamCompressor() {}
4561
+
4562
+ virtual bool Init(CompressionType type, CompressionSpeed speed) = 0;
4563
+ virtual bool Write(Span<const uint8_t> buf) = 0;
4564
+ virtual bool Finalize() = 0;
4565
+
4566
+ protected:
4567
+ const char *GetFileName() const { return writer->filename; }
4568
+ bool IsValid() const { return writer->IsValid(); }
4569
+
4570
+ bool WriteRaw(Span<const uint8_t> buf) { return writer->WriteRaw(buf); }
4571
+ };
4572
+
4573
+ typedef StreamCompressor *CreateCompressorFunc(StreamWriter *writer);
4574
+
4575
+ class StreamCompressorHelper {
4576
+ public:
4577
+ StreamCompressorHelper(CompressionType type, CreateCompressorFunc *func);
4578
+ };
4579
+
4580
+ #define RG_REGISTER_COMPRESSOR(Type, Cls) \
4581
+ static StreamCompressor *RG_UNIQUE_NAME(CreateCompressor)(StreamWriter *writer) \
4582
+ { \
4583
+ StreamCompressor *compressor = new Cls(writer); \
4584
+ return compressor; \
4585
+ } \
4586
+ static StreamCompressorHelper RG_UNIQUE_NAME(CreateCompressorHelper)((Type), RG_UNIQUE_NAME(CreateCompressor))
4587
+
4514
4588
  bool SpliceStream(StreamReader *reader, int64_t max_len, StreamWriter *writer);
4515
4589
 
4516
4590
  // For convenience, don't close them
@@ -0,0 +1,204 @@
1
+ // Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
2
+
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ // this software and associated documentation files (the “Software”), to deal in
5
+ // the Software without restriction, including without limitation the rights to use,
6
+ // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
7
+ // Software, and to permit persons to whom the Software is furnished to do so,
8
+ // subject to the following conditions:
9
+
10
+ // The above copyright notice and this permission notice shall be included in all
11
+ // copies or substantial portions of the Software.
12
+
13
+ // THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
14
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15
+ // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17
+ // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
+ // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
+ // OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ #include "libcc.hh"
23
+
24
+ #include "vendor/lz4/lib/lz4.h"
25
+ #include "vendor/lz4/lib/lz4hc.h"
26
+ #include "vendor/lz4/lib/lz4frame.h"
27
+
28
+ namespace RG {
29
+
30
+ class LZ4Decompressor: public StreamDecompressor {
31
+ LZ4F_dctx *decoder = nullptr;
32
+ bool done = false;
33
+
34
+ uint8_t in_buf[256 * 1024];
35
+ Size in_len = 0;
36
+ Size in_hint = RG_SIZE(in_buf);
37
+
38
+ uint8_t out_buf[256 * 1024];
39
+ Size out_len = 0;
40
+
41
+ public:
42
+ LZ4Decompressor(StreamReader *reader) : StreamDecompressor(reader) {}
43
+ ~LZ4Decompressor();
44
+
45
+ bool Init(CompressionType type) override;
46
+ Size Read(Size max_len, void *out_buf) override;
47
+ };
48
+
49
+ LZ4Decompressor::~LZ4Decompressor()
50
+ {
51
+ LZ4F_freeDecompressionContext(decoder);
52
+ }
53
+
54
+ bool LZ4Decompressor::Init(CompressionType)
55
+ {
56
+ LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&decoder, LZ4F_VERSION);
57
+ if (LZ4F_isError(err))
58
+ throw std::bad_alloc();
59
+
60
+ return true;
61
+ }
62
+
63
+ Size LZ4Decompressor::Read(Size max_len, void *user_buf)
64
+ {
65
+ for (;;) {
66
+ if (out_len || done) {
67
+ Size copy_len = std::min(max_len, out_len);
68
+
69
+ out_len -= copy_len;
70
+ memcpy(user_buf, out_buf, copy_len);
71
+ memmove(out_buf, out_buf + copy_len, out_len);
72
+
73
+ SetEOF(!out_len && done);
74
+ return copy_len;
75
+ }
76
+
77
+ if (in_len < in_hint) {
78
+ Size raw_len = ReadRaw(in_hint - in_len, in_buf + in_len);
79
+ if (raw_len < 0)
80
+ return -1;
81
+ in_len += raw_len;
82
+ }
83
+
84
+ const uint8_t *next_in = in_buf;
85
+ uint8_t *next_out = out_buf + out_len;
86
+ size_t avail_in = (size_t)in_len;
87
+ size_t avail_out = (size_t)(RG_SIZE(out_buf) - out_len);
88
+
89
+ LZ4F_decompressOptions_t opt = {};
90
+ size_t ret = LZ4F_decompress(decoder, next_out, &avail_out, next_in, &avail_in, &opt);
91
+
92
+ if (!ret) {
93
+ done = true;
94
+ } else if (LZ4F_isError(ret)) {
95
+ LogError("Malformed LZ4 stream in '%1': %2", GetFileName(), LZ4F_getErrorName(ret));
96
+ return -1;
97
+ }
98
+
99
+ memmove_safe(in_buf, in_buf + avail_in, (size_t)in_len - avail_in);
100
+ in_len -= avail_in;
101
+ in_hint = std::min(RG_SIZE(in_buf), (Size)ret);
102
+
103
+ out_len += (Size)avail_out;
104
+ }
105
+
106
+ RG_UNREACHABLE();
107
+ }
108
+
109
+ class LZ4Compressor: public StreamCompressor {
110
+ LZ4F_cctx *encoder = nullptr;
111
+ LZ4F_preferences_t prefs = {};
112
+
113
+ HeapArray<uint8_t> dynamic_buf;
114
+
115
+ public:
116
+ LZ4Compressor(StreamWriter *writer) : StreamCompressor(writer) {}
117
+ ~LZ4Compressor();
118
+
119
+ bool Init(CompressionType type, CompressionSpeed speed) override;
120
+ bool Write(Span<const uint8_t> buf) override;
121
+ bool Finalize() override;
122
+ };
123
+
124
+ LZ4Compressor::~LZ4Compressor()
125
+ {
126
+ LZ4F_freeCompressionContext(encoder);
127
+ }
128
+
129
+ bool LZ4Compressor::Init(CompressionType, CompressionSpeed speed)
130
+ {
131
+ LZ4F_errorCode_t err = LZ4F_createCompressionContext(&encoder, LZ4F_VERSION);
132
+ if (LZ4F_isError(err))
133
+ throw std::bad_alloc();
134
+
135
+ switch (speed) {
136
+ case CompressionSpeed::Default: { prefs.compressionLevel = LZ4HC_CLEVEL_MIN; } break;
137
+ case CompressionSpeed::Slow: { prefs.compressionLevel = LZ4HC_CLEVEL_MAX; } break;
138
+ case CompressionSpeed::Fast: { prefs.compressionLevel = 0; } break;
139
+ }
140
+
141
+ dynamic_buf.Grow(LZ4F_HEADER_SIZE_MAX);
142
+
143
+ size_t ret = LZ4F_compressBegin(encoder, dynamic_buf.end(), dynamic_buf.capacity - dynamic_buf.len, &prefs);
144
+
145
+ if (LZ4F_isError(ret)) {
146
+ LogError("Failed to start LZ4 stream for '%1': %2", GetFileName(), LZ4F_getErrorName(ret));
147
+ return false;
148
+ }
149
+
150
+ dynamic_buf.len += ret;
151
+
152
+ return true;
153
+ }
154
+
155
+ bool LZ4Compressor::Write(Span<const uint8_t> buf)
156
+ {
157
+ size_t needed = LZ4F_compressBound((size_t)buf.len, &prefs);
158
+ dynamic_buf.Grow((Size)needed);
159
+
160
+ size_t ret = LZ4F_compressUpdate(encoder, dynamic_buf.end(), (size_t)(dynamic_buf.capacity - dynamic_buf.len),
161
+ buf.ptr, (size_t)buf.len, nullptr);
162
+
163
+ if (LZ4F_isError(ret)) {
164
+ LogError("Failed to write LZ4 stream for '%1': %2", GetFileName(), LZ4F_getErrorName(ret));
165
+ return false;
166
+ }
167
+
168
+ dynamic_buf.len += (Size)ret;
169
+
170
+ if (dynamic_buf.len >= 512) {
171
+ if (!WriteRaw(dynamic_buf))
172
+ return false;
173
+ dynamic_buf.len = 0;
174
+ }
175
+
176
+ return true;
177
+ }
178
+
179
+ bool LZ4Compressor::Finalize()
180
+ {
181
+ size_t needed = LZ4F_compressBound(0, &prefs);
182
+ dynamic_buf.Grow((Size)needed);
183
+
184
+ size_t ret = LZ4F_compressEnd(encoder, dynamic_buf.end(),
185
+ (size_t)(dynamic_buf.capacity - dynamic_buf.len), nullptr);
186
+
187
+ if (LZ4F_isError(ret)) {
188
+ LogError("Failed to finalize LZ4 stream for '%1': %2", GetFileName(), LZ4F_getErrorName(ret));
189
+ return false;
190
+ }
191
+
192
+ dynamic_buf.len += (Size)ret;
193
+
194
+ if (!WriteRaw(dynamic_buf))
195
+ return false;
196
+ dynamic_buf.len = 0;
197
+
198
+ return true;
199
+ }
200
+
201
+ RG_REGISTER_DECOMPRESSOR(CompressionType::LZ4, LZ4Decompressor);
202
+ RG_REGISTER_COMPRESSOR(CompressionType::LZ4, LZ4Compressor);
203
+
204
+ }