Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8002e745e0 | |||
| b5742bc282 | |||
| 51305a1a80 | |||
| 1dc85c62fc |
@@ -13,13 +13,13 @@ jobs:
|
|||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
- uses: mlugg/setup-zig@v2
|
- uses: mlugg/setup-zig@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: sudo apt update && sudo apt install -y liblzma-dev liblzo2-dev
|
run: sudo apt update && sudo apt install -y zlib1g-dev libzstd-dev liblzma-dev liblz4-dev liblzo2-dev
|
||||||
- name: Build normal version
|
- name: Build normal version
|
||||||
run: zig build --release=fast -Duse_zig_decomp=true -Dversion=${{ github.ref_name }}
|
run: zig build --release=fast -Dversion=${{ github.ref_name }}
|
||||||
- name: Move zig build out
|
- name: Move normal build out
|
||||||
run: mv zig-out/bin/unsquashfs ./unsquashfs-x86_64-zig-libs
|
run: mv zig-out/bin/unsquashfs ./unsquashfs-x86_64-zig-libs
|
||||||
- name: Rebuild with C libraries
|
- name: Rebuild with C libraries
|
||||||
run: zig build --release=fast -Dversion="${{ github.ref_name }}"
|
run: zig build --release=fast -Duse_c_libs=true -Dversion="${{ github.ref_name }}"
|
||||||
- name: Move C build out
|
- name: Move C build out
|
||||||
run: mv zig-out/bin/unsquashfs ./unsquashfs-x86_64-c-libs
|
run: mv zig-out/bin/unsquashfs ./unsquashfs-x86_64-c-libs
|
||||||
- name: Release
|
- name: Release
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "extern/zstd"]
|
||||||
|
path = extern/zstd
|
||||||
|
url = https://github.com/facebook/zstd
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const Compile = std.Build.Step.Compile;
|
||||||
|
const ResolvedTarget = std.Build.ResolvedTarget;
|
||||||
|
const OptimizeMode = std.builtin.OptimizeMode;
|
||||||
|
const Module = std.Build.Module;
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
pub fn build(b: *std.Build) !void {
|
||||||
const use_zig_decomp = b.option(bool, "use_zig_decomp", "Use zig standard library for decompression.") orelse false;
|
const use_zig_decomp = b.option(bool, "use_zig_decomp", "Use Zig standard library for decompression instead of C libraries.") orelse false;
|
||||||
// const allow_lzo = b.option(bool, "allow_lzo", "Compile with lzo support") orelse false;
|
const allow_lzo = b.option(bool, "allow_lzo", "Compile with lzo support") orelse false;
|
||||||
const debug = b.option(bool, "debug", "Enable options to make debugging easier.") orelse false;
|
const debug = b.option(bool, "debug", "Enable options to make debugging easier.");
|
||||||
const version_string_option = b.option([]const u8, "version", "Version of the library/binary");
|
const version_string_option = b.option([]const u8, "version", "Version of the library/binary");
|
||||||
|
|
||||||
const zig_squashfs_options = b.addOptions();
|
const zig_squashfs_options = b.addOptions();
|
||||||
zig_squashfs_options.addOption(bool, "use_zig_decomp", use_zig_decomp);
|
zig_squashfs_options.addOption(bool, "use_zig_decomp", use_zig_decomp);
|
||||||
// zig_squashfs_options.addOption(bool, "allow_lzo", allow_lzo);
|
zig_squashfs_options.addOption(bool, "allow_lzo", allow_lzo);
|
||||||
|
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
@@ -22,32 +26,19 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.strip = if (debug == true) false else null,
|
.strip = if (debug == true) false else null,
|
||||||
});
|
});
|
||||||
mod.addOptions("config", zig_squashfs_options);
|
mod.addOptions("config", zig_squashfs_options);
|
||||||
|
|
||||||
if (!use_zig_decomp) {
|
if (!use_zig_decomp) {
|
||||||
var zlib_ng = b.dependency("zlib_ng", .{
|
var zlib = b.dependency("zlib_ng", .{});
|
||||||
.target = target,
|
mod.linkLibrary(zlib.artifact("zng"));
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
mod.linkLibrary(zlib_ng.artifact("zng"));
|
|
||||||
|
|
||||||
mod.linkSystemLibrary("lzma", .{ .preferred_link_mode = .static });
|
mod.linkSystemLibrary("lzma", .{ .preferred_link_mode = .static });
|
||||||
|
if (allow_lzo == true)
|
||||||
|
mod.linkSystemLibrary("minilzo", .{ .preferred_link_mode = .static });
|
||||||
|
mod.linkSystemLibrary("lz4", .{ .preferred_link_mode = .static });
|
||||||
|
|
||||||
var minilzo = b.dependency("minilzo", .{
|
const zstd_lib = buildZstdLibrary(b, target, optimize, debug);
|
||||||
.target = target,
|
mod.linkLibrary(zstd_lib);
|
||||||
.optimize = optimize,
|
mod.addIncludePath(b.path("extern/zstd/lib/"));
|
||||||
});
|
|
||||||
mod.linkLibrary(minilzo.artifact("minilzo"));
|
|
||||||
|
|
||||||
var lz4 = b.dependency("lz4", .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
mod.linkLibrary(lz4.artifact("lz4"));
|
|
||||||
|
|
||||||
var zstd = b.dependency("zstd", .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
mod.linkLibrary(zstd.artifact("zstd"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var version = version_string_option orelse "0.0.0-testing";
|
var version = version_string_option orelse "0.0.0-testing";
|
||||||
@@ -89,14 +80,15 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
const mod_tests = b.addTest(.{
|
const mod_tests = b.addTest(.{
|
||||||
.root_module = mod,
|
.root_module = mod,
|
||||||
.test_runner = .{
|
|
||||||
.mode = .simple,
|
|
||||||
.path = b.path("src/test.zig"),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const run_mod_tests = b.addRunArtifact(mod_tests);
|
const run_mod_tests = b.addRunArtifact(mod_tests);
|
||||||
|
const exe_tests = b.addTest(.{
|
||||||
|
.root_module = exe.root_module,
|
||||||
|
});
|
||||||
|
const run_exe_tests = b.addRunArtifact(exe_tests);
|
||||||
const test_step = b.step("test", "Run tests");
|
const test_step = b.step("test", "Run tests");
|
||||||
test_step.dependOn(&run_mod_tests.step);
|
test_step.dependOn(&run_mod_tests.step);
|
||||||
|
test_step.dependOn(&run_exe_tests.step);
|
||||||
|
|
||||||
// zls build check steps
|
// zls build check steps
|
||||||
const lib_check = b.addLibrary(.{
|
const lib_check = b.addLibrary(.{
|
||||||
@@ -111,3 +103,61 @@ pub fn build(b: *std.Build) !void {
|
|||||||
check.dependOn(&lib_check.step);
|
check.dependOn(&lib_check.step);
|
||||||
check.dependOn(&exe_check.step);
|
check.dependOn(&exe_check.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn buildZstdLibrary(b: *std.Build, target: ResolvedTarget, optimize: OptimizeMode, debug: ?bool) *Compile {
|
||||||
|
var zstd_lib = b.addLibrary(.{
|
||||||
|
.name = "zstd",
|
||||||
|
.linkage = .static,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = if (debug == true) .Debug else optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
.use_llvm = debug,
|
||||||
|
});
|
||||||
|
zstd_lib.root_module.addCSourceFiles(.{
|
||||||
|
.root = b.path("extern/zstd/lib/"),
|
||||||
|
.files = &.{
|
||||||
|
"common/debug.c",
|
||||||
|
"common/entropy_common.c",
|
||||||
|
"common/error_private.c",
|
||||||
|
"common/fse_decompress.c",
|
||||||
|
"common/pool.c",
|
||||||
|
"common/threading.c",
|
||||||
|
"common/xxhash.c",
|
||||||
|
"common/zstd_common.c",
|
||||||
|
"compress/fse_compress.c",
|
||||||
|
"compress/hist.c",
|
||||||
|
"compress/huf_compress.c",
|
||||||
|
"compress/zstd_compress.c",
|
||||||
|
"compress/zstd_compress_literals.c",
|
||||||
|
"compress/zstd_compress_sequences.c",
|
||||||
|
"compress/zstd_compress_superblock.c",
|
||||||
|
"compress/zstd_double_fast.c",
|
||||||
|
"compress/zstd_fast.c",
|
||||||
|
"compress/zstd_lazy.c",
|
||||||
|
"compress/zstd_ldm.c",
|
||||||
|
"compress/zstdmt_compress.c",
|
||||||
|
"compress/zstd_opt.c",
|
||||||
|
"compress/zstd_preSplit.c",
|
||||||
|
"decompress/huf_decompress.c",
|
||||||
|
"decompress/zstd_ddict.c",
|
||||||
|
"decompress/zstd_decompress_block.c",
|
||||||
|
"decompress/zstd_decompress.c",
|
||||||
|
"dictBuilder/cover.c",
|
||||||
|
"dictBuilder/divsufsort.c",
|
||||||
|
"dictBuilder/fastcover.c",
|
||||||
|
"dictBuilder/zdict.c",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
zstd_lib.root_module.addCSourceFiles(.{
|
||||||
|
.root = b.path("extern/zstd/lib/decompress"),
|
||||||
|
.files = &.{"huf_decompress_amd64.S"},
|
||||||
|
});
|
||||||
|
zstd_lib.installHeadersDirectory(b.path("extern/zstd/lib/"), &.{}, .{});
|
||||||
|
zstd_lib.installHeadersDirectory(b.path("extern/zstd/lib/common/"), &.{}, .{});
|
||||||
|
zstd_lib.installHeadersDirectory(b.path("extern/zstd/lib/compress/"), &.{}, .{});
|
||||||
|
zstd_lib.installHeadersDirectory(b.path("extern/zstd/lib/dictBuilder/"), &.{}, .{});
|
||||||
|
zstd_lib.installHeadersDirectory(b.path("extern/zstd/lib/"), &.{}, .{});
|
||||||
|
return zstd_lib;
|
||||||
|
}
|
||||||
|
|||||||
+3
-14
@@ -5,20 +5,9 @@
|
|||||||
.minimum_zig_version = "0.15.2",
|
.minimum_zig_version = "0.15.2",
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.zlib_ng = .{
|
.zlib_ng = .{
|
||||||
.url = "git+https://github.com/CalebQ42/zig-zlib-ng#5f2f02dfb28acca2517dacbbd09e9b987f57b133",
|
// .url = "https://github.com/CalebQ42/zig-zlib-ng/archive/refs/tags/2.3.3.tar.gz",
|
||||||
.hash = "zlib_ng-2.3.3-pre1-2HYS4ClFAABW8KlHMyBHtlNKE3V7kCS8wqfxawG7xeaa",
|
// .hash = "zlib_ng-2.3.3-2HYS4Bw_AADjgv7tkrqjjz2fVz5kRTvha8wN9LEcjYNp",
|
||||||
},
|
.path = "../zig-zlib-ng",
|
||||||
.zstd = .{
|
|
||||||
.url = "git+https://github.com/allyourcodebase/zstd.git?ref=1.5.7-1#e1a501be57f42c541e8a5597e4b59a074dfd09a3",
|
|
||||||
.hash = "zstd-1.5.7-1-KEItkAMwAAD6OKY3m0OOmXG7aL-aLUfrDqbP5J5oYapU",
|
|
||||||
},
|
|
||||||
.lz4 = .{
|
|
||||||
.url = "git+https://github.com/allyourcodebase/lz4.git?ref=1.10.0-6#41f52ab227caf9d48cf88c89a4d2946caa12b102",
|
|
||||||
.hash = "lz4-1.10.0-6-ewyzw-4NAAAWDpY4xpiqr4LQhZQAC0x_rGnW2iPh6jk2",
|
|
||||||
},
|
|
||||||
.minilzo = .{
|
|
||||||
.url = "git+https://github.com/CalebQ42/zig-minilzo.git#7cbae997b91a44d74b7cd6c073584dc9562a6c90",
|
|
||||||
.hash = "minilzo-2.10.0-Ij7BO8wLAADeWI4Pe4jp8XTDsDaquZR14oZ7_9yKKDWP",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.paths = .{
|
.paths = .{
|
||||||
|
|||||||
+1
Submodule extern/zstd added at f8745da6ff
+16
-24
@@ -5,10 +5,7 @@ const std = @import("std");
|
|||||||
const File = std.fs.File;
|
const File = std.fs.File;
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const config = @import("config");
|
const Decomp = @import("decomp.zig");
|
||||||
|
|
||||||
const cDecomp = @import("decomp/misc_c.zig");
|
|
||||||
const Decomp = @import("decomp/zig_decomp.zig");
|
|
||||||
const ExtractionOptions = @import("options.zig");
|
const ExtractionOptions = @import("options.zig");
|
||||||
const Inode = @import("inode.zig");
|
const Inode = @import("inode.zig");
|
||||||
const InodeRef = Inode.Ref;
|
const InodeRef = Inode.Ref;
|
||||||
@@ -20,18 +17,22 @@ const MetadataReader = @import("util/metadata.zig");
|
|||||||
const OffsetFile = @import("util/offset_file.zig");
|
const OffsetFile = @import("util/offset_file.zig");
|
||||||
const XattrTable = @import("xattr.zig");
|
const XattrTable = @import("xattr.zig");
|
||||||
|
|
||||||
|
const config = if (builtin.is_test) .{
|
||||||
|
.use_zig_decomp = builtin.link_libc != true,
|
||||||
|
.allow_lzo = false,
|
||||||
|
} else @import("config");
|
||||||
|
|
||||||
const Archive = @This();
|
const Archive = @This();
|
||||||
|
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
|
|
||||||
fil: OffsetFile,
|
fil: OffsetFile,
|
||||||
|
decomp: Decomp.DecompFn,
|
||||||
|
|
||||||
super: Superblock,
|
super: Superblock,
|
||||||
|
|
||||||
tables: ?Tables = null,
|
tables: ?Tables = null,
|
||||||
|
|
||||||
decomp: @import("decomp/types.zig").Decomp,
|
|
||||||
|
|
||||||
/// Default settings using std.Thread.getCpuCount() threads and the minimum of 4gb or half of system memory for memory usage.
|
/// Default settings using std.Thread.getCpuCount() threads and the minimum of 4gb or half of system memory for memory usage.
|
||||||
pub fn init(alloc: std.mem.Allocator, fil: File, offset: u64) !Archive {
|
pub fn init(alloc: std.mem.Allocator, fil: File, offset: u64) !Archive {
|
||||||
var super: Superblock = undefined;
|
var super: Superblock = undefined;
|
||||||
@@ -39,33 +40,24 @@ pub fn init(alloc: std.mem.Allocator, fil: File, offset: u64) !Archive {
|
|||||||
std.debug.assert(red == @sizeOf(Superblock));
|
std.debug.assert(red == @sizeOf(Superblock));
|
||||||
try super.validate();
|
try super.validate();
|
||||||
const off_fil: OffsetFile = .init(fil, offset);
|
const off_fil: OffsetFile = .init(fil, offset);
|
||||||
|
const decomp: Decomp.DecompFn = switch (super.compression) {
|
||||||
|
.gzip => Decomp.gzipDecompress,
|
||||||
|
.lzma => Decomp.lzmaDecompress,
|
||||||
|
.xz => Decomp.xzDecompress,
|
||||||
|
.zstd => Decomp.zstdDecompress,
|
||||||
|
.lz4 => if (!config.use_zig_decomp) Decomp.cLz4 else return error.Lz4Unsupported,
|
||||||
|
.lzo => if (!config.use_zig_decomp and config.allow_lzo) Decomp.lzoDecompress else return error.LzoUnsupported,
|
||||||
|
};
|
||||||
return .{
|
return .{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.fil = off_fil,
|
.fil = off_fil,
|
||||||
.decomp = if (config.use_zig_decomp)
|
.decomp = decomp,
|
||||||
switch (super.compression) {
|
|
||||||
.lz4 => return error.Lz4Unsupported,
|
|
||||||
.lzo => return error.LzoUnsupported,
|
|
||||||
.gzip => .{ .gzip = .{} },
|
|
||||||
.lzma => .{ .lzma = .{} },
|
|
||||||
.xz => .{ .xz = .{} },
|
|
||||||
.zstd => .{ .zstd = .{} },
|
|
||||||
}
|
|
||||||
else switch (super.compression) {
|
|
||||||
.gzip => .{ .gzip = .init(alloc) },
|
|
||||||
.zstd => .{ .zstd = .init(alloc) },
|
|
||||||
.xz => .{ .xz = .init(alloc) },
|
|
||||||
.lzma => .{ .lzma = .init(alloc) },
|
|
||||||
.lzo => .{ .lzo = .{} },
|
|
||||||
.lz4 => .{ .lz4 = .{} },
|
|
||||||
},
|
|
||||||
.super = super,
|
.super = super,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub fn deinit(self: *Archive) void {
|
pub fn deinit(self: *Archive) void {
|
||||||
if (self.tables != null)
|
if (self.tables != null)
|
||||||
self.tables.?.deinit();
|
self.tables.?.deinit();
|
||||||
self.decomp.deinit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inode(self: *Archive, alloc: std.mem.Allocator, num: u32) !Inode {
|
pub fn inode(self: *Archive, alloc: std.mem.Allocator, num: u32) !Inode {
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
pub const c = @cImport({
|
|
||||||
@cInclude("zlib-ng.h");
|
|
||||||
@cInclude("lzma.h");
|
|
||||||
@cInclude("lz4.h");
|
|
||||||
@cInclude("zstd.h");
|
|
||||||
@cInclude("zstd_errors.h");
|
|
||||||
@cInclude("lzo/minilzo.h");
|
|
||||||
});
|
|
||||||
+252
-16
@@ -1,25 +1,261 @@
|
|||||||
|
//! Implementations for decompression.
|
||||||
|
//! TODO: change to vtable interface to allow for shared decompressors for better performance/resource usage.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const Reader = std.Io.Reader;
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const Decompressor = @This();
|
const config = if (builtin.is_test) .{
|
||||||
|
.use_zig_decomp = builtin.link_libc != true,
|
||||||
|
.allow_lzo = false, // Change once LZO compilation is fixed
|
||||||
|
} else @import("config");
|
||||||
|
|
||||||
pub const Error = error{
|
const c = @cImport({
|
||||||
OutOfMemory,
|
@cInclude("zlib-ng.h");
|
||||||
BadInput,
|
@cInclude("lzma.h");
|
||||||
OutputTooSmall,
|
@cInclude("lz4.h");
|
||||||
ReadFailed,
|
@cInclude("zstd.h");
|
||||||
WriteFailed,
|
@cInclude("zstd_errors.h");
|
||||||
EndOfStream,
|
if (config.allow_lzo)
|
||||||
|
@cInclude("lzo/minilzo.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
pub const CompressionType = enum(u16) {
|
||||||
|
gzip = 1,
|
||||||
|
lzma,
|
||||||
|
lzo,
|
||||||
|
xz,
|
||||||
|
lz4,
|
||||||
|
zstd,
|
||||||
};
|
};
|
||||||
|
|
||||||
vtable: *const struct {
|
pub const DecompFn = *const fn (alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize; // TODO: replace anyerror to definitive error types.
|
||||||
decompress: *const fn (*Decompressor, []u8, []u8) Error!usize = DefaultDecompress,
|
|
||||||
stateless: *const fn (std.mem.Allocator, []u8, []u8) Error!usize,
|
|
||||||
},
|
|
||||||
|
|
||||||
pub fn decompress(self: *Decompressor, in: []u8, out: []u8) Error!usize {
|
pub const gzipDecompress = if (!config.use_zig_decomp) cGzip else zigGzip;
|
||||||
return self.vtable.decompress(self, in, out);
|
|
||||||
|
fn zigGzip(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
var rdr: Reader = .fixed(in);
|
||||||
|
const buf = try alloc.alloc(u8, out.len);
|
||||||
|
defer alloc.free(buf);
|
||||||
|
var decomp = std.compress.flate.Decompress.init(&rdr, .zlib, buf);
|
||||||
|
return decomp.reader.readSliceShort(out);
|
||||||
|
}
|
||||||
|
fn cGzip(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
_ = alloc;
|
||||||
|
var out_len: usize = out.len;
|
||||||
|
const res = c.zng_uncompress(out.ptr, &out_len, in.ptr, in.len);
|
||||||
|
return switch (res) {
|
||||||
|
c.Z_OK => out_len,
|
||||||
|
c.Z_MEM_ERROR => error.NotEnoughMemory,
|
||||||
|
c.Z_BUF_ERROR => error.OutBufferTooSmall,
|
||||||
|
c.Z_DATA_ERROR => error.BadData,
|
||||||
|
else => error.UnknownResult,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn DefaultDecompress(self: *Decompressor, in: []u8, out: []u8) Error!usize {
|
pub const lzmaDecompress = if (!config.use_zig_decomp) cLzma else zigLzma;
|
||||||
return self.vtable.stateless(std.heap.smp_allocator, in, out);
|
|
||||||
|
fn zigLzma(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
var rdr: Reader = .fixed(in);
|
||||||
|
var decomp = try std.compress.lzma.decompress(alloc, rdr.adaptToOldInterface());
|
||||||
|
return decomp.read(out);
|
||||||
}
|
}
|
||||||
|
fn cLzma(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
_ = alloc;
|
||||||
|
var stream: c.lzma_stream = .{
|
||||||
|
.next_in = in.ptr,
|
||||||
|
.avail_in = in.len,
|
||||||
|
.next_out = out.ptr,
|
||||||
|
.avail_out = out.len,
|
||||||
|
};
|
||||||
|
var res = c.lzma_alone_decoder(&stream, in.len * 2);
|
||||||
|
switch (res) {
|
||||||
|
c.LZMA_OK => {},
|
||||||
|
c.LZMA_MEM_ERROR => return error.LzmaMemoryError,
|
||||||
|
c.LZMA_PROG_ERROR => return error.LzmaProgramError,
|
||||||
|
else => return error.UnknownResult,
|
||||||
|
}
|
||||||
|
defer c.lzma_end(&stream);
|
||||||
|
while (res == c.LZMA_OK)
|
||||||
|
res = c.lzma_code(&stream, c.LZMA_RUN);
|
||||||
|
return switch (res) {
|
||||||
|
c.LZMA_STREAM_END => stream.total_out,
|
||||||
|
c.LZMA_MEM_ERROR => error.LzmaMemoryError,
|
||||||
|
c.LZMA_MEMLIMIT_ERROR => error.LzmaMemoryLimit,
|
||||||
|
c.LZMA_FORMAT_ERROR => error.LzmaBadFormat,
|
||||||
|
c.LZMA_DATA_ERROR => error.LzmaDataCorrupt,
|
||||||
|
c.LZMA_BUF_ERROR => error.LzmaCannotProgress,
|
||||||
|
c.LZMA_PROG_ERROR => error.LzmaProgramError,
|
||||||
|
else => error.UnknownResult,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub const lzoDecompress = if (!config.use_zig_decomp) cLzo else zigLzo;
|
||||||
|
|
||||||
|
// fn zigLzo(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
// _ = alloc;
|
||||||
|
// _ = in;
|
||||||
|
// _ = out;
|
||||||
|
// return error.LzoUnsupported;
|
||||||
|
// }
|
||||||
|
pub fn cLzo(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
_ = alloc;
|
||||||
|
var res = c.lzo_init();
|
||||||
|
if (res != 0) return error.LzoInitFailed;
|
||||||
|
var out_len: usize = out.len;
|
||||||
|
res = c.lzo1x_decompress(in.ptr, in.len, out.ptr, &out_len, null);
|
||||||
|
return switch (res) {
|
||||||
|
c.LZO_E_OK => out_len,
|
||||||
|
c.LZO_E_ERROR => error.LzoError,
|
||||||
|
c.LZO_E_OUT_OF_MEMORY => error.LzoOutOfMemory,
|
||||||
|
c.LZO_E_NOT_COMPRESSIBLE => error.LzoNotCompressible,
|
||||||
|
c.LZO_E_INPUT_OVERRUN => error.LzoInputOverrun,
|
||||||
|
c.LZO_E_OUTPUT_OVERRUN => error.LzoOutputOverrun,
|
||||||
|
c.LZO_E_LOOKBEHIND_OVERRUN => error.LzoLookbehindOverrun,
|
||||||
|
c.LZO_E_EOF_NOT_FOUND => error.LzoEofNotFound,
|
||||||
|
c.LZO_E_INPUT_NOT_CONSUMED => error.LzoInputNotConsumed,
|
||||||
|
c.LZO_E_NOT_YET_IMPLEMENTED => error.LzoNotYetImplemented,
|
||||||
|
c.LZO_E_INVALID_ARGUMENT => error.LzoInvalidArgument,
|
||||||
|
c.LZO_E_INVALID_ALIGNMENT => error.LzoInvalidAlignment,
|
||||||
|
c.LZO_E_OUTPUT_NOT_CONSUMED => error.LzoOutputNotConsumed,
|
||||||
|
c.LZO_E_INTERNAL_ERROR => error.LzoInternalError,
|
||||||
|
else => error.UnknownResult,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const xzDecompress = if (!config.use_zig_decomp) cXz else zigXz;
|
||||||
|
|
||||||
|
fn zigXz(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
var rdr: Reader = .fixed(in);
|
||||||
|
var decomp = try std.compress.xz.decompress(alloc, rdr.adaptToOldInterface());
|
||||||
|
return decomp.read(out);
|
||||||
|
}
|
||||||
|
fn cXz(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
_ = alloc;
|
||||||
|
var stream: c.lzma_stream = .{
|
||||||
|
.next_in = in.ptr,
|
||||||
|
.avail_in = in.len,
|
||||||
|
.next_out = out.ptr,
|
||||||
|
.avail_out = out.len,
|
||||||
|
// .allocator = _, TODO: create a custom allocator based on alloc,
|
||||||
|
};
|
||||||
|
var res = c.lzma_stream_decoder(&stream, in.len * 2, 0);
|
||||||
|
switch (res) {
|
||||||
|
c.LZMA_OK => {},
|
||||||
|
c.LZMA_MEM_ERROR => return error.LzmaMemoryError,
|
||||||
|
c.LZMA_PROG_ERROR => return error.LzmaProgramError,
|
||||||
|
else => return error.UnknownResult,
|
||||||
|
}
|
||||||
|
defer c.lzma_end(&stream);
|
||||||
|
while (res == c.LZMA_OK)
|
||||||
|
res = c.lzma_code(&stream, c.LZMA_RUN);
|
||||||
|
return switch (res) {
|
||||||
|
c.LZMA_STREAM_END => stream.total_out,
|
||||||
|
c.LZMA_MEM_ERROR => error.LzmaMemoryError,
|
||||||
|
c.LZMA_MEMLIMIT_ERROR => error.LzmaMemoryLimit,
|
||||||
|
c.LZMA_FORMAT_ERROR => error.LzmaBadFormat,
|
||||||
|
c.LZMA_DATA_ERROR => error.LzmaDataCorrupt,
|
||||||
|
c.LZMA_BUF_ERROR => error.LzmaCannotProgress,
|
||||||
|
c.LZMA_PROG_ERROR => error.LzmaProgramError,
|
||||||
|
else => error.UnknownResult,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub const lz4Decompress = if (!config.use_zig_decomp) cLz4 else zigLz4;
|
||||||
|
|
||||||
|
// fn zigLz4(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
// _ = alloc;
|
||||||
|
// _ = in;
|
||||||
|
// _ = out;
|
||||||
|
// return error.Lz4Unsupported;
|
||||||
|
// }
|
||||||
|
pub fn cLz4(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
_ = alloc;
|
||||||
|
const res = c.LZ4_decompress_safe(in.ptr, out.ptr, @intCast(in.len), @intCast(out.len));
|
||||||
|
if (res > 0) return @abs(res); // TODO: Find out what error values it can return.
|
||||||
|
return error.Lz4DecompressFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const zstdDecompress = if (!config.use_zig_decomp) cZstd else zigZstd;
|
||||||
|
|
||||||
|
pub fn zigZstd(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
var rdr: Reader = .fixed(in);
|
||||||
|
const buf = try alloc.alloc(u8, 1024 * 1024);
|
||||||
|
defer alloc.free(buf);
|
||||||
|
var decomp = std.compress.zstd.Decompress.init(&rdr, buf, .{});
|
||||||
|
return decomp.reader.readSliceShort(out) catch |err| {
|
||||||
|
return decomp.err orelse err;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn cZstd(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||||
|
_ = alloc;
|
||||||
|
const res = c.ZSTD_decompress(out.ptr, out.len, in.ptr, in.len);
|
||||||
|
if (c.ZSTD_isError(res) == 0) return res;
|
||||||
|
return switch (c.ZSTD_getErrorCode(res)) {
|
||||||
|
c.ZSTD_error_prefix_unknown => cZstdError.PrefixUnknown,
|
||||||
|
c.ZSTD_error_version_unsupported => cZstdError.VersionUnsupported,
|
||||||
|
c.ZSTD_error_frameParameter_unsupported => cZstdError.FrameParameterUnsupported,
|
||||||
|
c.ZSTD_error_frameParameter_windowTooLarge => cZstdError.FrameParameterWindowTooLarge,
|
||||||
|
c.ZSTD_error_corruption_detected => cZstdError.CorruptionDetected,
|
||||||
|
c.ZSTD_error_checksum_wrong => cZstdError.ChecksumWrong,
|
||||||
|
c.ZSTD_error_literals_headerWrong => cZstdError.LiteralsHeaderWrong,
|
||||||
|
c.ZSTD_error_dictionary_corrupted => cZstdError.DictionaryCorrupted,
|
||||||
|
c.ZSTD_error_dictionary_wrong => cZstdError.DictionaryWrong,
|
||||||
|
c.ZSTD_error_dictionaryCreation_failed => cZstdError.DictionaryCreationFailed,
|
||||||
|
c.ZSTD_error_parameter_unsupported => cZstdError.ParameterUnsupported,
|
||||||
|
c.ZSTD_error_parameter_combination_unsupported => cZstdError.ParameterCombinationUnsupported,
|
||||||
|
c.ZSTD_error_parameter_outOfBound => cZstdError.ParameterOutOfBound,
|
||||||
|
c.ZSTD_error_tableLog_tooLarge => cZstdError.TableLogTooLarge,
|
||||||
|
c.ZSTD_error_maxSymbolValue_tooLarge => cZstdError.MaxSymbolValueTooLarge,
|
||||||
|
c.ZSTD_error_maxSymbolValue_tooSmall => cZstdError.MaxSymbolValueTooSmall,
|
||||||
|
c.ZSTD_error_stabilityCondition_notRespected => cZstdError.StabilityConditionNotRespected,
|
||||||
|
c.ZSTD_error_stage_wrong => cZstdError.StageWrong,
|
||||||
|
c.ZSTD_error_init_missing => cZstdError.InitMissing,
|
||||||
|
c.ZSTD_error_memory_allocation => cZstdError.MemoryAllocation,
|
||||||
|
c.ZSTD_error_workSpace_tooSmall => cZstdError.WorkSpaceTooSmall,
|
||||||
|
c.ZSTD_error_dstSize_tooSmall => cZstdError.DstSizeTooSmall,
|
||||||
|
c.ZSTD_error_srcSize_wrong => cZstdError.SrcSizeWrong,
|
||||||
|
c.ZSTD_error_dstBuffer_null => cZstdError.DstBufferNull,
|
||||||
|
c.ZSTD_error_noForwardProgress_destFull => cZstdError.NoForwardProgressDestFull,
|
||||||
|
c.ZSTD_error_noForwardProgress_inputEmpty => cZstdError.NoForwardProgressInputEmpty,
|
||||||
|
else => cZstdError.Generic,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const cZstdError = error{
|
||||||
|
Generic,
|
||||||
|
PrefixUnknown,
|
||||||
|
VersionUnsupported,
|
||||||
|
FrameParameterUnsupported,
|
||||||
|
FrameParameterWindowTooLarge,
|
||||||
|
CorruptionDetected,
|
||||||
|
ChecksumWrong,
|
||||||
|
LiteralsHeaderWrong,
|
||||||
|
DictionaryCorrupted,
|
||||||
|
DictionaryWrong,
|
||||||
|
DictionaryCreationFailed,
|
||||||
|
ParameterUnsupported,
|
||||||
|
ParameterCombinationUnsupported,
|
||||||
|
ParameterOutOfBound,
|
||||||
|
TableLogTooLarge,
|
||||||
|
MaxSymbolValueTooLarge,
|
||||||
|
MaxSymbolValueTooSmall,
|
||||||
|
CannotProduceUncompressedBlock,
|
||||||
|
StabilityConditionNotRespected,
|
||||||
|
StageWrong,
|
||||||
|
InitMissing,
|
||||||
|
MemoryAllocation,
|
||||||
|
WorkSpaceTooSmall,
|
||||||
|
DstSizeTooSmall,
|
||||||
|
SrcSizeWrong,
|
||||||
|
DstBufferNull,
|
||||||
|
NoForwardProgressDestFull,
|
||||||
|
NoForwardProgressInputEmpty,
|
||||||
|
FrameIndexTooLarge,
|
||||||
|
SeekableIo,
|
||||||
|
DstBufferWrong,
|
||||||
|
SrcBufferWrong,
|
||||||
|
SequenceProducerFailed,
|
||||||
|
ExternalSequencesInvalid,
|
||||||
|
MaxCode,
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const c = @import("../../c.zig").c;
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
interface: Decompressor = .{ .vtable = &.{ .stateless = stateless } },
|
|
||||||
|
|
||||||
fn stateless(_: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
const res = c.LZ4_decompress_fast(in.ptr, out.ptr, @intCast(out.len));
|
|
||||||
if (res < 0) return Decompressor.Error.ReadFailed;
|
|
||||||
return @abs(res);
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const c = @import("../../c.zig").c;
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
streams: std.AutoHashMap(std.Thread.Id, c.lzma_stream),
|
|
||||||
|
|
||||||
interface: Decompressor,
|
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator) Self {
|
|
||||||
return .{
|
|
||||||
.alloc = alloc,
|
|
||||||
.streams = .init(alloc),
|
|
||||||
.interface = .{
|
|
||||||
.vtable = &.{
|
|
||||||
.decompress = decompress,
|
|
||||||
.stateless = stateless,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub fn deinit(self: *Self) void {
|
|
||||||
self.streams.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decompress(decomp: *Decompressor, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var self: *Self = @fieldParentPtr("interface", decomp);
|
|
||||||
|
|
||||||
var strm = try self.getOrCreate();
|
|
||||||
strm.next_in = in.ptr;
|
|
||||||
strm.avail_in = in.len;
|
|
||||||
strm.next_out = out.ptr;
|
|
||||||
strm.avail_out = out.len;
|
|
||||||
var res = c.lzma_alone_decoder(strm, out.len * 2);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
while (res == c.LZMA_OK)
|
|
||||||
res = c.lzma_code(strm, c.LZMA_RUN);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
return strm.total_out;
|
|
||||||
}
|
|
||||||
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var strm: c.lzma_stream = .{
|
|
||||||
.allocator = &.{
|
|
||||||
.alloc = lzmaAlloc,
|
|
||||||
.free = lzmaFree,
|
|
||||||
.@"opaque" = @ptrCast(@constCast(&alloc)),
|
|
||||||
},
|
|
||||||
.next_in = in.ptr,
|
|
||||||
.avail_in = in.len,
|
|
||||||
.next_out = out.ptr,
|
|
||||||
.avail_out = out.len,
|
|
||||||
};
|
|
||||||
var res = c.lzma_alone_decoder(&strm, out.len * 2);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
while (res == c.LZMA_OK)
|
|
||||||
res = c.lzma_code(&strm, c.LZMA_RUN);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
return strm.total_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn getOrCreate(self: *Self) !*c.lzma_stream {
|
|
||||||
const res = try self.streams.getOrPut(std.Thread.getCurrentId());
|
|
||||||
if (res.found_existing) return res.value_ptr;
|
|
||||||
res.value_ptr.* = .{ .allocator = &.{
|
|
||||||
.alloc = lzmaAlloc,
|
|
||||||
.free = lzmaFree,
|
|
||||||
.@"opaque" = @ptrCast(&self.alloc),
|
|
||||||
} };
|
|
||||||
return res.value_ptr;
|
|
||||||
}
|
|
||||||
inline fn decodeResult(res: usize) Error!void {
|
|
||||||
return switch (res) {
|
|
||||||
c.LZMA_OK, c.LZMA_STREAM_END => {},
|
|
||||||
c.LZMA_NO_CHECK => Error.NoCheck,
|
|
||||||
c.LZMA_UNSUPPORTED_CHECK => Error.UnsupportedCheck,
|
|
||||||
c.LZMA_GET_CHECK => Error.GetCheck,
|
|
||||||
c.LZMA_MEM_ERROR, c.LZMA_MEMLIMIT_ERROR => Error.OutOfMemory,
|
|
||||||
c.LZMA_FORMAT_ERROR => Error.Format,
|
|
||||||
c.LZMA_OPTIONS_ERROR => Error.Options,
|
|
||||||
c.LZMA_DATA_ERROR => Error.Data,
|
|
||||||
c.LZMA_BUF_ERROR => Error.Buffer,
|
|
||||||
c.LZMA_PROG_ERROR => Error.Program,
|
|
||||||
c.LZMA_SEEK_NEEDED => Error.SeekNeeded,
|
|
||||||
else => Error.Unknown,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
inline fn lzmaErrToDecompErr(err: Error) Decompressor.Error {
|
|
||||||
return switch (err) {
|
|
||||||
Error.OutOfMemory => Decompressor.Error.OutOfMemory,
|
|
||||||
Error.NoCheck => Decompressor.Error.ReadFailed,
|
|
||||||
Error.UnsupportedCheck => Decompressor.Error.ReadFailed,
|
|
||||||
Error.GetCheck => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Format => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Options => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Data => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Buffer => Decompressor.Error.WriteFailed,
|
|
||||||
Error.Program => Decompressor.Error.ReadFailed,
|
|
||||||
Error.SeekNeeded => Decompressor.Error.ReadFailed,
|
|
||||||
else => Decompressor.Error.ReadFailed,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lzmaAlloc(ptr: ?*anyopaque, size: usize, _: usize) callconv(.c) ?*anyopaque {
|
|
||||||
var alloc: *std.mem.Allocator = @ptrCast(@alignCast(@constCast(ptr)));
|
|
||||||
return alloc.rawAlloc(size, .@"1", 0);
|
|
||||||
}
|
|
||||||
fn lzmaFree(ptr: ?*anyopaque, mem_ptr: ?*anyopaque) callconv(.c) void {
|
|
||||||
var alloc: *std.mem.Allocator = @ptrCast(@alignCast(@constCast(ptr)));
|
|
||||||
alloc.rawFree(@ptrCast(mem_ptr), .@"1", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Error = error{
|
|
||||||
OutOfMemory,
|
|
||||||
NoCheck,
|
|
||||||
UnsupportedCheck,
|
|
||||||
GetCheck,
|
|
||||||
Format,
|
|
||||||
Options,
|
|
||||||
Data,
|
|
||||||
Buffer,
|
|
||||||
Program,
|
|
||||||
SeekNeeded,
|
|
||||||
Unknown,
|
|
||||||
};
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const c = @import("../../c.zig").c;
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
interface: Decompressor = .{ .vtable = &.{ .stateless = stateless } },
|
|
||||||
|
|
||||||
fn stateless(_: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var out_len: usize = out.len;
|
|
||||||
const res = c.lzo1x_decompress(in.ptr, in.len, out.ptr, &out_len, null);
|
|
||||||
decodeError(res) catch |err| return lzoErrToDecompErr(err);
|
|
||||||
return out_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn decodeError(res: c_int) Error!void {
|
|
||||||
return switch (res) {
|
|
||||||
c.LZO_E_OK => {},
|
|
||||||
c.LZO_E_EOF_NOT_FOUND => Error.EofNotFound,
|
|
||||||
c.LZO_E_INPUT_NOT_CONSUMED => Error.InputNotConsumed,
|
|
||||||
c.LZO_E_INPUT_OVERRUN => Error.InputOverrun,
|
|
||||||
c.LZO_E_INTERNAL_ERROR => Error.InternalError,
|
|
||||||
c.LZO_E_INVALID_ALIGNMENT => Error.InvalidAlignment,
|
|
||||||
c.LZO_E_INVALID_ARGUMENT => Error.InvalidArgument,
|
|
||||||
c.LZO_E_LOOKBEHIND_OVERRUN => Error.LookbehindOverrun,
|
|
||||||
c.LZO_E_NOT_COMPRESSIBLE => Error.NotCompressible,
|
|
||||||
c.LZO_E_NOT_YET_IMPLEMENTED => Error.NotYetImplemented,
|
|
||||||
c.LZO_E_OUTPUT_NOT_CONSUMED => Error.OutputNotConsumed,
|
|
||||||
c.LZO_E_OUTPUT_OVERRUN => Error.OutputOverrun,
|
|
||||||
c.LZO_E_OUT_OF_MEMORY => Error.OutOfMemory,
|
|
||||||
else => Error.Unknown,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
inline fn lzoErrToDecompErr(err: Error) Decompressor.Error {
|
|
||||||
return switch (err) {
|
|
||||||
Error.EofNotFound => Decompressor.Error.ReadFailed,
|
|
||||||
Error.InputNotConsumed => Decompressor.Error.ReadFailed,
|
|
||||||
Error.InputOverrun => Decompressor.Error.ReadFailed,
|
|
||||||
Error.InternalError => Decompressor.Error.ReadFailed,
|
|
||||||
Error.InvalidAlignment => Decompressor.Error.ReadFailed,
|
|
||||||
Error.InvalidArgument => Decompressor.Error.ReadFailed,
|
|
||||||
Error.LookbehindOverrun => Decompressor.Error.ReadFailed,
|
|
||||||
Error.NotCompressible => Decompressor.Error.ReadFailed,
|
|
||||||
Error.NotYetImplemented => Decompressor.Error.ReadFailed,
|
|
||||||
Error.OutputNotConsumed => Decompressor.Error.WriteFailed,
|
|
||||||
Error.OutputOverrun => Decompressor.Error.WriteFailed,
|
|
||||||
Error.OutOfMemory => Decompressor.Error.OutOfMemory,
|
|
||||||
else => Decompressor.Error.ReadFailed,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const Error = error{
|
|
||||||
EofNotFound,
|
|
||||||
InputNotConsumed,
|
|
||||||
InputOverrun,
|
|
||||||
InternalError,
|
|
||||||
InvalidAlignment,
|
|
||||||
InvalidArgument,
|
|
||||||
LookbehindOverrun,
|
|
||||||
NotCompressible,
|
|
||||||
NotYetImplemented,
|
|
||||||
OutputNotConsumed,
|
|
||||||
OutputOverrun,
|
|
||||||
OutOfMemory,
|
|
||||||
Unknown,
|
|
||||||
};
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const c = @import("../../c.zig").c;
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
streams: std.AutoHashMap(std.Thread.Id, c.lzma_stream),
|
|
||||||
|
|
||||||
interface: Decompressor,
|
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator) Self {
|
|
||||||
return .{
|
|
||||||
.alloc = alloc,
|
|
||||||
.streams = .init(alloc),
|
|
||||||
.interface = .{
|
|
||||||
.vtable = &.{
|
|
||||||
.decompress = decompress,
|
|
||||||
.stateless = stateless,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub fn deinit(self: *Self) void {
|
|
||||||
self.streams.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decompress(decomp: *Decompressor, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var self: *Self = @fieldParentPtr("interface", decomp);
|
|
||||||
|
|
||||||
var strm = try self.getOrCreate();
|
|
||||||
strm.next_in = in.ptr;
|
|
||||||
strm.avail_in = in.len;
|
|
||||||
strm.next_out = out.ptr;
|
|
||||||
strm.avail_out = out.len;
|
|
||||||
var res = c.lzma_stream_decoder(strm, out.len * 2, 0);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
while (res == c.LZMA_OK)
|
|
||||||
res = c.lzma_code(strm, c.LZMA_RUN);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
return strm.total_out;
|
|
||||||
}
|
|
||||||
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var strm: c.lzma_stream = .{
|
|
||||||
.allocator = &.{
|
|
||||||
.alloc = lzmaAlloc,
|
|
||||||
.free = lzmaFree,
|
|
||||||
.@"opaque" = @ptrCast(@constCast(&alloc)),
|
|
||||||
},
|
|
||||||
.next_in = in.ptr,
|
|
||||||
.avail_in = in.len,
|
|
||||||
.next_out = out.ptr,
|
|
||||||
.avail_out = out.len,
|
|
||||||
};
|
|
||||||
var res = c.lzma_stream_decoder(&strm, out.len * 2, 0);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
while (res == c.LZMA_OK)
|
|
||||||
res = c.lzma_code(&strm, c.LZMA_RUN);
|
|
||||||
decodeResult(res) catch |err| return lzmaErrToDecompErr(err);
|
|
||||||
return strm.total_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn getOrCreate(self: *Self) !*c.lzma_stream {
|
|
||||||
const res = try self.streams.getOrPut(std.Thread.getCurrentId());
|
|
||||||
if (res.found_existing) return res.value_ptr;
|
|
||||||
res.value_ptr.* = .{ .allocator = &.{
|
|
||||||
.alloc = lzmaAlloc,
|
|
||||||
.free = lzmaFree,
|
|
||||||
.@"opaque" = @ptrCast(&self.alloc),
|
|
||||||
} };
|
|
||||||
return res.value_ptr;
|
|
||||||
}
|
|
||||||
inline fn decodeResult(res: usize) Error!void {
|
|
||||||
return switch (res) {
|
|
||||||
c.LZMA_OK, c.LZMA_STREAM_END => {},
|
|
||||||
c.LZMA_NO_CHECK => Error.NoCheck,
|
|
||||||
c.LZMA_UNSUPPORTED_CHECK => Error.UnsupportedCheck,
|
|
||||||
c.LZMA_GET_CHECK => Error.GetCheck,
|
|
||||||
c.LZMA_MEM_ERROR, c.LZMA_MEMLIMIT_ERROR => Error.OutOfMemory,
|
|
||||||
c.LZMA_FORMAT_ERROR => Error.Format,
|
|
||||||
c.LZMA_OPTIONS_ERROR => Error.Options,
|
|
||||||
c.LZMA_DATA_ERROR => Error.Data,
|
|
||||||
c.LZMA_BUF_ERROR => Error.Buffer,
|
|
||||||
c.LZMA_PROG_ERROR => Error.Program,
|
|
||||||
c.LZMA_SEEK_NEEDED => Error.SeekNeeded,
|
|
||||||
else => Error.Unknown,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
inline fn lzmaErrToDecompErr(err: Error) Decompressor.Error {
|
|
||||||
return switch (err) {
|
|
||||||
Error.OutOfMemory => Decompressor.Error.OutOfMemory,
|
|
||||||
Error.NoCheck => Decompressor.Error.ReadFailed,
|
|
||||||
Error.UnsupportedCheck => Decompressor.Error.ReadFailed,
|
|
||||||
Error.GetCheck => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Format => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Options => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Data => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Buffer => Decompressor.Error.WriteFailed,
|
|
||||||
Error.Program => Decompressor.Error.ReadFailed,
|
|
||||||
Error.SeekNeeded => Decompressor.Error.ReadFailed,
|
|
||||||
else => Decompressor.Error.ReadFailed,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lzmaAlloc(ptr: ?*anyopaque, size: usize, _: usize) callconv(.c) ?*anyopaque {
|
|
||||||
var alloc: *std.mem.Allocator = @ptrCast(@alignCast(@constCast(ptr)));
|
|
||||||
return alloc.rawAlloc(size, .@"1", 0);
|
|
||||||
}
|
|
||||||
fn lzmaFree(ptr: ?*anyopaque, mem_ptr: ?*anyopaque) callconv(.c) void {
|
|
||||||
var alloc: *std.mem.Allocator = @ptrCast(@alignCast(@constCast(ptr)));
|
|
||||||
alloc.rawFree(@ptrCast(mem_ptr), .@"1", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Error = error{
|
|
||||||
OutOfMemory,
|
|
||||||
NoCheck,
|
|
||||||
UnsupportedCheck,
|
|
||||||
GetCheck,
|
|
||||||
Format,
|
|
||||||
Options,
|
|
||||||
Data,
|
|
||||||
Buffer,
|
|
||||||
Program,
|
|
||||||
SeekNeeded,
|
|
||||||
Unknown,
|
|
||||||
};
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const c = @import("../../c.zig").c;
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
streams: std.AutoHashMap(std.Thread.Id, c.zng_stream),
|
|
||||||
|
|
||||||
interface: Decompressor,
|
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator) Self {
|
|
||||||
return .{
|
|
||||||
.alloc = alloc,
|
|
||||||
.streams = .init(alloc),
|
|
||||||
.interface = .{
|
|
||||||
.vtable = &.{
|
|
||||||
.decompress = decompress,
|
|
||||||
.stateless = stateless,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub fn deinit(self: *Self) void {
|
|
||||||
self.streams.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decompress(decomp: *Decompressor, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
const self: *Self = @fieldParentPtr("interface", decomp);
|
|
||||||
|
|
||||||
var strm = try self.getOrCreate();
|
|
||||||
strm.next_in = in.ptr;
|
|
||||||
strm.avail_in = @truncate(in.len);
|
|
||||||
strm.next_out = out.ptr;
|
|
||||||
strm.total_out = out.len;
|
|
||||||
var res = c.zng_inflateReset(strm);
|
|
||||||
decodeError(res) catch |err| return zlibErrToDecompErr(err);
|
|
||||||
|
|
||||||
res = c.zng_inflate(strm, c.Z_FULL_FLUSH);
|
|
||||||
decodeError(res) catch |err| return zlibErrToDecompErr(err);
|
|
||||||
return strm.total_out;
|
|
||||||
}
|
|
||||||
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var strm: c.zng_stream = .{
|
|
||||||
.zalloc = zalloc,
|
|
||||||
.zfree = zfree,
|
|
||||||
.@"opaque" = @constCast(&alloc),
|
|
||||||
|
|
||||||
.next_in = in.ptr,
|
|
||||||
.avail_in = @truncate(in.len),
|
|
||||||
.next_out = out.ptr,
|
|
||||||
.total_out = out.len,
|
|
||||||
};
|
|
||||||
var res = c.zng_inflateInit(&strm);
|
|
||||||
decodeError(res) catch |err| return zlibErrToDecompErr(err);
|
|
||||||
|
|
||||||
res = c.zng_inflate(&strm, c.Z_FULL_FLUSH);
|
|
||||||
decodeError(res) catch |err| return zlibErrToDecompErr(err);
|
|
||||||
return strm.total_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getOrCreate(self: *Self) !*c.zng_stream {
|
|
||||||
const res = try self.streams.getOrPut(std.Thread.getCurrentId());
|
|
||||||
if (res.found_existing) return res.value_ptr;
|
|
||||||
res.value_ptr.* = .{
|
|
||||||
.zalloc = zalloc,
|
|
||||||
.zfree = zfree,
|
|
||||||
.@"opaque" = &self.alloc,
|
|
||||||
};
|
|
||||||
return res.value_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn zalloc(ptr: ?*anyopaque, size: c_uint, len: c_uint) callconv(.c) ?*anyopaque {
|
|
||||||
var alloc: *std.mem.Allocator = @ptrCast(@alignCast(@constCast(ptr)));
|
|
||||||
return alloc.rawAlloc(size * len, .@"1", 0);
|
|
||||||
}
|
|
||||||
fn zfree(ptr: ?*anyopaque, mem_ptr: ?*anyopaque) callconv(.c) void {
|
|
||||||
var alloc: *std.mem.Allocator = @ptrCast(@alignCast(@constCast(ptr)));
|
|
||||||
alloc.rawFree(@ptrCast(mem_ptr), .@"1", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn decodeError(res: i32) Error!void {
|
|
||||||
if (res >= 0) return;
|
|
||||||
return switch (res) {
|
|
||||||
c.Z_STREAM_ERROR => Error.Stream,
|
|
||||||
c.Z_DATA_ERROR => Error.Data,
|
|
||||||
c.Z_MEM_ERROR => Error.OutOfMemory,
|
|
||||||
c.Z_BUF_ERROR => Error.Buffer,
|
|
||||||
c.Z_VERSION_ERROR => Error.Version,
|
|
||||||
else => Error.Misc,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
inline fn zlibErrToDecompErr(err: Error) Decompressor.Error {
|
|
||||||
return switch (err) {
|
|
||||||
Error.OutOfMemory => Decompressor.Error.OutOfMemory,
|
|
||||||
Error.Misc => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Stream => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Data => Decompressor.Error.ReadFailed,
|
|
||||||
Error.Buffer => Decompressor.Error.WriteFailed,
|
|
||||||
Error.Version => Decompressor.Error.ReadFailed,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const Error = error{
|
|
||||||
OutOfMemory,
|
|
||||||
Misc,
|
|
||||||
Stream,
|
|
||||||
Data,
|
|
||||||
Buffer,
|
|
||||||
Version,
|
|
||||||
};
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const c = @import("../../c.zig").c;
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
ctx: std.AutoHashMap(std.Thread.Id, ?*c.ZSTD_DCtx),
|
|
||||||
|
|
||||||
interface: Decompressor,
|
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator) Self {
|
|
||||||
return .{
|
|
||||||
.alloc = alloc,
|
|
||||||
.ctx = .init(alloc),
|
|
||||||
.interface = .{
|
|
||||||
.vtable = &.{
|
|
||||||
.decompress = decompress,
|
|
||||||
.stateless = stateless,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub fn deinit(self: *Self) void {
|
|
||||||
self.ctx.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decompress(decomp: *Decompressor, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var self: *Self = @fieldParentPtr("interface", decomp);
|
|
||||||
|
|
||||||
const ctx = try self.getOrCreate();
|
|
||||||
const res = c.ZSTD_decompressDCtx(ctx, out.ptr, out.len, in.ptr, in.len);
|
|
||||||
decodeError(res) catch |err| return zstdErrToDecompErr(err);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
fn stateless(_: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
const res = c.ZSTD_decompress(out.ptr, out.len, in.ptr, in.len);
|
|
||||||
decodeError(res) catch |err| return zstdErrToDecompErr(err);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn getOrCreate(self: *Self) !?*c.ZSTD_DCtx {
|
|
||||||
const res = try self.ctx.getOrPut(std.Thread.getCurrentId());
|
|
||||||
if (res.found_existing) return res.value_ptr.*;
|
|
||||||
res.value_ptr.* = c.ZSTD_createDCtx();
|
|
||||||
return res.value_ptr.*;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn decodeError(res: usize) Error!void {
|
|
||||||
if (c.ZSTD_isError(res) == 0) return;
|
|
||||||
return switch (c.ZSTD_getErrorCode(res)) {
|
|
||||||
c.ZSTD_error_prefix_unknown => Error.PrefixUnknown,
|
|
||||||
c.ZSTD_error_version_unsupported => Error.VersionUnsupported,
|
|
||||||
c.ZSTD_error_frameParameter_unsupported => Error.FrameParameterUnsupported,
|
|
||||||
c.ZSTD_error_frameParameter_windowTooLarge => Error.FrameParameterWindowTooLarge,
|
|
||||||
c.ZSTD_error_corruption_detected => Error.CorruptionDetected,
|
|
||||||
c.ZSTD_error_checksum_wrong => Error.ChecksumWrong,
|
|
||||||
c.ZSTD_error_literals_headerWrong => Error.LiteralsHeaderWrong,
|
|
||||||
c.ZSTD_error_dictionary_corrupted => Error.DictionaryCorrupted,
|
|
||||||
c.ZSTD_error_dictionary_wrong => Error.DictionaryWrong,
|
|
||||||
c.ZSTD_error_dictionaryCreation_failed => Error.DictionaryCreationFailed,
|
|
||||||
c.ZSTD_error_parameter_unsupported => Error.ParameterUnsupported,
|
|
||||||
c.ZSTD_error_parameter_combination_unsupported => Error.ParameterCombinationUnsupported,
|
|
||||||
c.ZSTD_error_parameter_outOfBound => Error.ParameterOutOfBound,
|
|
||||||
c.ZSTD_error_tableLog_tooLarge => Error.TableLogTooLarge,
|
|
||||||
c.ZSTD_error_maxSymbolValue_tooLarge => Error.MaxSymbolValueTooLarge,
|
|
||||||
c.ZSTD_error_maxSymbolValue_tooSmall => Error.MaxSymbolValueTooSmall,
|
|
||||||
c.ZSTD_error_cannotProduce_uncompressedBlock => Error.CannotProduceUncompressedBlock,
|
|
||||||
c.ZSTD_error_stabilityCondition_notRespected => Error.StabilityConditionNotRespected,
|
|
||||||
c.ZSTD_error_stage_wrong => Error.StageWrong,
|
|
||||||
c.ZSTD_error_init_missing => Error.InitMissing,
|
|
||||||
c.ZSTD_error_memory_allocation => Error.MemoryAllocation,
|
|
||||||
c.ZSTD_error_workSpace_tooSmall => Error.WorkSpaceTooSmall,
|
|
||||||
c.ZSTD_error_dstSize_tooSmall => Error.DstSizeTooSmall,
|
|
||||||
c.ZSTD_error_srcSize_wrong => Error.SrcSizeWrong,
|
|
||||||
c.ZSTD_error_dstBuffer_null => Error.DstBufferNull,
|
|
||||||
c.ZSTD_error_noForwardProgress_destFull => Error.NoForwardProgressDestFull,
|
|
||||||
c.ZSTD_error_noForwardProgress_inputEmpty => Error.NoForwardProgressInputEmpty,
|
|
||||||
c.ZSTD_error_frameIndex_tooLarge => Error.FrameIndexTooLarge,
|
|
||||||
c.ZSTD_error_seekableIO => Error.SeekableIo,
|
|
||||||
c.ZSTD_error_dstBuffer_wrong => Error.DstBufferWrong,
|
|
||||||
c.ZSTD_error_srcBuffer_wrong => Error.SrcBufferWrong,
|
|
||||||
c.ZSTD_error_sequenceProducer_failed => Error.SequenceProducerFailed,
|
|
||||||
c.ZSTD_error_externalSequences_invalid => Error.ExternalSequencesInvalid,
|
|
||||||
else => Error.Generic,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
inline fn zstdErrToDecompErr(err: Error) Decompressor.Error {
|
|
||||||
return switch (err) {
|
|
||||||
Error.OutOfMemory => Decompressor.Error.OutOfMemory,
|
|
||||||
Error.Generic => Decompressor.Error.ReadFailed,
|
|
||||||
Error.PrefixUnknown => Decompressor.Error.ReadFailed,
|
|
||||||
Error.VersionUnsupported => Decompressor.Error.ReadFailed,
|
|
||||||
Error.FrameParameterUnsupported => Decompressor.Error.ReadFailed,
|
|
||||||
Error.FrameParameterWindowTooLarge => Decompressor.Error.ReadFailed,
|
|
||||||
Error.CorruptionDetected => Decompressor.Error.ReadFailed,
|
|
||||||
Error.ChecksumWrong => Decompressor.Error.ReadFailed,
|
|
||||||
Error.LiteralsHeaderWrong => Decompressor.Error.ReadFailed,
|
|
||||||
Error.DictionaryCorrupted => Decompressor.Error.ReadFailed,
|
|
||||||
Error.DictionaryWrong => Decompressor.Error.ReadFailed,
|
|
||||||
Error.DictionaryCreationFailed => Decompressor.Error.ReadFailed,
|
|
||||||
Error.ParameterUnsupported => Decompressor.Error.ReadFailed,
|
|
||||||
Error.ParameterCombinationUnsupported => Decompressor.Error.ReadFailed,
|
|
||||||
Error.ParameterOutOfBound => Decompressor.Error.ReadFailed,
|
|
||||||
Error.TableLogTooLarge => Decompressor.Error.ReadFailed,
|
|
||||||
Error.MaxSymbolValueTooLarge => Decompressor.Error.ReadFailed,
|
|
||||||
Error.MaxSymbolValueTooSmall => Decompressor.Error.ReadFailed,
|
|
||||||
Error.CannotProduceUncompressedBlock => Decompressor.Error.ReadFailed,
|
|
||||||
Error.StabilityConditionNotRespected => Decompressor.Error.ReadFailed,
|
|
||||||
Error.StageWrong => Decompressor.Error.ReadFailed,
|
|
||||||
Error.InitMissing => Decompressor.Error.ReadFailed,
|
|
||||||
Error.MemoryAllocation => Decompressor.Error.OutOfMemory,
|
|
||||||
Error.WorkSpaceTooSmall => Decompressor.Error.WriteFailed,
|
|
||||||
Error.DstSizeTooSmall => Decompressor.Error.WriteFailed,
|
|
||||||
Error.SrcSizeWrong => Decompressor.Error.ReadFailed,
|
|
||||||
Error.DstBufferNull => Decompressor.Error.WriteFailed,
|
|
||||||
Error.NoForwardProgressDestFull => Decompressor.Error.WriteFailed,
|
|
||||||
Error.NoForwardProgressInputEmpty => Decompressor.Error.ReadFailed,
|
|
||||||
Error.FrameIndexTooLarge => Decompressor.Error.ReadFailed,
|
|
||||||
Error.SeekableIo => Decompressor.Error.ReadFailed,
|
|
||||||
Error.DstBufferWrong => Decompressor.Error.WriteFailed,
|
|
||||||
Error.SrcBufferWrong => Decompressor.Error.ReadFailed,
|
|
||||||
Error.SequenceProducerFailed => Decompressor.Error.ReadFailed,
|
|
||||||
Error.ExternalSequencesInvalid => Decompressor.Error.ReadFailed,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const Error = error{
|
|
||||||
OutOfMemory,
|
|
||||||
Generic,
|
|
||||||
PrefixUnknown,
|
|
||||||
VersionUnsupported,
|
|
||||||
FrameParameterUnsupported,
|
|
||||||
FrameParameterWindowTooLarge,
|
|
||||||
CorruptionDetected,
|
|
||||||
ChecksumWrong,
|
|
||||||
LiteralsHeaderWrong,
|
|
||||||
DictionaryCorrupted,
|
|
||||||
DictionaryWrong,
|
|
||||||
DictionaryCreationFailed,
|
|
||||||
ParameterUnsupported,
|
|
||||||
ParameterCombinationUnsupported,
|
|
||||||
ParameterOutOfBound,
|
|
||||||
TableLogTooLarge,
|
|
||||||
MaxSymbolValueTooLarge,
|
|
||||||
MaxSymbolValueTooSmall,
|
|
||||||
CannotProduceUncompressedBlock,
|
|
||||||
StabilityConditionNotRespected,
|
|
||||||
StageWrong,
|
|
||||||
InitMissing,
|
|
||||||
MemoryAllocation,
|
|
||||||
WorkSpaceTooSmall,
|
|
||||||
DstSizeTooSmall,
|
|
||||||
SrcSizeWrong,
|
|
||||||
DstBufferNull,
|
|
||||||
NoForwardProgressDestFull,
|
|
||||||
NoForwardProgressInputEmpty,
|
|
||||||
FrameIndexTooLarge,
|
|
||||||
SeekableIo,
|
|
||||||
DstBufferWrong,
|
|
||||||
SrcBufferWrong,
|
|
||||||
SequenceProducerFailed,
|
|
||||||
ExternalSequencesInvalid,
|
|
||||||
};
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
const config = @import("config");
|
|
||||||
|
|
||||||
const Decompressor = @import("../decomp.zig");
|
|
||||||
const cLz4 = @import("c/lz4.zig");
|
|
||||||
const cLzma = @import("c/lzma.zig");
|
|
||||||
const cLzo = @import("c/lzo.zig");
|
|
||||||
const cXz = @import("c/xz.zig");
|
|
||||||
const cZlib = @import("c/zlib.zig");
|
|
||||||
const cZstd = @import("c/zstd.zig");
|
|
||||||
const zigLzma = @import("zig/lzma.zig");
|
|
||||||
const zigXz = @import("zig/xz.zig");
|
|
||||||
const zigZlib = @import("zig/zstd.zig");
|
|
||||||
const zigZstd = @import("zig/zstd.zig");
|
|
||||||
|
|
||||||
pub const Decomp = union(enum) {
|
|
||||||
gzip: if (config.use_zig_decomp) zigZlib else cZlib,
|
|
||||||
lzma: if (config.use_zig_decomp) zigLzma else cLzma,
|
|
||||||
lzo: if (config.use_zig_decomp) void else cLzo,
|
|
||||||
xz: if (config.use_zig_decomp) zigXz else cXz,
|
|
||||||
lz4: if (config.use_zig_decomp) void else cLz4,
|
|
||||||
zstd: if (config.use_zig_decomp) zigZstd else cZstd,
|
|
||||||
|
|
||||||
pub fn deinit(self: *Decomp) void {
|
|
||||||
switch (self) {
|
|
||||||
.gzip => self.gzip.deinit(),
|
|
||||||
.lzma => self.lzma.deinit(),
|
|
||||||
.xz => self.xz.deinit(),
|
|
||||||
.zstd => self.zstd.deinit(),
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decompressor(self: *Decomp) *Decompressor {
|
|
||||||
return switch (self) {
|
|
||||||
.gzip => &self.gzip.interface,
|
|
||||||
.lzma => &self.lzma.interface,
|
|
||||||
.lzo => &self.lzo.interface,
|
|
||||||
.xz => &self.xz.interface,
|
|
||||||
.lz4 => &self.lz4.interface,
|
|
||||||
.zstd => &self.zstd.interface,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const lzma = std.compress.lzma;
|
|
||||||
const Reader = std.Io.Reader;
|
|
||||||
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
interface: Decompressor = .{ .vtable = &.{ .stateless = stateless } },
|
|
||||||
|
|
||||||
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var rdr: Reader = .fixed(in);
|
|
||||||
var decomp = try lzma.decompress(alloc, rdr.adaptToOldInterface());
|
|
||||||
defer decomp.deinit();
|
|
||||||
return decomp.read(out) catch |err| switch (err) {
|
|
||||||
error.CorruptInput, error.EndOfStream, error.Overflow => return Decompressor.Error.ReadFailed,
|
|
||||||
else => return err,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const xz = std.compress.xz;
|
|
||||||
const Reader = std.Io.Reader;
|
|
||||||
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
interface: Decompressor = .{ .vtable = &.{ .stateless = stateless } },
|
|
||||||
|
|
||||||
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
var rdr: Reader = .fixed(in);
|
|
||||||
var decomp = try xz.decompress(alloc, rdr.adaptToOldInterface());
|
|
||||||
defer decomp.deinit();
|
|
||||||
return decomp.read(out) catch |err| switch (err) {
|
|
||||||
error.CorruptInput,
|
|
||||||
error.EndOfStream,
|
|
||||||
error.EndOfStreamWithNoError,
|
|
||||||
error.WrongChecksum,
|
|
||||||
error.Unsupported,
|
|
||||||
error.Overflow,
|
|
||||||
=> Decompressor.Error.ReadFailed,
|
|
||||||
else => return err,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const Reader = std.Io.Reader;
|
|
||||||
const flate = std.compress.flate;
|
|
||||||
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
interface: Decompressor = .{ .vtable = &.{ .stateless = stateless } },
|
|
||||||
|
|
||||||
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
const buf = try alloc.alloc(u8, out.len);
|
|
||||||
defer alloc.free(buf);
|
|
||||||
var rdr: Reader = .fixed(in);
|
|
||||||
|
|
||||||
var decomp = flate.Decompress.init(&rdr, .zlib, buf);
|
|
||||||
return decomp.reader.readSliceShort(out);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const Reader = std.Io.Reader;
|
|
||||||
const zstd = std.compress.zstd;
|
|
||||||
|
|
||||||
const Decompressor = @import("../../decomp.zig");
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
interface: Decompressor = .{ .vtable = &.{ .stateless = stateless } },
|
|
||||||
|
|
||||||
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
|
||||||
const buf = try alloc.alloc(u8, out.len * 2);
|
|
||||||
defer alloc.free(buf);
|
|
||||||
var rdr: Reader = .fixed(in);
|
|
||||||
|
|
||||||
var decomp = zstd.Decompress.init(&rdr, buf, .{ .window_len = @min(out.len, zstd.default_window_len) });
|
|
||||||
return decomp.reader.readSliceShort(out);
|
|
||||||
}
|
|
||||||
+2
-8
@@ -1,6 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
|
|
||||||
|
const CompressionType = @import("decomp.zig").CompressionType;
|
||||||
const InodeRef = @import("inode.zig").Ref;
|
const InodeRef = @import("inode.zig").Ref;
|
||||||
|
|
||||||
const SQUASHFS_MAGIC: u32 = std.mem.readInt(u32, "hsqs", .little);
|
const SQUASHFS_MAGIC: u32 = std.mem.readInt(u32, "hsqs", .little);
|
||||||
@@ -19,14 +20,7 @@ pub const Superblock = packed struct {
|
|||||||
mod_time: u32,
|
mod_time: u32,
|
||||||
block_size: u32,
|
block_size: u32,
|
||||||
frag_count: u32,
|
frag_count: u32,
|
||||||
compression: enum(u16) {
|
compression: CompressionType,
|
||||||
gzip = 1,
|
|
||||||
lzma,
|
|
||||||
lzo,
|
|
||||||
xz,
|
|
||||||
lz4,
|
|
||||||
zstd,
|
|
||||||
},
|
|
||||||
block_log: u16,
|
block_log: u16,
|
||||||
flags: packed struct {
|
flags: packed struct {
|
||||||
inode_uncompressed: bool,
|
inode_uncompressed: bool,
|
||||||
|
|||||||
+3
-3
@@ -2,13 +2,13 @@ const std = @import("std");
|
|||||||
const Mutex = std.Thread.Mutex;
|
const Mutex = std.Thread.Mutex;
|
||||||
|
|
||||||
const Archive = @import("archive.zig");
|
const Archive = @import("archive.zig");
|
||||||
|
const DecompFn = @import("decomp.zig").DecompFn;
|
||||||
const BlockSize = @import("inode_data/file.zig").BlockSize;
|
const BlockSize = @import("inode_data/file.zig").BlockSize;
|
||||||
const InodeRef = @import("inode.zig").Ref;
|
const InodeRef = @import("inode.zig").Ref;
|
||||||
const Superblock = @import("super.zig").Superblock;
|
const Superblock = @import("super.zig").Superblock;
|
||||||
const MetadataReader = @import("util/metadata.zig");
|
const MetadataReader = @import("util/metadata.zig");
|
||||||
const OffsetFile = @import("util/offset_file.zig");
|
const OffsetFile = @import("util/offset_file.zig");
|
||||||
const XattrTable = @import("xattr.zig");
|
const XattrTable = @import("xattr.zig");
|
||||||
const Decompressor = @import("decomp.zig");
|
|
||||||
|
|
||||||
/// Information about a fragment section. Multiple fragments are contained in the block described by a single FragEntry.
|
/// Information about a fragment section. Multiple fragments are contained in the block described by a single FragEntry.
|
||||||
/// The offset into the block and fragment size is stored in the file's inode.
|
/// The offset into the block and fragment size is stored in the file's inode.
|
||||||
@@ -49,7 +49,7 @@ pub fn Table(T: anytype) type {
|
|||||||
|
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
fil: OffsetFile,
|
fil: OffsetFile,
|
||||||
decomp: *Decompressor,
|
decomp: DecompFn,
|
||||||
tab_start: u64,
|
tab_start: u64,
|
||||||
|
|
||||||
tab: std.AutoHashMap(u32, []T),
|
tab: std.AutoHashMap(u32, []T),
|
||||||
@@ -57,7 +57,7 @@ pub fn Table(T: anytype) type {
|
|||||||
|
|
||||||
mut: Mutex = .{},
|
mut: Mutex = .{},
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator, fil: OffsetFile, decomp: *Decompressor, tab_start: u64, values: u32) !Self {
|
pub fn init(alloc: std.mem.Allocator, fil: OffsetFile, decomp: DecompFn, tab_start: u64, values: u32) !Self {
|
||||||
return .{
|
return .{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.fil = fil,
|
.fil = fil,
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const Decompressor = @import("decomp.zig");
|
const DecompFn = @import("decomp.zig").DecompFn;
|
||||||
const Table = @import("tables.zig").Table;
|
const Table = @import("tables.zig").Table;
|
||||||
const MetadataReader = @import("util/metadata.zig");
|
const MetadataReader = @import("util/metadata.zig");
|
||||||
const OffsetFile = @import("util/offset_file.zig");
|
const OffsetFile = @import("util/offset_file.zig");
|
||||||
@@ -38,14 +38,14 @@ const XattrTable = @This();
|
|||||||
|
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
fil: OffsetFile,
|
fil: OffsetFile,
|
||||||
decomp: *Decompressor,
|
decomp: DecompFn,
|
||||||
|
|
||||||
count: u32,
|
count: u32,
|
||||||
start: u64,
|
start: u64,
|
||||||
|
|
||||||
table: Table(Entry),
|
table: Table(Entry),
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator, fil: OffsetFile, decomp: *Decompressor, table_start: u64) !XattrTable {
|
pub fn init(alloc: std.mem.Allocator, fil: OffsetFile, decomp: DecompFn, table_start: u64) !XattrTable {
|
||||||
var info = packed struct {
|
var info = packed struct {
|
||||||
start: u64 = undefined,
|
start: u64 = undefined,
|
||||||
count: u32 = undefined,
|
count: u32 = undefined,
|
||||||
|
|||||||
Reference in New Issue
Block a user