koffi 2.7.1 → 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 +6 -0
- package/README.md +2 -2
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm32hf/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_riscv64hf64/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/unions.md +2 -2
- package/index.d.ts +2 -1
- package/index.js +23 -23
- package/indirect.js +23 -23
- package/package.json +2 -2
- package/src/core/libcc/brotli.cc +16 -24
- package/src/core/libcc/libcc.cc +63 -69
- package/src/core/libcc/libcc.hh +103 -110
- package/src/core/libcc/lz4.cc +18 -25
- package/src/core/libcc/miniz.cc +10 -18
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
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
|
+
|
|
7
13
|
#### Koffi 2.7.1 (2024-01-02)
|
|
8
14
|
|
|
9
15
|
- Support C-like `int[3]` syntax for [fixed array types](input.md#fixed-size-c-arrays)
|
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/
|
|
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/
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
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', {
|
|
53
|
-
DoSomething('string', {
|
|
52
|
+
DoSomething('int', { i: 42 });
|
|
53
|
+
DoSomething('string', { str: 'Hello!' });
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
### Win32 example
|
package/index.d.ts
CHANGED
|
@@ -132,7 +132,6 @@ declare module 'koffi' {
|
|
|
132
132
|
export function decode(value: any, offset: number, type: TypeSpec, len: number): any;
|
|
133
133
|
export function address(value: any): bigint;
|
|
134
134
|
export function call(value: any, type: TypeSpec, ...args: any[]): any;
|
|
135
|
-
export function encode(ref: any, type: TypeSpec): void;
|
|
136
135
|
export function encode(ref: any, type: TypeSpec, value: any): void;
|
|
137
136
|
export function encode(ref: any, type: TypeSpec, value: any, len: number): void;
|
|
138
137
|
export function encode(ref: any, offset: number, type: TypeSpec): void;
|
|
@@ -151,6 +150,8 @@ declare module 'koffi' {
|
|
|
151
150
|
export function config(cfg: Record<string, unknown>): Record<string, unknown>;
|
|
152
151
|
export function stats(): Record<string, unknown>;
|
|
153
152
|
|
|
153
|
+
export function free(value: any): void;
|
|
154
|
+
|
|
154
155
|
export function errno(): number;
|
|
155
156
|
export function errno(value: number): number;
|
|
156
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
|
|
73
|
-
let file = fs2.createWriteStream(
|
|
74
|
-
return [
|
|
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(
|
|
82
|
-
let reader = fs2.createReadStream(
|
|
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
|
|
123
|
-
let dirname = path.dirname(
|
|
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(
|
|
125
|
+
fs2.writeFileSync(filename3, data, { mode: header.mode });
|
|
126
126
|
} else if (header.type == "5") {
|
|
127
|
-
let
|
|
128
|
-
fs2.mkdirSync(
|
|
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(
|
|
236
|
+
function read_file_header(filename2, read) {
|
|
237
237
|
let fd = null;
|
|
238
238
|
try {
|
|
239
|
-
let fd2 = fs2.openSync(
|
|
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.
|
|
382
|
-
stable: "2.7.
|
|
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
|
|
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
|
-
|
|
544
|
-
|
|
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
|
|
73
|
-
let file = fs2.createWriteStream(
|
|
74
|
-
return [
|
|
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(
|
|
82
|
-
let reader = fs2.createReadStream(
|
|
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
|
|
123
|
-
let dirname = path.dirname(
|
|
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(
|
|
125
|
+
fs2.writeFileSync(filename3, data, { mode: header.mode });
|
|
126
126
|
} else if (header.type == "5") {
|
|
127
|
-
let
|
|
128
|
-
fs2.mkdirSync(
|
|
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(
|
|
236
|
+
function read_file_header(filename2, read) {
|
|
237
237
|
let fd = null;
|
|
238
238
|
try {
|
|
239
|
-
let fd2 = fs2.openSync(
|
|
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.
|
|
382
|
-
stable: "2.7.
|
|
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
|
|
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
|
-
|
|
464
|
-
|
|
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
package/src/core/libcc/brotli.cc
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
namespace RG {
|
|
28
28
|
|
|
29
|
-
class BrotliDecompressor: public
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
104
|
+
class BrotliCompressor: public StreamEncoder {
|
|
109
105
|
BrotliEncoderStateStruct *state = nullptr;
|
|
110
106
|
|
|
111
107
|
public:
|
|
112
|
-
BrotliCompressor(StreamWriter *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
|
|
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
|
-
|
|
131
|
+
BrotliCompressor::~BrotliCompressor()
|
|
132
|
+
{
|
|
133
|
+
BrotliEncoderDestroyInstance(state);
|
|
142
134
|
}
|
|
143
135
|
|
|
144
136
|
bool BrotliCompressor::Write(Span<const uint8_t> buf)
|
package/src/core/libcc/libcc.cc
CHANGED
|
@@ -1932,6 +1932,23 @@ bool GetDebugFlag(const char *name)
|
|
|
1932
1932
|
}
|
|
1933
1933
|
}
|
|
1934
1934
|
|
|
1935
|
+
#ifndef NDEBUG
|
|
1936
|
+
const char *DebugLogContext(const char *filename, int line)
|
|
1937
|
+
{
|
|
1938
|
+
static RG_THREAD_LOCAL LocalArray<char, 1024> buf;
|
|
1939
|
+
|
|
1940
|
+
buf.len = Fmt(buf.data, " [%1:%2] ", filename, line).len;
|
|
1941
|
+
|
|
1942
|
+
if (buf.len > 32) {
|
|
1943
|
+
char *ptr = buf.end() - 32;
|
|
1944
|
+
memcpy(ptr, " [...", 6);
|
|
1945
|
+
return ptr;
|
|
1946
|
+
} else {
|
|
1947
|
+
return buf.data;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
#endif
|
|
1951
|
+
|
|
1935
1952
|
static void RunLogFilter(Size idx, LogLevel level, const char *ctx, const char *msg)
|
|
1936
1953
|
{
|
|
1937
1954
|
const std::function<LogFilterFunc> &func = *log_filters[idx];
|
|
@@ -2001,9 +2018,9 @@ void DefaultLogHandler(LogLevel level, const char *ctx, const char *msg)
|
|
|
2001
2018
|
{
|
|
2002
2019
|
switch (level) {
|
|
2003
2020
|
case LogLevel::Debug:
|
|
2004
|
-
case LogLevel::Info: { PrintLn(stderr, "%!D..%1
|
|
2005
|
-
case LogLevel::Warning: { PrintLn(stderr, "%!M..%1
|
|
2006
|
-
case LogLevel::Error: { PrintLn(stderr, "%!R..%1
|
|
2021
|
+
case LogLevel::Info: { PrintLn(stderr, "%!D..%1%!0%2", ctx ? ctx : "", msg); } break;
|
|
2022
|
+
case LogLevel::Warning: { PrintLn(stderr, "%!M..%1%!0%2", ctx ? ctx : "", msg); } break;
|
|
2023
|
+
case LogLevel::Error: { PrintLn(stderr, "%!R..%1%!0%2", ctx ? ctx : "", msg); } break;
|
|
2007
2024
|
}
|
|
2008
2025
|
|
|
2009
2026
|
fflush(stderr);
|
|
@@ -2047,11 +2064,10 @@ bool RedirectLogToWindowsEvents(const char *name)
|
|
|
2047
2064
|
|
|
2048
2065
|
// Append context
|
|
2049
2066
|
if (ctx) {
|
|
2050
|
-
Size len = ConvertUtf8ToWin32Wide(ctx, buf_w.
|
|
2067
|
+
Size len = ConvertUtf8ToWin32Wide(ctx, buf_w.TakeAvailable());
|
|
2051
2068
|
if (len < 0)
|
|
2052
2069
|
return;
|
|
2053
|
-
|
|
2054
|
-
buf_w.len += len + 2;
|
|
2070
|
+
buf_w.len += len;
|
|
2055
2071
|
}
|
|
2056
2072
|
|
|
2057
2073
|
// Append message
|
|
@@ -6182,6 +6198,15 @@ StreamWriter stderr_st(stderr, "<stderr>");
|
|
|
6182
6198
|
static CreateDecompressorFunc *DecompressorFunctions[RG_LEN(CompressionTypeNames)];
|
|
6183
6199
|
static CreateCompressorFunc *CompressorFunctions[RG_LEN(CompressionTypeNames)];
|
|
6184
6200
|
|
|
6201
|
+
void StreamReader::SetDecoder(StreamDecoder *decoder)
|
|
6202
|
+
{
|
|
6203
|
+
RG_ASSERT(decoder);
|
|
6204
|
+
RG_ASSERT(!filename);
|
|
6205
|
+
RG_ASSERT(!this->decoder);
|
|
6206
|
+
|
|
6207
|
+
this->decoder = decoder;
|
|
6208
|
+
}
|
|
6209
|
+
|
|
6185
6210
|
bool StreamReader::Open(Span<const uint8_t> buf, const char *filename,
|
|
6186
6211
|
CompressionType compression_type)
|
|
6187
6212
|
{
|
|
@@ -6286,9 +6311,9 @@ bool StreamReader::Close(bool implicit)
|
|
|
6286
6311
|
{
|
|
6287
6312
|
RG_ASSERT(implicit || this != &stdin_st);
|
|
6288
6313
|
|
|
6289
|
-
if (
|
|
6290
|
-
|
|
6291
|
-
|
|
6314
|
+
if (decoder) {
|
|
6315
|
+
delete decoder;
|
|
6316
|
+
decoder = nullptr;
|
|
6292
6317
|
}
|
|
6293
6318
|
|
|
6294
6319
|
switch (source.type) {
|
|
@@ -6308,7 +6333,6 @@ bool StreamReader::Close(bool implicit)
|
|
|
6308
6333
|
|
|
6309
6334
|
filename = nullptr;
|
|
6310
6335
|
error = true;
|
|
6311
|
-
compression_type = CompressionType::None;
|
|
6312
6336
|
source.type = SourceType::Memory;
|
|
6313
6337
|
source.eof = false;
|
|
6314
6338
|
eof = false;
|
|
@@ -6323,6 +6347,11 @@ bool StreamReader::Rewind()
|
|
|
6323
6347
|
if (error) [[unlikely]]
|
|
6324
6348
|
return false;
|
|
6325
6349
|
|
|
6350
|
+
if (decoder) [[unlikely]] {
|
|
6351
|
+
LogError("Cannot rewind stream with decoder");
|
|
6352
|
+
return false;
|
|
6353
|
+
}
|
|
6354
|
+
|
|
6326
6355
|
switch (source.type) {
|
|
6327
6356
|
case SourceType::Memory: { source.u.memory.pos = 0; } break;
|
|
6328
6357
|
case SourceType::File: {
|
|
@@ -6339,14 +6368,6 @@ bool StreamReader::Rewind()
|
|
|
6339
6368
|
} break;
|
|
6340
6369
|
}
|
|
6341
6370
|
|
|
6342
|
-
if (decompressor) {
|
|
6343
|
-
RG_ASSERT(compression_type != CompressionType::None);
|
|
6344
|
-
delete decompressor;
|
|
6345
|
-
|
|
6346
|
-
if (!InitDecompressor(compression_type))
|
|
6347
|
-
return false;
|
|
6348
|
-
}
|
|
6349
|
-
|
|
6350
6371
|
source.eof = false;
|
|
6351
6372
|
eof = false;
|
|
6352
6373
|
|
|
@@ -6376,14 +6397,10 @@ Size StreamReader::Read(Span<uint8_t> out_buf)
|
|
|
6376
6397
|
return -1;
|
|
6377
6398
|
|
|
6378
6399
|
Size read_len = 0;
|
|
6379
|
-
if (
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
read_len = decompressor->Read(out_buf.len, out_buf.ptr);
|
|
6400
|
+
if (decoder) {
|
|
6401
|
+
read_len = decoder->Read(out_buf.len, out_buf.ptr);
|
|
6383
6402
|
error |= (read_len < 0);
|
|
6384
6403
|
} else {
|
|
6385
|
-
RG_ASSERT(compression_type == CompressionType::None);
|
|
6386
|
-
|
|
6387
6404
|
read_len = ReadRaw(out_buf.len, out_buf.ptr);
|
|
6388
6405
|
eof = source.eof;
|
|
6389
6406
|
}
|
|
@@ -6421,7 +6438,7 @@ Size StreamReader::ReadAll(Size max_len, HeapArray<uint8_t> *out_buf)
|
|
|
6421
6438
|
// For some files (such as in /proc), the file size is reported as 0 even though there
|
|
6422
6439
|
// is content inside, because these files are generated on demand. So we need to take
|
|
6423
6440
|
// the slow path for apparently empty files.
|
|
6424
|
-
if (
|
|
6441
|
+
if (!decoder && ComputeRawLen() > 0) {
|
|
6425
6442
|
if (raw_len > max_len) {
|
|
6426
6443
|
LogError("File '%1' is too large (limit = %2)", filename, FmtDiskSize(max_len));
|
|
6427
6444
|
return -1;
|
|
@@ -6510,19 +6527,10 @@ bool StreamReader::InitDecompressor(CompressionType type)
|
|
|
6510
6527
|
return false;
|
|
6511
6528
|
}
|
|
6512
6529
|
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
if (!decompressor) {
|
|
6516
|
-
error = true;
|
|
6517
|
-
return false;
|
|
6518
|
-
}
|
|
6519
|
-
if (!decompressor->Init(type)) {
|
|
6520
|
-
error = true;
|
|
6521
|
-
return false;
|
|
6522
|
-
}
|
|
6530
|
+
decoder = func(this, type);
|
|
6531
|
+
RG_ASSERT(decoder);
|
|
6523
6532
|
}
|
|
6524
6533
|
|
|
6525
|
-
compression_type = type;
|
|
6526
6534
|
return true;
|
|
6527
6535
|
}
|
|
6528
6536
|
|
|
@@ -6621,23 +6629,23 @@ void LineReader::PushLogFilter()
|
|
|
6621
6629
|
char ctx_buf[1024];
|
|
6622
6630
|
|
|
6623
6631
|
if (line_number > 0) {
|
|
6624
|
-
Fmt(ctx_buf, "%1
|
|
6632
|
+
Fmt(ctx_buf, "%1%2(%3): ", ctx ? ctx : "", st->GetFileName(), line_number);
|
|
6625
6633
|
} else {
|
|
6626
|
-
Fmt(ctx_buf, "%1%2
|
|
6634
|
+
Fmt(ctx_buf, "%1%2: ", ctx ? ctx : "", st->GetFileName());
|
|
6627
6635
|
}
|
|
6628
6636
|
|
|
6629
6637
|
func(level, ctx_buf, msg);
|
|
6630
6638
|
});
|
|
6631
6639
|
}
|
|
6632
6640
|
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6641
|
+
void StreamWriter::SetEncoder(StreamEncoder *encoder)
|
|
6642
|
+
{
|
|
6643
|
+
RG_ASSERT(encoder);
|
|
6644
|
+
RG_ASSERT(!filename);
|
|
6645
|
+
RG_ASSERT(!this->encoder);
|
|
6637
6646
|
|
|
6638
|
-
|
|
6639
|
-
}
|
|
6640
|
-
#endif
|
|
6647
|
+
this->encoder = encoder;
|
|
6648
|
+
}
|
|
6641
6649
|
|
|
6642
6650
|
bool StreamWriter::Open(HeapArray<uint8_t> *mem, const char *filename,
|
|
6643
6651
|
CompressionType compression_type, CompressionSpeed compression_speed)
|
|
@@ -6802,10 +6810,8 @@ bool StreamWriter::Write(Span<const uint8_t> buf)
|
|
|
6802
6810
|
if (error) [[unlikely]]
|
|
6803
6811
|
return false;
|
|
6804
6812
|
|
|
6805
|
-
if (
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
error |= !compressor->Write(buf);
|
|
6813
|
+
if (encoder) {
|
|
6814
|
+
error |= !encoder->Write(buf);
|
|
6809
6815
|
return !error;
|
|
6810
6816
|
} else {
|
|
6811
6817
|
return WriteRaw(buf);
|
|
@@ -6817,11 +6823,11 @@ bool StreamWriter::Close(bool implicit)
|
|
|
6817
6823
|
RG_ASSERT(implicit || this != &stdout_st);
|
|
6818
6824
|
RG_ASSERT(implicit || this != &stderr_st);
|
|
6819
6825
|
|
|
6820
|
-
if (
|
|
6821
|
-
|
|
6822
|
-
error |= !compressor->Finalize();
|
|
6826
|
+
if (encoder) {
|
|
6827
|
+
error = error || !encoder->Finalize();
|
|
6823
6828
|
|
|
6824
|
-
delete
|
|
6829
|
+
delete encoder;
|
|
6830
|
+
encoder = nullptr;
|
|
6825
6831
|
}
|
|
6826
6832
|
|
|
6827
6833
|
switch (dest.type) {
|
|
@@ -6880,7 +6886,6 @@ bool StreamWriter::Close(bool implicit)
|
|
|
6880
6886
|
|
|
6881
6887
|
filename = nullptr;
|
|
6882
6888
|
error = true;
|
|
6883
|
-
compression_type = CompressionType::None;
|
|
6884
6889
|
dest.type = DestinationType::Memory;
|
|
6885
6890
|
str_alloc.ReleaseAll();
|
|
6886
6891
|
|
|
@@ -6898,21 +6903,10 @@ bool StreamWriter::InitCompressor(CompressionType type, CompressionSpeed speed)
|
|
|
6898
6903
|
return false;
|
|
6899
6904
|
}
|
|
6900
6905
|
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
if (!compressor) {
|
|
6904
|
-
error = true;
|
|
6905
|
-
return false;
|
|
6906
|
-
}
|
|
6907
|
-
if (!compressor->Init(type, speed)) {
|
|
6908
|
-
error = true;
|
|
6909
|
-
return false;
|
|
6910
|
-
}
|
|
6906
|
+
encoder = func(this, type, speed);
|
|
6907
|
+
RG_ASSERT(encoder);
|
|
6911
6908
|
}
|
|
6912
6909
|
|
|
6913
|
-
compression_type = type;
|
|
6914
|
-
compression_speed = speed;
|
|
6915
|
-
|
|
6916
6910
|
return true;
|
|
6917
6911
|
}
|
|
6918
6912
|
|
|
@@ -7013,14 +7007,14 @@ bool IsDecompressorAvailable(CompressionType compression_type)
|
|
|
7013
7007
|
static bool CheckIniKey(Span<const char> key)
|
|
7014
7008
|
{
|
|
7015
7009
|
const auto test_char = [](char c) { return IsAsciiAlphaOrDigit(c) || c == '_' ||
|
|
7016
|
-
c == '-' || c == '.' || c == '/'; };
|
|
7010
|
+
c == '-' || c == '.' || c == '/' || c == '@'; };
|
|
7017
7011
|
|
|
7018
7012
|
if (!key.len) {
|
|
7019
7013
|
LogError("INI key cannot be empty");
|
|
7020
7014
|
return false;
|
|
7021
7015
|
}
|
|
7022
7016
|
if (!std::all_of(key.begin(), key.end(), test_char)) {
|
|
7023
|
-
LogError("INI key must only contain alphanumeric, '.', '-' or '
|
|
7017
|
+
LogError("INI key must only contain alphanumeric, '.', '-', '_', '/' or '@' characters");
|
|
7024
7018
|
return false;
|
|
7025
7019
|
}
|
|
7026
7020
|
|
package/src/core/libcc/libcc.hh
CHANGED
|
@@ -249,14 +249,6 @@ extern "C" void AssertMessage(const char *filename, int line, const char *cond);
|
|
|
249
249
|
#define RG_UNREACHABLE() __assume(0)
|
|
250
250
|
#endif
|
|
251
251
|
|
|
252
|
-
#if defined(__EMSCRIPTEN__)
|
|
253
|
-
#define RG_EXPORT EMSCRIPTEN_KEEPALIVE
|
|
254
|
-
#elif defined(_WIN32)
|
|
255
|
-
#define RG_EXPORT __declspec(dllexport)
|
|
256
|
-
#else
|
|
257
|
-
#define RG_EXPORT __attribute__((visibility("default")))
|
|
258
|
-
#endif
|
|
259
|
-
|
|
260
252
|
#define RG_DELETE_COPY(Cls) \
|
|
261
253
|
Cls(const Cls&) = delete; \
|
|
262
254
|
Cls &operator=(const Cls&) = delete;
|
|
@@ -1221,11 +1213,7 @@ public:
|
|
|
1221
1213
|
RG_ASSERT(len <= N - count);
|
|
1222
1214
|
|
|
1223
1215
|
T *first = data + len;
|
|
1224
|
-
#if __cplusplus >= 201703L
|
|
1225
1216
|
if constexpr(!std::is_trivial<T>::value) {
|
|
1226
|
-
#else
|
|
1227
|
-
if (true) {
|
|
1228
|
-
#endif
|
|
1229
1217
|
for (Size i = 0; i < count; i++) {
|
|
1230
1218
|
new (data + len) T();
|
|
1231
1219
|
len++;
|
|
@@ -1323,11 +1311,7 @@ public:
|
|
|
1323
1311
|
{
|
|
1324
1312
|
RemoveFrom(0);
|
|
1325
1313
|
Grow(other.capacity);
|
|
1326
|
-
#if __cplusplus >= 201703L
|
|
1327
1314
|
if constexpr(!std::is_trivial<T>::value) {
|
|
1328
|
-
#else
|
|
1329
|
-
if (true) {
|
|
1330
|
-
#endif
|
|
1331
1315
|
for (Size i = 0; i < other.len; i++) {
|
|
1332
1316
|
ptr[i] = other.ptr[i];
|
|
1333
1317
|
}
|
|
@@ -1432,11 +1416,7 @@ public:
|
|
|
1432
1416
|
Grow(count);
|
|
1433
1417
|
|
|
1434
1418
|
T *first = ptr + len;
|
|
1435
|
-
#if __cplusplus >= 201703L
|
|
1436
1419
|
if constexpr(!std::is_trivial<T>::value) {
|
|
1437
|
-
#else
|
|
1438
|
-
if (true) {
|
|
1439
|
-
#endif
|
|
1440
1420
|
for (Size i = 0; i < count; i++) {
|
|
1441
1421
|
new (ptr + len) T();
|
|
1442
1422
|
len++;
|
|
@@ -1454,11 +1434,7 @@ public:
|
|
|
1454
1434
|
Grow();
|
|
1455
1435
|
|
|
1456
1436
|
T *first = ptr + len;
|
|
1457
|
-
#if __cplusplus >= 201703L
|
|
1458
1437
|
if constexpr(!std::is_trivial<T>::value) {
|
|
1459
|
-
#else
|
|
1460
|
-
if (true) {
|
|
1461
|
-
#endif
|
|
1462
1438
|
new (ptr + len) T;
|
|
1463
1439
|
}
|
|
1464
1440
|
ptr[len++] = value;
|
|
@@ -1470,11 +1446,7 @@ public:
|
|
|
1470
1446
|
|
|
1471
1447
|
T *first = ptr + len;
|
|
1472
1448
|
for (const T &value: values) {
|
|
1473
|
-
#if __cplusplus >= 201703L
|
|
1474
1449
|
if constexpr(!std::is_trivial<T>::value) {
|
|
1475
|
-
#else
|
|
1476
|
-
if (true) {
|
|
1477
|
-
#endif
|
|
1478
1450
|
new (ptr + len) T;
|
|
1479
1451
|
}
|
|
1480
1452
|
ptr[len++] = value;
|
|
@@ -1486,11 +1458,7 @@ public:
|
|
|
1486
1458
|
{
|
|
1487
1459
|
RG_ASSERT(first >= 0 && first <= len);
|
|
1488
1460
|
|
|
1489
|
-
#if __cplusplus >= 201703L
|
|
1490
1461
|
if constexpr(!std::is_trivial<T>::value) {
|
|
1491
|
-
#else
|
|
1492
|
-
if (true) {
|
|
1493
|
-
#endif
|
|
1494
1462
|
for (Size i = first; i < len; i++) {
|
|
1495
1463
|
ptr[i].~T();
|
|
1496
1464
|
}
|
|
@@ -1796,11 +1764,7 @@ private:
|
|
|
1796
1764
|
void DeleteValues([[maybe_unused]] iterator_type begin,
|
|
1797
1765
|
[[maybe_unused]] iterator_type end)
|
|
1798
1766
|
{
|
|
1799
|
-
#if __cplusplus >= 201703L
|
|
1800
1767
|
if constexpr(!std::is_trivial<T>::value) {
|
|
1801
|
-
#else
|
|
1802
|
-
if (true) {
|
|
1803
|
-
#endif
|
|
1804
1768
|
for (iterator_type it = begin; it != end; ++it) {
|
|
1805
1769
|
it->~T();
|
|
1806
1770
|
}
|
|
@@ -2077,11 +2041,7 @@ public:
|
|
|
2077
2041
|
}
|
|
2078
2042
|
~HashTable()
|
|
2079
2043
|
{
|
|
2080
|
-
#if __cplusplus >= 201703L
|
|
2081
2044
|
if constexpr(std::is_trivial<ValueType>::value) {
|
|
2082
|
-
#else
|
|
2083
|
-
if (false) {
|
|
2084
|
-
#endif
|
|
2085
2045
|
count = 0;
|
|
2086
2046
|
Rehash(0);
|
|
2087
2047
|
} else {
|
|
@@ -2278,11 +2238,7 @@ private:
|
|
|
2278
2238
|
template <typename T = KeyType>
|
|
2279
2239
|
const ValueType *Find(Size *idx, const T &key) const
|
|
2280
2240
|
{
|
|
2281
|
-
#if __cplusplus >= 201703L
|
|
2282
2241
|
if constexpr(std::is_pointer<ValueType>::value) {
|
|
2283
|
-
#else
|
|
2284
|
-
if (false) {
|
|
2285
|
-
#endif
|
|
2286
2242
|
while (data[*idx]) {
|
|
2287
2243
|
const KeyType &it_key = Handler::GetKey(data[*idx]);
|
|
2288
2244
|
if (Handler::TestKeys(it_key, key))
|
|
@@ -3184,18 +3140,22 @@ static inline void Log(LogLevel level, const char *ctx, const char *fmt, Args...
|
|
|
3184
3140
|
|
|
3185
3141
|
// Shortcut log functions
|
|
3186
3142
|
#ifdef RG_DEBUG
|
|
3187
|
-
|
|
3188
|
-
|
|
3143
|
+
const char *DebugLogContext(const char *filename, int line);
|
|
3144
|
+
|
|
3145
|
+
#define LogDebug(...) Log(LogLevel::Debug, DebugLogContext(__FILE__, __LINE__) __VA_OPT__(,) __VA_ARGS__)
|
|
3146
|
+
#define LogInfo(...) Log(LogLevel::Info, nullptr __VA_OPT__(,) __VA_ARGS__)
|
|
3147
|
+
#define LogWarning(...) Log(LogLevel::Warning, DebugLogContext(__FILE__, __LINE__) __VA_OPT__(,) __VA_ARGS__)
|
|
3148
|
+
#define LogError(...) Log(LogLevel::Error, DebugLogContext(__FILE__, __LINE__) __VA_OPT__(,) __VA_ARGS__)
|
|
3189
3149
|
#else
|
|
3190
|
-
template <typename... Args>
|
|
3191
|
-
static inline void LogDebug(Args...) {}
|
|
3150
|
+
template <typename... Args>
|
|
3151
|
+
static inline void LogDebug(Args...) {}
|
|
3152
|
+
template <typename... Args>
|
|
3153
|
+
static inline void LogInfo(Args... args) { Log(LogLevel::Info, nullptr, args...); }
|
|
3154
|
+
template <typename... Args>
|
|
3155
|
+
static inline void LogWarning(Args... args) { Log(LogLevel::Warning, "Warning: ", args...); }
|
|
3156
|
+
template <typename... Args>
|
|
3157
|
+
static inline void LogError(Args... args) { Log(LogLevel::Error, "Error: ", args...); }
|
|
3192
3158
|
#endif
|
|
3193
|
-
template <typename... Args>
|
|
3194
|
-
static inline void LogInfo(Args... args) { Log(LogLevel::Info, nullptr, args...); }
|
|
3195
|
-
template <typename... Args>
|
|
3196
|
-
static inline void LogWarning(Args... args) { Log(LogLevel::Warning, "Warning", args...); }
|
|
3197
|
-
template <typename... Args>
|
|
3198
|
-
static inline void LogError(Args... args) { Log(LogLevel::Error, "Error", args...); }
|
|
3199
3159
|
|
|
3200
3160
|
void SetLogHandler(const std::function<LogFunc> &func);
|
|
3201
3161
|
void DefaultLogHandler(LogLevel level, const char *ctx, const char *msg);
|
|
@@ -3301,7 +3261,7 @@ static inline bool TestStrI(Span<const char> str1, const char *str2)
|
|
|
3301
3261
|
return (i == str1.len) && !str2[i];
|
|
3302
3262
|
}
|
|
3303
3263
|
static inline bool TestStrI(const char *str1, Span<const char> str2)
|
|
3304
|
-
{ return
|
|
3264
|
+
{ return TestStrI(str2, str1); }
|
|
3305
3265
|
static inline bool TestStrI(const char *str1, const char *str2)
|
|
3306
3266
|
{
|
|
3307
3267
|
Size i = 0;
|
|
@@ -4344,8 +4304,8 @@ enum class CompressionSpeed {
|
|
|
4344
4304
|
Fast
|
|
4345
4305
|
};
|
|
4346
4306
|
|
|
4347
|
-
class
|
|
4348
|
-
class
|
|
4307
|
+
class StreamDecoder;
|
|
4308
|
+
class StreamEncoder;
|
|
4349
4309
|
|
|
4350
4310
|
class StreamReader {
|
|
4351
4311
|
RG_DELETE_COPY(StreamReader)
|
|
@@ -4383,8 +4343,7 @@ class StreamReader {
|
|
|
4383
4343
|
bool eof = false;
|
|
4384
4344
|
} source;
|
|
4385
4345
|
|
|
4386
|
-
|
|
4387
|
-
StreamDecompressor *decompressor = nullptr;
|
|
4346
|
+
StreamDecoder *decoder = nullptr;
|
|
4388
4347
|
|
|
4389
4348
|
int64_t raw_len = -1;
|
|
4390
4349
|
Size raw_read = 0;
|
|
@@ -4408,6 +4367,9 @@ public:
|
|
|
4408
4367
|
: StreamReader() { Open(func, filename, compression_type); }
|
|
4409
4368
|
~StreamReader() { Close(true); }
|
|
4410
4369
|
|
|
4370
|
+
// Call before Open!
|
|
4371
|
+
void SetDecoder(StreamDecoder *decoder);
|
|
4372
|
+
|
|
4411
4373
|
bool Open(Span<const uint8_t> buf, const char *filename = nullptr,
|
|
4412
4374
|
CompressionType compression_type = CompressionType::None);
|
|
4413
4375
|
bool Open(FILE *fp, const char *filename,
|
|
@@ -4421,7 +4383,6 @@ public:
|
|
|
4421
4383
|
bool Rewind();
|
|
4422
4384
|
|
|
4423
4385
|
const char *GetFileName() const { return filename; }
|
|
4424
|
-
CompressionType GetCompressionType() const { return compression_type; }
|
|
4425
4386
|
int64_t GetReadLimit() { return read_max; }
|
|
4426
4387
|
bool IsValid() const { return filename && !error; }
|
|
4427
4388
|
bool IsEOF() const { return eof; }
|
|
@@ -4449,62 +4410,38 @@ private:
|
|
|
4449
4410
|
|
|
4450
4411
|
Size ReadRaw(Size max_len, void *out_buf);
|
|
4451
4412
|
|
|
4452
|
-
friend class
|
|
4413
|
+
friend class StreamDecoder;
|
|
4453
4414
|
};
|
|
4454
4415
|
|
|
4455
|
-
static inline Size ReadFile(const char *filename, CompressionType compression_type, Span<uint8_t> out_buf)
|
|
4456
|
-
{
|
|
4457
|
-
StreamReader st(filename, compression_type);
|
|
4458
|
-
return st.Read(out_buf);
|
|
4459
|
-
}
|
|
4460
4416
|
static inline Size ReadFile(const char *filename, Span<uint8_t> out_buf)
|
|
4461
4417
|
{
|
|
4462
4418
|
StreamReader st(filename);
|
|
4463
4419
|
return st.Read(out_buf);
|
|
4464
4420
|
}
|
|
4465
|
-
static inline Size ReadFile(const char *filename, CompressionType compression_type, Span<char> out_buf)
|
|
4466
|
-
{
|
|
4467
|
-
StreamReader st(filename, compression_type);
|
|
4468
|
-
return st.Read(out_buf);
|
|
4469
|
-
}
|
|
4470
4421
|
static inline Size ReadFile(const char *filename, Span<char> out_buf)
|
|
4471
4422
|
{
|
|
4472
4423
|
StreamReader st(filename);
|
|
4473
4424
|
return st.Read(out_buf);
|
|
4474
4425
|
}
|
|
4475
|
-
|
|
4476
|
-
static inline Size ReadFile(const char *filename, Size max_len, CompressionType compression_type,
|
|
4477
|
-
HeapArray<uint8_t> *out_buf)
|
|
4478
|
-
{
|
|
4479
|
-
StreamReader st(filename, compression_type);
|
|
4480
|
-
return st.ReadAll(max_len, out_buf);
|
|
4481
|
-
}
|
|
4482
4426
|
static inline Size ReadFile(const char *filename, Size max_len, HeapArray<uint8_t> *out_buf)
|
|
4483
4427
|
{
|
|
4484
4428
|
StreamReader st(filename);
|
|
4485
4429
|
return st.ReadAll(max_len, out_buf);
|
|
4486
4430
|
}
|
|
4487
|
-
static inline Size ReadFile(const char *filename, Size max_len, CompressionType compression_type,
|
|
4488
|
-
HeapArray<char> *out_buf)
|
|
4489
|
-
{
|
|
4490
|
-
StreamReader st(filename, compression_type);
|
|
4491
|
-
return st.ReadAll(max_len, out_buf);
|
|
4492
|
-
}
|
|
4493
4431
|
static inline Size ReadFile(const char *filename, Size max_len, HeapArray<char> *out_buf)
|
|
4494
4432
|
{
|
|
4495
4433
|
StreamReader st(filename);
|
|
4496
4434
|
return st.ReadAll(max_len, out_buf);
|
|
4497
4435
|
}
|
|
4498
4436
|
|
|
4499
|
-
class
|
|
4437
|
+
class StreamDecoder {
|
|
4500
4438
|
protected:
|
|
4501
4439
|
StreamReader *reader;
|
|
4502
4440
|
|
|
4503
4441
|
public:
|
|
4504
|
-
|
|
4505
|
-
virtual ~
|
|
4442
|
+
StreamDecoder(StreamReader *reader) : reader(reader) {}
|
|
4443
|
+
virtual ~StreamDecoder() {}
|
|
4506
4444
|
|
|
4507
|
-
virtual bool Init(CompressionType type) = 0;
|
|
4508
4445
|
virtual Size Read(Size max_len, void *out_buf) = 0;
|
|
4509
4446
|
|
|
4510
4447
|
protected:
|
|
@@ -4517,7 +4454,7 @@ protected:
|
|
|
4517
4454
|
void SetEOF(bool eof) { reader->eof = eof; }
|
|
4518
4455
|
};
|
|
4519
4456
|
|
|
4520
|
-
typedef
|
|
4457
|
+
typedef StreamDecoder *CreateDecompressorFunc(StreamReader *reader, CompressionType type);
|
|
4521
4458
|
|
|
4522
4459
|
class StreamDecompressorHelper {
|
|
4523
4460
|
public:
|
|
@@ -4525,9 +4462,9 @@ public:
|
|
|
4525
4462
|
};
|
|
4526
4463
|
|
|
4527
4464
|
#define RG_REGISTER_DECOMPRESSOR(Type, Cls) \
|
|
4528
|
-
static
|
|
4465
|
+
static StreamDecoder *RG_UNIQUE_NAME(CreateDecompressor)(StreamReader *reader, CompressionType type) \
|
|
4529
4466
|
{ \
|
|
4530
|
-
|
|
4467
|
+
StreamDecoder *decompressor = new Cls(reader, type); \
|
|
4531
4468
|
return decompressor; \
|
|
4532
4469
|
} \
|
|
4533
4470
|
static StreamDecompressorHelper RG_UNIQUE_NAME(CreateDecompressorHelper)((Type), RG_UNIQUE_NAME(CreateDecompressor))
|
|
@@ -4601,9 +4538,7 @@ class StreamWriter {
|
|
|
4601
4538
|
bool vt100;
|
|
4602
4539
|
} dest;
|
|
4603
4540
|
|
|
4604
|
-
|
|
4605
|
-
CompressionSpeed compression_speed = CompressionSpeed::Default;
|
|
4606
|
-
StreamCompressor *compressor = nullptr;
|
|
4541
|
+
StreamEncoder *encoder = nullptr;
|
|
4607
4542
|
|
|
4608
4543
|
int64_t raw_written = 0;
|
|
4609
4544
|
|
|
@@ -4633,6 +4568,9 @@ public:
|
|
|
4633
4568
|
: StreamWriter() { Open(func, filename, compression_type, compression_speed); }
|
|
4634
4569
|
~StreamWriter() { Close(true); }
|
|
4635
4570
|
|
|
4571
|
+
// Call before Open!
|
|
4572
|
+
void SetEncoder(StreamEncoder *encoder);
|
|
4573
|
+
|
|
4636
4574
|
bool Open(HeapArray<uint8_t> *mem, const char *filename = nullptr,
|
|
4637
4575
|
CompressionType compression_type = CompressionType::None,
|
|
4638
4576
|
CompressionSpeed compression_speed = CompressionSpeed::Default);
|
|
@@ -4655,8 +4593,6 @@ public:
|
|
|
4655
4593
|
bool Flush();
|
|
4656
4594
|
|
|
4657
4595
|
const char *GetFileName() const { return filename; }
|
|
4658
|
-
CompressionType GetCompressionType() const { return compression_type; }
|
|
4659
|
-
CompressionSpeed GetCompressionSpeed() const { return compression_speed; }
|
|
4660
4596
|
bool IsVt100() const { return dest.vt100; }
|
|
4661
4597
|
bool IsValid() const { return filename && !error; }
|
|
4662
4598
|
|
|
@@ -4677,33 +4613,30 @@ private:
|
|
|
4677
4613
|
|
|
4678
4614
|
bool WriteRaw(Span<const uint8_t> buf);
|
|
4679
4615
|
|
|
4680
|
-
friend class
|
|
4616
|
+
friend class StreamEncoder;
|
|
4681
4617
|
};
|
|
4682
4618
|
|
|
4683
|
-
static inline bool WriteFile(Span<const uint8_t> buf, const char *filename, unsigned int flags = 0
|
|
4684
|
-
CompressionType compression_type = CompressionType::None)
|
|
4619
|
+
static inline bool WriteFile(Span<const uint8_t> buf, const char *filename, unsigned int flags = 0)
|
|
4685
4620
|
{
|
|
4686
|
-
StreamWriter st(filename, flags
|
|
4621
|
+
StreamWriter st(filename, flags);
|
|
4687
4622
|
st.Write(buf);
|
|
4688
4623
|
return st.Close();
|
|
4689
4624
|
}
|
|
4690
|
-
static inline bool WriteFile(Span<const char> buf, const char *filename, unsigned int flags = 0
|
|
4691
|
-
CompressionType compression_type = CompressionType::None)
|
|
4625
|
+
static inline bool WriteFile(Span<const char> buf, const char *filename, unsigned int flags = 0)
|
|
4692
4626
|
{
|
|
4693
|
-
StreamWriter st(filename, flags
|
|
4627
|
+
StreamWriter st(filename, flags);
|
|
4694
4628
|
st.Write(buf);
|
|
4695
4629
|
return st.Close();
|
|
4696
4630
|
}
|
|
4697
4631
|
|
|
4698
|
-
class
|
|
4632
|
+
class StreamEncoder {
|
|
4699
4633
|
protected:
|
|
4700
4634
|
StreamWriter *writer;
|
|
4701
4635
|
|
|
4702
4636
|
public:
|
|
4703
|
-
|
|
4704
|
-
virtual ~
|
|
4637
|
+
StreamEncoder(StreamWriter *writer) : writer(writer) {}
|
|
4638
|
+
virtual ~StreamEncoder() {}
|
|
4705
4639
|
|
|
4706
|
-
virtual bool Init(CompressionType type, CompressionSpeed speed) = 0;
|
|
4707
4640
|
virtual bool Write(Span<const uint8_t> buf) = 0;
|
|
4708
4641
|
virtual bool Finalize() = 0;
|
|
4709
4642
|
|
|
@@ -4714,7 +4647,7 @@ protected:
|
|
|
4714
4647
|
bool WriteRaw(Span<const uint8_t> buf) { return writer->WriteRaw(buf); }
|
|
4715
4648
|
};
|
|
4716
4649
|
|
|
4717
|
-
typedef
|
|
4650
|
+
typedef StreamEncoder *CreateCompressorFunc(StreamWriter *writer, CompressionType type, CompressionSpeed speed);
|
|
4718
4651
|
|
|
4719
4652
|
class StreamCompressorHelper {
|
|
4720
4653
|
public:
|
|
@@ -4722,9 +4655,9 @@ public:
|
|
|
4722
4655
|
};
|
|
4723
4656
|
|
|
4724
4657
|
#define RG_REGISTER_COMPRESSOR(Type, Cls) \
|
|
4725
|
-
static
|
|
4658
|
+
static StreamEncoder *RG_UNIQUE_NAME(CreateCompressor)(StreamWriter *writer, CompressionType type, CompressionSpeed speed) \
|
|
4726
4659
|
{ \
|
|
4727
|
-
|
|
4660
|
+
StreamEncoder *compressor = new Cls(writer, type, speed); \
|
|
4728
4661
|
return compressor; \
|
|
4729
4662
|
} \
|
|
4730
4663
|
static StreamCompressorHelper RG_UNIQUE_NAME(CreateCompressorHelper)((Type), RG_UNIQUE_NAME(CreateCompressor))
|
|
@@ -4934,6 +4867,36 @@ bool OptionToEnum(Span<const OptionDesc> options, Span<const char> str, T *out_v
|
|
|
4934
4867
|
return false;
|
|
4935
4868
|
}
|
|
4936
4869
|
|
|
4870
|
+
template <typename T>
|
|
4871
|
+
bool OptionToEnumI(Span<const char *const> options, Span<const char> str, T *out_value)
|
|
4872
|
+
{
|
|
4873
|
+
for (Size i = 0; i < options.len; i++) {
|
|
4874
|
+
const char *opt = options[i];
|
|
4875
|
+
|
|
4876
|
+
if (TestStrI(opt, str)) {
|
|
4877
|
+
*out_value = (T)i;
|
|
4878
|
+
return true;
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4882
|
+
return false;
|
|
4883
|
+
}
|
|
4884
|
+
|
|
4885
|
+
template <typename T>
|
|
4886
|
+
bool OptionToEnumI(Span<const OptionDesc> options, Span<const char> str, T *out_value)
|
|
4887
|
+
{
|
|
4888
|
+
for (Size i = 0; i < options.len; i++) {
|
|
4889
|
+
const OptionDesc &desc = options[i];
|
|
4890
|
+
|
|
4891
|
+
if (TestStrI(desc.name, str)) {
|
|
4892
|
+
*out_value = (T)i;
|
|
4893
|
+
return true;
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
|
|
4897
|
+
return false;
|
|
4898
|
+
}
|
|
4899
|
+
|
|
4937
4900
|
template <typename T>
|
|
4938
4901
|
bool OptionToFlag(Span<const char *const> options, Span<const char> str, T *out_flags, bool enable = true)
|
|
4939
4902
|
{
|
|
@@ -4964,6 +4927,36 @@ bool OptionToFlag(Span<const OptionDesc> options, Span<const char> str, T *out_f
|
|
|
4964
4927
|
return false;
|
|
4965
4928
|
}
|
|
4966
4929
|
|
|
4930
|
+
template <typename T>
|
|
4931
|
+
bool OptionToFlagI(Span<const char *const> options, Span<const char> str, T *out_flags, bool enable = true)
|
|
4932
|
+
{
|
|
4933
|
+
for (Size i = 0; i < options.len; i++) {
|
|
4934
|
+
const char *opt = options[i];
|
|
4935
|
+
|
|
4936
|
+
if (TestStrI(opt, str)) {
|
|
4937
|
+
*out_flags = ApplyMask(*out_flags, 1u << i, enable);
|
|
4938
|
+
return true;
|
|
4939
|
+
}
|
|
4940
|
+
}
|
|
4941
|
+
|
|
4942
|
+
return false;
|
|
4943
|
+
}
|
|
4944
|
+
|
|
4945
|
+
template <typename T>
|
|
4946
|
+
bool OptionToFlagI(Span<const OptionDesc> options, Span<const char> str, T *out_flags, bool enable = true)
|
|
4947
|
+
{
|
|
4948
|
+
for (Size i = 0; i < options.len; i++) {
|
|
4949
|
+
const OptionDesc &desc = options[i];
|
|
4950
|
+
|
|
4951
|
+
if (TestStrI(desc.name, str)) {
|
|
4952
|
+
*out_flags = ApplyMask(*out_flags, 1u << i, enable);
|
|
4953
|
+
return true;
|
|
4954
|
+
}
|
|
4955
|
+
}
|
|
4956
|
+
|
|
4957
|
+
return false;
|
|
4958
|
+
}
|
|
4959
|
+
|
|
4967
4960
|
// ------------------------------------------------------------------------
|
|
4968
4961
|
// Console prompter (simplified readline)
|
|
4969
4962
|
// ------------------------------------------------------------------------
|
package/src/core/libcc/lz4.cc
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
namespace RG {
|
|
29
29
|
|
|
30
|
-
class LZ4Decompressor: public
|
|
30
|
+
class LZ4Decompressor: public StreamDecoder {
|
|
31
31
|
LZ4F_dctx *decoder = nullptr;
|
|
32
32
|
bool done = false;
|
|
33
33
|
|
|
@@ -39,25 +39,23 @@ class LZ4Decompressor: public StreamDecompressor {
|
|
|
39
39
|
Size out_len = 0;
|
|
40
40
|
|
|
41
41
|
public:
|
|
42
|
-
LZ4Decompressor(StreamReader *reader
|
|
42
|
+
LZ4Decompressor(StreamReader *reader, CompressionType type);
|
|
43
43
|
~LZ4Decompressor();
|
|
44
44
|
|
|
45
|
-
bool Init(CompressionType type) override;
|
|
46
45
|
Size Read(Size max_len, void *out_buf) override;
|
|
47
46
|
};
|
|
48
47
|
|
|
49
|
-
LZ4Decompressor
|
|
50
|
-
|
|
51
|
-
LZ4F_freeDecompressionContext(decoder);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
bool LZ4Decompressor::Init(CompressionType)
|
|
48
|
+
LZ4Decompressor::LZ4Decompressor(StreamReader *reader, CompressionType)
|
|
49
|
+
: StreamDecoder(reader)
|
|
55
50
|
{
|
|
56
51
|
LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&decoder, LZ4F_VERSION);
|
|
57
52
|
if (LZ4F_isError(err))
|
|
58
53
|
throw std::bad_alloc();
|
|
54
|
+
}
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
LZ4Decompressor::~LZ4Decompressor()
|
|
57
|
+
{
|
|
58
|
+
LZ4F_freeDecompressionContext(decoder);
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
Size LZ4Decompressor::Read(Size max_len, void *user_buf)
|
|
@@ -106,27 +104,22 @@ Size LZ4Decompressor::Read(Size max_len, void *user_buf)
|
|
|
106
104
|
RG_UNREACHABLE();
|
|
107
105
|
}
|
|
108
106
|
|
|
109
|
-
class LZ4Compressor: public
|
|
107
|
+
class LZ4Compressor: public StreamEncoder {
|
|
110
108
|
LZ4F_cctx *encoder = nullptr;
|
|
111
109
|
LZ4F_preferences_t prefs = {};
|
|
112
110
|
|
|
113
111
|
HeapArray<uint8_t> dynamic_buf;
|
|
114
112
|
|
|
115
113
|
public:
|
|
116
|
-
LZ4Compressor(StreamWriter *writer
|
|
114
|
+
LZ4Compressor(StreamWriter *writer, CompressionType type, CompressionSpeed speed);
|
|
117
115
|
~LZ4Compressor();
|
|
118
116
|
|
|
119
|
-
bool Init(CompressionType type, CompressionSpeed speed) override;
|
|
120
117
|
bool Write(Span<const uint8_t> buf) override;
|
|
121
118
|
bool Finalize() override;
|
|
122
119
|
};
|
|
123
120
|
|
|
124
|
-
LZ4Compressor
|
|
125
|
-
|
|
126
|
-
LZ4F_freeCompressionContext(encoder);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
bool LZ4Compressor::Init(CompressionType, CompressionSpeed speed)
|
|
121
|
+
LZ4Compressor::LZ4Compressor(StreamWriter *writer, CompressionType, CompressionSpeed speed)
|
|
122
|
+
: StreamEncoder(writer)
|
|
130
123
|
{
|
|
131
124
|
LZ4F_errorCode_t err = LZ4F_createCompressionContext(&encoder, LZ4F_VERSION);
|
|
132
125
|
if (LZ4F_isError(err))
|
|
@@ -141,15 +134,15 @@ bool LZ4Compressor::Init(CompressionType, CompressionSpeed speed)
|
|
|
141
134
|
dynamic_buf.Grow(LZ4F_HEADER_SIZE_MAX);
|
|
142
135
|
|
|
143
136
|
size_t ret = LZ4F_compressBegin(encoder, dynamic_buf.end(), dynamic_buf.capacity - dynamic_buf.len, &prefs);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
LogError("Failed to start LZ4 stream for '%1': %2", GetFileName(), LZ4F_getErrorName(ret));
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
137
|
+
if (LZ4F_isError(ret))
|
|
138
|
+
throw std::bad_alloc();
|
|
149
139
|
|
|
150
140
|
dynamic_buf.len += ret;
|
|
141
|
+
}
|
|
151
142
|
|
|
152
|
-
|
|
143
|
+
LZ4Compressor::~LZ4Compressor()
|
|
144
|
+
{
|
|
145
|
+
LZ4F_freeCompressionContext(encoder);
|
|
153
146
|
}
|
|
154
147
|
|
|
155
148
|
bool LZ4Compressor::Write(Span<const uint8_t> buf)
|
package/src/core/libcc/miniz.cc
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
namespace RG {
|
|
28
28
|
|
|
29
|
-
class MinizDecompressor: public
|
|
29
|
+
class MinizDecompressor: public StreamDecoder {
|
|
30
30
|
tinfl_decompressor inflator;
|
|
31
31
|
bool done = false;
|
|
32
32
|
|
|
@@ -45,21 +45,19 @@ class MinizDecompressor: public StreamDecompressor {
|
|
|
45
45
|
Size uncompressed_size = 0;
|
|
46
46
|
|
|
47
47
|
public:
|
|
48
|
-
MinizDecompressor(StreamReader *reader
|
|
48
|
+
MinizDecompressor(StreamReader *reader, CompressionType type);
|
|
49
49
|
~MinizDecompressor() {}
|
|
50
50
|
|
|
51
|
-
bool Init(CompressionType type) override;
|
|
52
51
|
Size Read(Size max_len, void *out_buf) override;
|
|
53
52
|
};
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
MinizDecompressor::MinizDecompressor(StreamReader *reader, CompressionType type)
|
|
55
|
+
: StreamDecoder(reader)
|
|
56
56
|
{
|
|
57
57
|
static_assert(RG_SIZE(out_buf) >= TINFL_LZ_DICT_SIZE);
|
|
58
58
|
|
|
59
59
|
tinfl_init(&inflator);
|
|
60
60
|
is_gzip = (type == CompressionType::Gzip);
|
|
61
|
-
|
|
62
|
-
return true;
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
Size MinizDecompressor::Read(Size max_len, void *user_buf)
|
|
@@ -217,7 +215,7 @@ truncated_error:
|
|
|
217
215
|
return -1;
|
|
218
216
|
}
|
|
219
217
|
|
|
220
|
-
class MinizCompressor: public
|
|
218
|
+
class MinizCompressor: public StreamEncoder {
|
|
221
219
|
tdefl_compressor deflator;
|
|
222
220
|
|
|
223
221
|
// Gzip support
|
|
@@ -229,10 +227,9 @@ class MinizCompressor: public StreamCompressor {
|
|
|
229
227
|
LocalArray<uint8_t, 1024> small_buf;
|
|
230
228
|
|
|
231
229
|
public:
|
|
232
|
-
MinizCompressor(StreamWriter *writer
|
|
230
|
+
MinizCompressor(StreamWriter *writer, CompressionType type, CompressionSpeed speed);
|
|
233
231
|
~MinizCompressor() {}
|
|
234
232
|
|
|
235
|
-
bool Init(CompressionType type, CompressionSpeed speed) override;
|
|
236
233
|
bool Write(Span<const uint8_t> buf) override;
|
|
237
234
|
bool Finalize() override;
|
|
238
235
|
|
|
@@ -240,7 +237,8 @@ private:
|
|
|
240
237
|
bool WriteDeflate(Span<const uint8_t> buf);
|
|
241
238
|
};
|
|
242
239
|
|
|
243
|
-
|
|
240
|
+
MinizCompressor::MinizCompressor(StreamWriter *writer, CompressionType type, CompressionSpeed speed)
|
|
241
|
+
: StreamEncoder(writer)
|
|
244
242
|
{
|
|
245
243
|
is_gzip = (type == CompressionType::Gzip);
|
|
246
244
|
|
|
@@ -256,10 +254,7 @@ bool MinizCompressor::Init(CompressionType type, CompressionSpeed speed)
|
|
|
256
254
|
MinizCompressor *compressor = (MinizCompressor *)udata;
|
|
257
255
|
return (int)compressor->WriteRaw(MakeSpan((uint8_t *)buf, len));
|
|
258
256
|
}, this, flags);
|
|
259
|
-
|
|
260
|
-
LogError("Failed to initialize Deflate compression for '%1'", GetFileName());
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
257
|
+
RG_ASSERT(status == TDEFL_STATUS_OKAY);
|
|
263
258
|
|
|
264
259
|
if (is_gzip) {
|
|
265
260
|
static uint8_t gzip_header[] = {
|
|
@@ -271,11 +266,8 @@ bool MinizCompressor::Init(CompressionType type, CompressionSpeed speed)
|
|
|
271
266
|
0 // OS
|
|
272
267
|
};
|
|
273
268
|
|
|
274
|
-
|
|
275
|
-
return false;
|
|
269
|
+
WriteRaw(gzip_header);
|
|
276
270
|
}
|
|
277
|
-
|
|
278
|
-
return true;
|
|
279
271
|
}
|
|
280
272
|
|
|
281
273
|
bool MinizCompressor::Write(Span<const uint8_t> buf)
|