27 #include "precompiled.h"
50 const u32 fat_time =
bits(fat_timedate, 0, 15);
51 const u32 fat_date =
bits(fat_timedate, 16, 31);
54 t.tm_sec =
bits(fat_time, 0,4) * 2;
55 t.tm_min =
bits(fat_time, 5,10);
56 t.tm_hour =
bits(fat_time, 11,15);
57 t.tm_mday =
bits(fat_date, 0,4);
58 t.tm_mon =
bits(fat_date, 5,8) - 1;
59 t.tm_year =
bits(fat_date, 9,15) + 80;
65 time_t ret = mktime(&t);
74 struct tm* t = localtime(&time);
78 (
u16(t->tm_min) << 5) |
79 (
u16(t->tm_hour) << 11)
84 (
u16(t->tm_mon+1) << 5) |
85 (
u16(t->tm_year-80) << 9)
107 #pragma pack(push, 1)
115 const size_t pathnameSize = pathnameUTF8.length();
128 memcpy((
char*)
this +
sizeof(
LFH), pathnameUTF8.c_str(), pathnameSize);
134 size_t size =
sizeof(
LFH);
163 const size_t pathnameLength = pathnameUTF8.length();
180 memcpy((
char*)
this +
sizeof(
CDFH), pathnameUTF8.c_str(), pathnameLength);
186 const char* pathname = (
const char*)
this +
sizeof(
CDFH);
187 return Path(std::string(pathname, length));
223 size_t size =
sizeof(
CDFH);
253 void Init(
size_t cd_numEntries,
off_t cd_ofs,
size_t cd_size)
314 return m_file->Pathname();
340 #if CODEC_COMPUTE_CHECKSUM
366 : lfh_dst(lfh_dst), lfh_bytes_remaining(lfh_bytes_remaining)
440 const size_t minFileSize =
sizeof(
LFH)+
sizeof(
CDFH)+
sizeof(
ECDR);
448 size_t cd_numEntries = 0;
457 const u8* pos = (
const u8*)buf.
get();
458 for(
size_t i = 0; i < cd_numEntries; i++)
466 if(!relativePathname.IsDirectory())
471 cb(relativePathname, fileInfo, archiveFile, cbData);
495 for(
const u8* p = start; p <= buf+size-recordSize; p++)
498 if(*(
u32*)p == magic)
517 const size_t scanSize = std::min(maxScanSize,
size_t(fileSize));
529 ecdr->
Decompose(cd_numEntries, cd_ofs, cd_size);
535 const size_t maxScanSize = 66000u;
543 ret =
ScanForEcdr(file, fileSize, (
u8*)buf.
get(), maxScanSize, cd_numEntries, cd_ofs, cd_size);
603 throw std::bad_alloc();
626 CFileInfo fileInfo(pathnameInArchive, size, mtime);
633 ENSURE((file && !data) || (data && !file));
647 const size_t pathnameLength = pathnameInArchive.
string().length();
664 const size_t csizeMax = codec->MaxOutputSize(
size_t(usize));
668 size_t csize;
u32 checksum;
670 u8* cdata = (
u8*)buf.
get() +
sizeof(
LFH) + pathnameLength;
691 lfh->
Init(fileInfo, (
off_t)csize, method, checksum, pathnameInArchive);
697 const size_t cdfhSize =
sizeof(
CDFH) + pathnameLength;
702 cdfh->
Init(fileInfo, ofs, (
off_t)csize, method, checksum, pathnameInArchive, slack);
706 const size_t packageSize =
sizeof(
LFH) + pathnameLength + csize;
720 static const wchar_t* incompressibleExtensions[] =
723 L
".jpg", L
".jpeg", L
".png",
727 for(
size_t i = 0; i <
ARRAY_SIZE(incompressibleExtensions); i++)
729 if(extension == incompressibleExtensions[i])
void(* ArchiveEntryCallback)(const VfsPath &pathname, const CFileInfo &fileInfo, PIArchiveFile archiveFile, uintptr_t cbData)
called for each archive entry.
PIArchiveWriter CreateArchiveWriter_Zip(const OsPath &archivePathname, bool noDeflate)
#define RVALUE(lvalue)
convert anything (lvalue or rvalue) to an rvalue
void Init(const CFileInfo &fileInfo, off_t csize, ZipMethod method, u32 checksum, const Path &pathname)
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
void Decompose(size_t &cd_numEntries, off_t &cd_ofs, size_t &cd_size) const
Status AddFileOrMemory(const CFileInfo &fileInfo, const OsPath &pathnameInArchive, const PFile &file, const u8 *data)
u32 read_le32(const void *p)
ArchiveWriter_Zip(const OsPath &archivePathname, bool noDeflate)
static u32 FAT_from_time_t(time_t time)
void SetOutputBuffer(u8 *out, size_t outSize)
std::string utf8_from_wstring(const std::wstring &src, Status *err)
opposite of wstring_from_utf8
#define FOURCC_LE(a, b, c, d)
little-endian version of FOURCC
static Status LocateCentralDirectory(const PFile &file, off_t fileSize, off_t &cd_ofs, size_t &cd_numEntries, size_t &cd_size)
const Status ARCHIVE_UNKNOWN_FORMAT
PICodec CreateCodec_ZLibNone()
LFH_Copier(u8 *lfh_dst, size_t lfh_bytes_remaining)
void * pool_alloc(Pool *p, size_t size)
Dole out memory from the pool.
static const u32 ecdr_magic
PIArchiveReader CreateArchiveReader_Zip(const OsPath &archivePathname)
size_t lfh_bytes_remaining
PICodec CreateDecompressor_ZLibDeflate()
shared_ptr< IArchiveWriter > PIArchiveWriter
const Status CANNOT_HANDLE
ArchiveReader_Zip(const OsPath &pathname)
Status pool_create(Pool *p, size_t max_size, size_t el_size)
Ready Pool for use.
const Status ARCHIVE_UNKNOWN_METHOD
u32 u32_from_u16(u16 hi, u16 lo)
assemble u64 from u32
Status AddMemory(const u8 *data, size_t size, time_t mtime, const OsPath &pathnameInArchive)
add a file to the archive, when it is already in memory and not on disk.
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
shared_ptr< IArchiveReader > PIArchiveReader
static const u32 lfh_magic
const String & string() const
Status operator()(const u8 *block, size_t size) const
static UniqueRange Allocate(size_t size, size_t alignment=maxSectorSize)
virtual Status ReadEntries(ArchiveEntryCallback cb, uintptr_t cbData)
virtual size_t Precedence() const
static Status ScanForEcdr(const PFile &file, off_t fileSize, u8 *buf, size_t maxScanSize, size_t &cd_numEntries, off_t &cd_ofs, size_t &cd_size)
static const u32 cdfh_magic
i64 Status
Error handling system.
static time_t time_t_from_FAT(u32 fat_timedate)
T bits(T num, size_t lo_idx, size_t hi_idx)
extract the value of bits hi_idx:lo_idx within num
allocator design parameters:
static bool IsFileTypeIncompressible(const OsPath &pathname)
#define DEBUG_WARN_ERR(status)
display the error dialog with text corresponding to the given error code.
off_t HeaderOffset() const
u16 read_le16(const void *p)
read a little-endian number from memory into native byte order.
virtual wchar_t LocationCode() const
#define THROW_STATUS_IF_ERR(expression)
void write(OutputCB &output, const T &data)
Outputs a structure, using sizeof to get the size.
virtual Status Load(const OsPath &name, const shared_ptr< u8 > &buf, size_t size) const
#define WARN_RETURN(status)
Status AddFile(const OsPath &pathname, const OsPath &pathnameInArchive)
add a file to the archive.
virtual OsPath Path() const
Status pool_destroy(Pool *p)
free all memory (address space + physical) that constitutes the given Pool.
static const u8 * FindRecord(const u8 *buf, size_t size, const u8 *start, u32 magic, size_t recordSize)
Scan buffer for a Zip file record.
shared_ptr< ICodec > PICodec
ArchiveFile_Zip(const PFile &file, off_t ofs, off_t csize, u32 checksum, ZipMethod method)
#define cassert(expr)
Compile-time assertion.
PICodec CreateCompressor_ZLibDeflate()
void Init(size_t cd_numEntries, off_t cd_ofs, size_t cd_size)
void Init(const CFileInfo &fileInfo, off_t ofs, off_t csize, ZipMethod method, u32 checksum, const Path &pathname, size_t slack)
void AdjustOffset() const
fix up m_ofs (adjust it to point to cdata instead of the LFH).
u16 m_cd_numEntriesOnDisk
Status GetFileInfo(const OsPath &pathname, CFileInfo *pPtrInfo)
#define RETURN_STATUS_IF_ERR(expression)
static Status Run(const Operation &op, const Parameters &p=Parameters(), const CompletedHook &completedHook=CompletedHook(), const IssueHook &issueHook=IssueHook())