*
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
#ifndef ICONTENTPROVIDER_H__
|
||||
#define ICONTENTPROVIDER_H__
|
||||
|
||||
#include "../IDataStream.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IFileSystem;
|
||||
|
||||
class IContentProvider
|
||||
{
|
||||
public:
|
||||
virtual ~IContentProvider(){};
|
||||
virtual void Close() = 0;
|
||||
virtual IFileSystem* getFileSystem() = 0;
|
||||
|
||||
protected:
|
||||
IDataStreamPtr g_dataStream;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef IFILE_H__
|
||||
#define IFILE_H__
|
||||
|
||||
#include "../IDataStream.h"
|
||||
#include "../LString.h"
|
||||
#include "IContentProvider.h"
|
||||
#include "../Types.h"
|
||||
#include "../delegate/Delegate.h"
|
||||
namespace LifeCore
|
||||
{
|
||||
enum FILE_ACCESS
|
||||
{
|
||||
FA_READ = 1,
|
||||
FA_WRITE = 2,
|
||||
FA_READ_WRITE = 3
|
||||
};
|
||||
|
||||
enum FILE_MODE
|
||||
{
|
||||
FM_CREATE_NEW = 1,
|
||||
FM_CREATE = 2,
|
||||
FM_OPEN = 3,
|
||||
FM_OPEN_OR_CREATE = 4,
|
||||
FM_TRUNCATE = 5,
|
||||
FM_APPEND = 6,
|
||||
};
|
||||
|
||||
class IFile
|
||||
{
|
||||
public:
|
||||
EVENT1(FileEvent, LifeCore::IFile*);
|
||||
FileEvent Event_EndReadAsync;
|
||||
|
||||
int Size;
|
||||
IContentProvider* Provider;
|
||||
String FileName;
|
||||
virtual ~IFile(){}
|
||||
virtual bool ReadAsync(char* buffer, size_t count_read)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(buffer);
|
||||
UNREFERENCED_PARAMETER(count_read);
|
||||
return false;
|
||||
}
|
||||
virtual IDataStreamPtr OpenRead() = 0;
|
||||
virtual IDataStreamPtr OpenWrite(int mode) = 0;
|
||||
virtual IDataStreamPtr OpenReadWrite(int mode) = 0;
|
||||
protected:
|
||||
_bool isOpen;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,158 @@
|
||||
#include "IFileSystem.h"
|
||||
#include "../log/CLog.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
/*IFolder* IFileSystem::GetFolder(const String& path)
|
||||
{
|
||||
String folder, rPath;
|
||||
GetRootFolderS(path, folder, rPath);
|
||||
|
||||
if(folder.length()<2)
|
||||
return g_rootFolder;
|
||||
else if(folder.length() <1)
|
||||
return (IFolder*)0;
|
||||
if(rPath.length()<2)
|
||||
{
|
||||
if (folder == g_rootFolder->Name)
|
||||
return g_rootFolder;
|
||||
else
|
||||
return g_rootFolder->GetFolder(folder);
|
||||
}
|
||||
else
|
||||
{
|
||||
IFolder* f = g_rootFolder;
|
||||
IFolder* t;
|
||||
do
|
||||
{
|
||||
GetRootFolderS(rPath, folder, rPath);
|
||||
t = f->GetFolder(folder);
|
||||
if(t)
|
||||
{
|
||||
f = t;
|
||||
}
|
||||
else
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
while(rPath.length()>1);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
IFile* IFileSystem::GetFile(const String& path)
|
||||
{
|
||||
String dir = GetFilePath(path, String(_text("/")));
|
||||
String file = GetFileName(path, String(_text("/")));
|
||||
IFolder* f = GetFolder(dir);
|
||||
if(f)
|
||||
return f->GetFile(file);
|
||||
return (IFile*)0;
|
||||
}*/
|
||||
int IFileSystem::NewFile(const String& path, int size)
|
||||
{
|
||||
String dir = GetFilePath(path, String(_text("/")));
|
||||
String fileName = GetFileName(path, String(_text("/")));
|
||||
IFolder* f;
|
||||
if(GetFolder(dir, &f) != SC_OK)
|
||||
{
|
||||
if(this->CreateFolder(dir) != SC_OK)
|
||||
return SC_FAIL;
|
||||
|
||||
if(GetFolder(dir, &f) != SC_OK)
|
||||
return SC_FAIL;
|
||||
}
|
||||
|
||||
IFile* file;
|
||||
if(f->GetFile(fileName, &file) != SC_OK)
|
||||
f->NewFile(fileName, size);
|
||||
|
||||
return SC_OK;
|
||||
}
|
||||
int IFileSystem::CreateFolder(const String& path)
|
||||
{
|
||||
String folder, rPath;
|
||||
IFolder* f;
|
||||
GetRootFolderS(path, folder, rPath);
|
||||
if(folder == g_rootFolder->Name)
|
||||
f = g_rootFolder;
|
||||
else
|
||||
return SC_FAIL;
|
||||
|
||||
do
|
||||
{
|
||||
GetRootFolderS(rPath, folder, rPath);
|
||||
if(folder == STR(""))
|
||||
return SC_OK;
|
||||
else
|
||||
{
|
||||
if(f->GetFolder(folder, &f) != SC_OK)
|
||||
{
|
||||
f = f->NewFolder(folder);
|
||||
}
|
||||
}
|
||||
} while (rPath != STR(""));
|
||||
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
int IFileSystem::GetFile(const String& path, IFile** file)
|
||||
{
|
||||
String dir = GetFilePath(path, String(_text("/")));
|
||||
String fileName = GetFileName(path, String(_text("/")));
|
||||
IFolder* f;
|
||||
if(GetFolder(dir, &f) == SC_OK)
|
||||
return f->GetFile(fileName, file);
|
||||
|
||||
return SC_FAIL;
|
||||
}
|
||||
int IFileSystem::GetFolder(const String& path, IFolder** output)
|
||||
{
|
||||
String folder, rPath;
|
||||
GetRootFolderS(path, folder, rPath);
|
||||
|
||||
if(folder.length()<2)
|
||||
{
|
||||
(*output) = g_rootFolder;
|
||||
return SC_OK;
|
||||
}
|
||||
else if(folder.length() < 1)
|
||||
{
|
||||
return SC_FAIL;
|
||||
}
|
||||
if(rPath.length()<2)
|
||||
{
|
||||
if (folder == g_rootFolder->Name)
|
||||
{
|
||||
(*output) = g_rootFolder;
|
||||
return SC_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_rootFolder->GetFolder(folder, output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IFolder* f = g_rootFolder;
|
||||
IFolder* t;
|
||||
do
|
||||
{
|
||||
GetRootFolderS(rPath, folder, rPath);
|
||||
if(f->GetFolder(folder, &t) == SC_OK)
|
||||
{
|
||||
f = t;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*output) = f;
|
||||
return SC_OK;
|
||||
}
|
||||
}
|
||||
while(rPath.length() > 1);
|
||||
(*output) = f;
|
||||
return SC_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#ifndef IFILESYSTEM_H__
|
||||
#define IFILESYSTEM_H__
|
||||
|
||||
#include "../IDataStream.h"
|
||||
#include "IContentProvider.h"
|
||||
#include "../LString.h"
|
||||
#include "IFolder.h"
|
||||
#include "../Types.h"
|
||||
#include <vector>
|
||||
#include "../Error.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IFileSystem
|
||||
{
|
||||
public:
|
||||
static const int IOBufferSize = 4096;
|
||||
String StorageName;
|
||||
int StorageID;
|
||||
IFolder* GetRootFolder()
|
||||
{
|
||||
return g_rootFolder;
|
||||
}
|
||||
IFileSystem(IFolder* rootFolder)
|
||||
{
|
||||
g_rootFolder = rootFolder;
|
||||
}
|
||||
~IFileSystem()
|
||||
{
|
||||
if(g_rootFolder)
|
||||
delete g_rootFolder;
|
||||
}
|
||||
int FileExists(String path)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int GetFile(const String& path, IFile** file);
|
||||
int GetFolder(const String& path, IFolder** output);
|
||||
|
||||
int NewFile(const String& path, int size);
|
||||
int CreateFolder(const String& path);
|
||||
|
||||
/*IFile* GetFile(const String& path);
|
||||
IFolder* GetFolder(const String& path);*/
|
||||
|
||||
void ReadFile(const String& src, void* buffer)
|
||||
{
|
||||
IFile* f1;
|
||||
|
||||
this->GetFile(src, &f1);
|
||||
|
||||
IDataStreamPtr srcStm = f1->OpenRead();
|
||||
|
||||
srcStm->Read(buffer, srcStm->Length());
|
||||
srcStm->Close();
|
||||
//f1->Close();
|
||||
}
|
||||
private:
|
||||
LifeCore::IFolder* g_rootFolder;
|
||||
std::vector<LifeCore::IFolder*> g_folders;
|
||||
byte g_ioBuffer[IOBufferSize];
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
#ifndef IFOLDER_H__
|
||||
#define IFOLDER_H__
|
||||
|
||||
#include "../IDataStream.h"
|
||||
#include "../LString.h"
|
||||
#include "IFile.h"
|
||||
#include <map>
|
||||
#include "../Error.h"
|
||||
#include "../log/CLog.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IFolder
|
||||
{
|
||||
public:
|
||||
IFolder()
|
||||
:g_parent(0)
|
||||
{folderCount=0;
|
||||
fileCount=0;
|
||||
}
|
||||
virtual ~IFolder(void){}
|
||||
virtual IFolder* NewFolder(const String& name) = 0;
|
||||
virtual IFile* NewFile(const String& name, int size) = 0;
|
||||
|
||||
int ID;
|
||||
String Name;
|
||||
int folderCount, fileCount;
|
||||
IFolder* getParent(){return g_parent;}
|
||||
void setParent(IFolder* parent){g_parent = parent;}
|
||||
String getPath()
|
||||
{
|
||||
if (g_parent)
|
||||
return g_parent->getPath() + _text("/") + this->Name;
|
||||
else
|
||||
return this->Name;
|
||||
}
|
||||
void AddFolder(IFolder* f)
|
||||
{
|
||||
if (f)
|
||||
{
|
||||
//g_folderCollection.insert(FolderPair(f->Name,f));
|
||||
g_folderCollection[f->Name] = f;
|
||||
f->setParent(this);
|
||||
folderCount++;
|
||||
}
|
||||
}
|
||||
void AddFile(IFile* file)
|
||||
{
|
||||
g_fileCollection[file->FileName] = file;
|
||||
fileCount++;
|
||||
//file->setParent(this);
|
||||
}
|
||||
bool FileExists(const String& name)
|
||||
{
|
||||
FileMapIterator it = g_fileCollection.find(name);
|
||||
|
||||
return (it != g_fileCollection.end());
|
||||
}
|
||||
bool FolderExists(const String& name)
|
||||
{
|
||||
FolderMapIterator it = g_folderCollection.find(name);
|
||||
|
||||
return (it != g_folderCollection.end());
|
||||
}
|
||||
int GetFolder(const String& name, LifeCore::IFolder** output)
|
||||
{
|
||||
LifeCore::IFolder* f = g_folderCollection[name];
|
||||
if(f)
|
||||
{
|
||||
(*output) = f;
|
||||
return SC_OK;
|
||||
}
|
||||
return SC_FAIL;
|
||||
}
|
||||
LifeCore::IFolder* GetFolder(int index)
|
||||
{
|
||||
FolderMap::iterator it = g_folderCollection.begin();
|
||||
std::advance(it, index);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
IFile* GetFile(int index)
|
||||
{
|
||||
FileMap::iterator it = g_fileCollection.begin();
|
||||
std::advance(it, index);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int GetFile(const String& name, IFile** output)
|
||||
{
|
||||
IFile* file = g_fileCollection[name];
|
||||
if(file)
|
||||
{
|
||||
(*output) = file;
|
||||
return SC_OK;
|
||||
}
|
||||
(*output) = 0;
|
||||
/*String msg = STR("Could not find file ") + name;
|
||||
//LOG_ERROR(msg,)
|
||||
CLog::me()->Write(msg);
|
||||
system("pause");
|
||||
exit(0);*/
|
||||
return SC_FAIL;
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::map<String, IFile*> FileMap;
|
||||
typedef std::pair<String, IFile*> FilePair;
|
||||
typedef std::map<String, IFile*>::const_iterator FileMapIterator;
|
||||
|
||||
typedef std::map<String, IFolder*> FolderMap;
|
||||
typedef std::pair<String, IFolder*> FolderPair;
|
||||
typedef std::map<String, IFolder*>::const_iterator FolderMapIterator;
|
||||
FileMap g_fileCollection;
|
||||
FolderMap g_folderCollection;
|
||||
IFolder* g_parent;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef ROOT_FOLDER_H__
|
||||
#define ROOT_FOLDER_H__
|
||||
|
||||
#include "vfs/IFolder.h"
|
||||
#include "log/CLog.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class RootFolder : public IFolder
|
||||
{
|
||||
public:
|
||||
RootFolder(){}
|
||||
~RootFolder(void){}
|
||||
IFolder* NewFolder(const String& name){printf("Can not create folder in root! Folder: %s\n", name.c_str()); return 0;};
|
||||
IFile* NewFile(const String& name, int size) {printf("Can not create file in root! File: %s\n", name.c_str());return 0;};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "WinFileStream.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
WinFileStream::WinFileStream(const String& path)
|
||||
:hFile(0)
|
||||
{
|
||||
hFile = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
WinFileStream::~WinFileStream()
|
||||
{
|
||||
if(hFile)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
}
|
||||
void WinFileStream::Close()
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
hFile = NULL;
|
||||
}
|
||||
size_t WinFileStream::Read(void* pBuffer, size_t countBytes)
|
||||
{
|
||||
unsigned long countRead = 0;
|
||||
ReadFile(hFile, pBuffer, countBytes, &countRead, NULL);
|
||||
return (int)countRead;
|
||||
}
|
||||
size_t WinFileStream::Write(const void* pBuffer, size_t countBytes)
|
||||
{
|
||||
unsigned long countWrite = 0;
|
||||
WriteFile(hFile, pBuffer, countBytes, &countWrite, NULL);
|
||||
return (int)countWrite;
|
||||
}
|
||||
void WinFileStream::Seek(int position)
|
||||
{
|
||||
SetFilePointer(hFile, position, NULL, SEEK_SET);
|
||||
}
|
||||
size_t WinFileStream::Tell()
|
||||
{
|
||||
return SetFilePointer(hFile, 0, NULL, SEEK_CUR);
|
||||
}
|
||||
size_t WinFileStream::Length()
|
||||
{
|
||||
int pos = Tell();
|
||||
int length = SetFilePointer(hFile, 0, NULL, SEEK_END);
|
||||
SetFilePointer(hFile, pos, NULL, SEEK_SET);
|
||||
return length;
|
||||
}
|
||||
bool WinFileStream::CanRead()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool WinFileStream::CanWrite()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef WinFileStream_h__
|
||||
#define WinFileStream_h__
|
||||
#include "../IDataStream.h"
|
||||
#include "../LString.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class WinFileStream : public IDataStream
|
||||
{
|
||||
public:
|
||||
WinFileStream(const String& path);
|
||||
~WinFileStream();
|
||||
void Close();
|
||||
size_t Read(void* pBuffer, size_t countBytes);
|
||||
size_t Write(const void* pBuffer, size_t countBytes);
|
||||
void Seek(int position);
|
||||
size_t Tell();
|
||||
size_t Length();
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
private:
|
||||
HANDLE hFile;
|
||||
};
|
||||
}
|
||||
#endif // WinFileStream_h__
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "IFSContentProvider.h"
|
||||
#include "../../log/CLog.h"
|
||||
namespace LifeCore
|
||||
{
|
||||
static const String pakPathSplitter(_text("\\"));
|
||||
|
||||
IFSContentProvider::IFSContentProvider(const String& file)
|
||||
{
|
||||
IFSFolder* folder = new IFSFolder();
|
||||
g_rootFolder = file;
|
||||
folder->Provider = this;
|
||||
folder->Name = GetDirectoryName(file);
|
||||
|
||||
folder->EntryName = file;
|
||||
|
||||
fileSystem = new IFileSystem(folder);
|
||||
|
||||
IFolder* root = fileSystem->GetRootFolder();
|
||||
|
||||
//printf("%s", file.c_str());
|
||||
ScanDir(file, root);
|
||||
}
|
||||
IFSContentProvider::~IFSContentProvider()
|
||||
{
|
||||
if(fileSystem)
|
||||
delete fileSystem;
|
||||
}
|
||||
void IFSContentProvider::ScanDir( String path, IFolder* directory)
|
||||
{
|
||||
WIN32_FIND_DATA FindData;
|
||||
String modified_address = path;
|
||||
DWORD tmp = 0;
|
||||
modified_address += _text("*");
|
||||
HANDLE Handle = FindFirstFile(modified_address.c_str() , &FindData);
|
||||
while( FindNextFile(Handle, &FindData) )
|
||||
{
|
||||
String file_name = FindData.cFileName;
|
||||
if( FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
||||
{
|
||||
if(STRCMP(FindData.cFileName, _text("..")))
|
||||
{
|
||||
String new_path = path;
|
||||
new_path += file_name;
|
||||
new_path += _text("\\");
|
||||
|
||||
IFSFolder* folder = new IFSFolder();
|
||||
folder->Provider = this;
|
||||
folder->Name = file_name;
|
||||
folder->EntryName = new_path;
|
||||
directory->AddFolder(folder);
|
||||
ScanDir( new_path, folder );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
String filepath = path + file_name;
|
||||
HANDLE hf = CreateFile(filepath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
IFSFile* file = new IFSFile();
|
||||
file->FileName = file_name;
|
||||
file->Provider = this;
|
||||
file->Size = GetFileSize(hf,&tmp);
|
||||
file->EntryName = filepath;
|
||||
directory->AddFile(file);
|
||||
CloseHandle(hf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef IFSCONTENTPROVIDER_H__
|
||||
#define IFSCONTENTPROVIDER_H__
|
||||
|
||||
#include "../IContentProvider.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFileSystem.h"
|
||||
#include "IFSFolder.h"
|
||||
#include <windows.h>
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IFSContentProvider : public IContentProvider
|
||||
{
|
||||
public:
|
||||
~IFSContentProvider();
|
||||
void Close(){}
|
||||
IFileSystem* getFileSystem(){return fileSystem;}
|
||||
IFSContentProvider(const String& file);
|
||||
String g_rootFolder;
|
||||
IFileSystem* fileSystem;
|
||||
|
||||
private:
|
||||
void ScanDir( String path, IFolder* directory);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "IFSFile.h"
|
||||
#include "IFSContentProvider.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
IFSFile::IFSFile()
|
||||
{
|
||||
}
|
||||
IFSFile::IFSFile(const String& path, int size)
|
||||
{
|
||||
isOpen = false;
|
||||
EntryName = path;
|
||||
HANDLE file = CreateFileA(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
if(size > 0)
|
||||
{
|
||||
SetFilePointer(file, size - 1, 0, FILE_BEGIN);
|
||||
char data = 0;
|
||||
DWORD numWrite = 0;
|
||||
WriteFile(file, &data, 1, &numWrite, NULL);
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
bool IFSFile::ReadAsync(char* buffer, size_t count_read)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(buffer);
|
||||
UNREFERENCED_PARAMETER(count_read);
|
||||
//TODO read!
|
||||
return true;
|
||||
}
|
||||
IDataStreamPtr IFSFile::OpenWrite(int mode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(mode);
|
||||
g_stream = new IFSStream(EntryName, FA_WRITE, this->Size);
|
||||
return IDataStreamPtr(g_stream);
|
||||
}
|
||||
IDataStreamPtr IFSFile::OpenReadWrite(int mode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(mode);
|
||||
return IDataStreamPtr(0);
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IDataStreamPtr IFSFile::OpenRead()
|
||||
{
|
||||
g_stream = new IFSStream(EntryName, FA_READ, this->Size);
|
||||
return IDataStreamPtr(g_stream);
|
||||
//g_stream = new IZipStream((this->Provider as IZipFileContentProvider).GetSource(), EntryName, FA_READ);
|
||||
//return g_stream;
|
||||
}
|
||||
void IFSFile::Close()
|
||||
{
|
||||
if(g_stream)
|
||||
{
|
||||
g_stream->Close();
|
||||
delete g_stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef IFSFILE_H__
|
||||
#define IFSFILE_H__
|
||||
|
||||
//#include "IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFile.h"
|
||||
#include "IFSStream.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IFSFile : public IFile
|
||||
{
|
||||
public:
|
||||
IFSFile();
|
||||
IFSFile(const String& path, int size);
|
||||
~IFSFile(){}
|
||||
String EntryName;
|
||||
bool ReadAsync(char* buffer, size_t count_read);
|
||||
IDataStreamPtr OpenWrite(int mode);
|
||||
IDataStreamPtr OpenReadWrite(int mode);
|
||||
IDataStreamPtr OpenRead();
|
||||
void Close();
|
||||
private:
|
||||
int offsetIndex;
|
||||
IFSStream* g_stream;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "IFSFolder.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
IFSFolder::~IFSFolder(void)
|
||||
{
|
||||
for( FolderMap::iterator it = g_folderCollection.begin(); it != g_folderCollection.end(); it++ )
|
||||
delete it->second;
|
||||
}
|
||||
IFSFolder::IFSFolder()
|
||||
|
||||
{
|
||||
}
|
||||
IFSFolder::IFSFolder(const String& folderName, const String& entryName)
|
||||
{
|
||||
this->Name = folderName;
|
||||
this->EntryName = entryName;
|
||||
|
||||
CreateDirectoryA(EntryName.c_str(), NULL);
|
||||
}
|
||||
IFolder* IFSFolder::NewFolder(const String& name)
|
||||
{
|
||||
IFolder* test;
|
||||
if(this->GetFolder(name, &test) != SC_OK)
|
||||
{
|
||||
IFSFolder* newFolder = new IFSFolder(name, this->EntryName + name + _text("\\"));
|
||||
newFolder->setParent(this);
|
||||
newFolder->Provider = this->Provider;
|
||||
this->AddFolder(newFolder);
|
||||
return newFolder;
|
||||
}
|
||||
else
|
||||
{
|
||||
return test;
|
||||
}
|
||||
}
|
||||
IFile* IFSFolder::NewFile(const String& name, int size)
|
||||
{
|
||||
IFile* f;
|
||||
if(this->GetFile(name, &f) != SC_OK)
|
||||
{
|
||||
IFSFile* newFile = new IFSFile(this->EntryName + name, size);
|
||||
newFile->FileName = name;
|
||||
newFile->Provider = this->Provider;
|
||||
this->AddFile(newFile);
|
||||
return newFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef IFSFOLDER_H__
|
||||
#define IFSFOLDER_H__
|
||||
|
||||
#include "../../IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFolder.h"
|
||||
#include "IFSFile.h"
|
||||
#include "../IContentProvider.h"
|
||||
#include <map>
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IFSFolder : public IFolder
|
||||
{
|
||||
public:
|
||||
IFSFolder();
|
||||
IFSFolder(const String& folderName, const String& entryName);
|
||||
~IFSFolder(void);
|
||||
IContentProvider* Provider;
|
||||
String EntryName;
|
||||
IFolder* NewFolder(const String& name);
|
||||
IFile* NewFile(const String& name, int size);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef IFSSTREAM_H__
|
||||
#define IFSSTREAM_H__
|
||||
|
||||
#include "../../IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IFSStream : public IDataStream
|
||||
{
|
||||
private:
|
||||
int openMode;
|
||||
size_t stmLength;
|
||||
HANDLE pFile;
|
||||
public:
|
||||
~IFSStream()
|
||||
{
|
||||
//printf("DESTRUCTING WIN FILE STREAM\n");
|
||||
Close();
|
||||
}
|
||||
void Close()
|
||||
{
|
||||
//printf("CLOSING WIN FILE STREAM\n");
|
||||
if(pFile)
|
||||
CloseHandle(pFile);
|
||||
pFile = (HANDLE)0;
|
||||
}
|
||||
IFSStream(String& path, int fileAccessMode, size_t size)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(size);
|
||||
this->stmLength = 0;
|
||||
openMode = fileAccessMode;
|
||||
if (fileAccessMode == FA_READ)
|
||||
{
|
||||
pFile = CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pFile = CreateFileA(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
|
||||
this->stmLength = SetFilePointer(pFile, 0, NULL, FILE_END);
|
||||
SetFilePointer(pFile, 0, NULL, FILE_BEGIN);
|
||||
}
|
||||
size_t Read(void* pBuffer, size_t countBytes)
|
||||
{
|
||||
DWORD numBytes = 0;
|
||||
|
||||
ReadFile(pFile,pBuffer,countBytes, &numBytes, NULL);
|
||||
return numBytes;
|
||||
}
|
||||
size_t Write(const void* pBuffer, size_t countBytes)
|
||||
{
|
||||
DWORD numBytes = 0;
|
||||
WriteFile(pFile,pBuffer,countBytes,&numBytes, NULL);
|
||||
return numBytes;
|
||||
}
|
||||
void Seek(size_t position)
|
||||
{
|
||||
SetFilePointer(pFile, position, NULL, FILE_BEGIN);
|
||||
}
|
||||
size_t Tell()
|
||||
{
|
||||
return SetFilePointer(pFile, 0, NULL, FILE_CURRENT);
|
||||
}
|
||||
size_t Length()
|
||||
{
|
||||
int pos = Tell();
|
||||
int length = SetFilePointer(pFile, 0, NULL, SEEK_END);
|
||||
SetFilePointer(pFile, pos, NULL, SEEK_SET);
|
||||
return length;
|
||||
}
|
||||
bool CanRead()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool CanWrite()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "IPakFile.h"
|
||||
#include "IPakFileContentProvider.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
IPakFile::IPakFile()
|
||||
{
|
||||
isOpen = false;
|
||||
}
|
||||
IDataStreamPtr IPakFile::OpenWrite(int mode)
|
||||
{
|
||||
printf("ow->mode: %i\n", mode);
|
||||
g_stream = new IPakStream(&((IPakFileContentProvider*)this->Provider)->g_sourceFile, EntryName, FA_WRITE);
|
||||
return IDataStreamPtr(g_stream);
|
||||
}
|
||||
IDataStreamPtr IPakFile::OpenReadWrite(int mode)
|
||||
{
|
||||
printf("or->mode: %i\n", mode);
|
||||
return IDataStreamPtr(0);
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IDataStreamPtr IPakFile::OpenRead()
|
||||
{
|
||||
IPakFileContentProvider* prov = (IPakFileContentProvider*)this->Provider;
|
||||
g_stream = new IPakStream(&prov->g_sourceFile, EntryName, FA_READ);
|
||||
return IDataStreamPtr(g_stream);
|
||||
//g_stream = new IZipStream((this->Provider as IZipFileContentProvider).GetSource(), EntryName, FA_READ);
|
||||
//return g_stream;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef IPAKFILE_H__
|
||||
#define IPAKFILE_H__
|
||||
|
||||
//#include "IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFile.h"
|
||||
#include "IPakStream.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IPakFile : public IFile
|
||||
{
|
||||
public:
|
||||
IPakFile();
|
||||
~IPakFile(){}
|
||||
String EntryName;
|
||||
IDataStreamPtr OpenWrite(int mode);
|
||||
IDataStreamPtr OpenReadWrite(int mode);
|
||||
IDataStreamPtr OpenRead();
|
||||
private:
|
||||
int offsetIndex;
|
||||
IPakStream* g_stream;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "IPakFileContentProvider.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
static const String pakPathSplitter(_text("/"));
|
||||
|
||||
IPakFileContentProvider::IPakFileContentProvider(IDataStream* pakFile, const String& name)
|
||||
{
|
||||
IPakFolder* folder = new IPakFolder();
|
||||
// g_rootFolder = pakFile;
|
||||
folder->Provider = this;
|
||||
folder->Name = name;
|
||||
|
||||
folder->EntryName = _text("");
|
||||
|
||||
fileSystem = new IFileSystem(folder);
|
||||
|
||||
g_sourceFile.Open(pakFile);
|
||||
|
||||
fileSystem->GetRootFolder();
|
||||
BuildTree();
|
||||
}
|
||||
void IPakFileContentProvider::BuildTree()
|
||||
{
|
||||
//g_sourceFile.LocateEntry(0);
|
||||
int numFiles = g_sourceFile.filesCount();
|
||||
|
||||
for (int i = 0; i < numFiles; i++)
|
||||
{
|
||||
//g_sourceFile.LocateEntry(i);
|
||||
entry_info info = g_sourceFile.GetEntryInfo(i);
|
||||
|
||||
String p = GetPakPathWithoutFilename(info.fileName);
|
||||
|
||||
IPakFolder* folder;
|
||||
|
||||
if(this->fileSystem->GetFolder(p, (IFolder**)&folder) != SC_OK)
|
||||
{
|
||||
printf("Failed to get folder! IPakFileContentProvider::BuildTree\n");
|
||||
return;
|
||||
}
|
||||
|
||||
IPakFile* file = new IPakFile();
|
||||
file->FileName = GetFileName(info.fileName, pakPathSplitter);
|
||||
file->Provider = this;
|
||||
file->Size = info.fileSize;
|
||||
file->EntryName = info.fileName;
|
||||
folder->AddFile(file);
|
||||
|
||||
//g_sourceFile.CloseCurrentEntry();
|
||||
}
|
||||
|
||||
//print folder tree
|
||||
String tab(_text("\t"));
|
||||
int cnt = fileSystem->GetRootFolder()->folderCount;
|
||||
for(int i = 0; i < cnt; i++)
|
||||
{
|
||||
IFolder* fld = fileSystem->GetRootFolder()->GetFolder(i);
|
||||
PRINT(_text("%s\n"), fld->Name.c_str());
|
||||
PRINT(_text("Files count: %i\n"), fld->fileCount);
|
||||
}
|
||||
}
|
||||
|
||||
String IPakFileContentProvider::GetPakPathWithoutFilename(const String& path)
|
||||
{
|
||||
int offset = path.find_last_of(_text("/"));
|
||||
if(offset>=0)
|
||||
{
|
||||
return path.substr(0, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _text("/");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef IPAKFILECONTENTPROVIDER_H__
|
||||
#define IPAKFILECONTENTPROVIDER_H__
|
||||
|
||||
#include "../IContentProvider.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFileSystem.h"
|
||||
#include "pak_io/PakFile.h"
|
||||
#include "IPakFolder.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IPakFileContentProvider : public IContentProvider
|
||||
{
|
||||
public:
|
||||
~IPakFileContentProvider(){};
|
||||
void Close(){}
|
||||
IFileSystem* getFileSystem(){return fileSystem;}
|
||||
IPakFileContentProvider(IDataStream* pakFile, const String& name);
|
||||
String g_rootFolder;
|
||||
PakFile g_sourceFile;
|
||||
IFileSystem* fileSystem;
|
||||
|
||||
private:
|
||||
void BuildTree();
|
||||
String GetPakPathWithoutFilename(const String& path);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "IPakFolder.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
IPakFolder::~IPakFolder(void)
|
||||
{
|
||||
for( FolderMap::iterator it = g_folderCollection.begin(); it != g_folderCollection.end(); it++ )
|
||||
delete it->second;
|
||||
}
|
||||
IFolder* IPakFolder::NewFolder(const String& name)
|
||||
{
|
||||
IPakFolder* newFolder = new IPakFolder();
|
||||
newFolder->Name = name;
|
||||
newFolder->setParent(this);
|
||||
newFolder->EntryName = this->EntryName + name + _text("/");
|
||||
newFolder->Provider = this->Provider;
|
||||
this->AddFolder(newFolder);
|
||||
return newFolder;
|
||||
}
|
||||
IFile* IPakFolder::NewFile(const String& name, int size)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(size);
|
||||
IFile* newFile = new IPakFile();
|
||||
newFile->FileName = name;
|
||||
newFile->Provider = this->Provider;
|
||||
IPakFile* xf = (IPakFile*)newFile;
|
||||
xf->EntryName = this->EntryName + name;
|
||||
this->AddFile(newFile);
|
||||
return newFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef IPAKFOLDER_H__
|
||||
#define IPAKFOLDER_H__
|
||||
|
||||
#include "../../IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFolder.h"
|
||||
#include "IPakFile.h"
|
||||
#include "../IContentProvider.h"
|
||||
#include <map>
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IPakFolder : public IFolder
|
||||
{
|
||||
public:
|
||||
~IPakFolder(void);
|
||||
IContentProvider* Provider;
|
||||
String EntryName;
|
||||
IFolder* NewFolder(const String& name);
|
||||
IFile* NewFile(const String& name, int size);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef IPAKSTREAM_H__
|
||||
#define IPAKSTREAM_H__
|
||||
|
||||
#include "../../IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include <assert.h>
|
||||
#include "pak_io/PakFile.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IPakStream : public IDataStream
|
||||
{
|
||||
private:
|
||||
PakFile* source;
|
||||
entry_info info;
|
||||
int openMode;
|
||||
size_t stmLength;
|
||||
PakEntryHandle entry;
|
||||
public:
|
||||
~IPakStream(){}
|
||||
void Close()
|
||||
{
|
||||
source->fclose(entry);
|
||||
openMode = 0;
|
||||
}
|
||||
IPakStream(PakFile* file, String& entryName, int fileAccessMode)
|
||||
{
|
||||
source = file;
|
||||
openMode = fileAccessMode;
|
||||
// source->CloseCurrentEntry();
|
||||
if (fileAccessMode == FA_READ)
|
||||
{
|
||||
entry = source->fopen(entryName);
|
||||
// source->LocateEntry(entry);
|
||||
//info = source->GetEntryInfo();
|
||||
stmLength = source->fget_size(entry);
|
||||
//source->OpenCurrentEntry();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Creation of new PAK entry is not implemented! IPakStream.h";
|
||||
//source->NewFileEntry(entry);
|
||||
}
|
||||
}
|
||||
size_t Read(void* pBuffer, size_t countBytes)
|
||||
{
|
||||
return source->fread(entry, pBuffer, countBytes);
|
||||
}
|
||||
size_t Write(const void* pBuffer, size_t countBytes)
|
||||
{
|
||||
source->fwrite(entry, pBuffer, countBytes);
|
||||
return countBytes;
|
||||
}
|
||||
void Seek(size_t position)
|
||||
{
|
||||
source->fseek(entry, position);
|
||||
}
|
||||
size_t Tell()
|
||||
{
|
||||
return source->ftell(entry);
|
||||
}
|
||||
size_t Length()
|
||||
{
|
||||
return source->fget_size(entry);
|
||||
}
|
||||
bool CanRead()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool CanWrite()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef ENTRY_INFO_H__
|
||||
#define ENTRY_INFO_H__
|
||||
#include "PakTypes.h"
|
||||
|
||||
#define MAX_ENTRY_NAME_LENGTH 0x100
|
||||
|
||||
typedef struct entry_info
|
||||
{
|
||||
int fileSize;
|
||||
tchar fileName[MAX_ENTRY_NAME_LENGTH];
|
||||
}entry_info;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "../../../LString.h"
|
||||
|
||||
#define MAX_ENTRY_NAME_LENGTH 0x100
|
||||
|
||||
typedef struct FileEntry
|
||||
{
|
||||
int parentIndex;
|
||||
int fileSize;
|
||||
int fileOffset;
|
||||
tchar name[MAX_ENTRY_NAME_LENGTH];
|
||||
}FileEntry, *PFileEntry, **LPFileEntry;
|
||||
@@ -0,0 +1,6 @@
|
||||
#define MAX_ENTRY_NAME_LENGTH 0x100
|
||||
|
||||
typedef struct FolderEntry
|
||||
{
|
||||
wchar_t name[MAX_ENTRY_NAME_LENGTH];
|
||||
}FolderEntry;
|
||||
@@ -0,0 +1,312 @@
|
||||
#include "PakFile.h"
|
||||
#include <assert.h>
|
||||
#include "../../../log/CLog.h"
|
||||
namespace LifeCore
|
||||
{
|
||||
PakFile::PakFile(void)
|
||||
:openEntriesCount(0)
|
||||
{
|
||||
currentMode = PM_IDLE;
|
||||
memset(&openEntries[0], 0, sizeof(OpenEntryInfo) * PAK_MAX_OPEN_ENTRY);
|
||||
}
|
||||
|
||||
PakFile::~PakFile(void)
|
||||
{
|
||||
}
|
||||
|
||||
int PakFile::Open(IDataStream* source)
|
||||
{
|
||||
curEntryId = 0;
|
||||
pFile = source;
|
||||
//
|
||||
// pFile = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(pFile->Length() == 0)
|
||||
{
|
||||
//write default header to created file
|
||||
header.version = PAK_VERSION;
|
||||
header.whiteSpacesCount = 0;
|
||||
header.filesCount = 0;
|
||||
header.foldersCount = 0;
|
||||
header.lastFolderId = 0;
|
||||
header.dataChunkLength = 0;
|
||||
header.extraDataOffset = sizeof(PakHeader);
|
||||
|
||||
pFile->Seek(header.extraDataOffset);
|
||||
// SetFilePointer(pFile, header.extraDataOffset, NULL, FILE_BEGIN);
|
||||
|
||||
freeFileSlots = 16;
|
||||
hFiles = (FileEntry*)malloc(sizeof(FileEntry) * 16);
|
||||
tmpEntry = hFiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD numWrite = 0;
|
||||
//read file header
|
||||
numWrite = pFile->Read(&header,sizeof(PakHeader));
|
||||
//ReadFile(pFile,&header,sizeof(PakHeader), &numWrite, NULL);
|
||||
|
||||
if(header.version != PAK_VERSION)
|
||||
{
|
||||
//CloseHandle(pFile);
|
||||
//pFile->Close();
|
||||
return PAK_BAD_FILE;
|
||||
}
|
||||
|
||||
pFile->Seek(header.extraDataOffset);
|
||||
|
||||
//read folder entries
|
||||
int cntAlloc;
|
||||
cntAlloc = header.foldersCount > 0 ? header.foldersCount : 16;
|
||||
freeFolderSlots = header.foldersCount > 0 ? 0 : 16;
|
||||
hFolders = (FolderEntry*)malloc(sizeof(FolderEntry) * cntAlloc);
|
||||
|
||||
pFile->Read(hFolders, sizeof(FolderEntry) * header.foldersCount);
|
||||
//ReadFile(pFile, hFolders, sizeof(FolderEntry) * header.foldersCount, &numWrite, NULL);
|
||||
|
||||
//read file entries
|
||||
cntAlloc = header.filesCount > 0 ? header.filesCount : 16;
|
||||
freeFileSlots = header.filesCount > 0 ? 0 : 16;
|
||||
hFiles = (FileEntry*)malloc(sizeof(FileEntry) * cntAlloc);
|
||||
|
||||
pFile->Read(hFiles, sizeof(FileEntry) * header.filesCount);
|
||||
//ReadFile(pFile, hFiles, sizeof(FileEntry) * header.filesCount, &numWrite, NULL);
|
||||
|
||||
tmpEntry = hFiles;
|
||||
}
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
void PakFile::DumpExtraData()
|
||||
{
|
||||
pFile->Seek(sizeof(PakHeader) + header.dataChunkLength);
|
||||
if(header.foldersCount > 0){
|
||||
pFile->Write(hFolders, sizeof(FolderEntry) * header.foldersCount);
|
||||
}
|
||||
|
||||
if(header.filesCount > 0)
|
||||
{
|
||||
pFile->Write(hFiles, sizeof(FileEntry) * header.filesCount);
|
||||
}
|
||||
}
|
||||
|
||||
void PakFile::DumpHeader()
|
||||
{
|
||||
DWORD numWrite = 0;
|
||||
pFile->Seek(0);
|
||||
//SetFilePointer(pFile, 0, NULL, FILE_BEGIN);
|
||||
//WriteFile(pFile, &header, sizeof(PakHeader), &numWrite, NULL);
|
||||
numWrite = pFile->Write(&header, sizeof(PakHeader));
|
||||
}
|
||||
|
||||
void PakFile::NewFolderEntry(const String& path)
|
||||
{
|
||||
CLog::me()->Write(path);
|
||||
/*FolderEntry newEntry;
|
||||
memset(newEntry.name,0,sizeof(wchar_t) * MAX_ENTRY_NAME_LENGTH);
|
||||
path.copy(newEntry.name, path.length());
|
||||
FolderCollection[path] = newEntry;
|
||||
header.foldersCount++;*/
|
||||
}
|
||||
PakEntryHandle PakFile::fopen(const String& name)
|
||||
{
|
||||
if(openEntriesCount >= PAK_MAX_OPEN_ENTRY)
|
||||
return -1;
|
||||
|
||||
if(LocateEntry(name) != PAK_OK)
|
||||
return -1;
|
||||
|
||||
openEntries[openEntriesCount].entry = tmpEntry;
|
||||
openEntries[openEntriesCount].position = 0;
|
||||
|
||||
openEntriesCount++;
|
||||
|
||||
return openEntriesCount - 1;
|
||||
}
|
||||
int PakFile::fread(PakEntryHandle entry, void* buffer, int length)
|
||||
{
|
||||
if(entry < 0 || entry >= PAK_MAX_OPEN_ENTRY)
|
||||
return -1;
|
||||
|
||||
OpenEntryInfo* info = &openEntries[entry];
|
||||
|
||||
int maxCnt = info->entry->fileSize - info->position;
|
||||
if(!length || !maxCnt)
|
||||
return 0;
|
||||
if(length > maxCnt)
|
||||
length = maxCnt;
|
||||
|
||||
//SetFilePointer(pFile, info->entry->fileOffset + info->position, NULL, FILE_BEGIN);
|
||||
pFile->Seek(info->entry->fileOffset + info->position);
|
||||
|
||||
DWORD numWrite = 0;
|
||||
numWrite = pFile->Read(buffer, length);
|
||||
//ReadFile(pFile, buffer, length, &numWrite, NULL);
|
||||
curFilePosition +=numWrite;
|
||||
info->position += numWrite;
|
||||
return numWrite;
|
||||
}
|
||||
int PakFile::fwrite(PakEntryHandle entry, const void* buffer, int length)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(entry);
|
||||
UNREFERENCED_PARAMETER(buffer);
|
||||
UNREFERENCED_PARAMETER(length);
|
||||
return 0;
|
||||
}
|
||||
void PakFile::fclose(PakEntryHandle entry)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(entry);
|
||||
}
|
||||
int PakFile::fget_size(PakEntryHandle entry)
|
||||
{
|
||||
if(entry < 0 || entry >= PAK_MAX_OPEN_ENTRY)
|
||||
throw "PAK entry is invalid! Can not seek";
|
||||
|
||||
return openEntries[entry].entry->fileSize;
|
||||
}
|
||||
void PakFile::fseek(PakEntryHandle entry, int position)
|
||||
{
|
||||
if(entry < 0 || entry >= PAK_MAX_OPEN_ENTRY)
|
||||
throw "PAK entry is invalid! Can not seek";
|
||||
|
||||
if(openEntries[entry].entry->fileSize < position || position < 0)
|
||||
throw "Invalid PAK position specified! Fseek()";
|
||||
|
||||
openEntries[entry].position = position;
|
||||
}
|
||||
int PakFile::ftell(PakEntryHandle entry)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if(entry < 0 || entry >= PAK_MAX_OPEN_ENTRY)
|
||||
return -1;
|
||||
#endif
|
||||
return openEntries[entry].position;
|
||||
}
|
||||
void PakFile::NewFileEntry(const String& path)
|
||||
{
|
||||
if(!freeFileSlots)
|
||||
{
|
||||
hFiles = (FileEntry*)realloc(hFiles, sizeof(FileEntry) * header.filesCount + sizeof(FileEntry) * 16);
|
||||
freeFileSlots = 16;
|
||||
}
|
||||
|
||||
//SetFilePointer(pFile, sizeof(PakHeader) + header.dataChunkLength, NULL, FILE_BEGIN);
|
||||
pFile->Seek(sizeof(PakHeader) + header.dataChunkLength);
|
||||
currentMode = PM_WRITE_ENTRY;
|
||||
tmpEntry = hFiles + header.filesCount;
|
||||
header.filesCount++;
|
||||
|
||||
freeFileSlots--;
|
||||
memset(tmpEntry,0,sizeof(FileEntry));
|
||||
path.copy(tmpEntry->name, path.length());
|
||||
tmpEntry->fileOffset = sizeof(PakHeader) + header.dataChunkLength;
|
||||
}
|
||||
|
||||
/*void PakFile::CloseCurrentEntry()
|
||||
{
|
||||
currentMode = PM_IDLE;
|
||||
}
|
||||
void PakFile::WriteCurrentEntry(const void* pData, int length)
|
||||
{
|
||||
DWORD numWrite = 0;
|
||||
//WriteFile(pFile, pData, length, &numWrite, NULL);
|
||||
numWrite = pFile->Write(pData, length);
|
||||
header.dataChunkLength+=length;
|
||||
tmpEntry->fileSize+=length;
|
||||
curFilePosition+=numWrite;
|
||||
}*/
|
||||
int PakFile::LocateEntry(const String& name)
|
||||
{
|
||||
int lastEntry = curEntryId;
|
||||
for(int i = 0; i < header.filesCount; i++)
|
||||
{
|
||||
curEntryId = i;
|
||||
LocateEntry(curEntryId);
|
||||
if(tmpEntry->name == name)
|
||||
return PAK_OK;
|
||||
}
|
||||
curEntryId = lastEntry;
|
||||
LocateEntry(curEntryId);
|
||||
return PAK_ARG_ERROR;
|
||||
}
|
||||
int PakFile::LocateEntry(int id)
|
||||
{
|
||||
if(id >= header.filesCount)
|
||||
return PAK_ARG_ERROR;
|
||||
curEntryId = id;
|
||||
tmpEntry = hFiles + id;
|
||||
return PAK_OK;
|
||||
}
|
||||
void PakFile::Close()
|
||||
{
|
||||
header.extraDataOffset = sizeof(PakHeader) + header.dataChunkLength;
|
||||
DumpHeader();
|
||||
DumpExtraData();
|
||||
}
|
||||
|
||||
void PakFile::DeleteFileEntry(const String& path)
|
||||
{
|
||||
if(LocateEntry(path) == PAK_OK)
|
||||
{
|
||||
if(IsLastEntry(tmpEntry))
|
||||
{
|
||||
header.filesCount--;
|
||||
header.dataChunkLength-= tmpEntry->fileSize;
|
||||
memset(tmpEntry, 0, sizeof(FileEntry));
|
||||
}
|
||||
else
|
||||
{
|
||||
header.filesCount--;
|
||||
memmove(tmpEntry, tmpEntry + 1, (header.filesCount - curEntryId) * sizeof(FileEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOL PakFile::IsLastEntry(const FileEntry* entry)
|
||||
{
|
||||
return (UINT)(entry->fileOffset + entry->fileSize) == sizeof(PakHeader) + header.dataChunkLength;
|
||||
}
|
||||
/*void PakFile::OpenCurrentEntry()
|
||||
{
|
||||
curFilePosition = 0;
|
||||
currentMode = PM_READ_ENTRY;
|
||||
//SetFilePointer(pFile, tmpEntry->fileOffset, NULL, FILE_BEGIN);
|
||||
pFile->Seek(tmpEntry->fileOffset);
|
||||
}
|
||||
int PakFile::ReadCurrentEntry(void *pBuffer, int length)
|
||||
{
|
||||
int maxCnt = tmpEntry->fileSize - curFilePosition;
|
||||
if(!length || !maxCnt)
|
||||
return 0;
|
||||
if(length > maxCnt)
|
||||
length = maxCnt;
|
||||
DWORD numWrite = 0;
|
||||
//ReadFile(pFile, pBuffer, length, &numWrite, NULL);
|
||||
numWrite = pFile->Read(pBuffer, length);
|
||||
|
||||
curFilePosition +=numWrite;
|
||||
return numWrite;
|
||||
}*/
|
||||
/*void PakFile::SeekCurrentEntry(int position)
|
||||
{
|
||||
SetFilePointer(pFile, tmpEntry->fileOffset + position, NULL, FILE_BEGIN);
|
||||
pFile->Seek(tmpEntry->fileOffset + position);
|
||||
curFilePosition = position;
|
||||
}
|
||||
int PakFile::TellCurrentEntry()
|
||||
{
|
||||
return curFilePosition;
|
||||
}*/
|
||||
int PakFile::filesCount()
|
||||
{
|
||||
return header.filesCount;
|
||||
}
|
||||
entry_info PakFile::GetEntryInfo(int id)
|
||||
{
|
||||
if(id < 0 || id >= filesCount())
|
||||
throw "PAK entry is invalid! Can not get info";
|
||||
FileEntry* entry = hFiles + id;
|
||||
entry_info info;
|
||||
strcpy_s(info.fileName, entry->name);
|
||||
info.fileSize = entry->fileSize;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef PAK_FILE_H__
|
||||
#define PAK_FILE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include "../../../LString.h"
|
||||
#include "PakTypes.h"
|
||||
#include <windows.h>
|
||||
#include "pakHeader.h"
|
||||
#include "FolderEntry.h"
|
||||
#include "FileEntry.h"
|
||||
#include "EntryInfo.h"
|
||||
#include "../../../IDataStream.h"
|
||||
#include <map>
|
||||
#define PAK_VERSION 0x0100
|
||||
#define PAK_MAX_OPEN_ENTRY 256
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
struct OpenEntryInfo
|
||||
{
|
||||
FileEntry* entry;
|
||||
int position;
|
||||
};
|
||||
typedef int PakEntryHandle;
|
||||
|
||||
class PakFile
|
||||
{
|
||||
enum PAK_MODE
|
||||
{
|
||||
PM_WRITE_ENTRY = 0,
|
||||
PM_READ_ENTRY = 1,
|
||||
PM_EDIT_ENTRY = 2,
|
||||
PM_IDLE = 3
|
||||
};
|
||||
|
||||
public:
|
||||
PakFile(void);
|
||||
~PakFile(void);
|
||||
int Open(IDataStream* source);
|
||||
|
||||
void Close();
|
||||
int filesCount();
|
||||
entry_info GetEntryInfo(int id);
|
||||
PakEntryHandle fopen(const String& name);
|
||||
int fread(PakEntryHandle entry, void* buffer, int length);
|
||||
int fwrite(PakEntryHandle entry, const void* buffer, int length);
|
||||
int ftell(PakEntryHandle entry);
|
||||
void fseek(PakEntryHandle entry, int position);
|
||||
void fclose(PakEntryHandle entry);
|
||||
int fget_size(PakEntryHandle entry);
|
||||
private:
|
||||
int curFilePosition;
|
||||
int curEntryId;
|
||||
int freeFileSlots;
|
||||
int freeFolderSlots;
|
||||
int currentMode;
|
||||
FolderEntry* hFolders;
|
||||
FileEntry* hFiles;
|
||||
IDataStream* pFile;
|
||||
PakHeader header;
|
||||
void DumpExtraData();
|
||||
void DumpHeader();
|
||||
FileEntry* tmpEntry;
|
||||
|
||||
void NewFolderEntry(const String& path);
|
||||
void NewFileEntry(const String& path);
|
||||
void DeleteFileEntry(const String& path);
|
||||
|
||||
int LocateEntry(const String& name);
|
||||
int LocateEntry(int id);
|
||||
|
||||
OpenEntryInfo openEntries[PAK_MAX_OPEN_ENTRY];
|
||||
int openEntriesCount;
|
||||
|
||||
BOOL IsLastEntry(const FileEntry* entry);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef PAK_TYPES_H__
|
||||
#define PAK_TYPES_H__
|
||||
|
||||
#define PAK_ARG_ERROR (-100)
|
||||
#define PAK_INTERNAL_ERROR (-101)
|
||||
#define PAK_BAD_FILE (-102)
|
||||
#define PAK_OK (0)
|
||||
#include "../../../LString.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define PATH_SPLITTER _text("\\")
|
||||
#else
|
||||
#define PATH_SPLITTER _text("/")
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <vector>
|
||||
|
||||
typedef struct PakHeader
|
||||
{
|
||||
int version;
|
||||
int whiteSpacesCount;
|
||||
int filesCount;
|
||||
int foldersCount;
|
||||
int extraDataOffset;
|
||||
int lastFolderId;
|
||||
int dataChunkLength;
|
||||
} PakHeader;
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
// The following macros define the minimum required platform. The minimum required platform
|
||||
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||
// your application. The macros work by enabling all features available on platform versions up to and
|
||||
// including the version specified.
|
||||
|
||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
|
||||
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "IZipFile.h"
|
||||
#include "IZipFileContentProvider.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
IZipFile::IZipFile()
|
||||
{
|
||||
isOpen = false;
|
||||
}
|
||||
IDataStreamPtr IZipFile::OpenWrite(int mode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(mode);
|
||||
g_stream = new IZipStream(((IZipFileContentProvider*)this->Provider)->g_sourceFile, EntryName, FA_WRITE, ((IZipFileContentProvider*)this->Provider)->g_rootFolder);
|
||||
return IDataStreamPtr(g_stream);
|
||||
}
|
||||
IDataStreamPtr IZipFile::OpenReadWrite(int mode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(mode);
|
||||
throw;
|
||||
//return IDataStreamPtr(0);
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IDataStreamPtr IZipFile::OpenRead()
|
||||
{
|
||||
IZipFileContentProvider* prov = (IZipFileContentProvider*)this->Provider;
|
||||
prov->g_sourceFile = unzOpen(prov->g_rootFolder.c_str());
|
||||
g_stream = new IZipStream(prov->g_sourceFile, EntryName, FA_READ, NULL);
|
||||
return IDataStreamPtr(g_stream);
|
||||
//g_stream = new IZipStream((this->Provider as IZipFileContentProvider).GetSource(), EntryName, FA_READ);
|
||||
//return g_stream;
|
||||
}
|
||||
void IZipFile::Close()
|
||||
{
|
||||
if(g_stream)
|
||||
{
|
||||
g_stream->Close();
|
||||
delete g_stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef IZIPFILE_H__
|
||||
#define IZIPFILE_H__
|
||||
|
||||
//#include "IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFile.h"
|
||||
#include "IZipStream.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IZipFile : public IFile
|
||||
{
|
||||
public:
|
||||
IZipFile();
|
||||
~IZipFile(){}
|
||||
String EntryName;
|
||||
IDataStreamPtr OpenWrite(int mode);
|
||||
IDataStreamPtr OpenReadWrite(int mode);
|
||||
IDataStreamPtr OpenRead();
|
||||
void Close();
|
||||
private:
|
||||
int offsetIndex;
|
||||
IZipStream* g_stream;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "IZipFileContentProvider.h"
|
||||
namespace LifeCore
|
||||
{
|
||||
static const String zipPathSplitter(_text("/"));
|
||||
|
||||
IZipFileContentProvider::IZipFileContentProvider(const String& zipFile)
|
||||
{
|
||||
IZipFolder* folder = new IZipFolder();
|
||||
g_rootFolder = zipFile;
|
||||
folder->Provider = this;
|
||||
folder->Name = GetFileNameWithoutExtention(zipFile);
|
||||
|
||||
folder->EntryName = _text("");
|
||||
|
||||
g_fs = new IFileSystem(folder);
|
||||
|
||||
g_sourceFile = unzOpen(zipFile.c_str());
|
||||
|
||||
unzGetGlobalInfo(g_sourceFile,&globalInfo);
|
||||
g_fs->GetRootFolder();
|
||||
BuildTree();
|
||||
unzClose(g_sourceFile);
|
||||
}
|
||||
|
||||
void IZipFileContentProvider::BuildTree()
|
||||
{
|
||||
unzGoToFirstFile(g_sourceFile);
|
||||
|
||||
for (unsigned int i = 0; i < globalInfo.number_entry; i++)
|
||||
{
|
||||
tchar fileName[256+1] = {0};
|
||||
unz_file_info fileInfo;
|
||||
|
||||
unzGetCurrentFileInfo(g_sourceFile,&fileInfo,fileName,256,NULL,0,NULL, 0);
|
||||
|
||||
if (fileInfo.size_filename >0 && fileName[fileInfo.size_filename-1] == '/')
|
||||
{
|
||||
/* string path = entry.Name;
|
||||
path = path.Replace('/', '\\');
|
||||
IZipFolder folder = BuildDirectory(path);*/
|
||||
}
|
||||
else//is file
|
||||
{
|
||||
String sd = String(fileName);
|
||||
String p = GetZipPathWithoutFilename(sd);
|
||||
IZipFolder* folder;
|
||||
g_fs->GetFolder(p, (IFolder**)&folder);
|
||||
|
||||
IZipFile* file = new IZipFile();
|
||||
file->FileName = GetFileName(sd, zipPathSplitter);
|
||||
file->Provider = this;
|
||||
file->Size = fileInfo.uncompressed_size;
|
||||
file->EntryName = sd;
|
||||
folder->AddFile(file);
|
||||
}
|
||||
unzCloseCurrentFile(g_sourceFile);
|
||||
unzGoToNextFile(g_sourceFile);
|
||||
}
|
||||
|
||||
//print folder tree
|
||||
String tab(_text("\t"));
|
||||
int cnt = g_fs->GetRootFolder()->folderCount;
|
||||
for(int i = 0; i < cnt; i++)
|
||||
{
|
||||
IFolder* fld = g_fs->GetRootFolder()->GetFolder(i);
|
||||
PRINT(_text("%s\n"), fld->Name.c_str());
|
||||
PRINT(_text("Files count: %i\n"), fld->fileCount);
|
||||
}
|
||||
}
|
||||
|
||||
String IZipFileContentProvider::GetZipPathWithoutFilename(const String& path)
|
||||
{
|
||||
int offset = path.find_last_of(_text("/"));
|
||||
if(offset>=0)
|
||||
{
|
||||
return path.substr(0, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _text("/");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
#ifndef IZIPFILECONTENTPROVIDER_H__
|
||||
#define IZIPFILECONTENTPROVIDER_H__
|
||||
|
||||
#include "../IContentProvider.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFileSystem.h"
|
||||
//#include "test.h"
|
||||
#include "../../minizip/unzip.h"
|
||||
#include "IZipFolder.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IZipFileContentProvider : public IContentProvider
|
||||
{
|
||||
public:
|
||||
~IZipFileContentProvider(){};
|
||||
void Close(){}
|
||||
IFileSystem* getFileSystem(){return g_fs;}
|
||||
IZipFileContentProvider(const String& zipFile);
|
||||
String g_rootFolder;
|
||||
|
||||
protected:
|
||||
unz_global_info globalInfo;
|
||||
|
||||
IFileSystem* g_fs;
|
||||
void BuildTree();
|
||||
String GetZipPathWithoutFilename(const String& path);
|
||||
public:
|
||||
unzFile g_sourceFile;
|
||||
|
||||
/*private:
|
||||
|
||||
private string GetFilename(string path)
|
||||
{
|
||||
return System.IO.Path.GetFileName("C:\\" + path);
|
||||
}
|
||||
|
||||
private IZipFolder BuildDirectory(string path)
|
||||
{
|
||||
string[] parts = path.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
IZipFolder folder = (IZipFolder)g_fs.GetRootFolder();
|
||||
string npath = "";
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
npath+=parts[i] + "/";
|
||||
IZipFolder f= (IZipFolder)folder.GetFolder(parts[i]);
|
||||
if (f != null)
|
||||
{
|
||||
folder = f;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = new IZipFolder();
|
||||
f.EntryName = npath;
|
||||
f.Name = parts[i];
|
||||
f.Provider = this;
|
||||
folder.AddFolder(f);
|
||||
folder = f;
|
||||
}
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
private int ScanFolder(IFolder f)
|
||||
{
|
||||
string P = f.Path;
|
||||
string[] dirs = System.IO.Directory.GetDirectories(g_rootFolder + P);
|
||||
for (int i = 0; i < dirs.Length; i++)
|
||||
{
|
||||
}
|
||||
|
||||
string[] files = System.IO.Directory.GetFiles(g_rootFolder + P);
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
IFSFile desc = new IFSFile();
|
||||
desc.FileName = System.IO.Path.GetFileName(files[i]);
|
||||
desc.Provider = this;
|
||||
FileInfo info = new FileInfo(files[i]);
|
||||
desc.Size = (int)info.Length;
|
||||
desc.FSPath = files[i];
|
||||
f.AddFile(desc);
|
||||
}
|
||||
|
||||
return dirs.Length;
|
||||
}
|
||||
|
||||
private string GetDirFromPath(string path)
|
||||
{
|
||||
string[] dirs = path.Split(System.IO.Path.DirectorySeparatorChar);
|
||||
return dirs[dirs.Length - 1];
|
||||
}
|
||||
|
||||
public:
|
||||
ZipFile GetSource()
|
||||
{
|
||||
return g_sourceFile;
|
||||
}
|
||||
|
||||
IFolder CreateFolder(string path)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IFileDescriptor CreateFile(string path)
|
||||
{
|
||||
System.IO.File.Create(path).Close();
|
||||
IFSFile file = new IFSFile();
|
||||
file.FileName = System.IO.Path.GetFileName(path);
|
||||
file.FSPath = path;
|
||||
file.Provider = this;
|
||||
return file;
|
||||
}
|
||||
|
||||
override void Close()
|
||||
{
|
||||
if (g_dataStream != null)
|
||||
g_dataStream.Close();
|
||||
}
|
||||
|
||||
override LifeEngine.FileSystem.IFileSystem FileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
return g_fs;
|
||||
}
|
||||
}*/
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "IZipFolder.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
IZipFolder::~IZipFolder(void)
|
||||
{
|
||||
for( FolderMap::iterator it = g_folderCollection.begin(); it != g_folderCollection.end(); it++ )
|
||||
delete it->second;
|
||||
}
|
||||
IFolder* IZipFolder::NewFolder(const String& name)
|
||||
{
|
||||
IZipFolder* newFolder = new IZipFolder();
|
||||
newFolder->Name = name;
|
||||
newFolder->setParent(this);
|
||||
newFolder->EntryName = this->EntryName + name + _text("/");
|
||||
newFolder->Provider = this->Provider;
|
||||
this->AddFolder(newFolder);
|
||||
return newFolder;
|
||||
}
|
||||
IFile* IZipFolder::NewFile(const String& name, int size)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(size);
|
||||
IFile* newFile = new IZipFile();
|
||||
newFile->FileName = name;
|
||||
newFile->Provider = this->Provider;
|
||||
IZipFile* xf = (IZipFile*)newFile;
|
||||
xf->EntryName = this->EntryName + name;
|
||||
this->AddFile(newFile);
|
||||
return newFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef IZIPFOLDER_H__
|
||||
#define IZIPFOLDER_H__
|
||||
|
||||
#include "../../IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include "../IFile.h"
|
||||
#include "../IFolder.h"
|
||||
#include "IZipFile.h"
|
||||
#include "../IContentProvider.h"
|
||||
#include <map>
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IZipFolder : public IFolder
|
||||
{
|
||||
public:
|
||||
~IZipFolder(void);
|
||||
IContentProvider* Provider;
|
||||
String EntryName;
|
||||
IFolder* NewFolder(const String& name);
|
||||
IFile* NewFile(const String& name, int size);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
#ifndef IZIPSTREAM_H__
|
||||
#define IZIPSTREAM_H__
|
||||
|
||||
#include "../../IDataStream.h"
|
||||
#include "../../LString.h"
|
||||
#include <assert.h>
|
||||
#include "../../minizip/unzip.h"
|
||||
#include "../../minizip/zip.h"
|
||||
|
||||
namespace LifeCore
|
||||
{
|
||||
class IZipStream : public IDataStream
|
||||
{
|
||||
private:
|
||||
size_t stmLength;
|
||||
unzFile source;
|
||||
zipFile dest;
|
||||
zip_fileinfo destInfo;
|
||||
unz_file_info fileInfo;
|
||||
int openMode;
|
||||
public:
|
||||
~IZipStream(){}
|
||||
void Close()
|
||||
{
|
||||
if(openMode == FA_READ)
|
||||
{
|
||||
if(source)
|
||||
{
|
||||
unzCloseCurrentFile(source);
|
||||
unzClose(source);
|
||||
}
|
||||
}
|
||||
else //write
|
||||
{
|
||||
if(dest)
|
||||
{
|
||||
zipCloseFileInZip(dest);
|
||||
zipClose(dest, "ONOTOLE NEGODUE");
|
||||
}
|
||||
}
|
||||
openMode = 0;
|
||||
}
|
||||
IZipStream(unzFile& file, String& entry, int fileAccessMode, const String& archivePath)
|
||||
{
|
||||
source = file;
|
||||
openMode = fileAccessMode;
|
||||
if (fileAccessMode == FA_READ)
|
||||
{
|
||||
tchar fileName[256] = {0};
|
||||
unzLocateFile(file, entry.c_str(), 1);
|
||||
unzGetCurrentFileInfo(file,&fileInfo,fileName,256,NULL,0,NULL, 0);
|
||||
stmLength = fileInfo.uncompressed_size;
|
||||
unzOpenCurrentFile(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = zipOpen(archivePath.c_str(), 2);
|
||||
destInfo.tmz_date.tm_sec = destInfo.tmz_date.tm_min = destInfo.tmz_date.tm_hour =
|
||||
destInfo.tmz_date.tm_mday = destInfo.tmz_date.tm_mon = destInfo.tmz_date.tm_year = 0;
|
||||
destInfo.dosDate = 0;
|
||||
destInfo.internal_fa = 0;
|
||||
destInfo.external_fa = 0;
|
||||
|
||||
#ifdef _UNICODE
|
||||
char tmp[64] = {0};
|
||||
wcstombs(tmp,entry.c_str(),entry.length());
|
||||
zipOpenNewFileInZip(dest, tmp,&destInfo,NULL,0,NULL, 0, NULL, 0, 0);
|
||||
#else
|
||||
zipOpenNewFileInZip(dest, entry.c_str(),&destInfo,NULL,0,NULL, 0, NULL, 0, 0);
|
||||
#endif
|
||||
}
|
||||
//g_openMode = mode;
|
||||
}
|
||||
size_t Read(void* pBuffer, size_t countBytes)
|
||||
{
|
||||
return unzReadCurrentFile(source, pBuffer, countBytes);
|
||||
}
|
||||
size_t Write(const void* pBuffer, size_t countBytes)
|
||||
{
|
||||
zipWriteInFileInZip(dest, pBuffer,countBytes);
|
||||
return countBytes;
|
||||
}
|
||||
void Seek(size_t position)
|
||||
{
|
||||
printf("100500&%i\n", position);
|
||||
printf("Unimplemented SEEK operation in IZipStream");
|
||||
}
|
||||
size_t Tell()
|
||||
{
|
||||
printf("Unimplemented TELL operation in IZipStream");
|
||||
return 0;
|
||||
}
|
||||
size_t Length()
|
||||
{
|
||||
return stmLength;
|
||||
}
|
||||
bool CanRead()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool CanWrite()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user