FS.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (c) 2013-2016, The PurpleI2P Project
  3. *
  4. * This file is part of Purple i2pd project and licensed under BSD3
  5. *
  6. * See full license text in LICENSE file at top of project tree
  7. */
  8. #ifndef FS_H__
  9. #define FS_H__
  10. #include <vector>
  11. #include <string>
  12. #include <iostream>
  13. #include <sstream>
  14. #include <functional>
  15. namespace i2p {
  16. namespace fs {
  17. extern std::string dirSep;
  18. /**
  19. * @brief Class to work with NetDb & Router profiles
  20. *
  21. * Usage:
  22. *
  23. * const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
  24. * auto h = HashedStorage("name", "y", "z-", ".txt");
  25. * h.SetPlace("/tmp/hs-test");
  26. * h.GetName() -> gives "name"
  27. * h.GetRoot() -> gives "/tmp/hs-test/name"
  28. * h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet
  29. * h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt
  30. * h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists
  31. * std::vector<std::string> files;
  32. * h.Traverse(files); <- finds all files in storage and saves in given vector
  33. */
  34. class HashedStorage {
  35. protected:
  36. std::string root; /**< path to storage with it's name included */
  37. std::string name; /**< name of the storage */
  38. std::string prefix1; /**< hashed directory prefix */
  39. std::string prefix2; /**< prefix of file in storage */
  40. std::string suffix; /**< suffix of file in storage (extension) */
  41. public:
  42. typedef std::function<void(const std::string &)> FilenameVisitor;
  43. HashedStorage(const char *n, const char *p1, const char *p2, const char *s):
  44. name(n), prefix1(p1), prefix2(p2), suffix(s) {};
  45. /** create subdirs in storage */
  46. bool Init(const char* chars, size_t cnt);
  47. const std::string & GetRoot() const { return root; }
  48. const std::string & GetName() const { return name; }
  49. /** set directory where to place storage directory */
  50. void SetPlace(const std::string & path);
  51. /** path to file with given ident */
  52. std::string Path(const std::string & ident) const;
  53. /** remove file by ident */
  54. void Remove(const std::string & ident);
  55. /** find all files in storage and store list in provided vector */
  56. void Traverse(std::vector<std::string> & files);
  57. /** visit every file in this storage with a visitor */
  58. void Iterate(FilenameVisitor v);
  59. };
  60. /** @brief Returns current application name, default 'i2pd' */
  61. const std::string & GetAppName ();
  62. /** @brief Set application name, affects autodetection of datadir */
  63. void SetAppName (const std::string& name);
  64. /** @brief Returns datadir path */
  65. const std::string & GetDataDir();
  66. /**
  67. * @brief Set datadir either from cmdline option or using autodetection
  68. * @param cmdline_param Value of cmdline parameter --datadir=<something>
  69. * @param isService Value of cmdline parameter --service
  70. *
  71. * Examples of autodetected paths:
  72. *
  73. * Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\
  74. * Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\
  75. * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
  76. * Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
  77. */
  78. void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
  79. /**
  80. * @brief Create subdirectories inside datadir
  81. */
  82. bool Init();
  83. /**
  84. * @brief Get list of files in directory
  85. * @param path Path to directory
  86. * @param files Vector to store found files
  87. * @return true on success and false if directory not exists
  88. */
  89. bool ReadDir(const std::string & path, std::vector<std::string> & files);
  90. /**
  91. * @brief Remove file with given path
  92. * @param path Absolute path to file
  93. * @return true on success, false if file not exists, throws exception on error
  94. */
  95. bool Remove(const std::string & path);
  96. /**
  97. * @brief Check existence of file
  98. * @param path Absolute path to file
  99. * @return true if file exists, false otherwise
  100. */
  101. bool Exists(const std::string & path);
  102. uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch
  103. bool CreateDirectory (const std::string& path);
  104. template<typename T>
  105. void _ExpandPath(std::stringstream & path, T c) {
  106. path << i2p::fs::dirSep << c;
  107. }
  108. template<typename T, typename ... Other>
  109. void _ExpandPath(std::stringstream & path, T c, Other ... other) {
  110. _ExpandPath(path, c);
  111. _ExpandPath(path, other ...);
  112. }
  113. /**
  114. * @brief Get path relative to datadir
  115. *
  116. * Examples (with datadir = "/tmp/i2pd"):
  117. *
  118. * i2p::fs::Path("test") -> '/tmp/i2pd/test'
  119. * i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt'
  120. */
  121. template<typename ... Other>
  122. std::string DataDirPath(Other ... components) {
  123. std::stringstream s("");
  124. s << i2p::fs::GetDataDir();
  125. _ExpandPath(s, components ...);
  126. return s.str();
  127. }
  128. template<typename Storage, typename... Filename>
  129. std::string StorageRootPath (const Storage& storage, Filename... filenames)
  130. {
  131. std::stringstream s("");
  132. s << storage.GetRoot ();
  133. _ExpandPath(s, filenames...);
  134. return s.str();
  135. }
  136. } // fs
  137. } // i2p
  138. #endif // /* FS_H__ */