Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
20
Src/Wasabi/api/filereader/api_filereader.cpp
Normal file
20
Src/Wasabi/api/filereader/api_filereader.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <precomp.h>
|
||||
#include "api_filereader.h"
|
||||
|
||||
#ifdef CBCLASS
|
||||
#undef CBCLASS
|
||||
#endif
|
||||
#define CBCLASS api_fileReaderI
|
||||
START_DISPATCH;
|
||||
CB(API_FILEREADER_FILEOPEN, fileOpen);
|
||||
VCB(API_FILEREADER_FILECLOSE, fileClose);
|
||||
CB(API_FILEREADER_FILEREAD, fileRead);
|
||||
CB(API_FILEREADER_FILEWRITE, fileWrite);
|
||||
CB(API_FILEREADER_FILESEEK, fileSeek);
|
||||
CB(API_FILEREADER_FILETELL, fileTell);
|
||||
CB(API_FILEREADER_FILEGETFILESIZE, fileGetFileSize);
|
||||
// CB(API_FILEREADER_FILEEXISTS, fileExists);
|
||||
CB(API_FILEREADER_FILEREMOVE, fileRemove);
|
||||
CB(API_FILEREADER_FILEREMOVEUNDOABLE, fileRemoveUndoable);
|
||||
CB(API_FILEREADER_FILEMOVE, fileMove);
|
||||
END_DISPATCH;
|
104
Src/Wasabi/api/filereader/api_filereader.h
Normal file
104
Src/Wasabi/api/filereader/api_filereader.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
#ifndef __API_FILEREADER_H
|
||||
#define __API_FILEREADER_H
|
||||
|
||||
#include <bfc/dispatch.h>
|
||||
|
||||
class NOVTABLE api_fileReader : public Dispatchable
|
||||
{
|
||||
public:
|
||||
void *fileOpen(const wchar_t *filename, OSFNCSTR mode);
|
||||
void fileClose(void *fileHandle);
|
||||
size_t fileRead(void *buffer, size_t size, void *fileHandle);
|
||||
size_t fileWrite(const void *buffer, int size, void *fileHandle);
|
||||
int fileSeek(int64_t offset, int origin, void *fileHandle);
|
||||
uint64_t fileTell(void *fileHandle);
|
||||
uint64_t fileGetFileSize(void *fileHandle);
|
||||
//int fileExists(const wchar_t *filename);
|
||||
int fileRemove(const wchar_t *filename);
|
||||
int fileRemoveUndoable(const wchar_t *filename);
|
||||
int fileMove(const wchar_t *filename, const wchar_t *destfilename);
|
||||
|
||||
enum {
|
||||
API_FILEREADER_FILEOPEN = 0,
|
||||
API_FILEREADER_FILECLOSE = 10,
|
||||
API_FILEREADER_FILEREAD = 20,
|
||||
API_FILEREADER_FILEWRITE = 30,
|
||||
API_FILEREADER_FILESEEK = 40,
|
||||
API_FILEREADER_FILETELL = 50,
|
||||
API_FILEREADER_FILEGETFILESIZE = 60,
|
||||
//API_FILEREADER_FILEEXISTS = 70,
|
||||
API_FILEREADER_FILEREMOVE = 80,
|
||||
API_FILEREADER_FILEREMOVEUNDOABLE = 90,
|
||||
API_FILEREADER_FILEMOVE = 100,
|
||||
};
|
||||
};
|
||||
|
||||
inline void *api_fileReader::fileOpen(const wchar_t *filename, OSFNCSTR mode) {
|
||||
return _call(API_FILEREADER_FILEOPEN, (void *)NULL, filename, mode);
|
||||
}
|
||||
|
||||
inline void api_fileReader::fileClose(void *fileHandle) {
|
||||
_voidcall(API_FILEREADER_FILECLOSE, fileHandle);
|
||||
}
|
||||
|
||||
inline size_t api_fileReader::fileRead(void *buffer, size_t size, void *fileHandle) {
|
||||
return _call(API_FILEREADER_FILEREAD, (size_t)0, buffer, size, fileHandle);
|
||||
}
|
||||
|
||||
inline size_t api_fileReader::fileWrite(const void *buffer, int size, void *fileHandle) {
|
||||
return _call(API_FILEREADER_FILEWRITE, (size_t)0, buffer, size, fileHandle);
|
||||
}
|
||||
|
||||
inline int api_fileReader::fileSeek(int64_t offset, int origin, void *fileHandle) {
|
||||
return _call(API_FILEREADER_FILESEEK, (int)0, offset, origin, fileHandle);
|
||||
}
|
||||
|
||||
inline uint64_t api_fileReader::fileTell(void *fileHandle) {
|
||||
return _call(API_FILEREADER_FILETELL, (uint64_t)0, fileHandle);
|
||||
}
|
||||
|
||||
inline uint64_t api_fileReader::fileGetFileSize(void *fileHandle) {
|
||||
return _call(API_FILEREADER_FILEGETFILESIZE, (uint64_t)0, fileHandle);
|
||||
}
|
||||
|
||||
/*inline int api_fileReader::fileExists(const wchar_t *filename) {
|
||||
return _call(API_FILEREADER_FILEEXISTS, (int)0, filename);
|
||||
}*/
|
||||
|
||||
inline int api_fileReader::fileRemove(const wchar_t *filename) {
|
||||
return _call(API_FILEREADER_FILEREMOVE, (int)0, filename);
|
||||
}
|
||||
|
||||
inline int api_fileReader::fileRemoveUndoable(const wchar_t *filename) {
|
||||
return _call(API_FILEREADER_FILEREMOVEUNDOABLE, (int)0, filename);
|
||||
}
|
||||
|
||||
inline int api_fileReader::fileMove(const wchar_t *filename, const wchar_t *destfilename) {
|
||||
return _call(API_FILEREADER_FILEMOVE, (int)0, filename, destfilename);
|
||||
}
|
||||
|
||||
class api_fileReaderI : public api_fileReader {
|
||||
public:
|
||||
virtual void *fileOpen(const wchar_t *filename, const wchar_t *mode)=0;
|
||||
virtual void fileClose(void *fileHandle)=0;
|
||||
virtual size_t fileRead(void *buffer, size_t size, void *fileHandle)=0;
|
||||
virtual int fileWrite(const void *buffer, int size, void *fileHandle)=0;
|
||||
virtual int fileSeek(int64_t offset, int origin, void *fileHandle)=0;
|
||||
virtual uint64_t fileTell(void *fileHandle)=0;
|
||||
virtual uint64_t fileGetFileSize(void *fileHandle)=0;
|
||||
//virtual int fileExists(const wchar_t *filename)=0;
|
||||
virtual int fileRemove(const wchar_t *filename)=0;
|
||||
virtual int fileRemoveUndoable(const wchar_t *filename)=0;
|
||||
virtual int fileMove(const wchar_t *filename, const wchar_t *destfilename)=0;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
// {E357E736-4967-4279-B948-5073A186F565}
|
||||
static const GUID fileReaderApiServiceGuid =
|
||||
{ 0xe357e736, 0x4967, 0x4279, { 0xb9, 0x48, 0x50, 0x73, 0xa1, 0x86, 0xf5, 0x65 } };
|
||||
|
||||
extern api_fileReader *fileApi;
|
||||
|
||||
#endif
|
22
Src/Wasabi/api/filereader/api_readercallback.h
Normal file
22
Src/Wasabi/api/filereader/api_readercallback.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef __WASABI_API_READERCALLBACK_H
|
||||
#define __WASABI_API_READERCALLBACK_H
|
||||
|
||||
#include <bfc/dispatch.h>
|
||||
|
||||
class NOVTABLE api_readercallback : public Dispatchable
|
||||
{
|
||||
public:
|
||||
void metaDataReader_onData(const char *data, int size);
|
||||
|
||||
enum
|
||||
{
|
||||
METADATAREADERONDATA = 10,
|
||||
};
|
||||
};
|
||||
|
||||
inline void api_readercallback::metaDataReader_onData(const char *data, int size)
|
||||
{
|
||||
_voidcall(METADATAREADERONDATA, data, size);
|
||||
}
|
||||
|
||||
#endif
|
53
Src/Wasabi/api/filereader/filereaderapi.cpp
Normal file
53
Src/Wasabi/api/filereader/filereaderapi.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <precomp.h>
|
||||
#include "filereaderapi.h"
|
||||
#include <api/filereader/local/fileread.h>
|
||||
|
||||
api_fileReader *fileApi = NULL;
|
||||
|
||||
|
||||
FileReaderApi::FileReaderApi() {
|
||||
}
|
||||
|
||||
FileReaderApi::~FileReaderApi() {
|
||||
}
|
||||
|
||||
void *FileReaderApi::fileOpen(const wchar_t *filename, const wchar_t *mode) {
|
||||
return FileReaders::open(filename, mode);
|
||||
}
|
||||
|
||||
void FileReaderApi::fileClose(void *fileHandle) {
|
||||
FileReaders::close(fileHandle);
|
||||
}
|
||||
|
||||
size_t FileReaderApi::fileRead(void *buffer, size_t size, void *fileHandle) {
|
||||
return FileReaders::read(buffer, size, fileHandle);
|
||||
}
|
||||
|
||||
int FileReaderApi::fileWrite(const void *buffer, int size, void *fileHandle) {
|
||||
return FileReaders::write(buffer, size, fileHandle);
|
||||
}
|
||||
|
||||
int FileReaderApi::fileSeek(int64_t offset, int origin, void *fileHandle) {
|
||||
return FileReaders::seek(offset, origin, fileHandle);
|
||||
}
|
||||
|
||||
uint64_t FileReaderApi::fileTell(void *fileHandle) {
|
||||
return FileReaders::tell(fileHandle);
|
||||
}
|
||||
|
||||
uint64_t FileReaderApi::fileGetFileSize(void *fileHandle) {
|
||||
return FileReaders::getFileSize(fileHandle);
|
||||
}
|
||||
|
||||
int FileReaderApi::fileRemove(const wchar_t *filename) {
|
||||
return FileReaders::remove(filename);
|
||||
}
|
||||
|
||||
int FileReaderApi::fileRemoveUndoable(const wchar_t *filename) {
|
||||
return FileReaders::removeUndoable(filename);
|
||||
}
|
||||
|
||||
int FileReaderApi::fileMove(const wchar_t *filename, const wchar_t *destfilename) {
|
||||
return FileReaders::move(filename, destfilename);
|
||||
}
|
||||
|
25
Src/Wasabi/api/filereader/filereaderapi.h
Normal file
25
Src/Wasabi/api/filereader/filereaderapi.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef _FILEREADERAPI_H
|
||||
#define _FILEREADERAPI_H
|
||||
|
||||
#include <api/filereader/api_filereader.h>
|
||||
|
||||
class FileReaderApi : public api_fileReaderI
|
||||
{
|
||||
public:
|
||||
FileReaderApi();
|
||||
virtual ~FileReaderApi();
|
||||
|
||||
virtual void *fileOpen(const wchar_t *filename, const wchar_t *mode);
|
||||
virtual void fileClose(void *fileHandle);
|
||||
virtual size_t fileRead(void *buffer, size_t size, void *fileHandle);
|
||||
virtual int fileWrite(const void *buffer, int size, void *fileHandle);
|
||||
virtual int fileSeek(int64_t offset, int origin, void *fileHandle);
|
||||
virtual uint64_t fileTell(void *fileHandle);
|
||||
virtual uint64_t fileGetFileSize(void *fileHandle);
|
||||
//virtual int fileExists(const wchar_t *filename);
|
||||
virtual int fileRemove(const wchar_t *filename);
|
||||
virtual int fileRemoveUndoable(const wchar_t *filename);
|
||||
virtual int fileMove(const wchar_t *filename, const wchar_t *destfilename);
|
||||
};
|
||||
|
||||
#endif
|
132
Src/Wasabi/api/filereader/local/fileread.cpp
Normal file
132
Src/Wasabi/api/filereader/local/fileread.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
#include <precomp.h>
|
||||
#include "fileread.h"
|
||||
#include <api/service/svc_enum.h>
|
||||
|
||||
void *FileReaders::open(const wchar_t *filename, const wchar_t *mode) {
|
||||
int m=0;
|
||||
|
||||
const wchar_t *p=mode;
|
||||
wchar_t c;
|
||||
while(c=*(p++))
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case 'r': m=SvcFileReader::READ; break;
|
||||
case 'w': m=SvcFileReader::WRITE; break;
|
||||
case 'a': m=SvcFileReader::APPEND; break;
|
||||
case '+': m|=SvcFileReader::PLUS; break;
|
||||
case 'b': m|=SvcFileReader::BINARY; break;
|
||||
case 't': m|=SvcFileReader::TEXT; break;
|
||||
}
|
||||
}
|
||||
|
||||
return FileReaderEnum(filename, m).getFirst();
|
||||
}
|
||||
|
||||
void FileReaders::close(void *handle)
|
||||
{
|
||||
svc_fileReader *fr=(svc_fileReader *)handle;
|
||||
fr->close();
|
||||
SvcEnum::release(fr);
|
||||
}
|
||||
|
||||
size_t FileReaders::read(void *buffer, size_t size, void *handle)
|
||||
{
|
||||
svc_fileReader *fr=(svc_fileReader *)handle;
|
||||
return fr->read((int8_t *)buffer,size);
|
||||
}
|
||||
|
||||
size_t FileReaders::write(const void *buffer, size_t size, void *handle)
|
||||
{
|
||||
svc_fileReader *fr=(svc_fileReader *)handle;
|
||||
return fr->write((int8_t *)buffer,size);
|
||||
}
|
||||
|
||||
int FileReaders::seek(int64_t offset, int origin, void *handle)
|
||||
{
|
||||
svc_fileReader *fr=(svc_fileReader *)handle;
|
||||
if(!fr->canSeek()) return -1;
|
||||
if(origin==SEEK_SET) return fr->seek(offset);
|
||||
if(origin==SEEK_CUR) return fr->seek(fr->getPos()+offset);
|
||||
return fr->seek(fr->getLength()-offset);
|
||||
}
|
||||
|
||||
uint64_t FileReaders::tell(void *handle)
|
||||
{
|
||||
svc_fileReader *fr=(svc_fileReader *)handle;
|
||||
return fr->getPos();
|
||||
}
|
||||
|
||||
uint64_t FileReaders::getFileSize(void *handle)
|
||||
{
|
||||
svc_fileReader *fr=(svc_fileReader *)handle;
|
||||
return fr->getLength();
|
||||
}
|
||||
|
||||
int FileReaders::exists(const wchar_t *filename) {
|
||||
// Note that we do not do a system lock on the service since we can just
|
||||
// release it directly via the factory
|
||||
waService *s;
|
||||
for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
|
||||
svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
|
||||
if(fr->isMine(filename) == 1 || fr->open(filename)) {
|
||||
int ret=fr->exists(filename);
|
||||
fr->close();
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
return ret;
|
||||
}
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FileReaders::remove(const wchar_t *filename) {
|
||||
// Note that we do not do a system lock on the service since we can just
|
||||
// release it directly via the factory
|
||||
waService *s;
|
||||
for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
|
||||
svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
|
||||
if (fr->isMine(filename) == 1 || fr->open(filename)) {
|
||||
fr->close();
|
||||
int ret = fr->remove(filename);
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
return ret;
|
||||
}
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FileReaders::removeUndoable(const wchar_t *filename) {
|
||||
// Note that we do not do a system lock on the service since we can just
|
||||
// release it directly via the factory
|
||||
waService *s;
|
||||
for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
|
||||
svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
|
||||
if(fr->isMine(filename) == 1 || fr->open(filename)) {
|
||||
fr->close();
|
||||
int ret = fr->removeUndoable(filename);
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
return ret;
|
||||
}
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FileReaders::move(const wchar_t *filename, const wchar_t *destfilename) {
|
||||
// Note that we do not do a system lock on the service since we can just
|
||||
// release it directly via the factory
|
||||
waService *s;
|
||||
for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
|
||||
svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
|
||||
if(fr->isMine(filename) == 1 || fr->open(filename)) {
|
||||
fr->close();
|
||||
int ret = fr->move(filename,destfilename);
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
return ret;
|
||||
}
|
||||
s->releaseInterface(fr); fr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
23
Src/Wasabi/api/filereader/local/fileread.h
Normal file
23
Src/Wasabi/api/filereader/local/fileread.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _FILEREADERS_H
|
||||
#define _FILEREADERS_H
|
||||
|
||||
#include <api/filereader/svc_filereadI.h>
|
||||
#include <api/service/servicei.h>
|
||||
|
||||
class FileReaders
|
||||
{
|
||||
public:
|
||||
static void *open(const wchar_t *filename, const wchar_t *mode);
|
||||
static void close(void *handle);
|
||||
static size_t read(void *buffer, size_t size, void *handle);
|
||||
static size_t write(const void *buffer, size_t size, void *handle);
|
||||
static int seek(int64_t offset, int origin, void *handle);
|
||||
static uint64_t tell(void *handle);
|
||||
static uint64_t getFileSize(void *handle);
|
||||
static int exists(const wchar_t *filename);
|
||||
static int remove(const wchar_t *filename);
|
||||
static int removeUndoable(const wchar_t *filename);
|
||||
static int move(const wchar_t *filename, const wchar_t *destfilename);
|
||||
};
|
||||
|
||||
#endif//_FILEREADERS_H
|
100
Src/Wasabi/api/filereader/svc_filereadI.h
Normal file
100
Src/Wasabi/api/filereader/svc_filereadI.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
#ifndef __WASABI_SVC_FILEREADI_H
|
||||
#define __WASABI_SVC_FILEREADI_H
|
||||
|
||||
#include <api/service/svcs/svc_fileread.h>
|
||||
#include <api/filereader/api_readercallback.h>
|
||||
// derive from this one
|
||||
class NOVTABLE svc_fileReaderI : public svc_fileReader
|
||||
{
|
||||
public:
|
||||
virtual int isMine(const wchar_t *filename, int mode = SvcFileReader::READ) { return -1; }
|
||||
virtual int open(const wchar_t *filename, int mode = SvcFileReader::READ) = 0; // return 1 on success
|
||||
virtual size_t read(int8_t *buffer, size_t length) = 0; // return number of bytes read (if < length then eof)
|
||||
virtual size_t write(const int8_t *buffer, size_t length) = 0; // return number of bytes written
|
||||
virtual void close() = 0; //must be safe to call even when not open
|
||||
|
||||
virtual int canSetEOF() { return 0; }
|
||||
virtual int setEOF(uint64_t newlen) { return -1; }
|
||||
|
||||
virtual void abort() { } // tells the reader to abort its current prebuffering/reader
|
||||
|
||||
virtual int getLength() { return -1; } // return -1 on unknown/infinite
|
||||
virtual int getPos() = 0;
|
||||
|
||||
virtual int canSeek() { return 0; }
|
||||
virtual int seek(uint64_t position) { return 0; }
|
||||
virtual uint64_t bytesAvailable(uint64_t requested) { return requested; }
|
||||
|
||||
virtual int hasHeaders() { return 0; }
|
||||
virtual const char *getHeader(const char *header) { return (const char *)NULL; }
|
||||
|
||||
virtual int exists(const wchar_t *filename) { return 0; } // return 1 if true, 0 if not, -1 if unknown
|
||||
|
||||
virtual int remove(const wchar_t *filename) { return 0; } // return 1 on success, 0 on error
|
||||
|
||||
virtual int removeUndoable(const wchar_t *filename) { return -1; }
|
||||
|
||||
virtual int move(const wchar_t *filename, const wchar_t *destfilename) { return 0; } // return 1 on success, 0 on error
|
||||
|
||||
virtual void setMetaDataCallback(api_readercallback *cb) { }
|
||||
|
||||
virtual int canPrefetch() { return 1; } // return 1 if your reader should prefetch infos about the file in pledit
|
||||
// (HTTP reader will return 0 here for instance)
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
||||
// derive from this one
|
||||
class NOVTABLE MetaDataReaderCallbackI : public api_readercallback {
|
||||
public:
|
||||
virtual void metaDataReader_onData(const char *data, int size)=0;
|
||||
|
||||
protected:
|
||||
#undef CBCLASS
|
||||
#define CBCLASS MetaDataReaderCallbackI
|
||||
START_DISPATCH_INLINE;
|
||||
VCB(METADATAREADERONDATA, metaDataReader_onData);
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
};
|
||||
|
||||
#include <api/service/svcs/svc_redir.h>
|
||||
#include <bfc/std_file.h> // for WA_MAX_PATH but this needs to be in a better place
|
||||
|
||||
#define MAX_FILEREADER_REDIRECT 256
|
||||
|
||||
// note: this class handles both redirection and calling open()
|
||||
class FileReaderEnum : public SvcEnumT<svc_fileReader> {
|
||||
public:
|
||||
FileReaderEnum(const wchar_t *filename, int mode=SvcFileReader::READ, int allow_redirect=FALSE) :
|
||||
fn(filename), m(mode)
|
||||
{
|
||||
if (allow_redirect) {
|
||||
for (int done = 0, c = 0; !done && c < MAX_FILEREADER_REDIRECT; done = 1, c++) {
|
||||
RedirectEnum re(fn);
|
||||
svc_redirect *svc;
|
||||
while ((svc = re.getNext(FALSE)) != NULL) {
|
||||
wchar_t buf[WA_MAX_PATH]=L"";
|
||||
if (svc->redirect(fn, L"Filename", buf, WA_MAX_PATH)) {
|
||||
fn = buf;
|
||||
done = 0;
|
||||
}
|
||||
re.getLastFactory()->releaseInterface(svc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual int testService(svc_fileReader *svc) {
|
||||
if (!svc->isMine(fn)) return 0;
|
||||
return !!svc->open(fn, m);
|
||||
}
|
||||
|
||||
private:
|
||||
const wchar_t *fn;
|
||||
int m;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
176
Src/Wasabi/api/filereader/zip/zipread.cpp
Normal file
176
Src/Wasabi/api/filereader/zip/zipread.cpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
#include <precomp.h>
|
||||
#define REAL_STDIO
|
||||
#include "zipread.h"
|
||||
#include <zlib/unzip.h>
|
||||
#include <bfc/parse/pathparse.h>
|
||||
#include <api/skin/api_skin.h>
|
||||
|
||||
#define UNZIPBUFSIZE 65536
|
||||
|
||||
int ZipRead::open(const char *filename, int mode) {
|
||||
unzFile f=NULL;
|
||||
int success=0;
|
||||
|
||||
if (WASABI_API_SKIN == NULL) return 0;
|
||||
PathParser pp1(WASABI_API_SKIN->getSkinsPath());
|
||||
PathParser pp2(filename);
|
||||
int v;
|
||||
for (v=0;v<pp1.getNumStrings();v++)
|
||||
if (!STRCASEEQLSAFE(pp1.enumString(v), pp2.enumString(v))) return 0;
|
||||
String walName = pp2.enumString(v);
|
||||
String file;
|
||||
for (v=v+1;v<pp2.getNumStrings();v++) {
|
||||
if (!file.isempty()) file.cat(DIRCHARSTR);
|
||||
file += pp2.enumString(v);
|
||||
}
|
||||
|
||||
// is there a zip file?
|
||||
String zipName;
|
||||
Std::fileInfoStruct zipFi;
|
||||
if(!Std::getFileInfos(zipName=StringPrintf("%s%s.wal",WASABI_API_SKIN->getSkinsPath(),walName.getValue()),&zipFi) &&
|
||||
!Std::getFileInfos(zipName=StringPrintf("%s%s.wsz",WASABI_API_SKIN->getSkinsPath(),walName.getValue()),&zipFi) &&
|
||||
!Std::getFileInfos(zipName=StringPrintf("%s%s.zip",WASABI_API_SKIN->getSkinsPath(),walName.getValue()),&zipFi))
|
||||
return 0; // zip not found
|
||||
|
||||
if(zipTmpDir.isempty()) {
|
||||
char tmpPath[WA_MAX_PATH];
|
||||
Std::getTempPath(sizeof(tmpPath)-1,tmpPath);
|
||||
zipTmpDir=StringPrintf("%s_wa3sktmp",tmpPath);
|
||||
Std::createDirectory(zipTmpDir);
|
||||
}
|
||||
|
||||
// check in cached opened zip dirs
|
||||
int badcrc=0;
|
||||
for(int i=0;i<openedZipHandles.getNumItems();i++) {
|
||||
if(!STRICMP(openedZipHandles[i].name->getValue(), walName)) {
|
||||
if(!MEMCMP(&openedZipHandles[i].checksum,&zipFi,sizeof(zipFi))) {
|
||||
// try to find it in the dezipped temp dir
|
||||
handle=openInTempDir(walName,file);
|
||||
if(handle) return 1;
|
||||
else return 0;
|
||||
} else {
|
||||
// bad checksum
|
||||
badcrc=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// is the dezipped dir is here?
|
||||
if(!badcrc) {
|
||||
StringPrintf tmpf("%s%s%s%s_wa3chksum",zipTmpDir.getValue(),DIRCHARSTR,walName.getValue(),DIRCHARSTR);
|
||||
FILE *fh=fopen(tmpf,"rb");
|
||||
if(fh) {
|
||||
Std::fileInfoStruct tmpFi={0,};
|
||||
fread(&tmpFi,1,sizeof(tmpFi),fh);
|
||||
fclose(fh);
|
||||
if(!MEMCMP(&tmpFi,&zipFi,sizeof(tmpFi))) {
|
||||
// checksum correct
|
||||
openedZipEntry ze={new String(walName), new String(zipName)};
|
||||
ze.checksum=tmpFi;
|
||||
openedZipHandles.addItem(ze);
|
||||
handle=openInTempDir(walName,file);
|
||||
if(handle) return 1;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not found, so try to find it in a zip file
|
||||
f = unzOpen(zipName);
|
||||
if(!f) return 0;
|
||||
|
||||
StringPrintf zDir("%s%s%s",zipTmpDir.getValue(),DIRCHARSTR,walName.getValue());
|
||||
Std::removeDirectory(zDir,1);
|
||||
|
||||
// unpack the zip in temp folder
|
||||
String dirmask;
|
||||
unzGoToFirstFile(f);
|
||||
Std::createDirectory(zDir);
|
||||
do {
|
||||
char filename[MAX_PATH];
|
||||
unzGetCurrentFileInfo(f,NULL,filename,sizeof(filename),NULL,0,NULL,0);
|
||||
if (unzOpenCurrentFile(f) == UNZ_OK) {
|
||||
int l;
|
||||
dirmask.printf("%s%s%s",zDir.getValue(),DIRCHARSTR,filename);
|
||||
if (Std::isDirChar(dirmask.lastChar())) {
|
||||
// create dir
|
||||
Std::createDirectory(dirmask);
|
||||
} else {
|
||||
// create file
|
||||
FILE *fp = fopen(dirmask,"wb");
|
||||
if(!fp) {
|
||||
String dir=dirmask;
|
||||
char *p=(char *)Std::filename(dir);
|
||||
if(p) {
|
||||
*p=0;
|
||||
Std::createDirectory(dir);
|
||||
fp = fopen(dirmask,"wb");
|
||||
}
|
||||
}
|
||||
if (fp) {
|
||||
do {
|
||||
MemBlock<char> buf(UNZIPBUFSIZE);
|
||||
l=unzReadCurrentFile(f,buf.getMemory(),buf.getSizeInBytes());
|
||||
if (l > 0) fwrite(buf.getMemory(),1,l,fp);
|
||||
} while (l > 0);
|
||||
fclose(fp);
|
||||
success=1;
|
||||
}
|
||||
}
|
||||
if (unzCloseCurrentFile(f) == UNZ_CRCERROR) success=0;
|
||||
}
|
||||
} while (unzGoToNextFile(f) == UNZ_OK);
|
||||
unzClose(f);
|
||||
|
||||
// write the checksum file
|
||||
Std::fileInfoStruct fi;
|
||||
Std::getFileInfos(zipName, &fi);
|
||||
FILE *fh=fopen(StringPrintf("%s%s_wa3chksum",zDir.getValue(),DIRCHARSTR),"wt");
|
||||
fwrite(&fi,1,sizeof(fi),fh);
|
||||
fclose(fh);
|
||||
|
||||
openedZipEntry ze={new String(walName), new String(zipName)};
|
||||
ze.checksum=fi;
|
||||
openedZipHandles.addItem(ze);
|
||||
|
||||
// try to find it (again) in the dezipped temp dir
|
||||
handle=openInTempDir(walName,file);
|
||||
if(handle) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *ZipRead::openInTempDir(const char *walName, const char *file) {
|
||||
StringPrintf tmpf("%s%s%s%s%s",zipTmpDir.getValue(),DIRCHARSTR,walName,DIRCHARSTR,file);
|
||||
FILE *fh=fopen(tmpf,"rb");
|
||||
if(fh) return fh;
|
||||
// okay maybe the file isn't in the root dir of the zip file
|
||||
fh=fopen(StringPrintf("%s%s%s%s%s%s%s",zipTmpDir.getValue(),DIRCHARSTR,walName,DIRCHARSTR,walName,DIRCHARSTR,file),"rb");
|
||||
if(fh) return fh;
|
||||
// definitely not here
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ZipRead::close() {
|
||||
fclose(handle);
|
||||
}
|
||||
|
||||
int ZipRead::read(char *buffer, int size) {
|
||||
return fread(buffer,1,size,handle);
|
||||
}
|
||||
|
||||
int ZipRead::getPos() {
|
||||
return ftell(handle);
|
||||
}
|
||||
|
||||
int ZipRead::getLength() {
|
||||
int pos=ftell(handle);
|
||||
fseek(handle,0,SEEK_END);
|
||||
int length=ftell(handle);
|
||||
fseek(handle,pos,SEEK_SET);
|
||||
return length;
|
||||
}
|
||||
|
||||
using namespace wasabi;
|
||||
|
||||
TList<ZipRead::openedZipEntry> ZipRead::openedZipHandles;;
|
39
Src/Wasabi/api/filereader/zip/zipread.h
Normal file
39
Src/Wasabi/api/filereader/zip/zipread.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef _ZIPREAD_H
|
||||
#define _ZIPREAD_H
|
||||
|
||||
#include <api/service/svcs/svc_fileread.h>
|
||||
#include <api/service/servicei.h>
|
||||
#include <bfc/memblock.h>
|
||||
#include <bfc/string/string.h>
|
||||
#include <bfc/ptrlist.h>
|
||||
#include <bfc/tlist.h>
|
||||
|
||||
class ZipRead : public svc_fileReaderI {
|
||||
public:
|
||||
// service
|
||||
static const char *getServiceName() { return "ZIP file reader"; }
|
||||
|
||||
int open(const char *filename, int mode=SvcFileReader::READ);
|
||||
int read(char *buffer, int length);
|
||||
int write(const char *buffer, int length) { return 0; }
|
||||
void close();
|
||||
int getPos();
|
||||
int getLength();
|
||||
|
||||
private:
|
||||
FILE *openInTempDir(const char *walName, const char *file);
|
||||
|
||||
typedef struct {
|
||||
String *name;
|
||||
String *zipName;
|
||||
Std::fileInfoStruct checksum;
|
||||
} openedZipEntry;
|
||||
|
||||
static wasabi::TList<openedZipEntry> openedZipHandles;
|
||||
|
||||
String zipTmpDir;
|
||||
|
||||
FILE *handle;
|
||||
};
|
||||
|
||||
#endif//_ZIPREAD_H
|
Loading…
Add table
Add a link
Reference in a new issue