mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
* stdlib: implement `std::compression::zip` and `std::compression::deflate` - C3 implementation of DEFLATE (RFC 1951) and ZIP archive handling. - Support for reading and writing archives using STORE and DEFLATE methods. - Decompression supports both fixed and dynamic Huffman blocks. - Compression using greedy LZ77 matching. - Zero dependencies on libc. - Stream-based entry reading and writing. - Full unit test coverage. NOTE: This is an initial implementation. Future improvements could be: - Optimization of the LZ77 matching (lazy matching). - Support for dynamic Huffman blocks in compression. - ZIP64 support for large files/archives. - Support for encryption and additional compression methods. * optimizations+refactoring deflate: - replace linear search with hash-based match finding. - implement support for dynamic Huffman blocks using the Package-Merge algorithm. - add streaming decompression. - add buffered StreamBitReader. zip: - add ZIP64 support. - add CP437 and UTF-8 filename encoding detection. - add DOS date/time conversion and timestamp preservation. - add ZipEntryReader for streaming entry reads. - implement ZipArchive.extract and ZipArchive.recover helpers. other: - Add `set_modified_time` to std::io; - Add benchmarks and a few more unit tests. * zip: add archive comment support add tests * forgot to rename the benchmark :( * detect utf8 names on weird zips fix method not passed to open_writer * another edge case where directory doesn't end with / * testing utilities - detect encrypted zip - `ZipArchive.open_writer` default to DEFLATE * fix zip64 creation, add tests * fix ZIP header endianness for big-endian compatibility Update ZipLFH, ZipCDH, ZipEOCD, Zip64EOCD, and Zip64Locator structs to use little-endian bitstruct types from std::core::bitorder * fix ZipEntryReader position tracking and seek logic ZIP_METHOD_STORE added a test to track this * add package-merge algorithm attribution Thanks @konimarti * standalone deflate_benchmark.c3 against `miniz` * fix integer overflows, leaks and improve safety * a few safety for 32-bit systems and tests * deflate compress optimization * improve match finding, hash updates, and buffer usage * use ulong for zip offsets * style changes (#18) * style changes * update tests * style changes in `deflate.c3` * fix typo * Allocator first. Some changes to deflate to use `copy_to` * Fix missing conversion on 32 bits. * Fix deflate stream. Formatting. Prefer switch over if-elseif * - Stream functions now use long/ulong rather than isz/usz for seek/available. - `instream.seek` is replaced by `set_cursor` and `cursor`. - `instream.available`, `cursor` etc are long/ulong rather than isz/usz to be correct on 32-bit. * Update to constdef * Fix test --------- Co-authored-by: Book-reader <thevoid@outlook.co.nz> Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
120 lines
2.8 KiB
Plaintext
120 lines
2.8 KiB
Plaintext
module std::io::os;
|
|
import libc, std::os, std::io;
|
|
|
|
fn void? native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || env::ANDROID || env::BSD_FAMILY) => @pool()
|
|
{
|
|
$if env::DARWIN || env::LINUX || env::ANDROID || env::BSD_FAMILY:
|
|
int res = libc::stat(path.zstr_tcopy(), stat);
|
|
$else
|
|
unreachable("Stat unimplemented");
|
|
int res = 0;
|
|
$endif
|
|
if (res != 0)
|
|
{
|
|
switch (libc::errno())
|
|
{
|
|
case errno::EBADF:
|
|
return io::FILE_NOT_VALID~;
|
|
case errno::EFAULT:
|
|
unreachable("Invalid stat");
|
|
case errno::EIO:
|
|
return io::GENERAL_ERROR~;
|
|
case errno::EACCES:
|
|
return io::NO_PERMISSION~;
|
|
case errno::ELOOP:
|
|
return io::NO_PERMISSION~;
|
|
case errno::ENAMETOOLONG:
|
|
return io::NAME_TOO_LONG~;
|
|
case errno::ENOENT:
|
|
return io::FILE_NOT_FOUND~;
|
|
case errno::ENOTDIR:
|
|
return io::FILE_NOT_DIR~;
|
|
case errno::EOVERFLOW:
|
|
return io::GENERAL_ERROR~;
|
|
default:
|
|
return io::UNKNOWN_ERROR~;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn usz? native_file_size(String path) @if(env::WIN32) => @pool()
|
|
{
|
|
Win32_FILE_ATTRIBUTE_DATA data;
|
|
win32::getFileAttributesExW(path.to_temp_wstring()!, Win32_GET_FILEEX_INFO_LEVELS.STANDARD, &data);
|
|
Win32_LARGE_INTEGER size;
|
|
size.lowPart = data.nFileSizeLow;
|
|
size.highPart = data.nFileSizeHigh;
|
|
return (usz)size.quadPart;
|
|
}
|
|
|
|
fn ulong? native_file_size(String path) @if(!env::WIN32 && !env::DARWIN && !env::LINUX && !env::ANDROID && !env::BSD_FAMILY)
|
|
{
|
|
File f = file::open(path, "r")!;
|
|
defer (void)f.close();
|
|
f.set_cursor(0, FROM_END)!;
|
|
return f.cursor();
|
|
}
|
|
|
|
fn ulong? native_file_size(String path) @if(env::DARWIN || env::LINUX || env::ANDROID || env::BSD_FAMILY)
|
|
{
|
|
Stat stat;
|
|
native_stat(&stat, path)!;
|
|
return stat.st_size;
|
|
}
|
|
|
|
fn bool native_file_or_dir_exists(String path)
|
|
{
|
|
$switch:
|
|
$case env::DARWIN:
|
|
$case env::FREEBSD:
|
|
$case env::NETBSD:
|
|
$case env::OPENBSD:
|
|
$case env::LINUX:
|
|
$case env::ANDROID:
|
|
Stat stat;
|
|
return @ok(native_stat(&stat, path));
|
|
$case env::WIN32:
|
|
@pool()
|
|
{
|
|
return (bool)win32::pathFileExistsW(path.to_temp_utf16()) ?? false;
|
|
};
|
|
$case env::POSIX:
|
|
@pool()
|
|
{
|
|
return posix::access(path.zstr_tcopy(), 0 /* F_OK */) != -1;
|
|
};
|
|
$default:
|
|
unreachable("Not supported");
|
|
$endswitch
|
|
}
|
|
|
|
fn bool native_is_file(String path)
|
|
{
|
|
$switch:
|
|
$case env::DARWIN:
|
|
$case env::FREEBSD:
|
|
$case env::NETBSD:
|
|
$case env::OPENBSD:
|
|
$case env::LINUX:
|
|
$case env::ANDROID:
|
|
Stat stat;
|
|
return @ok(native_stat(&stat, path)) && libc_S_ISTYPE(stat.st_mode, libc::S_IFREG);
|
|
$default:
|
|
File? f = file::open(path, "r");
|
|
defer (void)f.close();
|
|
return @ok(f);
|
|
$endswitch
|
|
}
|
|
|
|
fn bool native_is_dir(String path)
|
|
{
|
|
$if env::DARWIN || env::LINUX || env::ANDROID || env::BSD_FAMILY:
|
|
Stat stat;
|
|
return @ok(native_stat(&stat, path)) && libc_S_ISTYPE(stat.st_mode, libc::S_IFDIR);
|
|
$else
|
|
return native_file_or_dir_exists(path) && !native_is_file(path);
|
|
$endif
|
|
}
|
|
|
|
|