mountpointmgr.H 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. * */
  13. /*
  14. * mountpointmgr.H
  15. *
  16. * Created on: May 1, 2013
  17. * Author: xaxaxa
  18. */
  19. #ifndef MOUNTPOINTMGR_H_
  20. #define MOUNTPOINTMGR_H_
  21. #include <map>
  22. #include <cpoll/cpoll.H>
  23. #include <rgc.H>
  24. #include "split.H"
  25. using namespace CP;
  26. using namespace RGC;
  27. using namespace std;
  28. namespace cppsp
  29. {
  30. template<class T> struct less;
  31. template<>
  32. struct less<String> : binary_function<String, String, bool>
  33. {
  34. bool operator()(const String& x, const String& y) const {
  35. if (x.len == 0 || y.len == 0) return x.len < y.len;
  36. int complen = x.len < y.len ? x.len : y.len;
  37. int tmp = memcmp(x.d, y.d, complen);
  38. if (tmp == 0) return x.len < y.len;
  39. else return tmp < 0;
  40. }
  41. };
  42. #if false
  43. class MountPointMgr
  44. {
  45. public:
  46. map<String, Object*, cppsp::less<String> > items;
  47. Object* _find(String path) {
  48. auto it = items.upper_bound(path);
  49. if (it == items.end() && items.begin() == items.end()) return nullptr;
  50. it--;
  51. if (it == items.end()) return nullptr;
  52. if ((*it).first.len > path.len) return nullptr;
  53. int complen = (*it).first.len < path.len ? (*it).first.len : path.len;
  54. if (memcmp((*it).first.d, path.d, complen) == 0) return (*it).second;
  55. return nullptr;
  56. }
  57. Object* find(String path) {
  58. if (path.len > 0 && path.d[path.len - 1] == '/') {
  59. return _find(path);
  60. } else {
  61. char tmp[path.len + 1];
  62. memcpy(tmp, path.d, path.len);
  63. tmp[path.len] = '/';
  64. return _find( {tmp, path.len + 1});
  65. }
  66. }
  67. bool mount(String path, Object* handler) {
  68. String tmp;
  69. if (path.len > 0 && path.d[path.len - 1] == '/') {
  70. tmp.len = path.len;
  71. tmp.d = (char*) malloc(tmp.len + 1); //insert null byte just in case
  72. memcpy(tmp.d, path.d, tmp.len);
  73. tmp.d[tmp.len] = '\0';
  74. } else {
  75. tmp.len = path.len + 1;
  76. tmp.d = (char*) malloc(tmp.len + 1);
  77. memcpy(tmp.d, path.d, path.len);
  78. tmp.d[path.len] = '/';
  79. tmp.d[tmp.len] = '\0';
  80. }
  81. auto it = items.find(tmp);
  82. if (it == items.end()) {
  83. items.insert( {tmp, handler});
  84. return true;
  85. } else {
  86. free(tmp.d);
  87. return false;
  88. }
  89. }
  90. Object* umount(String path) {
  91. String tmp;
  92. if (path.len > 0 && path.d[path.len - 1] == '/') {
  93. tmp.d = nullptr;
  94. } else {
  95. tmp.len = path.len + 1;
  96. tmp.d = (char*) malloc(tmp.len + 1);
  97. memcpy(tmp.d, path.d, path.len);
  98. tmp.d[path.len] = '/';
  99. tmp.d[tmp.len] = '\0';
  100. }
  101. auto it = items.find(tmp.d == nullptr ? path : tmp);
  102. Object* o;
  103. if (it != items.end()) {
  104. o = (*it).second;
  105. free((*it).first.d);
  106. items.erase(it);
  107. } else {
  108. o = nullptr;
  109. }
  110. if (tmp.d != nullptr) free(tmp.d);
  111. return o;
  112. }
  113. MountPointMgr() {
  114. }
  115. virtual ~MountPointMgr() {
  116. }
  117. };
  118. #endif
  119. class MountPointMgr
  120. {
  121. public:
  122. struct dirent
  123. {
  124. Object* obj;
  125. void* children;
  126. dirent() :
  127. obj(nullptr), children(nullptr) {
  128. }
  129. };
  130. typedef map<String, dirent, cppsp::less<String> > Map;
  131. dirent root;
  132. Object* find(String path) {
  133. split spl(path.d, path.len, '/');
  134. dirent* curr = &root;
  135. Object* o = root.obj;
  136. while (spl.read()) {
  137. if (spl.value.len <= 0) goto aaaaa;
  138. {
  139. //printf("spl.value=(len=%i) %s\n", spl.value.len, spl.value.toSTDString().c_str());
  140. if (curr->children == nullptr) {
  141. //printf("curr->children==NULL\n");
  142. break;
  143. }
  144. Map* m = (Map*) curr->children;
  145. auto it = m->find(spl.value);
  146. if (it == m->end()) {
  147. //printf("it == m->end(); spl.value=%s\n", spl.value.toSTDString().c_str());
  148. break;
  149. }
  150. curr = &(*it).second;
  151. if (curr->obj != NULL) o = curr->obj;
  152. }
  153. aaaaa: ;
  154. }
  155. return o;
  156. }
  157. bool mount(String path, Object* handler) {
  158. split spl(path.d, path.len, '/');
  159. dirent* curr = &root;
  160. while (spl.read()) {
  161. if (spl.value.len <= 0) goto aaaaa;
  162. {
  163. //printf("spl.value=(len=%i) %s\n", spl.value.len, spl.value.toSTDString().c_str());
  164. Map* m;
  165. if (curr->children == nullptr) {
  166. curr->children = m = new Map();
  167. } else {
  168. m = (Map*) curr->children;
  169. }
  170. auto it = m->find(spl.value);
  171. if (it == m->end()) {
  172. String s;
  173. s.d = (char*) malloc((s.len = spl.value.len));
  174. memcpy(s.d, spl.value.d, s.len);
  175. curr = &(*m)[s];
  176. } else curr = &(*it).second;
  177. }
  178. aaaaa: ;
  179. }
  180. if (curr->obj == nullptr) {
  181. curr->obj = handler;
  182. return true;
  183. }
  184. return false;
  185. }
  186. Object* umount(String path) {
  187. split spl(path.d, path.len, '/');
  188. dirent* curr = &root;
  189. while (spl.read()) {
  190. if (spl.value.len <= 0) goto aaaaa;
  191. {
  192. Map* m;
  193. if (curr->children == nullptr) {
  194. return nullptr;
  195. } else {
  196. m = (Map*) curr->children;
  197. }
  198. auto it = m->find(spl.value);
  199. if (it == m->end()) {
  200. return nullptr;
  201. } else curr = &(*it).second;
  202. }
  203. aaaaa: ;
  204. }
  205. Object* o = curr->obj;
  206. curr->obj = NULL;
  207. return o;
  208. }
  209. template<class SW>
  210. void print(SW& sw, dirent* d, string s = "/", int l = 0) {
  211. char tmp[l + 1];
  212. memset(tmp, ' ', l);
  213. tmp[l] = 0;
  214. if (d->obj != NULL) sw.writeF("%s%s\n", (char*) tmp, s.c_str());
  215. if (d->children == nullptr) {
  216. return;
  217. } else {
  218. Map* m = (Map*) d->children;
  219. for (auto it = m->begin(); it != m->end(); it++) {
  220. print(sw, &(*it).second, s + (*it).first.toSTDString() + "/", l + 1);
  221. }
  222. }
  223. }
  224. template<class SW>
  225. void print(SW& sw) {
  226. print(sw, &root);
  227. }
  228. void clear(dirent* d) {
  229. if (d->obj != nullptr) {
  230. d->obj->destruct();
  231. d->obj = nullptr;
  232. }
  233. if (d->children != nullptr) {
  234. Map* m = (Map*) d->children;
  235. for (auto it = m->begin(); it != m->end(); it++) {
  236. clear(&(*it).second);
  237. String s = (*it).first;
  238. free(s.d);
  239. }
  240. delete m;
  241. d->children = nullptr;
  242. }
  243. }
  244. void clear() {
  245. clear(&root);
  246. }
  247. MountPointMgr() {
  248. }
  249. virtual ~MountPointMgr() {
  250. clear();
  251. }
  252. };
  253. } /* namespace cppsp */
  254. #endif /* MOUNTPOINTMGR_H_ */