CmFileSystem.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "CmFileSystem.h"
  2. #include "CmDataStream.h"
  3. #include "CmPath.h"
  4. #include "CmException.h"
  5. #include <boost/filesystem.hpp>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #if CM_PLATFORM == CM_PLATFORM_LINUX || CM_PLATFORM == CM_PLATFORM_APPLE || \
  9. CM_PLATFORM == CM_PLATFORM_SYMBIAN || CM_PLATFORM == CM_PLATFORM_IPHONE
  10. # include <sys/param.h>
  11. # define MAX_PATH MAXPATHLEN
  12. #endif
  13. #if CM_PLATFORM == CM_PLATFORM_WIN32
  14. # define WIN32_LEAN_AND_MEAN
  15. # if !defined(NOMINMAX) && defined(_MSC_VER)
  16. # define NOMINMAX // required to stop windows.h messing up std::min
  17. # endif
  18. # include <windows.h>
  19. # include <direct.h>
  20. # include <io.h>
  21. #endif
  22. namespace CamelotFramework
  23. {
  24. DataStreamPtr FileSystem::open(const String& fullPath, bool readOnly)
  25. {
  26. // Use filesystem to determine size
  27. // (quicker than streaming to the end and back)
  28. struct stat tagStat;
  29. int ret = stat(fullPath.c_str(), &tagStat);
  30. assert(ret == 0 && "Problem getting file size" );
  31. (void)ret; // Silence warning
  32. // Always open in binary mode
  33. // Also, always include reading
  34. std::ios::openmode mode = std::ios::in | std::ios::binary;
  35. std::shared_ptr<std::istream> baseStream = 0;
  36. std::shared_ptr<std::ifstream> roStream = 0;
  37. std::shared_ptr<std::fstream> rwStream = 0;
  38. if (!readOnly)
  39. {
  40. mode |= std::ios::out;
  41. rwStream = std::shared_ptr<std::fstream>(CM_NEW(std::fstream, ScratchAlloc) std::fstream(),
  42. &MemAllocDeleter<std::fstream, ScratchAlloc>::deleter);
  43. rwStream->open(fullPath.c_str(), mode);
  44. baseStream = rwStream;
  45. }
  46. else
  47. {
  48. roStream = std::shared_ptr<std::ifstream>(CM_NEW(std::ifstream, ScratchAlloc) std::ifstream(),
  49. &MemAllocDeleter<std::ifstream, ScratchAlloc>::deleter);
  50. roStream->open(fullPath.c_str(), mode);
  51. baseStream = roStream;
  52. }
  53. // Should check ensure open succeeded, in case fail for some reason.
  54. if (baseStream->fail())
  55. CM_EXCEPT(FileNotFoundException, "Cannot open file: " + fullPath);
  56. /// Construct return stream, tell it to delete on destroy
  57. FileDataStream* stream = 0;
  58. if (rwStream)
  59. {
  60. // use the writeable stream
  61. stream = cm_new<FileDataStream, ScratchAlloc>(fullPath, rwStream, (size_t)tagStat.st_size, true);
  62. }
  63. else
  64. {
  65. // read-only stream
  66. stream = cm_new<FileDataStream, ScratchAlloc>(fullPath, roStream, (size_t)tagStat.st_size, true);
  67. }
  68. return DataStreamPtr(stream, &MemAllocDeleter<FileDataStream, ScratchAlloc>::deleter);
  69. }
  70. DataStreamPtr FileSystem::create(const String& fullPath)
  71. {
  72. // Always open in binary mode
  73. // Also, always include reading
  74. std::ios::openmode mode = std::ios::out | std::ios::binary;
  75. std::shared_ptr<std::fstream> rwStream(CM_NEW(std::fstream, ScratchAlloc) std::fstream(),
  76. &MemAllocDeleter<std::fstream, ScratchAlloc>::deleter);
  77. rwStream->open(fullPath.c_str(), mode);
  78. // Should check ensure open succeeded, in case fail for some reason.
  79. if (rwStream->fail())
  80. CM_EXCEPT(FileNotFoundException, "Cannot open file: " + fullPath);
  81. /// Construct return stream, tell it to delete on destroy
  82. FileDataStream* stream = CM_NEW(FileDataStream, ScratchAlloc) FileDataStream(fullPath, rwStream, 0, true);
  83. return DataStreamPtr(stream, &MemAllocDeleter<FileDataStream, ScratchAlloc>::deleter);
  84. }
  85. void FileSystem::remove(const String& fullPath)
  86. {
  87. ::remove(fullPath.c_str());
  88. }
  89. bool FileSystem::fileExists(const String& fullPath)
  90. {
  91. if(boost::filesystem::exists(fullPath) && !boost::filesystem::is_directory(fullPath))
  92. return true;
  93. return false;
  94. }
  95. bool FileSystem::dirExists(const String& fullPath)
  96. {
  97. if(boost::filesystem::exists(fullPath) && boost::filesystem::is_directory(fullPath))
  98. return true;
  99. return false;
  100. }
  101. void FileSystem::createDir(const String& fullPath)
  102. {
  103. boost::filesystem::create_directory(fullPath);
  104. }
  105. void FileSystem::deleteDir(const String& fullPath)
  106. {
  107. boost::filesystem::remove_all(fullPath);
  108. }
  109. vector<String>::type FileSystem::getFiles(const String& dirPath)
  110. {
  111. boost::filesystem::directory_iterator dirIter(dirPath);
  112. vector<String>::type foundFiles;
  113. while(dirIter != boost::filesystem::directory_iterator())
  114. {
  115. if(boost::filesystem::is_regular_file(dirIter->path()))
  116. foundFiles.push_back(dirIter->path().string());
  117. dirIter++;
  118. }
  119. return foundFiles;
  120. }
  121. String FileSystem::getCurrentPath()
  122. {
  123. return boost::filesystem::current_path().string();
  124. }
  125. bool FileSystem::isValidFileName(const String& name)
  126. {
  127. return boost::filesystem::portable_file_name(name);
  128. }
  129. String FileSystem::getDirectoryPath(const String& path)
  130. {
  131. boost::filesystem::path p(path);
  132. if(!is_directory(p))
  133. {
  134. boost::filesystem::path dir = p.parent_path();
  135. return dir.string();
  136. }
  137. return path;
  138. }
  139. }