1 /*
2  * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #pragma once
20 
21 #include "noexcept.h"
22 #include "User.h"
23 #include "FastAlloc.h"
24 #include "MerkleTree.h"
25 #include "Streams.h"
26 #include "MediaInfo.h"
27 
28 namespace dcpp {
29 
30 class ListLoader;
31 
32 class DirectoryListing : boost::noncopyable
33 {
34 public:
35     class Directory;
36 
37     class File : public FastAlloc<File> {
38     public:
39         typedef File* Ptr;
40         struct FileSort {
operatorFileSort41             bool operator()(const Ptr& a, const Ptr& b) const {
42                 return Util::stricmp(a->getName().c_str(), b->getName().c_str()) < 0;
43             }
44         };
45         typedef vector<Ptr> List;
46         typedef List::iterator Iter;
47 
File(Directory * aDir,const string & aName,int64_t aSize,const TTHValue & aTTH)48         File(Directory* aDir, const string& aName, int64_t aSize, const TTHValue& aTTH) noexcept :
49             name(aName), size(aSize), parent(aDir), tthRoot(aTTH), adls(false)
50         {
51         }
52 
53         File(const File& rhs, bool _adls = false) : name(rhs.name), size(rhs.size), parent(rhs.parent), tthRoot(rhs.tthRoot), adls(_adls)
54         {
55         }
56 
57         File& operator=(const File& rhs) {
58             name = rhs.name; size = rhs.size; parent = rhs.parent; tthRoot = rhs.tthRoot;
59             return *this;
60         }
61 
~File()62         ~File() { }
63 
64         GETSET(string, name, Name);
65         GETSET(int64_t, size, Size);
66         GETSET(Directory*, parent, Parent);
67         GETSET(TTHValue, tthRoot, TTH);
68         GETSET(bool, adls, Adls);
69         GETSET(uint64_t, ts, TS);
70         GETSET(uint64_t, hit, Hit);
71         MediaInfo mediaInfo;
72     };
73 
74     class Directory : public FastAlloc<Directory>, boost::noncopyable {
75     public:
76         typedef Directory* Ptr;
77         struct DirSort {
operatorDirSort78             bool operator()(const Ptr& a, const Ptr& b) const {
79                 return Util::stricmp(a->getName().c_str(), b->getName().c_str()) < 0;
80             }
81         };
82         typedef vector<Ptr> List;
83         typedef List::iterator Iter;
84 
85         typedef unordered_set<TTHValue> TTHSet;
86 
87         List directories;
88         File::List files;
89 
Directory(Directory * aParent,const string & aName,bool _adls,bool aComplete)90         Directory(Directory* aParent, const string& aName, bool _adls, bool aComplete)
91             : name(aName), parent(aParent), adls(_adls), complete(aComplete) { }
92 
~Directory()93         virtual ~Directory() {
94             for_each(directories.begin(), directories.end(), DeleteFunction());
95             for_each(files.begin(), files.end(), DeleteFunction());
96         }
97 
98         size_t getTotalFileCount(bool adls = false);
99         int64_t getTotalSize(bool adls = false);
100         void filterList(DirectoryListing& dirList);
101         void filterList(TTHSet& l);
102         void getHashList(TTHSet& l);
103 
getFileCount()104         size_t getFileCount() { return files.size(); }
105 
getSize()106         int64_t getSize() {
107             int64_t x = 0;
108             for(auto i = files.begin(); i != files.end(); ++i) {
109                 x+=(*i)->getSize();
110             }
111             return x;
112         }
113 
114         GETSET(string, name, Name);
115         GETSET(Directory*, parent, Parent);
116         GETSET(bool, adls, Adls);
117         GETSET(bool, complete, Complete);
118 
119     };
120 
121     class AdlDirectory : public Directory {
122     public:
AdlDirectory(const string & aFullPath,Directory * aParent,const string & aName)123         AdlDirectory(const string& aFullPath, Directory* aParent, const string& aName) : Directory(aParent, aName, true, true), fullPath(aFullPath) { }
124 
125         GETSET(string, fullPath, FullPath);
126     };
127 
128     DirectoryListing(const HintedUser& aUser);
129     ~DirectoryListing();
130 
131     void loadFile(const string& name);
132 
133     string updateXML(const std::string&);
134     string loadXML(InputStream& xml, bool updating);
135 
136     void download(const string& aDir, const string& aTarget, bool highPrio);
137     void download(Directory* aDir, const string& aTarget, bool highPrio);
138     void download(File* aFile, const string& aTarget, bool view, bool highPrio);
139 
140     string getPath(const Directory* d) const;
getPath(const File * f)141     string getPath(const File* f) const { return getPath(f->getParent()); }
142 
143     /** returns the local path of the file when browsing own file list */
144     StringList getLocalPaths(const File* f) const;
145     /** returns the local paths of the directory when browsing own file list */
146     StringList getLocalPaths(const Directory* d) const;
147 
148     int64_t getTotalSize(bool adls = false) { return root->getTotalSize(adls); }
149     size_t getTotalFileCount(bool adls = false) { return root->getTotalFileCount(adls); }
150 
getRoot()151     const Directory* getRoot() const { return root; }
getRoot()152     Directory* getRoot() { return root; }
153 
154     static UserPtr getUserFromFilename(const string& fileName);
155 
156     GETSET(HintedUser, user, User);
157 
158     Directory* find(const string& aName, Directory* current);
159 
160 private:
161     friend class ListLoader;
162 
163     Directory* root;
164 
165 };
166 
167 inline bool operator==(DirectoryListing::Directory::Ptr a, const string& b) { return Util::stricmp(a->getName(), b) == 0; }
168 inline bool operator==(DirectoryListing::File::Ptr a, const string& b) { return Util::stricmp(a->getName(), b) == 0; }
169 
170 } // namespace dcpp
171