File indexing completed on 2026-08-06 09:38:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LWH_Tree_H
0010 #define LWH_Tree_H
0011
0012
0013
0014
0015 #include "AITree.h"
0016 #include "ManagedObject.h"
0017 #include <fstream>
0018 #include <iostream>
0019 #include <vector>
0020 #include <set>
0021 #include <map>
0022 #include <string>
0023
0024 namespace LWH {
0025
0026 using namespace AIDA;
0027
0028
0029
0030
0031
0032 class Tree: public ITree {
0033
0034 public:
0035
0036
0037 friend class AnalysisFactory;
0038
0039
0040 typedef std::vector<std::string> Path;
0041
0042
0043 typedef std::set<Path> PathSet;
0044
0045
0046 typedef std::map<std::string, IManagedObject *> ObjMap;
0047
0048 public:
0049
0050
0051
0052
0053 Tree(std::string storename, bool xml = true)
0054 : name(storename), flat(!xml), cwd("/"), overwrite(true) {
0055 dirs.insert(Path());
0056 }
0057
0058
0059
0060
0061 Tree(): name(""), flat(false), cwd("/") {
0062 dirs.insert(Path());
0063 }
0064
0065
0066
0067
0068 Tree(const Tree & dt)
0069 : ITree(dt), name(dt.name), flat(dt.flat), dirs(dt.dirs),
0070 objs(dt.objs), cwd(dt.cwd), overwrite(true) {}
0071
0072
0073 virtual ~Tree() {
0074 for ( ObjMap::iterator it = objs.begin(); it != objs.end(); ++it )
0075 delete it->second;
0076 }
0077
0078
0079
0080
0081
0082 std::string storeName() const {
0083 return name;
0084 }
0085
0086
0087
0088
0089
0090
0091
0092 IManagedObject * find(const std::string & path) {
0093 ObjMap::const_iterator it = objs.find(path);
0094 return it == objs.end()? (IManagedObject *)0: it->second;
0095 }
0096
0097
0098
0099
0100
0101 ITree * findTree(const std::string &) {
0102 return 0;
0103 }
0104
0105
0106
0107
0108
0109
0110
0111 bool cd(const std::string & dir) {
0112 PathSet::iterator it = dirs.find(purgepath(str2pth(fullpath(sts(dir)))));
0113 if ( it == dirs.end() ) return false;
0114 cwd = pth2str(*it);
0115 return true;
0116 }
0117
0118
0119
0120
0121 bool insert(std::string str, IManagedObject * o) {
0122 Path path = purgepath(str2pth(fullpath(str)));
0123 if ( dirs.find(path) == dirs.end() ) {
0124 std::string fullname = pth2str(path);
0125 path.pop_back();
0126 if ( dirs.find(path) != dirs.end() ) {
0127 ObjMap::iterator old = objs.find(fullname);
0128 if ( old == objs.end() || overwrite ) {
0129 if ( old != objs.end() ) {
0130 delete old->second;
0131 objs.erase(old);
0132 }
0133 objs[fullname] = o;
0134 return true;
0135 }
0136 }
0137 }
0138 return false;
0139 }
0140
0141
0142
0143
0144
0145 std::string pwd() const {
0146 return cwd;
0147 }
0148
0149
0150
0151
0152
0153
0154 bool ls(const std::string & = ".", bool = false,
0155 std::ostream & = std::cout) const {
0156 return false;
0157 }
0158
0159
0160
0161
0162 std::vector<std::string> listObjectNames(const std::string & = ".",
0163 bool = false) const {
0164 return std::vector<std::string>();
0165 }
0166
0167
0168
0169
0170 std::vector<std::string> listObjectTypes(const std::string & = ".",
0171 bool = false) const {
0172 return std::vector<std::string>();
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182 bool mkdir(const std::string & dir) {
0183 Path p = purgepath(str2pth(fullpath(sts(dir))));
0184 Path base = p;
0185 base.pop_back();
0186 if ( dirs.find(base) == dirs.end() ) return false;
0187 dirs.insert(p);
0188 return true;
0189 }
0190
0191
0192
0193
0194
0195
0196
0197
0198 bool mkdirs(const std::string & dir) {
0199 return mkdirs(purgepath(str2pth(fullpath(sts(dir)))));
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209 bool mkdirs(Path p) {
0210 if ( dirs.find(p) != dirs.end() ) return true;
0211 dirs.insert(p);
0212 p.pop_back();
0213 return mkdirs(p);
0214 }
0215
0216
0217
0218
0219
0220
0221
0222 bool rmdir(const std::string & dir) {
0223 Path path = purgepath(str2pth(fullpath(sts(dir))));
0224 if ( dirs.find(path) == dirs.end() ) return false;
0225 for ( ObjMap::const_iterator it = objs.begin(); it != objs.end(); ++it )
0226 if ( it->first.substr(0, dir.length()) == dir ) return false;
0227 dirs.erase(path);
0228 return true;
0229 }
0230
0231
0232
0233
0234
0235
0236
0237 bool rm(const std::string & path) {
0238 ObjMap::iterator it = objs.find(fullpath(path));
0239 if ( it == objs.end() ) return false;
0240 delete it->second;
0241 objs.erase(it);
0242 return true;
0243 }
0244
0245
0246
0247
0248
0249
0250
0251 std::string findPath(const IManagedObject & o) const {
0252 for ( ObjMap::const_iterator it = objs.begin(); it != objs.end(); ++it )
0253 if ( it->second == &o ) return it->first;
0254 return "";
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264 bool mv(const std::string & oldp, const std::string & newp) {
0265 Path newpath = purgepath(str2pth(fullpath(sts(newp))));
0266 std::string foldp = fullpath(oldp);
0267 Path oldpath = purgepath(str2pth(foldp));
0268 ObjMap::iterator it = objs.find(foldp);
0269 if ( it == objs.end() ) return false;
0270 if ( dirs.find(newpath) != dirs.end() ) return false;
0271 newpath.push_back(oldpath.back());
0272 if ( !insert(pth2str(newpath), it->second) ) return false;
0273 objs.erase(foldp);
0274 return true;
0275 }
0276
0277
0278
0279
0280
0281 bool commit() {
0282 std::ofstream of(name.c_str());
0283 if ( !of ) return false;
0284 if ( !flat ) of
0285 << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE aida SYSTEM "
0286 << "\"http://aida.freehep.org/schemas/3.0/aida.dtd\">\n"
0287 << "<aida version=\"3.0\">\n"
0288 << "<implementation version=\"1.0\" package=\"FreeHEP\"/>" << std::endl;
0289 for ( ObjMap::const_iterator it = objs.begin(); it != objs.end(); ++it ) {
0290 ManagedObject * o = dynamic_cast<ManagedObject *>(it->second);
0291 if ( !o ) continue;
0292 std::string path = it->first.substr(0, it->first.rfind('/'));
0293 std::string name = it->first.substr(it->first.rfind('/') + 1);
0294 if ( flat )
0295 o->writeFLAT(of, path, name);
0296 else
0297 o->writeXML(of, path, name);
0298 }
0299 if ( !flat ) of << "</aida>" << std::endl;
0300 return of.good();
0301 }
0302
0303
0304
0305
0306 void setOverwrite(bool o = true) {
0307 overwrite = o;
0308 }
0309
0310
0311
0312
0313
0314 bool cp(const std::string &, const std::string &, bool = false) {
0315 return false;
0316 }
0317
0318
0319
0320
0321
0322 bool symlink(const std::string &, const std::string &) {
0323 return false;
0324 }
0325
0326
0327
0328
0329
0330 bool mount(const std::string &, ITree &, const std::string &) {
0331 return false;
0332 }
0333
0334
0335
0336
0337
0338 bool unmount(const std::string &) {
0339 return false;
0340 }
0341
0342
0343
0344
0345 bool close() {
0346 return commit();
0347 }
0348
0349
0350
0351
0352
0353 void * cast(const std::string &) const {
0354 return 0;
0355 }
0356
0357 protected:
0358
0359
0360 std::string sts(std::string s) const {
0361 if ( s[s.length() - 1] == '/' ) s = s.substr(0, s.length() - 1);
0362 if ( s[s.length() - 1] == '/' ) return "";
0363 return s;
0364 }
0365
0366
0367 std::string stn(std::string s) const {
0368 std::string::size_type slash = s.rfind('/');
0369 return s.substr(0, slash);
0370 }
0371
0372
0373 std::string fullpath(std::string d) const {
0374 if ( d[0] != '/' ) d = cwd + "/" + d;
0375 return pth2str(purgepath(str2pth(d)));
0376 }
0377
0378
0379 Path str2pth(std::string s) const {
0380 Path pth;
0381 std::string::size_type i = s.find_first_not_of("/");
0382 while ( i != std::string::npos ) {
0383 s = s.substr(i);
0384 i = s.find_first_of("/");
0385 pth.push_back(s.substr(0, i));
0386 if ( i == std::string::npos ) return pth;
0387 s = s.substr(i);
0388 i = s.find_first_not_of("/");
0389 }
0390 return pth;
0391 }
0392
0393
0394 std::string pth2str(const Path & pth) const {
0395 std::string str;
0396 for ( int i = 0, N = pth.size(); i < N; ++i ) str += "/" + pth[i];
0397 return str;
0398 }
0399
0400
0401 Path purgepath(const Path & pth) const {
0402 Path p;
0403 for ( int i = 0, N = pth.size(); i < N; ++i ) {
0404 if ( pth[i] == ".." ) p.pop_back();
0405 else if ( pth[i] != "." ) p.push_back(pth[i]);
0406 }
0407 return p;
0408 }
0409
0410 private:
0411
0412
0413 std::string name;
0414
0415
0416 bool flat;
0417
0418
0419 PathSet dirs;
0420
0421
0422 ObjMap objs;
0423
0424
0425 std::string cwd;
0426
0427
0428 bool overwrite;
0429
0430 };
0431
0432 }
0433
0434 #endif