mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 05:42:29 +00:00
Refactor out some duplicated code
This commit is contained in:
parent
e963d9c8e3
commit
579b597ded
58 changed files with 1110 additions and 3214 deletions
|
@ -18,75 +18,12 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
static int popcnt3(int x) {
|
||||
return !!(x & 1) + !!(x & 2) + !!(x & 4);
|
||||
}
|
||||
|
||||
static struct timespec WindowsTimeToTime(uint64_t x) {
|
||||
return (struct timespec){x / HECTONANOSECONDS - MODERNITYSECONDS,
|
||||
x % HECTONANOSECONDS * 100};
|
||||
}
|
||||
|
||||
static void GetZipCfileTimestamps(const uint8_t *zcf, struct stat *st) {
|
||||
const uint8_t *p, *pe;
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraNtfs &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 4) == 1 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 8) {
|
||||
st->st_mtim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8));
|
||||
if (ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 * 2 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 16) {
|
||||
st->st_atim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8 * 2));
|
||||
}
|
||||
if (ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4 + 8 * 3 &&
|
||||
READ16LE(ZIP_EXTRA_CONTENT(p) + 6) >= 24) {
|
||||
st->st_ctim = WindowsTimeToTime(READ64LE(ZIP_EXTRA_CONTENT(p) + 8 * 3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraExtendedTimestamp &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) > 1 &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) ==
|
||||
1 + 4 * popcnt3(*ZIP_EXTRA_CONTENT(p) & 7)) {
|
||||
if (*ZIP_EXTRA_CONTENT(p) & 1) {
|
||||
st->st_mtim.tv_sec = READ32LE(ZIP_EXTRA_CONTENT(p) + 1);
|
||||
}
|
||||
if (*ZIP_EXTRA_CONTENT(p) & 2) {
|
||||
st->st_atim.tv_sec = READ32LE(ZIP_EXTRA_CONTENT(p) + 1 +
|
||||
4 * (*ZIP_EXTRA_CONTENT(p) & 1));
|
||||
}
|
||||
if (*ZIP_EXTRA_CONTENT(p) & 4) {
|
||||
st->st_ctim.tv_sec = READ32LE(ZIP_EXTRA_CONTENT(p) + 1 +
|
||||
4 * popcnt3(*ZIP_EXTRA_CONTENT(p) & 3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (p = ZIP_CFILE_EXTRA(zcf), pe = p + ZIP_CFILE_EXTRASIZE(zcf); p + 4 <= pe;
|
||||
p += ZIP_EXTRA_SIZE(p)) {
|
||||
if (ZIP_EXTRA_HEADERID(p) == kZipExtraUnix &&
|
||||
ZIP_EXTRA_CONTENTSIZE(p) >= 4 + 4) {
|
||||
st->st_atim.tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 0);
|
||||
st->st_mtim.tv_sec = (int32_t)READ32LE(ZIP_EXTRA_CONTENT(p) + 4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
st->st_mtim.tv_sec = DosDateTimeToUnix(ZIP_CFILE_LASTMODIFIEDDATE(zcf),
|
||||
ZIP_CFILE_LASTMODIFIEDTIME(zcf));
|
||||
}
|
||||
|
||||
int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) {
|
||||
size_t lf;
|
||||
if (zipos && st) {
|
||||
|
@ -100,7 +37,8 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) {
|
|||
st->st_size = GetZipLfileUncompressedSize(zipos->map + lf);
|
||||
st->st_blocks =
|
||||
roundup(GetZipLfileCompressedSize(zipos->map + lf), 512) / 512;
|
||||
GetZipCfileTimestamps(zipos->map + cf, st);
|
||||
GetZipCfileTimestamps(zipos->map + cf, &st->st_mtim, &st->st_atim,
|
||||
&st->st_ctim, 0);
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue