This commit is contained in:
2025-05-13 02:46:21 +03:00
parent 143e16692e
commit 86914b7fcc
610 changed files with 92343 additions and 2 deletions
+22
View File
@@ -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
+52
View File
@@ -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
+158
View File
@@ -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;
}
}
}
+64
View File
@@ -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
+120
View File
@@ -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
+19
View File
@@ -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
+57
View File
@@ -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;
}
}
+25
View File
@@ -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);
}
}
}
}
+26
View File
@@ -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
+62
View File
@@ -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;
}
}
}
+29
View File
@@ -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
+53
View File
@@ -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;
}
}
}
+26
View File
@@ -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
+86
View File
@@ -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
+31
View File
@@ -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;
}
}
+26
View File
@@ -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
+31
View File
@@ -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;
}
}
+24
View File
@@ -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
+77
View File
@@ -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
+13
View File
@@ -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
+11
View File
@@ -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;
+6
View File
@@ -0,0 +1,6 @@
#define MAX_ENTRY_NAME_LENGTH 0x100
typedef struct FolderEntry
{
wchar_t name[MAX_ENTRY_NAME_LENGTH];
}FolderEntry;
+312
View File
@@ -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;
}
}
+80
View File
@@ -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
+16
View File
@@ -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
+12
View File
@@ -0,0 +1,12 @@
#include <vector>
typedef struct PakHeader
{
int version;
int whiteSpacesCount;
int filesCount;
int foldersCount;
int extraDataOffset;
int lastFolderId;
int dataChunkLength;
} PakHeader;
+12
View File
@@ -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
+41
View File
@@ -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;
}
}
}
+27
View File
@@ -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("/");
}
}
}
+130
View File
@@ -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
+31
View File
@@ -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;
}
}
+25
View File
@@ -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
+108
View File
@@ -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