File.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Author: Patrick-Christopher Mattulat
  3. * Company: Lynar Studios
  4. * E-Mail: webmaster@lynarstudios.com
  5. * Created: 2020-08-15
  6. * Changed: 2020-08-15
  7. *
  8. * */
  9. #include "File.hpp"
  10. #include "../exception/FileOperationException.hpp"
  11. #include "FilePathSeparatorMatch.hpp"
  12. #include <fstream>
  13. #include <sys/stat.h>
  14. #include <algorithm>
  15. #ifdef unix
  16. #include <unistd.h>
  17. #include <vector>
  18. #include <sstream>
  19. #endif
  20. ls_std::File::File(std::string _absoluteFilePath) : Class("File"),
  21. absoluteFilePath(ls_std::File::_normalizePath(std::move(_absoluteFilePath)))
  22. {}
  23. bool ls_std::File::operator==(File &_file)
  24. {
  25. return this->absoluteFilePath == _file.getAbsoluteFilePath();
  26. }
  27. bool ls_std::File::operator!=(File &_file)
  28. {
  29. return this->absoluteFilePath != _file.getAbsoluteFilePath();
  30. }
  31. bool ls_std::File::canExecute()
  32. {
  33. bool executable {};
  34. struct stat _stat {};
  35. if(stat(this->absoluteFilePath.c_str(), &_stat) == 0) {
  36. executable = (_stat.st_mode & (unsigned short) S_IEXEC) != 0;
  37. }
  38. return executable;
  39. }
  40. void ls_std::File::create()
  41. {
  42. if(!this->_exists(this->absoluteFilePath)) {
  43. std::ofstream file {this->absoluteFilePath};
  44. file.close();
  45. } else {
  46. throw ls_std::FileOperationException{this->absoluteFilePath};
  47. }
  48. }
  49. bool ls_std::File::exists()
  50. {
  51. return this->_exists(this->absoluteFilePath);
  52. }
  53. std::string ls_std::File::getAbsoluteFilePath() {
  54. return this->absoluteFilePath;
  55. }
  56. std::string ls_std::File::getName()
  57. {
  58. std::string copy = this->absoluteFilePath;
  59. // if it's a directory, remove separator from end, if it does exist
  60. if(this->_isDirectory(this->absoluteFilePath)) {
  61. copy.erase(std::remove_if(copy.end() - 1, copy.end(), ls_std::FilePathSeparatorMatch()), copy.end());
  62. }
  63. // now get the file / directory name
  64. auto base = std::find_if(copy.rbegin(), copy.rend(), ls_std::FilePathSeparatorMatch()).base();
  65. return std::string(base, copy.end());
  66. }
  67. long ls_std::File::getSize()
  68. {
  69. std::streampos fileSize {};
  70. if(this->_exists(this->absoluteFilePath)) {
  71. std::ifstream fileHandler{this->absoluteFilePath, std::ios::in};
  72. fileSize = fileHandler.tellg();
  73. fileHandler.seekg(0, std::ios::end);
  74. fileSize = fileHandler.tellg() - fileSize;
  75. fileHandler.close();
  76. }
  77. return fileSize;
  78. }
  79. bool ls_std::File::isDirectory()
  80. {
  81. return this->_isDirectory(this->absoluteFilePath);
  82. }
  83. bool ls_std::File::isFile()
  84. {
  85. return this->_isFile(this->absoluteFilePath);
  86. }
  87. void ls_std::File::makeDirectory()
  88. {
  89. if(ls_std::File::_mkdir(this->absoluteFilePath)) {
  90. throw ls_std::FileOperationException {this->absoluteFilePath};
  91. }
  92. }
  93. void ls_std::File::makeDirectories() {
  94. std::vector<std::string> subDirectories = ls_std::File::_splitIntoSubDirectoryNames(this->absoluteFilePath);
  95. const char separator = ls_std::FilePathSeparator::getOperatingSystemSpecificSeparator();
  96. std::string currentHierarchy {};
  97. for(const auto& subDirectory : subDirectories) {
  98. currentHierarchy += subDirectory;
  99. if(!this->_exists(currentHierarchy)) {
  100. ls_std::File::_mkdir(currentHierarchy);
  101. }
  102. currentHierarchy += separator;
  103. }
  104. }
  105. void ls_std::File::remove()
  106. {
  107. if(this->_isFile(this->absoluteFilePath)) {
  108. if(std::remove(this->absoluteFilePath.c_str())) {
  109. throw ls_std::FileOperationException{this->absoluteFilePath};
  110. }
  111. }
  112. if(this->_isDirectory(this->absoluteFilePath)) {
  113. if(rmdir(this->absoluteFilePath.c_str())) {
  114. throw ls_std::FileOperationException{this->absoluteFilePath};
  115. }
  116. }
  117. }
  118. bool ls_std::File::_exists(const std::string& path)
  119. {
  120. struct stat _stat {};
  121. return (stat(this->absoluteFilePath.c_str(), &_stat) == 0);
  122. }
  123. bool ls_std::File::_isDirectory(const std::string& path)
  124. {
  125. bool match {};
  126. struct stat _stat {};
  127. if(stat(this->absoluteFilePath.c_str(), &_stat) == 0) {
  128. match = _stat.st_mode & (unsigned short) S_IFDIR;
  129. }
  130. return match;
  131. }
  132. bool ls_std::File::_isFile(const std::string& path)
  133. {
  134. bool match {};
  135. struct stat _stat {};
  136. if(stat(this->absoluteFilePath.c_str(), &_stat) == 0) {
  137. match = _stat.st_mode & (unsigned short) S_IFREG;
  138. }
  139. return match;
  140. }
  141. int ls_std::File::_mkdir(const std::string& path) {
  142. int result {};
  143. #ifdef _WIN32
  144. result = mkdir(path.c_str());
  145. #endif
  146. #ifdef unix
  147. result = mkdir(path.c_str(), 0777);
  148. #endif
  149. return result;
  150. }
  151. std::string ls_std::File::_normalizePath(std::string path)
  152. {
  153. #ifdef unix
  154. std::replace(path.begin(), path.end(), '\\', '/');
  155. #endif
  156. #ifdef _WIN32
  157. std::replace(path.begin(), path.end(), '/', '\\');
  158. #endif
  159. return path;
  160. }
  161. std::vector<std::string> ls_std::File::_splitIntoSubDirectoryNames(const std::string& path) {
  162. std::vector<std::string> subDirectoryNames {};
  163. std::stringstream _stream {path};
  164. std::string subDirectoryName {};
  165. const char separator = ls_std::FilePathSeparator::getOperatingSystemSpecificSeparator();
  166. while(std::getline(_stream, subDirectoryName, separator)) {
  167. subDirectoryNames.push_back(subDirectoryName);
  168. }
  169. return subDirectoryNames;
  170. }