00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "nstream.h"
00036
00037 #include <fstream>
00038 #ifdef WIN32
00039 #define stat _stat
00040 #include <sys/types.h>
00041 #else // WIN32
00042 #include <unistd.h>
00043 #endif // WIN32
00044 #include <sys/stat.h>
00045
00046 #include "common/wave_ex.h"
00047 #include "perf/perf.h"
00048 #include "util/file.h"
00049 #include "util/token_stream.h"
00050
00051
00052 namespace nstream {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static smart_ptr<Entry> getEntryForName(IN const char * name,
00063 IN const char * rootDir);
00064
00065
00066 static std::string
00067 getFullPath
00068 (
00069 IN const char * rootDir,
00070 IN const char * name
00071 )
00072 {
00073 ASSERT(rootDir, "null");
00074 ASSERT(name, "null");
00075
00076 std::string retval;
00077 appendPath(rootDir, name, retval);
00078 return retval;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 class FSStream : public Stream {
00091 public:
00092
00093 ~FSStream(void) throw() { }
00094
00095
00096 std::istream& getStream(void) { return m_stream; }
00097 smart_ptr<File> getFile(void);
00098
00099
00100 static smart_ptr<Stream> create(IN const char * name,
00101 IN const char * rootDir);
00102
00103 private:
00104
00105 FSStream(void) throw() { }
00106
00107
00108 std::ifstream m_stream;
00109 std::string m_name;
00110 std::string m_rootDir;
00111 };
00112
00113
00114
00115 smart_ptr<File>
00116 FSStream::getFile
00117 (
00118 void
00119 )
00120 {
00121
00122 smart_ptr<File> file =
00123 getEntryForName(m_name.c_str(), m_rootDir.c_str());
00124
00125
00126
00127
00128 THROW(file,
00129 "filesystem stream is for file now gone: " << m_rootDir << "/"
00130 << m_name);
00131
00132
00133 return file;
00134 }
00135
00136
00137
00138 smart_ptr<Stream>
00139 FSStream::create
00140 (
00141 IN const char * name,
00142 IN const char * rootDir
00143 )
00144 {
00145 ASSERT(name, "null");
00146 ASSERT(rootDir, "null");
00147
00148 smart_ptr<FSStream> local = new FSStream;
00149 ASSERT(local, "out of memory");
00150
00151 local->m_name = name;
00152 local->m_rootDir = rootDir;
00153
00154
00155 std::string full_path = getFullPath(rootDir, name);
00156
00157
00158 local->m_stream.open(full_path.c_str(), std::ios::binary);
00159 THROW(local->m_stream.good(),
00160 "Failed to open file for reading: " << full_path);
00161
00162
00163 return local;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 class FSFile : public File {
00176 public:
00177
00178 ~FSFile(void) throw() { }
00179
00180
00181 eType getType(void) const throw() { return eType_File; }
00182 const char * getName(void) const throw() { return m_name.c_str(); }
00183 smart_ptr<Manager> getManager(void) {
00184 return getFilesystemManager(m_rootDir.c_str());
00185 }
00186
00187
00188 smart_ptr<Stream> openStream(void);
00189
00190
00191 static smart_ptr<File> create(IN const char * name,
00192 IN const char * rootDir);
00193
00194 private:
00195
00196 FSFile(void) throw() { }
00197
00198
00199 std::string m_name;
00200 std::string m_rootDir;
00201 };
00202
00203
00204
00205 smart_ptr<Stream>
00206 FSFile::openStream
00207 (
00208 void
00209 )
00210 {
00211 return FSStream::create(m_name.c_str(), m_rootDir.c_str());
00212 }
00213
00214
00215
00216 smart_ptr<File>
00217 FSFile::create
00218 (
00219 IN const char * name,
00220 IN const char * rootDir
00221 )
00222 {
00223 ASSERT(name, "null");
00224 ASSERT(rootDir, "null");
00225
00226 smart_ptr<FSFile> local = new FSFile;
00227 ASSERT(local, "out of memory");
00228
00229 local->m_name = name;
00230 local->m_rootDir = rootDir;
00231
00232 return local;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 class FSFolder : public Folder {
00249 public:
00250
00251 ~FSFolder(void) throw();
00252
00253
00254 eType getType(void) const throw() { return eType_Folder; }
00255 const char * getName(void) const throw() { return m_name.c_str(); }
00256 smart_ptr<Manager> getManager(void) {
00257 return getFilesystemManager(m_rootDir.c_str());
00258 }
00259
00260
00261 smart_ptr<Entry> getChildByName(IN const char * name);
00262 void resetIteration(void);
00263 smart_ptr<Entry> getNextChild(void);
00264
00265
00266 static smart_ptr<Folder> create(IN const char * name,
00267 IN const char * root);
00268
00269 private:
00270
00271 FSFolder(void) throw();
00272 void closeDir(void) throw();
00273
00274
00275 DIR * m_DIR;
00276 std::string m_name;
00277 std::string m_rootDir;
00278 };
00279
00280
00281
00282 FSFolder::FSFolder(void)
00283 throw()
00284 :
00285 m_DIR(NULL)
00286 {
00287 }
00288
00289
00290
00291 FSFolder::~FSFolder(void)
00292 throw()
00293 {
00294 this->closeDir();
00295 }
00296
00297
00298
00299 smart_ptr<Entry>
00300 FSFolder::getChildByName
00301 (
00302 IN const char * name
00303 )
00304 {
00305 ASSERT(name, "null");
00306
00307 std::string relPath = getFullPath(m_name.c_str(), name);
00308 return getEntryForName(relPath.c_str(), m_rootDir.c_str());
00309 }
00310
00311
00312
00313 void
00314 FSFolder::resetIteration
00315 (
00316 void
00317 )
00318 {
00319 this->closeDir();
00320 }
00321
00322
00323
00324 smart_ptr<Entry>
00325 FSFolder::getNextChild
00326 (
00327 void
00328 )
00329 {
00330 if (!m_DIR) {
00331
00332 std::string full_path =
00333 getFullPath(m_rootDir.c_str(), m_name.c_str());
00334 m_DIR = opendir(full_path.c_str());
00335 THROW(m_DIR,
00336 "Failed to open directory: " << full_path);
00337 }
00338
00339
00340 struct dirent * entry = NULL;
00341 while (true) {
00342 entry = readdir(m_DIR);
00343 if (!entry) {
00344
00345 this->closeDir();
00346 return NULL;
00347 }
00348
00349
00350
00351 if (!strcmp(".", entry->d_name) ||
00352 !strcmp("..", entry->d_name)) {
00353 continue;
00354 }
00355
00356
00357 break;
00358 }
00359 ASSERT(entry, "null");
00360
00361
00362 std::string relPath = getFullPath(m_name.c_str(), entry->d_name);
00363 return getEntryForName(relPath.c_str(), m_rootDir.c_str());
00364 }
00365
00366
00367
00368 void
00369 FSFolder::closeDir
00370 (
00371 void
00372 )
00373 throw()
00374 {
00375 if (m_DIR) {
00376 closedir(m_DIR);
00377 m_DIR = NULL;
00378 }
00379 }
00380
00381
00382
00383 smart_ptr<Folder>
00384 FSFolder::create
00385 (
00386 IN const char * name,
00387 IN const char * rootDir
00388 )
00389 {
00390 ASSERT(name, "null");
00391 ASSERT(rootDir, "null");
00392
00393
00394
00395
00396 smart_ptr<FSFolder> local = new FSFolder();
00397 ASSERT(local, "out of memory");
00398
00399 local->m_name = name;
00400 local->m_rootDir = rootDir;
00401
00402 return local;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 class FSMgr : public Manager {
00415 public:
00416
00417 ~FSMgr(void) throw() { }
00418
00419
00420 void initialize(IN const char * rootDir);
00421
00422
00423 smart_ptr<Entry> getEntry(IN const char * name);
00424 smart_ptr<Folder> getRoot(void);
00425 std::string getFullName(IN const char * name);
00426
00427 private:
00428
00429 std::string m_rootDir;
00430 };
00431
00432
00433
00434 void
00435 FSMgr::initialize
00436 (
00437 IN const char * rootDir
00438 )
00439 {
00440 ASSERT(rootDir, "null");
00441
00442 m_rootDir = rootDir;
00443 }
00444
00445
00446
00447 smart_ptr<Entry>
00448 FSMgr::getEntry
00449 (
00450 IN const char * name
00451 )
00452 {
00453 ASSERT(name, "null");
00454
00455 return getEntryForName(name, m_rootDir.c_str());
00456 }
00457
00458
00459
00460 smart_ptr<Folder>
00461 FSMgr::getRoot
00462 (
00463 void
00464 )
00465 {
00466 return FSFolder::create("", m_rootDir.c_str());
00467 }
00468
00469
00470
00471 std::string
00472 FSMgr::getFullName
00473 (
00474 IN const char * name
00475 )
00476 {
00477 ASSERT(name, "null");
00478 return getFullPath(m_rootDir.c_str(), name);
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 static smart_ptr<Entry>
00490 getEntryForName
00491 (
00492 IN const char * name,
00493 IN const char * rootDir
00494 )
00495 {
00496 ASSERT(name, "null");
00497 ASSERT(rootDir, "null");
00498
00499
00500
00501
00502 std::string full_path = getFullPath(rootDir, name);
00503 const char * path = full_path.c_str();
00504
00505
00506 struct stat sb;
00507 if (stat(path, &sb)) {
00508 DPRINTF("Could not stat filesystem path: %s", path);
00509 return NULL;
00510 }
00511
00512
00513 if (S_IFDIR & sb.st_mode) {
00514 return FSFolder::create(name, rootDir);
00515 }
00516
00517
00518 return FSFile::create(name, rootDir);
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 smart_ptr<Manager>
00530 getFilesystemManager
00531 (
00532 IN const char * root_dir
00533 )
00534 {
00535 ASSERT(root_dir, "null");
00536
00537 smart_ptr<FSMgr> local = new FSMgr;
00538 local->initialize(root_dir);
00539
00540 return local;
00541 }
00542
00543
00544
00545 };
00546