|
|
@@ -0,0 +1,110 @@
|
|
|
+#include "CmFileSystem.h"
|
|
|
+#include "CmDataStream.h"
|
|
|
+#include "CmPath.h"
|
|
|
+#include "CmException.h"
|
|
|
+
|
|
|
+#include <sys/types.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+
|
|
|
+#if CM_PLATFORM == CM_PLATFORM_LINUX || CM_PLATFORM == CM_PLATFORM_APPLE || \
|
|
|
+ CM_PLATFORM == CM_PLATFORM_SYMBIAN || CM_PLATFORM == CM_PLATFORM_IPHONE
|
|
|
+# include <sys/param.h>
|
|
|
+# 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 <windows.h>
|
|
|
+# include <direct.h>
|
|
|
+# include <io.h>
|
|
|
+#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());
|
|
|
+ }
|
|
|
+}
|