Started work on actual decompression implementations
This commit is contained in:
+10
-4
@@ -5,8 +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 = "git+https://github.com/CalebQ42/zig-zlib-ng#5f2f02dfb28acca2517dacbbd09e9b987f57b133",
|
||||||
.hash = "zlib_ng-2.3.3-pre1-2HYS4ClFAABW8KlHMyBHtlNKE3V7kCS8wqfxawG7xeaa",
|
// .hash = "zlib_ng-2.3.3-pre1-2HYS4ClFAABW8KlHMyBHtlNKE3V7kCS8wqfxawG7xeaa",
|
||||||
|
.path = "../zig-zlib-ng",
|
||||||
},
|
},
|
||||||
.zstd = .{
|
.zstd = .{
|
||||||
.url = "git+https://github.com/allyourcodebase/zstd.git?ref=1.5.7-1#e1a501be57f42c541e8a5597e4b59a074dfd09a3",
|
.url = "git+https://github.com/allyourcodebase/zstd.git?ref=1.5.7-1#e1a501be57f42c541e8a5597e4b59a074dfd09a3",
|
||||||
@@ -17,8 +18,13 @@
|
|||||||
.hash = "lz4-1.10.0-6-ewyzw-4NAAAWDpY4xpiqr4LQhZQAC0x_rGnW2iPh6jk2",
|
.hash = "lz4-1.10.0-6-ewyzw-4NAAAWDpY4xpiqr4LQhZQAC0x_rGnW2iPh6jk2",
|
||||||
},
|
},
|
||||||
.minilzo = .{
|
.minilzo = .{
|
||||||
.url = "git+https://github.com/CalebQ42/zig-minilzo.git#7cbae997b91a44d74b7cd6c073584dc9562a6c90",
|
// .url = "git+https://github.com/CalebQ42/zig-minilzo.git#7cbae997b91a44d74b7cd6c073584dc9562a6c90",
|
||||||
.hash = "minilzo-2.10.0-Ij7BO8wLAADeWI4Pe4jp8XTDsDaquZR14oZ7_9yKKDWP",
|
// .hash = "minilzo-2.10.0-Ij7BO8wLAADeWI4Pe4jp8XTDsDaquZR14oZ7_9yKKDWP",
|
||||||
|
.path = "../zig-minilzo",
|
||||||
|
},
|
||||||
|
.fastlzma2 = .{
|
||||||
|
.url = "git+https://github.com/allyourcodebase/fast-lzma2#d7615e0c957a62fcd6691b3fe9519a091885bfa2",
|
||||||
|
.hash = "fastlzma2-0.0.0-gNWHgVeLAAD0Tlak3xhNcgpPSYcjyJppq0tlGmPKCC_V",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.paths = .{
|
.paths = .{
|
||||||
|
|||||||
+15
-14
@@ -9,26 +9,27 @@ super: Superblock,
|
|||||||
pub fn init(fil: std.fs.File, offset: u64) !Archive {
|
pub fn init(fil: std.fs.File, offset: u64) !Archive {
|
||||||
var super: Superblock = undefined;
|
var super: Superblock = undefined;
|
||||||
var fil_rdr = fil.reader(&[0]u8{});
|
var fil_rdr = fil.reader(&[0]u8{});
|
||||||
try fil_rdr.seekTo(offset);
|
if (offset > 0)
|
||||||
|
try fil_rdr.seekTo(offset);
|
||||||
try fil_rdr.interface.readSliceEndian(Superblock, @ptrCast(&super), .little);
|
try fil_rdr.interface.readSliceEndian(Superblock, @ptrCast(&super), .little);
|
||||||
|
try super.validate();
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.super = super,
|
.super = super,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const Error = error{
|
||||||
|
BadMagic,
|
||||||
|
BadBlockLog,
|
||||||
|
BadVersion,
|
||||||
|
BadCheck,
|
||||||
|
};
|
||||||
|
|
||||||
// Superblock
|
// Superblock
|
||||||
|
|
||||||
const SQUASHFS_MAGIC: u32 = std.mem.readInt(u32, "hsqs", .little);
|
const SQUASHFS_MAGIC: u32 = std.mem.readInt(u32, "hsqs", .little);
|
||||||
|
|
||||||
const SuperblockError = error{
|
|
||||||
InvalidMagic,
|
|
||||||
InvalidBlockLog,
|
|
||||||
InvalidVersion,
|
|
||||||
InvalidCheck,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A squashfs Superblock
|
|
||||||
pub const Superblock = packed struct {
|
pub const Superblock = packed struct {
|
||||||
magic: u32,
|
magic: u32,
|
||||||
inode_count: u32,
|
inode_count: u32,
|
||||||
@@ -36,7 +37,7 @@ pub const Superblock = packed struct {
|
|||||||
block_size: u32,
|
block_size: u32,
|
||||||
frag_count: u32,
|
frag_count: u32,
|
||||||
compression: enum(u16) {
|
compression: enum(u16) {
|
||||||
gzip = 1,
|
gzip = 1, // Though officially named gzip, it actually uses zlib.
|
||||||
lzma,
|
lzma,
|
||||||
lzo,
|
lzo,
|
||||||
xz,
|
xz,
|
||||||
@@ -74,12 +75,12 @@ pub const Superblock = packed struct {
|
|||||||
/// Validate the Superblock. If an error is returned, it's likely the archive is corrupted or not a squashfs archive.
|
/// Validate the Superblock. If an error is returned, it's likely the archive is corrupted or not a squashfs archive.
|
||||||
fn validate(self: Superblock) !void {
|
fn validate(self: Superblock) !void {
|
||||||
if (self.magic != SQUASHFS_MAGIC)
|
if (self.magic != SQUASHFS_MAGIC)
|
||||||
return SuperblockError.InvalidMagic;
|
return Error.BadMagic;
|
||||||
if (self.flags.check)
|
if (self.flags.check)
|
||||||
return SuperblockError.InvalidCheck;
|
return Error.BadCheck;
|
||||||
if (self.ver_maj != 4 or self.ver_min != 0)
|
if (self.ver_maj != 4 or self.ver_min != 0)
|
||||||
return SuperblockError.InvalidVersion;
|
return Error.BadVersion;
|
||||||
if (std.math.log2(self.block_size) != self.block_log)
|
if (std.math.log2(self.block_size) != self.block_log)
|
||||||
return SuperblockError.InvalidBlockLog;
|
return Error.BadBlockLog;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
pub const c = @cImport({
|
||||||
|
@cInclude("zlib-ng.h");
|
||||||
|
@cInclude("lzo/minilzo.h");
|
||||||
|
@cInclude("lz4.h");
|
||||||
|
@cInclude("zstd.h");
|
||||||
|
@cInclude("lzma.h");
|
||||||
|
});
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const Error = error{
|
pub const Error = error{
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
EndOfStream,
|
EndOfStream,
|
||||||
ReadFailed,
|
ReadFailed,
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const c = @import("../../c_libs.zig").c;
|
||||||
|
const Decompressor = @import("../../decomp.zig");
|
||||||
|
|
||||||
|
const Zlib = @This();
|
||||||
|
|
||||||
|
streams: std.AutoHashMap(std.Thread.Id, c.zng_stream),
|
||||||
|
|
||||||
|
interface: Decompressor,
|
||||||
|
|
||||||
|
err: ?Error = null,
|
||||||
|
|
||||||
|
pub fn init(alloc: std.mem.Allocator) !Zlib {
|
||||||
|
return .{
|
||||||
|
.streams = try .init(alloc),
|
||||||
|
.interface = .{
|
||||||
|
.alloc = alloc,
|
||||||
|
.vtable = .{ .decompress = decompress, .stateless = stateless },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getOrCreate(self: *Zlib) !*c.zng_stream {
|
||||||
|
const res = try self.streams.getOrPut(std.Thread.getCurrentId());
|
||||||
|
if (res.found_existing) return res.value_ptr;
|
||||||
|
res.value_ptr.* = .{
|
||||||
|
.@"opaque" = self,
|
||||||
|
.zalloc = zalloc,
|
||||||
|
.zfree = zfree,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decompress(decomp: *Decompressor, in: []u8, out: []u8) Decompressor.Error!usize {
|
||||||
|
var self: *Zlib = @fieldParentPtr("interface", decomp);
|
||||||
|
|
||||||
|
var stream = try self.getOrCreate();
|
||||||
|
stream.next_in = in.ptr;
|
||||||
|
stream.avail_in = in.len;
|
||||||
|
stream.next_out = out.ptr;
|
||||||
|
stream.avail_out = out.len;
|
||||||
|
var res = c.zng_inflateReset(stream);
|
||||||
|
decodeError(res) catch |err| {
|
||||||
|
self.err = err;
|
||||||
|
return Decompressor.Error.ReadFailed;
|
||||||
|
};
|
||||||
|
res = c.zng_inflate(stream, c.Z_FINISH);
|
||||||
|
decodeError(res) catch |err| {
|
||||||
|
self.err = err;
|
||||||
|
return switch (err) {
|
||||||
|
Error.OutOfMemory => err,
|
||||||
|
else => Decompressor.Error.ReadFailed,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
||||||
|
_ = alloc;
|
||||||
|
var out_len = 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 => Decompressor.Error.OutOfMemory,
|
||||||
|
c.Z_BUF_ERROR => Decompressor.Error.WriteFailed,
|
||||||
|
else => Decompressor.Error.ReadFailed,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn decodeError(res: i32) Error!void {
|
||||||
|
return switch (res) {
|
||||||
|
c.Z_OK => {},
|
||||||
|
c.Z_STREAM_ERROR => Error.Stream,
|
||||||
|
c.Z_BUF_ERROR => Error.Buffer,
|
||||||
|
c.Z_MEM_ERROR => Error.OutOfMemory,
|
||||||
|
c.Z_DATA_ERROR => Error.Data,
|
||||||
|
c.Z_VERSION_ERROR => Error.Version,
|
||||||
|
else => Error.Unknown,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zalloc(ptr: ?*anyopaque, items: c_uint, size: c_uint) callconv(.c) ?*anyopaque {
|
||||||
|
var self: *Zlib = @ptrCast(ptr);
|
||||||
|
return self.interface.alloc.rawAlloc(items * size, .@"1", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zfree(ptr: ?*anyopaque, addr: ?*anyopaque) callconv(.c) void {
|
||||||
|
var self: *Zlib = @ptrCast(ptr);
|
||||||
|
self.interface.alloc.rawFree(@ptrCast(addr), .@"1", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Error = error{
|
||||||
|
OutOfMemory,
|
||||||
|
Stream,
|
||||||
|
Buffer,
|
||||||
|
Data,
|
||||||
|
Version,
|
||||||
|
Unknown,
|
||||||
|
};
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const c = @import("../../c_libs.zig").c;
|
||||||
|
const Decompressor = @import("../../decomp.zig");
|
||||||
|
|
||||||
|
const Zstd = @This();
|
||||||
|
|
||||||
|
context: std.AutoHashMap(std.Thread.Id, ?*c.ZSTD_DCtx),
|
||||||
|
|
||||||
|
interface: Decompressor,
|
||||||
|
|
||||||
|
err: ?Error = null,
|
||||||
|
|
||||||
|
pub fn init(alloc: std.mem.Allocator) !Zstd {
|
||||||
|
return .{
|
||||||
|
.streams = try .init(alloc),
|
||||||
|
.interface = .{
|
||||||
|
.alloc = alloc,
|
||||||
|
.vtable = .{ .decompress = decompress, .stateless = stateless },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getOrCreate(self: *Zstd) !*c.ZSTD_DCtx {
|
||||||
|
const res = try self.context.getOrPut(std.Thread.getCurrentId());
|
||||||
|
if (res.found_existing) return res.value_ptr;
|
||||||
|
res.value_ptr.* = c.ZSTD_createDCtx();
|
||||||
|
if (res.value_ptr.* == null) return Error.OutOfMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decompress(decomp: *Decompressor, in: []u8, out: []u8) Decompressor.Error!usize {
|
||||||
|
var self: *Zstd = @fieldParentPtr("interface", decomp);
|
||||||
|
|
||||||
|
const ctx = self.getOrCreate();
|
||||||
|
const res = c.ZSTD_decompressDCtx(ctx, out.ptr, out.len, in.ptr, in.len);
|
||||||
|
decodeError(res) catch |err| {
|
||||||
|
self.err = err;
|
||||||
|
return ZstdErrorToDecompError(err);
|
||||||
|
};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
fn stateless(alloc: std.mem.Allocator, in: []u8, out: []u8) Decompressor.Error!usize {
|
||||||
|
_ = alloc;
|
||||||
|
const res = c.ZSTD_decompress(out.ptr, out.len, in.ptr, in.len);
|
||||||
|
decodeError(res) catch |err| return ZstdErrorToDecompError(err);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn decodeError(res: usize) Error!void {
|
||||||
|
if (c.ZSTD_isError(res) == 0) return;
|
||||||
|
return switch (c.ZSTD_getErrorCode(res)) {
|
||||||
|
c.ZSTD_error_GENERIC => Error.Generic,
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
inline fn ZstdErrorToDecompError(err: Error) Decompressor.Error {
|
||||||
|
return switch (err) {
|
||||||
|
Error.OutOfMemory => err,
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub 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,
|
||||||
|
};
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
const config = @import("config");
|
||||||
|
|
||||||
|
const Zlib = if (config.use_zig_decomp) @import("zig/zlib.zig") else @import("c/zlib.zig");
|
||||||
|
const Lzma = if (config.use_zig_decomp) @import("zig/lzma.zig") else @import("c/lzma.zig");
|
||||||
|
const Lzo = if (config.use_zig_decomp) void else @import("c/lzo.zig");
|
||||||
|
const Xz = if (config.use_zig_decomp) @import("zig/xz.zig") else @import("c/xz.zig");
|
||||||
|
const Lz4 = if (config.use_zig_decomp) void else @import("c/lz4.zig");
|
||||||
|
const Zstd = if (config.use_zig_decomp) @import("zig/zstd.zig") else @import("c/zstd.zig");
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const flate = std.compress.flate;
|
||||||
|
const Reader = std.Io.Reader;
|
||||||
|
|
||||||
|
const Decompressor = @import("../../decomp.zig");
|
||||||
|
|
||||||
|
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 = .static(in);
|
||||||
|
var decomp = flate.Decompress.init(&rdr, .zlib, buf);
|
||||||
|
return decomp.reader.readSliceShort(out);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const zstd = std.compress.zstd;
|
||||||
|
const Reader = std.Io.Reader;
|
||||||
|
|
||||||
|
const Decompressor = @import("../../decomp.zig");
|
||||||
|
|
||||||
|
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 = .static(in);
|
||||||
|
var decomp = zstd.Decompress.init(&rdr, buf, .{ .window_len = out.len * 2 });
|
||||||
|
return decomp.reader.readSliceShort(out);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user