#include "CmFileSystem.h" #include "CmDataStream.h" #include "CmPath.h" #include "CmException.h" #include #include #if CM_PLATFORM == CM_PLATFORM_LINUX || CM_PLATFORM == CM_PLATFORM_APPLE || \ CM_PLATFORM == CM_PLATFORM_SYMBIAN || CM_PLATFORM == CM_PLATFORM_IPHONE # include # define MAX_PATH MAXPATHLEN #endif #if CM_PLATFORM == CM_PLATFORM_WIN32 # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) # define NOMINMAX // required to stop windows.h messing up std::min # endif # include # include # include #endif namespace CamelotEngine { DataStreamPtr FileSystem::open(const String& fullPath, bool readOnly) { // Use filesystem to determine size // (quicker than streaming to the end and back) struct stat tagStat; int ret = stat(fullPath.c_str(), &tagStat); assert(ret == 0 && "Problem getting file size" ); (void)ret; // Silence warning // Always open in binary mode // Also, always include reading std::ios::openmode mode = std::ios::in | std::ios::binary; std::istream* baseStream = 0; std::ifstream* roStream = 0; std::fstream* rwStream = 0; if (!readOnly) { mode |= std::ios::out; rwStream = new std::fstream(); rwStream->open(fullPath.c_str(), mode); baseStream = rwStream; } else { roStream = new std::ifstream(); roStream->open(fullPath.c_str(), mode); baseStream = roStream; } // Should check ensure open succeeded, in case fail for some reason. if (baseStream->fail()) { if(roStream != nullptr) delete roStream; if(rwStream != nullptr) delete rwStream; CM_EXCEPT(FileNotFoundException, "Cannot open file: " + fullPath); } /// Construct return stream, tell it to delete on destroy FileDataStream* stream = 0; if (rwStream) { // use the writeable stream stream = new FileDataStream(fullPath, rwStream, (size_t)tagStat.st_size, true); } else { // read-only stream stream = new FileDataStream(fullPath, roStream, (size_t)tagStat.st_size, true); } return DataStreamPtr(stream); } DataStreamPtr FileSystem::create(const String& fullPath) { // Always open in binary mode // Also, always include reading std::ios::openmode mode = std::ios::out | std::ios::binary; std::fstream* rwStream = new std::fstream(); rwStream->open(fullPath.c_str(), mode); // Should check ensure open succeeded, in case fail for some reason. if (rwStream->fail()) { if(rwStream != nullptr) delete rwStream; CM_EXCEPT(FileNotFoundException, "Cannot open file: " + fullPath); } /// Construct return stream, tell it to delete on destroy FileDataStream* stream = new FileDataStream(fullPath, rwStream, 0, true); return DataStreamPtr(stream); } void FileSystem::remove(const String& fullPath) { ::remove(fullPath.c_str()); } }