Initial sources
This commit is contained in:
57
engine/filesystem/file.cpp
Normal file
57
engine/filesystem/file.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <assert.h>
|
||||
#include "filesystem/file.h"
|
||||
|
||||
static const char* s_stdioOpeningMode[] = { "rb", "wb" };
|
||||
static int s_stdioSeekDir[] = { SEEK_SET, SEEK_CUR, SEEK_END };
|
||||
|
||||
File::File(const char* path, FileAccess access)
|
||||
{
|
||||
m_filehandle = fopen(path, s_stdioOpeningMode[(int)access]);
|
||||
assert(m_filehandle && "Unable to open file");
|
||||
}
|
||||
|
||||
File::~File()
|
||||
{
|
||||
if (m_filehandle)
|
||||
{
|
||||
fclose(m_filehandle);
|
||||
m_filehandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void File::Seek(SeekDir seekdir, long offset)
|
||||
{
|
||||
fseek(m_filehandle, offset, s_stdioSeekDir[(int)seekdir]);
|
||||
}
|
||||
|
||||
size_t File::Tell()
|
||||
{
|
||||
return (size_t)ftell(m_filehandle);
|
||||
}
|
||||
|
||||
bool File::Eof()
|
||||
{
|
||||
return !!feof(m_filehandle);
|
||||
}
|
||||
|
||||
size_t File::Read(void* buffer, size_t size)
|
||||
{
|
||||
return fread(buffer, 1, size, m_filehandle);
|
||||
}
|
||||
|
||||
size_t File::Write(void const* buffer, size_t size)
|
||||
{
|
||||
return fwrite(buffer, size, 1, m_filehandle);
|
||||
}
|
||||
|
||||
void File::ReadStringBuffer(char* buffer, size_t bufferSize)
|
||||
{
|
||||
Seek(Seek_End, 0);
|
||||
size_t length = Tell();
|
||||
Seek(Seek_Begin, 0);
|
||||
|
||||
assert(length <= bufferSize);
|
||||
|
||||
Read(buffer, length);
|
||||
buffer[length] = '\0';
|
||||
}
|
||||
28
engine/filesystem/file.h
Normal file
28
engine/filesystem/file.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef FILE_H
|
||||
#define FILE_H
|
||||
|
||||
#include "filesystem/filecommon.h"
|
||||
|
||||
class File
|
||||
{
|
||||
public:
|
||||
File(const char* path, FileAccess access);
|
||||
~File();
|
||||
|
||||
FILE* GetHandle() { return m_filehandle; }
|
||||
|
||||
void Seek(SeekDir seekdir, long offset);
|
||||
size_t Tell();
|
||||
bool Eof();
|
||||
|
||||
size_t Read(void* buffer, size_t size);
|
||||
size_t Write(void const* buffer, size_t size);
|
||||
|
||||
// helpers
|
||||
void ReadStringBuffer(char* buffer, size_t bufferSize);
|
||||
|
||||
private:
|
||||
FILE* m_filehandle;
|
||||
};
|
||||
|
||||
#endif
|
||||
21
engine/filesystem/filecommon.h
Normal file
21
engine/filesystem/filecommon.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef FILECOMMON_H
|
||||
#define FILECOMMON_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const int kMaxPathLength = 260;
|
||||
|
||||
enum FileAccess
|
||||
{
|
||||
FileAccess_Read,
|
||||
FileAccess_Write
|
||||
};
|
||||
|
||||
enum SeekDir
|
||||
{
|
||||
Seek_Begin,
|
||||
Seek_Current,
|
||||
Seek_End
|
||||
};
|
||||
|
||||
#endif // !FILECOMMON_H
|
||||
316
engine/filesystem/filemanager.cpp
Normal file
316
engine/filesystem/filemanager.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <assert.h>
|
||||
#include "filesystem/stream.h"
|
||||
#include "filesystem/filemanager.h"
|
||||
|
||||
void RecursiveSearch(const std::string& path, std::vector<std::string>& files);
|
||||
void osResolvePath(char* path);
|
||||
|
||||
FileManager* g_fileManager;
|
||||
|
||||
FileManager::FileManager()
|
||||
{
|
||||
static char currentDirectory[kMaxPathLength];
|
||||
GetCurrentDirectoryA(kMaxPathLength, currentDirectory);
|
||||
strcat(currentDirectory, "/");
|
||||
|
||||
osResolvePath(currentDirectory);
|
||||
|
||||
m_defaultPath = currentDirectory;
|
||||
}
|
||||
|
||||
FileManager::~FileManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FileManager::SetDefaultPath(const char* path)
|
||||
{
|
||||
m_defaultPath = path;
|
||||
}
|
||||
|
||||
bool FileManager::FileExist(const char* filename)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
char pathBuffer[kMaxPathLength];
|
||||
if (!strstr(filename, m_defaultPath))
|
||||
sprintf(pathBuffer, "%s%s", m_defaultPath, filename);
|
||||
else
|
||||
strcpy(pathBuffer, filename);
|
||||
|
||||
osResolvePath(pathBuffer);
|
||||
|
||||
DWORD dwAttrib = GetFileAttributes(pathBuffer);
|
||||
return (dwAttrib != 0xffffffff && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
#else
|
||||
FILE* file;
|
||||
|
||||
if ((file = fopen(filename, "r")) != NULL)
|
||||
{
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
File* FileManager::OpenFile(const char* path, FileAccess access)
|
||||
{
|
||||
char pathBuffer[kMaxPathLength];
|
||||
if (!strstr(path, m_defaultPath))
|
||||
sprintf(pathBuffer, "%s%s", m_defaultPath, path);
|
||||
else
|
||||
strcpy(pathBuffer, path);
|
||||
|
||||
osResolvePath(pathBuffer);
|
||||
|
||||
return new File(pathBuffer, access);
|
||||
}
|
||||
|
||||
void FileManager::CloseFile(File*& file)
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
delete file;
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
StreamBase* FileManager::OpenStream(const char* fname, FileAccess access)
|
||||
{
|
||||
char pathBuffer[kMaxPathLength];
|
||||
if (!strstr(fname, m_defaultPath))
|
||||
sprintf(pathBuffer, "%s%s", m_defaultPath, fname);
|
||||
else
|
||||
strcpy(pathBuffer, fname);
|
||||
|
||||
osResolvePath(pathBuffer);
|
||||
|
||||
if (!g_fileManager->FileExist( pathBuffer ))
|
||||
return NULL;
|
||||
|
||||
File* file = new File(pathBuffer, access);
|
||||
return CreateFileStream(file);
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <io.h>
|
||||
#include <time.h>
|
||||
|
||||
void GetFileListFromFolder(const char* path, const char* findingPattern, std::vector<std::string>& filesList)
|
||||
{
|
||||
struct _finddata_t c_file;
|
||||
long hFile;
|
||||
|
||||
char pathfind[kMaxPathLength];
|
||||
sprintf(pathfind, "%s/%s", path, findingPattern);
|
||||
osResolvePath(pathfind);
|
||||
|
||||
if ((hFile = _findfirst(pathfind, &c_file)) != -1L) {
|
||||
do {
|
||||
char buffer[kMaxPathLength];
|
||||
sprintf(buffer, "%s/%s", path, c_file.name);
|
||||
filesList.push_back(buffer);
|
||||
} while (_findnext(hFile, &c_file) == 0);
|
||||
_findclose(hFile);
|
||||
}
|
||||
}
|
||||
|
||||
void osResolvePath(char* path)
|
||||
{
|
||||
assert(path);
|
||||
|
||||
size_t length = strlen(path);
|
||||
|
||||
for (int i = 0; i < (int)length; i++) {
|
||||
if (path[i] == '/')
|
||||
path[i] = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
bool osDirectoryIsExist(const char* path)
|
||||
{
|
||||
DWORD ftyp = GetFileAttributesA(path);
|
||||
if (ftyp == 0xffffffff)
|
||||
return false;
|
||||
|
||||
if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void osCreateDirectory(const char* path)
|
||||
{
|
||||
CreateDirectoryA(path, NULL);
|
||||
}
|
||||
|
||||
void RecursiveSearch(const std::string& path, std::vector<std::string>& files)
|
||||
{
|
||||
struct _finddata_t c_file;
|
||||
long hFile;
|
||||
|
||||
std::string bufferPath;
|
||||
bufferPath += path;
|
||||
bufferPath += "/";
|
||||
bufferPath += "*.*";
|
||||
|
||||
if ((hFile = _findfirst(bufferPath.c_str(), &c_file)) != -1L)
|
||||
{
|
||||
do {
|
||||
if (strcmp(c_file.name, ".") == 0 ||
|
||||
strcmp(c_file.name, "..") == 0 ||
|
||||
strcmp(c_file.name, ".git") == 0 ||
|
||||
strcmp(c_file.name, ".gitignore") == 0 ||
|
||||
strcmp(c_file.name, ".gitignore") == 0 ||
|
||||
strcmp(c_file.name, ".vs") == 0)
|
||||
continue;
|
||||
|
||||
if (c_file.attrib & _A_SUBDIR)
|
||||
{
|
||||
std::string nextPath;
|
||||
nextPath += path;
|
||||
nextPath += "/";
|
||||
nextPath += c_file.name;
|
||||
|
||||
RecursiveSearch(nextPath, files);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string filepath;
|
||||
filepath += path;
|
||||
filepath += "/";
|
||||
filepath += c_file.name;
|
||||
files.push_back(filepath);
|
||||
}
|
||||
|
||||
} while (_findnext(hFile, &c_file) == 0);
|
||||
_findclose(hFile);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#include <dirent.h>
|
||||
|
||||
bool match(const char* pattern, const char* str, int p = 0, int c = 0)
|
||||
{
|
||||
if (pattern[p] == '\0')
|
||||
{
|
||||
return str[c] == '\0';
|
||||
}
|
||||
else if (pattern[p] == '*')
|
||||
{
|
||||
for (; str[c] != '\0'; c++)
|
||||
{
|
||||
if (match(pattern, str, p + 1, c))
|
||||
return true;
|
||||
}
|
||||
return match(pattern, str, p + 1, c);
|
||||
}
|
||||
else if (pattern[p] != '?' && pattern[p] != str[c])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return match(pattern, str, p + 1, c + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GetFileListFromFolder(const char* path, const char* findingPattern, std::vector<std::string>& filesList)
|
||||
{
|
||||
DIR* dir;
|
||||
dirent* ent;
|
||||
|
||||
if ((dir = opendir(path)) != NULL)
|
||||
{
|
||||
while ((ent = readdir(dir)) != NULL)
|
||||
{
|
||||
if (match(findingPattern, ent->d_name))
|
||||
{
|
||||
char buffer[kMaxPathLength];
|
||||
snprintf(buffer, kMaxPathLength, "%s/%s", path, ent->d_name);
|
||||
filesList.push_back(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace fs
|
||||
{
|
||||
std::string getFileExtension(const std::string& filename)
|
||||
{
|
||||
size_t whereIsDot = filename.find_last_of('.');
|
||||
if (whereIsDot != std::string::npos) {
|
||||
return filename.substr(whereIsDot);
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string getFilePath(const std::string& filename)
|
||||
{
|
||||
size_t lastindex = filename.find_last_of("/");
|
||||
if (lastindex == std::string::npos) {
|
||||
lastindex = filename.find_last_of("\\");
|
||||
}
|
||||
|
||||
if (lastindex != std::string::npos) {
|
||||
|
||||
return filename.substr(0, lastindex);
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string getFileNameWithoutExtension(const std::string& filename)
|
||||
{
|
||||
size_t lastindex = filename.find_last_of(".");
|
||||
if (lastindex != std::string::npos) {
|
||||
return filename.substr(0, lastindex);
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string getFilenameWithoutPath(const std::string& filename)
|
||||
{
|
||||
size_t whereIsSlash = filename.find_last_of('/');
|
||||
if (whereIsSlash == std::string::npos) {
|
||||
whereIsSlash = filename.find_last_of('\\');
|
||||
}
|
||||
|
||||
if (whereIsSlash == std::string::npos) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string string = filename.substr(whereIsSlash + 1);
|
||||
return string;
|
||||
}
|
||||
|
||||
std::string getFilenameWithoutPathAndExtension(const std::string& filename)
|
||||
{
|
||||
size_t whereIsDot = filename.find_last_of('.');
|
||||
size_t whereIsSlash = filename.find_last_of('/');
|
||||
if (whereIsSlash == std::string::npos) {
|
||||
whereIsSlash = filename.find_last_of('\\');
|
||||
}
|
||||
|
||||
if (whereIsDot == std::string::npos && whereIsSlash == std::string::npos) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string string = filename.substr(whereIsSlash + 1);
|
||||
whereIsDot = string.find_last_of('.');
|
||||
string = string.substr(0, whereIsDot);
|
||||
|
||||
return string;
|
||||
}
|
||||
}
|
||||
51
engine/filesystem/filemanager.h
Normal file
51
engine/filesystem/filemanager.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef FILEMANAGER_H
|
||||
#define FILEMANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "filesystem/file.h"
|
||||
|
||||
class StreamBase;
|
||||
|
||||
class FileManager
|
||||
{
|
||||
public:
|
||||
FileManager();
|
||||
~FileManager();
|
||||
|
||||
void SetDefaultPath(const char* path);
|
||||
const char* GetDefaultPath() { return m_defaultPath; }
|
||||
|
||||
bool FileExist(const char* filename);
|
||||
|
||||
File* OpenFile(const char* path, FileAccess access);
|
||||
void CloseFile(File*& file);
|
||||
|
||||
StreamBase* OpenStream(const char* fname, FileAccess access);
|
||||
|
||||
private:
|
||||
const char* m_defaultPath;
|
||||
};
|
||||
|
||||
extern FileManager* g_fileManager;
|
||||
|
||||
void GetFileListFromFolder(const char* path, const char* findingPattern, std::vector<std::string>& filesList);
|
||||
|
||||
void osResolvePath(char* path);
|
||||
bool osDirectoryIsExist(const char* path);
|
||||
void osCreateDirectory(const char* path);
|
||||
|
||||
// Filename helper
|
||||
|
||||
namespace fs
|
||||
{
|
||||
std::string getFileExtension(const std::string& filename);
|
||||
std::string getFilePath(const std::string& filename);
|
||||
std::string getFileNameWithoutExtension(const std::string& filename);
|
||||
std::string getFilenameWithoutPath(const std::string& filename);
|
||||
std::string getFilenameWithoutPathAndExtension(const std::string& filename);
|
||||
};
|
||||
|
||||
|
||||
#endif // !FILEMANAGER_H
|
||||
61
engine/filesystem/stream.cpp
Normal file
61
engine/filesystem/stream.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <assert.h>
|
||||
#include "filesystem/stream.h"
|
||||
#include "filesystem/filemanager.h"
|
||||
|
||||
class FileStream : public StreamBase
|
||||
{
|
||||
public:
|
||||
FileStream(File* file);
|
||||
~FileStream();
|
||||
|
||||
size_t Read(void* buffer, size_t size);
|
||||
size_t Write(void* buffer, size_t size);
|
||||
void Seek(SeekDir way, long offset);
|
||||
size_t Tell();
|
||||
bool Eof();
|
||||
|
||||
private:
|
||||
File* m_file;
|
||||
};
|
||||
|
||||
FileStream::FileStream(File* file)
|
||||
{
|
||||
assert(file && "Cannot open file stream with nullptr file handle.");
|
||||
m_file = file;
|
||||
}
|
||||
|
||||
FileStream::~FileStream()
|
||||
{
|
||||
if (m_file)
|
||||
g_fileManager->CloseFile(m_file);
|
||||
}
|
||||
|
||||
size_t FileStream::Read(void* buffer, size_t size)
|
||||
{
|
||||
return m_file->Read(buffer, size);
|
||||
}
|
||||
|
||||
size_t FileStream::Write(void* buffer, size_t size)
|
||||
{
|
||||
return m_file->Write(buffer, size);
|
||||
}
|
||||
|
||||
void FileStream::Seek(SeekDir way, long offset)
|
||||
{
|
||||
m_file->Seek(way, offset);
|
||||
}
|
||||
|
||||
size_t FileStream::Tell()
|
||||
{
|
||||
return m_file->Tell();
|
||||
}
|
||||
|
||||
bool FileStream::Eof()
|
||||
{
|
||||
return m_file->Eof();;
|
||||
}
|
||||
|
||||
StreamBase* CreateFileStream(File* file)
|
||||
{
|
||||
return new FileStream(file);
|
||||
}
|
||||
21
engine/filesystem/stream.h
Normal file
21
engine/filesystem/stream.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef STREAM_H
|
||||
#define STREAM_H
|
||||
|
||||
#include "filesystem/filecommon.h"
|
||||
|
||||
class StreamBase
|
||||
{
|
||||
public:
|
||||
virtual ~StreamBase() {}
|
||||
|
||||
virtual size_t Read(void* buffer, size_t size) = 0;
|
||||
virtual size_t Write(void* buffer, size_t size) = 0;
|
||||
virtual void Seek(SeekDir way, long offset) = 0;
|
||||
virtual size_t Tell() = 0;
|
||||
virtual bool Eof() = 0;
|
||||
};
|
||||
|
||||
class File;
|
||||
StreamBase* CreateFileStream(File* file);
|
||||
|
||||
#endif // !STREAM_H
|
||||
Reference in New Issue
Block a user