FileManager.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include "../include/FileManager.h"
  2. #include <boost/filesystem.hpp>
  3. #include <boost/range/iterator_range.hpp>
  4. #include <string>
  5. #include "../include/Config.h"
  6. FileManager::FileManager()
  7. : deleteAllowed(Config::getValue("deleteAllowed") == "true"),
  8. fileDirectory(Config::getValue("filedirectory") + ((Config::getValue("filedirectory").back() != '/') ? "/" : "")) {}
  9. FileManager::~FileManager() {
  10. cancelPut();
  11. closeGetFile();
  12. }
  13. bool FileManager::isUploading() { return this->putFile.is_open(); }
  14. bool FileManager::isDownloading() { return this->getFile.is_open(); }
  15. bool FileManager::openPutFile(const std::string &filename) {
  16. this->putBaseFileName = filename;
  17. this->putFileName = this->fileDirectory;
  18. this->putFileName.append(filename);
  19. std::ifstream ifile(this->putFileName);
  20. if (ifile.is_open()) {
  21. // file alread exists
  22. ifile.close();
  23. closePutFile();
  24. return false;
  25. }
  26. // open file and test if it already exists
  27. this->putFile.open(this->putFileName, std::ios::app | std::ios::binary);
  28. return true;
  29. }
  30. std::pair<bool, int> FileManager::openGetFile(const std::string &filename) {
  31. this->getBaseFileName = filename;
  32. std::string file = this->fileDirectory;
  33. file.append(filename);
  34. this->getFile.open(file, std::ios::ate | std::ios::binary);
  35. if (this->getFile.is_open() == 0) {
  36. // file does not exist or cannot be opened
  37. return std::pair<bool, int>(false, -1);
  38. } else {
  39. this->getFileSize = this->getFile.tellg();
  40. int chunks = this->getFileSize / max_data_length + (this->getFileSize % max_data_length == 0 ? 0 : 1);
  41. this->getFile.seekg(std::ios::beg);
  42. return std::pair<bool, int>(true, chunks);
  43. }
  44. }
  45. void FileManager::closePutFile() { this->putFile.close(); }
  46. void FileManager::closeGetFile() { this->getFile.close(); }
  47. void FileManager::cancelPut() {
  48. if (isUploading()) {
  49. closePutFile();
  50. std::remove(this->putFileName.c_str());
  51. }
  52. }
  53. bool FileManager::checkFilename(const std::string &name) { return name.find('/') == std::string::npos; }
  54. std::string FileManager::getGetBaseFileName() { return this->getBaseFileName; }
  55. std::string FileManager::getPutBaseFileName() { return this->putBaseFileName; }
  56. void FileManager::writePut(const std::vector<char> &data) { this->putFile.write(data.data(), data.size()); }
  57. std::vector<char> FileManager::readGet() {
  58. // store position before read
  59. std::streamoff read = this->getFile.tellg();
  60. if (read + max_data_length > this->getFileSize) {
  61. read = this->getFileSize % max_data_length;
  62. } else {
  63. read = max_data_length;
  64. }
  65. std::vector<char> data;
  66. data.resize(read);
  67. this->getFile.read(data.data(), read);
  68. return data;
  69. }
  70. int FileManager::openList() {
  71. // add empty chunk vector
  72. this->list.push_back(std::vector<std::string>());
  73. int cursize = 0;
  74. for (const auto &entry : boost::filesystem::directory_iterator(this->fileDirectory)) {
  75. // getting filename from
  76. if (boost::filesystem::is_directory(entry.path()))
  77. continue;
  78. const std::string s = entry.path().filename().string();
  79. // check if the size is too big
  80. if (s.length() > max_data_length)
  81. return -1;
  82. cursize += s.length() + 3;
  83. if (cursize > max_data_length) {
  84. this->list.push_back(std::vector<std::string>());
  85. cursize = 0;
  86. }
  87. // add string to its chunk
  88. this->list.back().push_back(s);
  89. }
  90. // empty list if no file was read
  91. if (this->list.size() == 1 && this->list.back().size() == 0) {
  92. this->list.clear();
  93. }
  94. return this->list.size();
  95. }
  96. int FileManager::getRemainingListChunks() { return this->list.size(); }
  97. int FileManager::getListSize() {
  98. int size = 0;
  99. for (const std::vector<std::string> &l : this->list) {
  100. size += l.size();
  101. }
  102. return size;
  103. }
  104. std::vector<std::string> FileManager::getNextChunkFromList() {
  105. if (getRemainingListChunks() == 0) { // This should never happen!!!
  106. return std::vector<std::string>();
  107. }
  108. std::vector<std::string> ret = this->list.back();
  109. this->list.pop_back();
  110. return ret;
  111. }
  112. void FileManager::cancelList() { this->list.clear(); }
  113. std::pair<std::vector<char>, FileManager::Error> FileManager::getBytesFromFile(const std::string &filename, int numOfBytes) {
  114. std::ifstream file;
  115. std::string fname = this->fileDirectory;
  116. fname.append(filename);
  117. file.open(fname, std::ios::ate | std::ios::binary);
  118. std::vector<char> bytes;
  119. if (!file.is_open()) {
  120. return std::make_pair(bytes, FileManager::Error::no_such_file);
  121. }
  122. auto size = file.tellg();
  123. if (size < numOfBytes) {
  124. return std::make_pair(bytes, FileManager::Error::file_too_small);
  125. }
  126. bytes.resize(numOfBytes);
  127. file.seekg(0, std::ios::beg);
  128. file.read(bytes.data(), numOfBytes);
  129. file.close();
  130. return std::make_pair(bytes, FileManager::Error::no_error);
  131. }
  132. FileManager::Error FileManager::deleteFile(const std::string &filename) {
  133. if (!this->deleteAllowed) {
  134. return not_allowed;
  135. }
  136. std::string fname = this->fileDirectory;
  137. fname.append(filename);
  138. if (!boost::filesystem::exists(fname)) {
  139. return no_such_file;
  140. }
  141. boost::filesystem::remove(fname);
  142. return no_error;
  143. }
  144. int FileManager::openExtendedList() {
  145. this->extendedlist.push_back(std::vector<std::tuple<std::string, std::string, double>>());
  146. int cursize = 0;
  147. for (const auto &entry : boost::filesystem::directory_iterator(this->fileDirectory)) {
  148. // getting filename from
  149. if (boost::filesystem::is_directory(entry.path()))
  150. continue;
  151. const std::string name = entry.path().filename().string();
  152. // calc head
  153. std::string head;
  154. std::pair<std::vector<char>, FileManager::Error> h = getBytesFromFile(name, 32);
  155. if (h.second == FileManager::file_too_small)
  156. h = getBytesFromFile(name, 4);
  157. if (h.second == FileManager::no_error) {
  158. std::string s(h.first.begin(), h.first.end());
  159. head = s;
  160. } else
  161. head = "";
  162. // calc size in kbyte
  163. std::string fname = this->fileDirectory;
  164. fname.append(name);
  165. std::ifstream file(fname, std::ios::ate | std::ios::binary);
  166. double size = (double)((double)file.tellg() / (double)1000.0);
  167. cursize += name.length() + head.length() + std::to_string(size).length() + 7;
  168. if (cursize > max_data_length) {
  169. this->extendedlist.push_back(std::vector<std::tuple<std::string, std::string, double>>());
  170. cursize = 0;
  171. }
  172. std::tuple<std::string, std::string, double> p = std::tuple(name, head, size);
  173. this->extendedlist.back().push_back(p);
  174. }
  175. if (this->extendedlist.size() == 1 && this->extendedlist.back().size() == 0) {
  176. this->extendedlist.clear();
  177. }
  178. return this->extendedlist.size();
  179. }
  180. int FileManager::getRemainingExtendedListChunks() { return this->extendedlist.size(); }
  181. std::vector<std::tuple<std::string, std::string, double>> FileManager::getNextChunkFromExtendedList() {
  182. if (getRemainingExtendedListChunks() == 0)
  183. return std::vector<std::tuple<std::string, std::string, double>>();
  184. std::vector<std::tuple<std::string, std::string, double>> ret = this->extendedlist.back();
  185. this->extendedlist.pop_back();
  186. return ret;
  187. }
  188. int FileManager::getExtendedListSize() {
  189. int size = 0;
  190. for (const std::vector<std::tuple<std::string, std::string, double>> v : this->extendedlist)
  191. size += v.size();
  192. return size;
  193. }
  194. void FileManager::cancelExtendedList() { this->extendedlist.clear(); }