diff --git a/libs/openFrameworks/utils/ofFileUtils.cpp b/libs/openFrameworks/utils/ofFileUtils.cpp index 3259c5c5c1a..9304a833c7e 100644 --- a/libs/openFrameworks/utils/ofFileUtils.cpp +++ b/libs/openFrameworks/utils/ofFileUtils.cpp @@ -3,69 +3,68 @@ #include "ofUtils.h" #ifndef TARGET_WIN32 - #include - #include - #include +#include +#include +#include #endif #ifdef TARGET_OSX - #include /* _NSGetExecutablePath */ - #include /* PATH_MAX */ +#include /* _NSGetExecutablePath */ +#include /* PATH_MAX */ #endif // FIXME: better explicit declaration -using std::string; -using std::vector; using std::fstream; +using std::ios; using std::istream; using std::ostream; -using std::ios; +using std::string; +using std::vector; -namespace{ - bool enableDataPath = true; +namespace { +bool enableDataPath = true; - //-------------------------------------------------- +//-------------------------------------------------- // MARK: - near future // of::filesystem::path defaultDataPath(){ - std::string defaultDataPath(){ - #if defined TARGET_OSX - try{ - return of::filesystem::canonical(ofFilePath::getCurrentExeDir() / of::filesystem::path("../../../data/")).string(); - }catch(...){ - return (ofFilePath::getCurrentExeDir() / of::filesystem::path("../../../data/")).string(); - } - #elif defined TARGET_ANDROID - return string("sdcard/"); - #else - try{ - return of::filesystem::canonical(ofFilePath::join(ofFilePath::getCurrentExeDir(), "data/")).make_preferred().string(); - }catch(...){ - return (ofFilePath::getCurrentExeDir() / of::filesystem::path("data/")).string(); - } - #endif - } - - //-------------------------------------------------- - of::filesystem::path & defaultWorkingDirectory(){ - static auto * defaultWorkingDirectory = new of::filesystem::path(ofFilePath::getCurrentExeDir()); - return * defaultWorkingDirectory; - } +std::string defaultDataPath() { +#if defined TARGET_OSX +try { + return of::filesystem::canonical(ofFilePath::getCurrentExeDir() / of::filesystem::path("../../../data/")).string(); +} catch (...) { + return (ofFilePath::getCurrentExeDir() / of::filesystem::path("../../../data/")).string(); +} +#elif defined TARGET_ANDROID +return string("sdcard/"); +#else +try { + return of::filesystem::canonical(ofFilePath::join(ofFilePath::getCurrentExeDir(), "data/")).make_preferred().string(); +} catch (...) { + return (ofFilePath::getCurrentExeDir() / of::filesystem::path("data/")).string(); +} +#endif +} - //-------------------------------------------------- - of::filesystem::path & dataPathRoot(){ - static auto * dataPathRoot = new of::filesystem::path(defaultDataPath()); - return *dataPathRoot; - } +//-------------------------------------------------- +of::filesystem::path & defaultWorkingDirectory() { +static auto * defaultWorkingDirectory = new of::filesystem::path(ofFilePath::getCurrentExeDir()); +return *defaultWorkingDirectory; } -namespace of{ - namespace priv{ - void initfileutils(){ - defaultWorkingDirectory() = of::filesystem::absolute(of::filesystem::current_path()); - } - } +//-------------------------------------------------- +of::filesystem::path & dataPathRoot() { +static auto * dataPathRoot = new of::filesystem::path(defaultDataPath()); +return *dataPathRoot; +} } +namespace of { +namespace priv { +void initfileutils() { +defaultWorkingDirectory() = of::filesystem::absolute(of::filesystem::current_path()); +} +} +} //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ @@ -75,391 +74,387 @@ namespace of{ //-------------------------------------------------- ofBuffer::ofBuffer() -:currentLine(end(),end()){ +: currentLine(end(), end()) { } //-------------------------------------------------- ofBuffer::ofBuffer(const char * buffer, std::size_t size) -:buffer(buffer,buffer+size) -,currentLine(end(),end()){ +: buffer(buffer, buffer + size) +, currentLine(end(), end()) { } //-------------------------------------------------- ofBuffer::ofBuffer(istream & stream, std::size_t ioBlockSize) -:currentLine(end(),end()){ - set(stream, ioBlockSize); +: currentLine(end(), end()) { +set(stream, ioBlockSize); } //-------------------------------------------------- -bool ofBuffer::set(istream & stream, std::size_t ioBlockSize){ - if(stream.bad()){ - clear(); - return false; - }else{ - buffer.clear(); - } +bool ofBuffer::set(istream & stream, std::size_t ioBlockSize) { +if (stream.bad()) { + clear(); + return false; +} else { + buffer.clear(); +} - vector aux_buffer(ioBlockSize); - while(stream.good()){ - stream.read(&aux_buffer[0], ioBlockSize); - append(aux_buffer.data(), stream.gcount()); - } - return true; +vector aux_buffer(ioBlockSize); +while (stream.good()) { + stream.read(&aux_buffer[0], ioBlockSize); + append(aux_buffer.data(), stream.gcount()); +} +return true; } //-------------------------------------------------- -void ofBuffer::setall(char mem){ - buffer.assign(buffer.size(), mem); +void ofBuffer::setall(char mem) { +buffer.assign(buffer.size(), mem); } //-------------------------------------------------- bool ofBuffer::writeTo(ostream & stream) const { - if(stream.bad()){ - return false; - } - stream.write(buffer.data(), buffer.size()); - return stream.good(); +if (stream.bad()) { + return false; +} +stream.write(buffer.data(), buffer.size()); +return stream.good(); } //-------------------------------------------------- -void ofBuffer::set(const char * buffer, std::size_t size){ - this->buffer.assign(buffer, buffer+size); +void ofBuffer::set(const char * buffer, std::size_t size) { +this->buffer.assign(buffer, buffer + size); } //-------------------------------------------------- -void ofBuffer::set(const std::string & text){ - set(text.c_str(), text.size()); +void ofBuffer::set(const std::string & text) { +set(text.c_str(), text.size()); } //-------------------------------------------------- -void ofBuffer::append(const std::string& buffer){ - append(buffer.c_str(), buffer.size()); +void ofBuffer::append(const std::string & buffer) { +append(buffer.c_str(), buffer.size()); } //-------------------------------------------------- -void ofBuffer::append(const char * buffer, std::size_t size){ - this->buffer.insert(this->buffer.end(), buffer, buffer + size); +void ofBuffer::append(const char * buffer, std::size_t size) { +this->buffer.insert(this->buffer.end(), buffer, buffer + size); } //-------------------------------------------------- -void ofBuffer::reserve(std::size_t size){ - buffer.reserve(size); +void ofBuffer::reserve(std::size_t size) { +buffer.reserve(size); } //-------------------------------------------------- -void ofBuffer::clear(){ - buffer.clear(); +void ofBuffer::clear() { +buffer.clear(); } //-------------------------------------------------- -void ofBuffer::allocate(std::size_t size){ - resize(size); +void ofBuffer::allocate(std::size_t size) { +resize(size); } //-------------------------------------------------- -void ofBuffer::resize(std::size_t size){ - buffer.resize(size); +void ofBuffer::resize(std::size_t size) { +buffer.resize(size); } - //-------------------------------------------------- -char * ofBuffer::getData(){ - return buffer.data(); +char * ofBuffer::getData() { +return buffer.data(); } //-------------------------------------------------- -const char * ofBuffer::getData() const{ - return buffer.data(); +const char * ofBuffer::getData() const { +return buffer.data(); } //-------------------------------------------------- -char * ofBuffer::getBinaryBuffer(){ - return getData(); +char * ofBuffer::getBinaryBuffer() { +return getData(); } //-------------------------------------------------- const char * ofBuffer::getBinaryBuffer() const { - return getData(); +return getData(); } //-------------------------------------------------- string ofBuffer::getText() const { - if(buffer.empty()){ - return ""; - } - return std::string(buffer.begin(), buffer.end()); +if (buffer.empty()) { + return ""; +} +return std::string(buffer.begin(), buffer.end()); } //-------------------------------------------------- ofBuffer::operator std::string() const { - return getText(); +return getText(); } //-------------------------------------------------- -ofBuffer & ofBuffer::operator=(const std::string & text){ - set(text); - return *this; +ofBuffer & ofBuffer::operator=(const std::string & text) { +set(text); +return *this; } //-------------------------------------------------- std::size_t ofBuffer::size() const { - return buffer.size(); +return buffer.size(); } //-------------------------------------------------- -string ofBuffer::getNextLine(){ - if(currentLine.empty()){ - currentLine = getLines().begin(); - }else{ - ++currentLine; - } - return currentLine.asString(); +string ofBuffer::getNextLine() { +if (currentLine.empty()) { + currentLine = getLines().begin(); +} else { + ++currentLine; +} +return currentLine.asString(); } //-------------------------------------------------- -string ofBuffer::getFirstLine(){ - currentLine = getLines().begin(); - return currentLine.asString(); +string ofBuffer::getFirstLine() { +currentLine = getLines().begin(); +return currentLine.asString(); } //-------------------------------------------------- -bool ofBuffer::isLastLine(){ - return currentLine == getLines().end(); +bool ofBuffer::isLastLine() { +return currentLine == getLines().end(); } //-------------------------------------------------- -void ofBuffer::resetLineReader(){ - currentLine = getLines().begin(); +void ofBuffer::resetLineReader() { +currentLine = getLines().begin(); } //-------------------------------------------------- -vector::iterator ofBuffer::begin(){ - return buffer.begin(); +vector::iterator ofBuffer::begin() { +return buffer.begin(); } //-------------------------------------------------- -vector::iterator ofBuffer::end(){ - return buffer.end(); +vector::iterator ofBuffer::end() { +return buffer.end(); } //-------------------------------------------------- -vector::const_iterator ofBuffer::begin() const{ - return buffer.begin(); +vector::const_iterator ofBuffer::begin() const { +return buffer.begin(); } //-------------------------------------------------- -vector::const_iterator ofBuffer::end() const{ - return buffer.end(); +vector::const_iterator ofBuffer::end() const { +return buffer.end(); } //-------------------------------------------------- -vector::reverse_iterator ofBuffer::rbegin(){ - return buffer.rbegin(); +vector::reverse_iterator ofBuffer::rbegin() { +return buffer.rbegin(); } //-------------------------------------------------- -vector::reverse_iterator ofBuffer::rend(){ - return buffer.rend(); +vector::reverse_iterator ofBuffer::rend() { +return buffer.rend(); } //-------------------------------------------------- -vector::const_reverse_iterator ofBuffer::rbegin() const{ - return buffer.rbegin(); +vector::const_reverse_iterator ofBuffer::rbegin() const { +return buffer.rbegin(); } //-------------------------------------------------- -vector::const_reverse_iterator ofBuffer::rend() const{ - return buffer.rend(); +vector::const_reverse_iterator ofBuffer::rend() const { +return buffer.rend(); } //-------------------------------------------------- ofBuffer::Line::Line(vector::iterator _begin, vector::iterator _end) - :_current(_begin) - ,_begin(_begin) - ,_end(_end){ +: _current(_begin) +, _begin(_begin) +, _end(_end) { - if(_begin == _end){ - line = ""; - return; - } +if (_begin == _end) { + line = ""; + return; +} - _current = std::find(_begin, _end, '\n'); - if(_current - 1 >= _begin && *(_current - 1) == '\r'){ - line = string(_begin, _current - 1); - }else{ - line = string(_begin, _current); - } - if(_current != _end){ - _current+=1; - } +_current = std::find(_begin, _end, '\n'); +if (_current - 1 >= _begin && *(_current - 1) == '\r') { + line = string(_begin, _current - 1); +} else { + line = string(_begin, _current); +} +if (_current != _end) { + _current += 1; +} } //-------------------------------------------------- -const std::string & ofBuffer::Line::operator*() const{ - return line; +const std::string & ofBuffer::Line::operator*() const { +return line; } //-------------------------------------------------- -const std::string * ofBuffer::Line::operator->() const{ - return &line; +const std::string * ofBuffer::Line::operator->() const { +return &line; } //-------------------------------------------------- -const std::string & ofBuffer::Line::asString() const{ - return line; +const std::string & ofBuffer::Line::asString() const { +return line; } //-------------------------------------------------- -ofBuffer::Line & ofBuffer::Line::operator++(){ - *this = Line(_current,_end); - return *this; +ofBuffer::Line & ofBuffer::Line::operator++() { +*this = Line(_current, _end); +return *this; } //-------------------------------------------------- ofBuffer::Line ofBuffer::Line::operator++(int) { - Line tmp(*this); - operator++(); - return tmp; +Line tmp(*this); +operator++(); +return tmp; } //-------------------------------------------------- -bool ofBuffer::Line::operator!=(Line const& rhs) const{ - return rhs._begin != _begin || rhs._end != _end; +bool ofBuffer::Line::operator!=(Line const & rhs) const { +return rhs._begin != _begin || rhs._end != _end; } //-------------------------------------------------- -bool ofBuffer::Line::operator==(Line const& rhs) const{ - return rhs._begin == _begin && rhs._end == _end; +bool ofBuffer::Line::operator==(Line const & rhs) const { +return rhs._begin == _begin && rhs._end == _end; } -bool ofBuffer::Line::empty() const{ - return _begin == _end; +bool ofBuffer::Line::empty() const { +return _begin == _end; } - - //-------------------------------------------------- ofBuffer::RLine::RLine(vector::reverse_iterator _rbegin, vector::reverse_iterator _rend) - :_current(_rbegin) - ,_rbegin(_rbegin) - ,_rend(_rend){ +: _current(_rbegin) +, _rbegin(_rbegin) +, _rend(_rend) { - if(_rbegin == _rend){ - line = ""; - return; - } - _current = std::find(_rbegin+1, _rend, '\n'); - line = string(_current.base(), _rbegin.base() - 1); - if(_current < _rend-1 && *(_current + 1) == '\r'){ - _current+=1; - } +if (_rbegin == _rend) { + line = ""; + return; +} +_current = std::find(_rbegin + 1, _rend, '\n'); +line = string(_current.base(), _rbegin.base() - 1); +if (_current < _rend - 1 && *(_current + 1) == '\r') { + _current += 1; +} } //-------------------------------------------------- -const std::string & ofBuffer::RLine::operator*() const{ - return line; +const std::string & ofBuffer::RLine::operator*() const { +return line; } //-------------------------------------------------- -const std::string * ofBuffer::RLine::operator->() const{ - return &line; +const std::string * ofBuffer::RLine::operator->() const { +return &line; } //-------------------------------------------------- -const std::string & ofBuffer::RLine::asString() const{ - return line; +const std::string & ofBuffer::RLine::asString() const { +return line; } //-------------------------------------------------- -ofBuffer::RLine & ofBuffer::RLine::operator++(){ - *this = RLine(_current,_rend); - return *this; +ofBuffer::RLine & ofBuffer::RLine::operator++() { +*this = RLine(_current, _rend); +return *this; } //-------------------------------------------------- ofBuffer::RLine ofBuffer::RLine::operator++(int) { - RLine tmp(*this); - operator++(); - return tmp; +RLine tmp(*this); +operator++(); +return tmp; } //-------------------------------------------------- -bool ofBuffer::RLine::operator!=(RLine const& rhs) const{ - return rhs._rbegin != _rbegin || rhs._rend != _rend; +bool ofBuffer::RLine::operator!=(RLine const & rhs) const { +return rhs._rbegin != _rbegin || rhs._rend != _rend; } //-------------------------------------------------- -bool ofBuffer::RLine::operator==(RLine const& rhs) const{ - return rhs._rbegin == _rbegin && rhs._rend == _rend; +bool ofBuffer::RLine::operator==(RLine const & rhs) const { +return rhs._rbegin == _rbegin && rhs._rend == _rend; } -bool ofBuffer::RLine::empty() const{ - return _rbegin == _rend; +bool ofBuffer::RLine::empty() const { +return _rbegin == _rend; } //-------------------------------------------------- ofBuffer::Lines::Lines(vector::iterator begin, vector::iterator end) -:_begin(begin) -,_end(end){} +: _begin(begin) +, _end(end) { } //-------------------------------------------------- -ofBuffer::Line ofBuffer::Lines::begin(){ - return Line(_begin,_end); +ofBuffer::Line ofBuffer::Lines::begin() { +return Line(_begin, _end); } //-------------------------------------------------- -ofBuffer::Line ofBuffer::Lines::end(){ - return Line(_end,_end); +ofBuffer::Line ofBuffer::Lines::end() { +return Line(_end, _end); } - //-------------------------------------------------- ofBuffer::RLines::RLines(vector::reverse_iterator rbegin, vector::reverse_iterator rend) -:_rbegin(rbegin) -,_rend(rend){} +: _rbegin(rbegin) +, _rend(rend) { } //-------------------------------------------------- -ofBuffer::RLine ofBuffer::RLines::begin(){ - return RLine(_rbegin,_rend); +ofBuffer::RLine ofBuffer::RLines::begin() { +return RLine(_rbegin, _rend); } //-------------------------------------------------- -ofBuffer::RLine ofBuffer::RLines::end(){ - return RLine(_rend,_rend); +ofBuffer::RLine ofBuffer::RLines::end() { +return RLine(_rend, _rend); } //-------------------------------------------------- -ofBuffer::Lines ofBuffer::getLines(){ - return ofBuffer::Lines(begin(), end()); +ofBuffer::Lines ofBuffer::getLines() { +return ofBuffer::Lines(begin(), end()); } //-------------------------------------------------- -ofBuffer::RLines ofBuffer::getReverseLines(){ - return ofBuffer::RLines(rbegin(), rend()); +ofBuffer::RLines ofBuffer::getReverseLines() { +return ofBuffer::RLines(rbegin(), rend()); } //-------------------------------------------------- -ostream & operator<<(ostream & ostr, const ofBuffer & buf){ - buf.writeTo(ostr); - return ostr; +ostream & operator<<(ostream & ostr, const ofBuffer & buf) { +buf.writeTo(ostr); +return ostr; } //-------------------------------------------------- -istream & operator>>(istream & istr, ofBuffer & buf){ - buf.set(istr); - return istr; +istream & operator>>(istream & istr, ofBuffer & buf) { +buf.set(istr); +return istr; } //-------------------------------------------------- -ofBuffer ofBufferFromFile(const of::filesystem::path & path, bool binary){ - ofFile f(path,ofFile::ReadOnly, binary); - return ofBuffer(f); +ofBuffer ofBufferFromFile(const of::filesystem::path & path, bool binary) { +ofFile f(path, ofFile::ReadOnly, binary); +return ofBuffer(f); } //-------------------------------------------------- -bool ofBufferToFile(const of::filesystem::path & path, const ofBuffer& buffer, bool binary){ - ofFile f(path, ofFile::WriteOnly, binary); - return buffer.writeTo(f); +bool ofBufferToFile(const of::filesystem::path & path, const ofBuffer & buffer, bool binary) { +ofFile f(path, ofFile::WriteOnly, binary); +return buffer.writeTo(f); } //------------------------------------------------------------------------------------------------------------ @@ -470,181 +465,180 @@ bool ofBufferToFile(const of::filesystem::path & path, const ofBuffer& buffer, b //------------------------------------------------------------------------------------------------------------ ofFile::ofFile() -:mode(Reference) -,binary(true){ +: mode(Reference) +, binary(true) { } ofFile::ofFile(const of::filesystem::path & path, Mode mode, bool binary) -:mode(mode) -,binary(true){ - open(path, mode, binary); +: mode(mode) +, binary(true) { +open(path, mode, binary); } //------------------------------------------------------------------------------------------------------------- -ofFile::~ofFile(){ - //close(); +ofFile::~ofFile() { +//close(); } //------------------------------------------------------------------------------------------------------------- ofFile::ofFile(const ofFile & mom) -:basic_ios() -,fstream() -,mode(Reference) -,binary(true){ - copyFrom(mom); +: basic_ios() +, fstream() +, mode(Reference) +, binary(true) { +copyFrom(mom); } //------------------------------------------------------------------------------------------------------------- -ofFile & ofFile::operator=(const ofFile & mom){ - copyFrom(mom); - return *this; +ofFile & ofFile::operator=(const ofFile & mom) { +copyFrom(mom); +return *this; } //------------------------------------------------------------------------------------------------------------- -void ofFile::copyFrom(const ofFile & mom){ - if(&mom != this){ - Mode new_mode = mom.mode; - if(new_mode != Reference && new_mode != ReadOnly){ - new_mode = ReadOnly; - ofLogWarning("ofFile") << "copyFrom(): copying a writable file, opening new copy as read only"; - } - open(mom.myFile.string(), new_mode, mom.binary); +void ofFile::copyFrom(const ofFile & mom) { +if (&mom != this) { + Mode new_mode = mom.mode; + if (new_mode != Reference && new_mode != ReadOnly) { + new_mode = ReadOnly; + ofLogWarning("ofFile") << "copyFrom(): copying a writable file, opening new copy as read only"; } + open(mom.myFile.string(), new_mode, mom.binary); +} } //------------------------------------------------------------------------------------------------------------ -bool ofFile::openStream(Mode _mode, bool _binary){ - mode = _mode; - binary = _binary; - ios_base::openmode binary_mode = binary ? ios::binary : (ios_base::openmode)0; - switch(_mode) { - case WriteOnly: - case ReadWrite: - case Append: - if(!ofDirectory(ofFilePath::getEnclosingDirectory(path())).exists()){ - ofFilePath::createEnclosingDirectory(path()); - } - break; - case Reference: - case ReadOnly: - break; +bool ofFile::openStream(Mode _mode, bool _binary) { +mode = _mode; +binary = _binary; +ios_base::openmode binary_mode = binary ? ios::binary : (ios_base::openmode)0; +switch (_mode) { +case WriteOnly: +case ReadWrite: +case Append: + if (!ofDirectory(ofFilePath::getEnclosingDirectory(path())).exists()) { + ofFilePath::createEnclosingDirectory(path()); } - switch(_mode){ - case Reference: - return true; - break; - - case ReadOnly: - if(exists() && isFile()){ - fstream::open(path().c_str(), ios::in | binary_mode); - } - break; - - case WriteOnly: - fstream::open(path().c_str(), ios::out | binary_mode); - break; - - case ReadWrite: - fstream::open(path().c_str(), ios_base::in | ios_base::out | binary_mode); - break; - - case Append: - fstream::open(path().c_str(), ios::out | ios::app | binary_mode); - break; + break; +case Reference: +case ReadOnly: + break; +} +switch (_mode) { +case Reference: + return true; + break; + +case ReadOnly: + if (exists() && isFile()) { + fstream::open(path().c_str(), ios::in | binary_mode); } - return fstream::good(); + break; + +case WriteOnly: + fstream::open(path().c_str(), ios::out | binary_mode); + break; + +case ReadWrite: + fstream::open(path().c_str(), ios_base::in | ios_base::out | binary_mode); + break; + +case Append: + fstream::open(path().c_str(), ios::out | ios::app | binary_mode); + break; +} +return fstream::good(); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::open(const of::filesystem::path & _path, Mode _mode, bool binary){ - close(); - myFile = ofToDataPath(_path); - return openStream(_mode, binary); +bool ofFile::open(const of::filesystem::path & _path, Mode _mode, bool binary) { +close(); +myFile = ofToDataPath(_path); +return openStream(_mode, binary); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::openFromCWD(const of::filesystem::path & _path, Mode _mode, bool binary){ +bool ofFile::openFromCWD(const of::filesystem::path & _path, Mode _mode, bool binary) { +close(); +myFile = _path; +return openStream(_mode, binary); +} + +//------------------------------------------------------------------------------------------------------------- +bool ofFile::changeMode(Mode _mode, bool binary) { +if (_mode != mode) { + auto _path = path(); close(); myFile = _path; return openStream(_mode, binary); +} else { + return true; } - -//------------------------------------------------------------------------------------------------------------- -bool ofFile::changeMode(Mode _mode, bool binary){ - if(_mode != mode){ - auto _path = path(); - close(); - myFile = _path; - return openStream(_mode, binary); - } - else{ - return true; - } } //------------------------------------------------------------------------------------------------------------- -bool ofFile::isWriteMode(){ - return mode != ReadOnly; +bool ofFile::isWriteMode() { +return mode != ReadOnly; } //------------------------------------------------------------------------------------------------------------- -void ofFile::close(){ - myFile = of::filesystem::path(); - if(mode!=Reference) fstream::close(); +void ofFile::close() { +myFile = of::filesystem::path(); +if (mode != Reference) fstream::close(); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::create(){ - return create(path()); +bool ofFile::create() { +return create(path()); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::create(const of::filesystem::path & path){ - bool success = false; +bool ofFile::create(const of::filesystem::path & path) { +bool success = false; - auto oldmode = this->mode; - auto oldpath = this->path(); - success = open(path,ofFile::WriteOnly,binary); - close(); +auto oldmode = this->mode; +auto oldpath = this->path(); +success = open(path, ofFile::WriteOnly, binary); +close(); - if( !oldpath.empty() ){ - open(oldpath,oldmode,binary); - } +if (!oldpath.empty()) { + open(oldpath, oldmode, binary); +} - return success; +return success; } //------------------------------------------------------------------------------------------------------------ -ofBuffer ofFile::readToBuffer(){ - if(myFile.string().empty() || !of::filesystem::exists(myFile)){ - return ofBuffer(); - } +ofBuffer ofFile::readToBuffer() { +if (myFile.string().empty() || !of::filesystem::exists(myFile)) { + return ofBuffer(); +} - return ofBuffer(*this); +return ofBuffer(*this); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::writeFromBuffer(const ofBuffer & buffer){ - if(myFile.string().empty()){ - return false; - } - if(!isWriteMode()){ - ofLogError("ofFile") << "writeFromBuffer(): trying to write to read only file \"" << myFile.string() << "\""; - } - return buffer.writeTo(*this); +bool ofFile::writeFromBuffer(const ofBuffer & buffer) { +if (myFile.string().empty()) { + return false; +} +if (!isWriteMode()) { + ofLogError("ofFile") << "writeFromBuffer(): trying to write to read only file \"" << myFile.string() << "\""; +} +return buffer.writeTo(*this); } //------------------------------------------------------------------------------------------------------------ -std::filebuf *ofFile::getFileBuffer() const { - return rdbuf(); +std::filebuf * ofFile::getFileBuffer() const { +return rdbuf(); } //------------------------------------------------------------------------------------------------------------ bool ofFile::exists() const { - if(path().empty()){ - return false; - } - return of::filesystem::exists(myFile); +if (path().empty()) { + return false; +} +return of::filesystem::exists(myFile); } //------------------------------------------------------------------------------------------------------------ @@ -652,74 +646,73 @@ bool ofFile::exists() const { //of::filesystem::path ofFile::path() const { //return myFile; std::string ofFile::path() const { - return myFile.string(); +return myFile.string(); } //------------------------------------------------------------------------------------------------------------ string ofFile::getExtension() const { - auto dotext = myFile.extension().string(); - // FIXME: probably not needed; - if(!dotext.empty() && dotext.front()=='.'){ - return std::string(dotext.begin()+1,dotext.end()); - }else{ - return dotext; - } +auto dotext = myFile.extension().string(); +// FIXME: probably not needed; +if (!dotext.empty() && dotext.front() == '.') { + return std::string(dotext.begin() + 1, dotext.end()); +} else { + return dotext; +} } //------------------------------------------------------------------------------------------------------------ string ofFile::getFileName() const { - return myFile.filename().string(); +return myFile.filename().string(); } //------------------------------------------------------------------------------------------------------------ string ofFile::getBaseName() const { - return myFile.stem().string(); +return myFile.stem().string(); } //------------------------------------------------------------------------------------------------------------ // MARK: - near future //of::filesystem::path ofFile::getEnclosingDirectory() const { std::string ofFile::getEnclosingDirectory() const { - return ofFilePath::getEnclosingDirectory(path()); +return ofFilePath::getEnclosingDirectory(path()); } //------------------------------------------------------------------------------------------------------------ // MARK: - near future //of::filesystem::path ofFile::getAbsolutePath() const { std::string ofFile::getAbsolutePath() const { - return ofFilePath::getAbsolutePath(path()); +return ofFilePath::getAbsolutePath(path()); } //------------------------------------------------------------------------------------------------------------ bool ofFile::canRead() const { - + #ifdef TARGET_WIN32 - DWORD attr = GetFileAttributes(myFile.native().c_str()); - if (attr == INVALID_FILE_ATTRIBUTES) - { - return false; - } - return true; +DWORD attr = GetFileAttributes(myFile.native().c_str()); +if (attr == INVALID_FILE_ATTRIBUTES) { + return false; +} +return true; #else - struct stat info; - stat(path().c_str(), &info); // Error check omitted - auto perm = of::filesystem::status(myFile).permissions(); +struct stat info; +stat(path().c_str(), &info); // Error check omitted +auto perm = of::filesystem::status(myFile).permissions(); #if OF_USING_STD_FS - if(geteuid() == info.st_uid){ - return (perm & of::filesystem::perms::owner_read) != of::filesystem::perms::none; - }else if (getegid() == info.st_gid){ - return (perm & of::filesystem::perms::group_read) != of::filesystem::perms::none; - }else{ - return (perm & of::filesystem::perms::others_read) != of::filesystem::perms::none; - } +if (geteuid() == info.st_uid) { + return (perm & of::filesystem::perms::owner_read) != of::filesystem::perms::none; +} else if (getegid() == info.st_gid) { + return (perm & of::filesystem::perms::group_read) != of::filesystem::perms::none; +} else { + return (perm & of::filesystem::perms::others_read) != of::filesystem::perms::none; +} #else - if(geteuid() == info.st_uid){ - return perm & of::filesystem::perms::owner_read; - }else if (getegid() == info.st_gid){ - return perm & of::filesystem::perms::group_read; - }else{ - return perm & of::filesystem::perms::others_read; - } +if (geteuid() == info.st_uid) { + return perm & of::filesystem::perms::owner_read; +} else if (getegid() == info.st_gid) { + return perm & of::filesystem::perms::group_read; +} else { + return perm & of::filesystem::perms::others_read; +} #endif #endif } @@ -727,32 +720,32 @@ bool ofFile::canRead() const { //------------------------------------------------------------------------------------------------------------ bool ofFile::canWrite() const { #ifdef TARGET_WIN32 - DWORD attr = GetFileAttributes(myFile.native().c_str()); - if (attr == INVALID_FILE_ATTRIBUTES){ - return false; - }else{ - return (attr & FILE_ATTRIBUTE_READONLY) == 0; - } +DWORD attr = GetFileAttributes(myFile.native().c_str()); +if (attr == INVALID_FILE_ATTRIBUTES) { + return false; +} else { + return (attr & FILE_ATTRIBUTE_READONLY) == 0; +} #else - struct stat info; - stat(path().c_str(), &info); // Error check omitted - auto perm = of::filesystem::status(myFile).permissions(); +struct stat info; +stat(path().c_str(), &info); // Error check omitted +auto perm = of::filesystem::status(myFile).permissions(); #if OF_USING_STD_FS - if(geteuid() == info.st_uid){ - return (perm & of::filesystem::perms::owner_write) != of::filesystem::perms::none; - }else if (getegid() == info.st_gid){ - return (perm & of::filesystem::perms::group_write) != of::filesystem::perms::none; - }else{ - return (perm & of::filesystem::perms::others_write) != of::filesystem::perms::none; - } +if (geteuid() == info.st_uid) { + return (perm & of::filesystem::perms::owner_write) != of::filesystem::perms::none; +} else if (getegid() == info.st_gid) { + return (perm & of::filesystem::perms::group_write) != of::filesystem::perms::none; +} else { + return (perm & of::filesystem::perms::others_write) != of::filesystem::perms::none; +} #else - if(geteuid() == info.st_uid){ - return perm & of::filesystem::owner_write; - }else if (getegid() == info.st_gid){ - return perm & of::filesystem::group_write; - }else{ - return perm & of::filesystem::others_write; - } +if (geteuid() == info.st_uid) { + return perm & of::filesystem::owner_write; +} else if (getegid() == info.st_gid) { + return perm & of::filesystem::group_write; +} else { + return perm & of::filesystem::others_write; +} #endif #endif } @@ -760,54 +753,54 @@ bool ofFile::canWrite() const { //------------------------------------------------------------------------------------------------------------ bool ofFile::canExecute() const { #ifdef TARGET_WIN32 - return getExtension() == "exe"; +return getExtension() == "exe"; #else - struct stat info; - stat(path().c_str(), &info); // Error check omitted - auto perm = of::filesystem::status(myFile).permissions(); +struct stat info; +stat(path().c_str(), &info); // Error check omitted +auto perm = of::filesystem::status(myFile).permissions(); #if OF_USING_STD_FS - if(geteuid() == info.st_uid){ - return (perm & of::filesystem::perms::owner_exec) != of::filesystem::perms::none; - }else if (getegid() == info.st_gid){ - return (perm & of::filesystem::perms::group_exec) != of::filesystem::perms::none; - }else{ - return (perm & of::filesystem::perms::others_exec) != of::filesystem::perms::none; - } +if (geteuid() == info.st_uid) { + return (perm & of::filesystem::perms::owner_exec) != of::filesystem::perms::none; +} else if (getegid() == info.st_gid) { + return (perm & of::filesystem::perms::group_exec) != of::filesystem::perms::none; +} else { + return (perm & of::filesystem::perms::others_exec) != of::filesystem::perms::none; +} #else - if(geteuid() == info.st_uid){ - return perm & of::filesystem::owner_exe; - }else if (getegid() == info.st_gid){ - return perm & of::filesystem::group_exe; - }else{ - return perm & of::filesystem::others_exe; - } +if (geteuid() == info.st_uid) { + return perm & of::filesystem::owner_exe; +} else if (getegid() == info.st_gid) { + return perm & of::filesystem::group_exe; +} else { + return perm & of::filesystem::others_exe; +} #endif #endif } //------------------------------------------------------------------------------------------------------------ bool ofFile::isFile() const { - return of::filesystem::is_regular_file(myFile); +return of::filesystem::is_regular_file(myFile); } //------------------------------------------------------------------------------------------------------------ bool ofFile::isLink() const { - return of::filesystem::is_symlink(myFile); +return of::filesystem::is_symlink(myFile); } //------------------------------------------------------------------------------------------------------------ bool ofFile::isDirectory() const { - return of::filesystem::is_directory(myFile); +return of::filesystem::is_directory(myFile); } //------------------------------------------------------------------------------------------------------------ bool ofFile::isDevice() const { #ifdef TARGET_WIN32 - return false; +return false; #else #if OF_USING_STD_FS - return of::filesystem::is_block_file(of::filesystem::status(myFile)); +return of::filesystem::is_block_file(of::filesystem::status(myFile)); #else - return of::filesystem::status(myFile).type() == of::filesystem::block_file; +return of::filesystem::status(myFile).type() == of::filesystem::block_file; #endif #endif } @@ -815,337 +808,335 @@ bool ofFile::isDevice() const { //------------------------------------------------------------------------------------------------------------ bool ofFile::isHidden() const { #ifdef TARGET_WIN32 - return false; +return false; #else - return myFile.filename() != "." && myFile.filename() != ".." && myFile.filename().string()[0] == '.'; +return myFile.filename() != "." && myFile.filename() != ".." && myFile.filename().string()[0] == '.'; #endif } //------------------------------------------------------------------------------------------------------------ -void ofFile::setWriteable(bool flag){ - try{ +void ofFile::setWriteable(bool flag) { +try { #if !OF_USING_STD_FS || (OF_USING_STD_FS && OF_USE_EXPERIMENTAL_FS) - if(flag){ - of::filesystem::permissions(myFile,of::filesystem::perms::owner_write | of::filesystem::perms::add_perms); - }else{ - of::filesystem::permissions(myFile,of::filesystem::perms::owner_write | of::filesystem::perms::remove_perms); - } + if (flag) { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_write | of::filesystem::perms::add_perms); + } else { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_write | of::filesystem::perms::remove_perms); + } #else - if(flag){ - of::filesystem::permissions(myFile, - of::filesystem::perms::owner_write, - of::filesystem::perm_options::add); - }else{ - of::filesystem::permissions(myFile, - of::filesystem::perms::owner_write, - of::filesystem::perm_options::remove); - } -#endif - }catch(std::exception & e){ - ofLogError() << "Couldn't set write permission on " << myFile << ": " << e.what(); + if (flag) { + of::filesystem::permissions(myFile, + of::filesystem::perms::owner_write, + of::filesystem::perm_options::add); + } else { + of::filesystem::permissions(myFile, + of::filesystem::perms::owner_write, + of::filesystem::perm_options::remove); } +#endif +} catch (std::exception & e) { + ofLogError() << "Couldn't set write permission on " << myFile << ": " << e.what(); +} } //------------------------------------------------------------------------------------------------------------ // deprecated -void ofFile::setReadOnly(bool flag){ - setWriteable(!flag); +void ofFile::setReadOnly(bool flag) { +setWriteable(!flag); } //------------------------------------------------------------------------------------------------------------ -void ofFile::setReadable(bool flag){ - try{ +void ofFile::setReadable(bool flag) { +try { #if !OF_USING_STD_FS || (OF_USING_STD_FS && OF_USE_EXPERIMENTAL_FS) - if(flag){ - of::filesystem::permissions(myFile,of::filesystem::perms::owner_read | of::filesystem::perms::add_perms); - }else{ - of::filesystem::permissions(myFile,of::filesystem::perms::owner_read | of::filesystem::perms::remove_perms); - } + if (flag) { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_read | of::filesystem::perms::add_perms); + } else { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_read | of::filesystem::perms::remove_perms); + } #else - if(flag){ - of::filesystem::permissions(myFile, - of::filesystem::perms::owner_read, - of::filesystem::perm_options::add); - }else{ - of::filesystem::permissions(myFile, - of::filesystem::perms::owner_read, - of::filesystem::perm_options::remove); - } -#endif - }catch(std::exception & e){ - ofLogError() << "Couldn't set read permission on " << myFile << ": " << e.what(); + if (flag) { + of::filesystem::permissions(myFile, + of::filesystem::perms::owner_read, + of::filesystem::perm_options::add); + } else { + of::filesystem::permissions(myFile, + of::filesystem::perms::owner_read, + of::filesystem::perm_options::remove); } +#endif +} catch (std::exception & e) { + ofLogError() << "Couldn't set read permission on " << myFile << ": " << e.what(); +} } //------------------------------------------------------------------------------------------------------------ -void ofFile::setExecutable(bool flag){ - try{ +void ofFile::setExecutable(bool flag) { +try { #if OF_USING_STD_FS -# if OF_USE_EXPERIMENTAL_FS - if(flag){ - of::filesystem::permissions(myFile, of::filesystem::perms::owner_exec | of::filesystem::perms::add_perms); - } else{ - of::filesystem::permissions(myFile, of::filesystem::perms::owner_exec | of::filesystem::perms::remove_perms); - } -# else - if(flag){ - of::filesystem::permissions(myFile, - of::filesystem::perms::owner_exec, - of::filesystem::perm_options::add); - } else{ - of::filesystem::permissions(myFile, - of::filesystem::perms::owner_exec, - of::filesystem::perm_options::remove); - } -# endif +#if OF_USE_EXPERIMENTAL_FS + if (flag) { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_exec | of::filesystem::perms::add_perms); + } else { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_exec | of::filesystem::perms::remove_perms); + } #else - if(flag){ - of::filesystem::permissions(myFile, of::filesystem::perms::owner_exe | of::filesystem::perms::add_perms); - } else{ - of::filesystem::permissions(myFile, of::filesystem::perms::owner_exe | of::filesystem::perms::remove_perms); - } + if (flag) { + of::filesystem::permissions(myFile, + of::filesystem::perms::owner_exec, + of::filesystem::perm_options::add); + } else { + of::filesystem::permissions(myFile, + of::filesystem::perms::owner_exec, + of::filesystem::perm_options::remove); + } #endif - }catch(std::exception & e){ - ofLogError() << "Couldn't set executable permission on " << myFile << ": " << e.what(); +#else + if (flag) { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_exe | of::filesystem::perms::add_perms); + } else { + of::filesystem::permissions(myFile, of::filesystem::perms::owner_exe | of::filesystem::perms::remove_perms); } +#endif +} catch (std::exception & e) { + ofLogError() << "Couldn't set executable permission on " << myFile << ": " << e.what(); +} } //------------------------------------------------------------------------------------------------------------ -bool ofFile::copyTo(const of::filesystem::path& _path, bool bRelativeToData, bool overwrite) const{ - auto path = _path; +bool ofFile::copyTo(const of::filesystem::path & _path, bool bRelativeToData, bool overwrite) const { +auto path = _path; - if(path.empty()){ - ofLogError("ofFile") << "copyTo(): destination path " << _path << " is empty"; - return false; - } - if(isDirectory()){ - ofDirectory tmp; - //don't want to add ofToDataPath to myFile path as it was already done in ofFile::open - tmp.openFromCWD(myFile); - return tmp.copyTo(path,bRelativeToData,overwrite); - } - if(!exists()){ - ofLogError("ofFile") << "copyTo(): source file " << this->path() << " does not exist"; - return false; - } +if (path.empty()) { + ofLogError("ofFile") << "copyTo(): destination path " << _path << " is empty"; + return false; +} +if (isDirectory()) { + ofDirectory tmp; + //don't want to add ofToDataPath to myFile path as it was already done in ofFile::open + tmp.openFromCWD(myFile); + return tmp.copyTo(path, bRelativeToData, overwrite); +} +if (!exists()) { + ofLogError("ofFile") << "copyTo(): source file " << this->path() << " does not exist"; + return false; +} - //bRelativeToData is handled here for the destination path - so we pass false to static functions below - if(bRelativeToData){ - path = ofToDataPath(path); - } +//bRelativeToData is handled here for the destination path - so we pass false to static functions below +if (bRelativeToData) { + path = ofToDataPath(path); +} - if(ofFile::doesFileExist(path, false)){ - if(isFile()){ - ofFile tmp; - tmp.openFromCWD(path,ofFile::Reference); - if(tmp.isDirectory()){ - path = path / getFileName(); - } +if (ofFile::doesFileExist(path, false)) { + if (isFile()) { + ofFile tmp; + tmp.openFromCWD(path, ofFile::Reference); + if (tmp.isDirectory()) { + path = path / getFileName(); } - if(ofFile::doesFileExist(path, false)){ - if(overwrite){ - ofFile::removeFile(path, false); - }else{ - ofLogWarning("ofFile") << "copyTo(): destination file \"" << path << "\" already exists, set bool overwrite to true if you want to overwrite it"; - } + } + if (ofFile::doesFileExist(path, false)) { + if (overwrite) { + ofFile::removeFile(path, false); + } else { + ofLogWarning("ofFile") << "copyTo(): destination file \"" << path << "\" already exists, set bool overwrite to true if you want to overwrite it"; } } +} - try{ - ofDirectory destDir; - auto p = ofFilePath::getEnclosingDirectory(path,false); - destDir.openFromCWD(p); - if(!destDir.exists()){ - ofFilePath::createEnclosingDirectory(path, false); - } - of::filesystem::copy_file(myFile,path); - }catch(std::exception & except){ - ofLogError("ofFile") << "copyTo(): unable to copy \"" << path << "\": " << except.what(); - return false; +try { + ofDirectory destDir; + auto p = ofFilePath::getEnclosingDirectory(path, false); + destDir.openFromCWD(p); + if (!destDir.exists()) { + ofFilePath::createEnclosingDirectory(path, false); } + of::filesystem::copy_file(myFile, path); +} catch (std::exception & except) { + ofLogError("ofFile") << "copyTo(): unable to copy \"" << path << "\": " << except.what(); + return false; +} - return true; +return true; } //------------------------------------------------------------------------------------------------------------ -bool ofFile::moveTo(const of::filesystem::path& _path, bool bRelativeToData, bool overwrite){ - auto path = _path; +bool ofFile::moveTo(const of::filesystem::path & _path, bool bRelativeToData, bool overwrite) { +auto path = _path; - if(path.empty()){ - ofLogError("ofFile") << "moveTo(): destination path is empty"; - return false; - } - if(!exists()){ - ofLogError("ofFile") << "moveTo(): source file does not exist"; - return false; - } +if (path.empty()) { + ofLogError("ofFile") << "moveTo(): destination path is empty"; + return false; +} +if (!exists()) { + ofLogError("ofFile") << "moveTo(): source file does not exist"; + return false; +} - if(bRelativeToData){ - path = ofToDataPath(path); - } - if(ofFile::doesFileExist(path, false)){ - - if(isFile()){ - ofFile tmp; - tmp.openFromCWD(path,ofFile::Reference); - if(tmp.isDirectory()){ - path = path / getFileName(); - } +if (bRelativeToData) { + path = ofToDataPath(path); +} +if (ofFile::doesFileExist(path, false)) { + + if (isFile()) { + ofFile tmp; + tmp.openFromCWD(path, ofFile::Reference); + if (tmp.isDirectory()) { + path = path / getFileName(); } - if(ofFile::doesFileExist(path, false)){ - if(overwrite){ - ofFile::removeFile(path, false); - }else{ - ofLogWarning("ofFile") << "copyTo(): destination file \"" << path << "\" already exists, set bool overwrite to true if you want to overwrite it"; - } + } + if (ofFile::doesFileExist(path, false)) { + if (overwrite) { + ofFile::removeFile(path, false); + } else { + ofLogWarning("ofFile") << "copyTo(): destination file \"" << path << "\" already exists, set bool overwrite to true if you want to overwrite it"; } } +} - try{ - auto mode = this->mode; - if(mode != ofFile::Reference){ - changeMode(ofFile::Reference, binary); - } - ofDirectory destDir; - destDir.openFromCWD(ofFilePath::getEnclosingDirectory(path,false)); - if(!destDir.exists()){ - ofFilePath::createEnclosingDirectory(path,false); - } - of::filesystem::rename(myFile,path); - myFile = path; - if(mode != ofFile::Reference){ - changeMode(mode, binary); - } +try { + auto mode = this->mode; + if (mode != ofFile::Reference) { + changeMode(ofFile::Reference, binary); } - catch(std::exception & except){ - ofLogError("ofFile") << "moveTo(): unable to move \"" << path << "\": " << except.what(); - return false; + ofDirectory destDir; + destDir.openFromCWD(ofFilePath::getEnclosingDirectory(path, false)); + if (!destDir.exists()) { + ofFilePath::createEnclosingDirectory(path, false); + } + of::filesystem::rename(myFile, path); + myFile = path; + if (mode != ofFile::Reference) { + changeMode(mode, binary); } +} catch (std::exception & except) { + ofLogError("ofFile") << "moveTo(): unable to move \"" << path << "\": " << except.what(); + return false; +} - return true; +return true; } //------------------------------------------------------------------------------------------------------------ -bool ofFile::renameTo(const of::filesystem::path& path, bool bRelativeToData, bool overwrite){ - return moveTo(path,bRelativeToData,overwrite); +bool ofFile::renameTo(const of::filesystem::path & path, bool bRelativeToData, bool overwrite) { +return moveTo(path, bRelativeToData, overwrite); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::remove(bool recursive){ - if(myFile.string().empty()){ - ofLogError("ofFile") << "remove(): file path is empty"; - return false; - } - if(!exists()){ - ofLogError("ofFile") << "remove(): file does not exist"; - return false; - } +bool ofFile::remove(bool recursive) { +if (myFile.string().empty()) { + ofLogError("ofFile") << "remove(): file path is empty"; + return false; +} +if (!exists()) { + ofLogError("ofFile") << "remove(): file does not exist"; + return false; +} - try{ - if(mode!=Reference){ - open(path(),Reference,binary); - } - if(recursive){ - of::filesystem::remove_all(myFile); - }else{ - of::filesystem::remove(myFile); - } - }catch(std::exception & except){ - ofLogError("ofFile") << "remove(): unable to remove \"" << myFile << "\": " << except.what(); - return false; +try { + if (mode != Reference) { + open(path(), Reference, binary); } + if (recursive) { + of::filesystem::remove_all(myFile); + } else { + of::filesystem::remove(myFile); + } +} catch (std::exception & except) { + ofLogError("ofFile") << "remove(): unable to remove \"" << myFile << "\": " << except.what(); + return false; +} - return true; +return true; } //------------------------------------------------------------------------------------------------------------ -uint64_t ofFile::getSize() const { - try{ - return of::filesystem::file_size(myFile); - }catch(std::exception & except){ - ofLogError("ofFile") << "getSize(): unable to get size of \"" << myFile << "\": " << except.what(); - return 0; - } +std::uintmax_t ofFile::getSize() const { +try { + return of::filesystem::file_size(myFile); +} catch (std::exception & except) { + ofLogError("ofFile") << "getSize(): unable to get size of \"" << myFile << "\": " << except.what(); + return 0; +} } //------------------------------------------------------------------------------------------------------------ bool ofFile::operator==(const ofFile & file) const { - return getAbsolutePath() == file.getAbsolutePath(); +return getAbsolutePath() == file.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ bool ofFile::operator!=(const ofFile & file) const { - return getAbsolutePath() != file.getAbsolutePath(); +return getAbsolutePath() != file.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ bool ofFile::operator<(const ofFile & file) const { - return getAbsolutePath() < file.getAbsolutePath(); +return getAbsolutePath() < file.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ bool ofFile::operator<=(const ofFile & file) const { - return getAbsolutePath() <= file.getAbsolutePath(); +return getAbsolutePath() <= file.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ bool ofFile::operator>(const ofFile & file) const { - return getAbsolutePath() > file.getAbsolutePath(); +return getAbsolutePath() > file.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ bool ofFile::operator>=(const ofFile & file) const { - return getAbsolutePath() >= file.getAbsolutePath(); +return getAbsolutePath() >= file.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ // ofFile Static Methods //------------------------------------------------------------------------------------------------------------ -bool ofFile::copyFromTo(const of::filesystem::path& pathSrc, const of::filesystem::path& pathDst, bool bRelativeToData, bool overwrite){ - ofFile tmp; - if( bRelativeToData ){ - tmp.open(pathSrc,ofFile::Reference); - }else{ - tmp.openFromCWD(pathSrc,ofFile::Reference); - } - return tmp.copyTo(pathDst,bRelativeToData,overwrite); +bool ofFile::copyFromTo(const of::filesystem::path & pathSrc, const of::filesystem::path & pathDst, bool bRelativeToData, bool overwrite) { +ofFile tmp; +if (bRelativeToData) { + tmp.open(pathSrc, ofFile::Reference); +} else { + tmp.openFromCWD(pathSrc, ofFile::Reference); +} +return tmp.copyTo(pathDst, bRelativeToData, overwrite); } //be careful with slashes here - appending a slash when moving a folder will causes mad headaches //------------------------------------------------------------------------------------------------------------ -bool ofFile::moveFromTo(const of::filesystem::path& pathSrc, const of::filesystem::path& pathDst, bool bRelativeToData, bool overwrite){ - ofFile tmp; - if( bRelativeToData ){ - tmp.open(pathSrc,ofFile::Reference); - }else{ - tmp.openFromCWD(pathSrc,ofFile::Reference); - } - return tmp.moveTo(pathDst, bRelativeToData, overwrite); +bool ofFile::moveFromTo(const of::filesystem::path & pathSrc, const of::filesystem::path & pathDst, bool bRelativeToData, bool overwrite) { +ofFile tmp; +if (bRelativeToData) { + tmp.open(pathSrc, ofFile::Reference); +} else { + tmp.openFromCWD(pathSrc, ofFile::Reference); +} +return tmp.moveTo(pathDst, bRelativeToData, overwrite); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::doesFileExist(const of::filesystem::path& _fPath, bool bRelativeToData){ - ofFile tmp; - if(bRelativeToData){ - tmp.open(_fPath,ofFile::Reference); - }else{ - tmp.openFromCWD(_fPath,ofFile::Reference); - } - return !_fPath.empty() && tmp.exists(); +bool ofFile::doesFileExist(const of::filesystem::path & _fPath, bool bRelativeToData) { +ofFile tmp; +if (bRelativeToData) { + tmp.open(_fPath, ofFile::Reference); +} else { + tmp.openFromCWD(_fPath, ofFile::Reference); +} +return !_fPath.empty() && tmp.exists(); } //------------------------------------------------------------------------------------------------------------ -bool ofFile::removeFile(const of::filesystem::path& _path, bool bRelativeToData){ - ofFile tmp; - if(bRelativeToData){ - tmp.open(_path,ofFile::Reference); - }else{ - tmp.openFromCWD(_path,ofFile::Reference); - } - return tmp.remove(); +bool ofFile::removeFile(const of::filesystem::path & _path, bool bRelativeToData) { +ofFile tmp; +if (bRelativeToData) { + tmp.open(_path, ofFile::Reference); +} else { + tmp.openFromCWD(_path, ofFile::Reference); +} +return tmp.remove(); } - //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ @@ -1154,58 +1145,57 @@ bool ofFile::removeFile(const of::filesystem::path& _path, bool bRelativeToData) //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ -ofDirectory::ofDirectory(){ - showHidden = false; +ofDirectory::ofDirectory() { +showHidden = false; } //------------------------------------------------------------------------------------------------------------ -ofDirectory::ofDirectory(const of::filesystem::path & path){ - showHidden = false; - open(path); +ofDirectory::ofDirectory(const of::filesystem::path & path) { +showHidden = false; +open(path); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::open(const of::filesystem::path & path){ - originalDirectory = ofFilePath::getPathForDirectory(path.string()); - files.clear(); - myDir = of::filesystem::path(ofToDataPath(originalDirectory)); +void ofDirectory::open(const of::filesystem::path & path) { +originalDirectory = ofFilePath::getPathForDirectory(path.string()); +files.clear(); +myDir = of::filesystem::path(ofToDataPath(originalDirectory)); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::openFromCWD(const of::filesystem::path & path){ - originalDirectory = ofFilePath::getPathForDirectory(path.string()); - files.clear(); - myDir = of::filesystem::path(originalDirectory); +void ofDirectory::openFromCWD(const of::filesystem::path & path) { +originalDirectory = ofFilePath::getPathForDirectory(path.string()); +files.clear(); +myDir = of::filesystem::path(originalDirectory); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::close(){ - myDir = of::filesystem::path(); +void ofDirectory::close() { +myDir = of::filesystem::path(); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::create(bool recursive){ +bool ofDirectory::create(bool recursive) { - if(!myDir.string().empty()){ - try{ - if(recursive){ - of::filesystem::create_directories(myDir); - }else{ - of::filesystem::create_directory(myDir); - } - } - catch(std::exception & except){ - ofLogError("ofDirectory") << "create(): " << except.what(); - return false; +if (!myDir.string().empty()) { + try { + if (recursive) { + of::filesystem::create_directories(myDir); + } else { + of::filesystem::create_directory(myDir); } + } catch (std::exception & except) { + ofLogError("ofDirectory") << "create(): " << except.what(); + return false; } +} - return true; +return true; } //------------------------------------------------------------------------------------------------------------ bool ofDirectory::exists() const { - return (myDir == "" || of::filesystem::exists(myDir)); +return (myDir == "" || of::filesystem::exists(myDir)); } //------------------------------------------------------------------------------------------------------------ @@ -1213,7 +1203,7 @@ bool ofDirectory::exists() const { //of::filesystem::path ofDirectory::path() const { // return myDir; std::string ofDirectory::path() const { - return myDir.string(); +return myDir.string(); } //------------------------------------------------------------------------------------------------------------ @@ -1226,362 +1216,359 @@ std::string ofDirectory::path() const { // } //} std::string ofDirectory::getAbsolutePath() const { - try{ - return of::filesystem::canonical(of::filesystem::absolute(myDir)).string(); - }catch(...){ - return of::filesystem::absolute(myDir).string(); - } +try { + return of::filesystem::canonical(of::filesystem::absolute(myDir)).string(); +} catch (...) { + return of::filesystem::absolute(myDir).string(); +} } //------------------------------------------------------------------------------------------------------------ bool ofDirectory::canRead() const { - return ofFile(myDir,ofFile::Reference).canRead(); +return ofFile(myDir, ofFile::Reference).canRead(); } //------------------------------------------------------------------------------------------------------------ bool ofDirectory::canWrite() const { - return ofFile(myDir,ofFile::Reference).canWrite(); +return ofFile(myDir, ofFile::Reference).canWrite(); } //------------------------------------------------------------------------------------------------------------ bool ofDirectory::canExecute() const { - return ofFile(myDir,ofFile::Reference).canExecute(); +return ofFile(myDir, ofFile::Reference).canExecute(); } //------------------------------------------------------------------------------------------------------------ bool ofDirectory::isHidden() const { - return ofFile(myDir,ofFile::Reference).isHidden(); +return ofFile(myDir, ofFile::Reference).isHidden(); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::setWriteable(bool flag){ - return ofFile(myDir,ofFile::Reference).setWriteable(flag); +void ofDirectory::setWriteable(bool flag) { +return ofFile(myDir, ofFile::Reference).setWriteable(flag); } //------------------------------------------------------------------------------------------------------------ // deprecated -void ofDirectory::setReadOnly(bool flag){ - setWriteable(!flag); +void ofDirectory::setReadOnly(bool flag) { +setWriteable(!flag); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::setReadable(bool flag){ - return ofFile(myDir,ofFile::Reference).setReadable(flag); +void ofDirectory::setReadable(bool flag) { +return ofFile(myDir, ofFile::Reference).setReadable(flag); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::setExecutable(bool flag){ - return ofFile(myDir,ofFile::Reference).setExecutable(flag); +void ofDirectory::setExecutable(bool flag) { +return ofFile(myDir, ofFile::Reference).setExecutable(flag); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::setShowHidden(bool showHidden){ - this->showHidden = showHidden; +void ofDirectory::setShowHidden(bool showHidden) { +this->showHidden = showHidden; } //------------------------------------------------------------------------------------------------------------ bool ofDirectory::isDirectory() const { - return of::filesystem::is_directory(myDir); +return of::filesystem::is_directory(myDir); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::copyTo(const of::filesystem::path& _path, bool bRelativeToData, bool overwrite){ - auto path = _path; +bool ofDirectory::copyTo(const of::filesystem::path & _path, bool bRelativeToData, bool overwrite) { +auto path = _path; - if(myDir.string().empty()){ - ofLogError("ofDirectory") << "copyTo(): source path is empty"; - return false; - } - if(!of::filesystem::exists(myDir)){ - ofLogError("ofDirectory") << "copyTo(): source directory does not exist"; - return false; - } - if(!of::filesystem::is_directory(myDir)){ - ofLogError("ofDirectory") << "copyTo(): source path is not a directory"; +if (myDir.string().empty()) { + ofLogError("ofDirectory") << "copyTo(): source path is empty"; + return false; +} +if (!of::filesystem::exists(myDir)) { + ofLogError("ofDirectory") << "copyTo(): source directory does not exist"; + return false; +} +if (!of::filesystem::is_directory(myDir)) { + ofLogError("ofDirectory") << "copyTo(): source path is not a directory"; + return false; +} + +if (bRelativeToData) { + path = ofToDataPath(path, bRelativeToData); +} + +if (ofDirectory::doesDirectoryExist(path, false)) { + if (overwrite) { + ofDirectory::removeDirectory(path, true, false); + } else { + ofLogWarning("ofDirectory") << "copyTo(): dest \"" << path << "\" already exists, set bool overwrite to true to overwrite it"; return false; } +} - if(bRelativeToData){ - path = ofToDataPath(path, bRelativeToData); - } +//our path is bRelativeToData handled from above - so can't open via the constructor approach +ofDirectory dir; +dir.openFromCWD(path); +dir.create(true); - if(ofDirectory::doesDirectoryExist(path, false)){ - if(overwrite){ - ofDirectory::removeDirectory(path, true, false); - }else{ - ofLogWarning("ofDirectory") << "copyTo(): dest \"" << path << "\" already exists, set bool overwrite to true to overwrite it"; +// Iterate through the source directory +for (of::filesystem::directory_iterator file(myDir); file != of::filesystem::directory_iterator(); ++file) { + auto currentPath = of::filesystem::absolute(file->path()); + auto dst = of::filesystem::path(path) / currentPath.filename(); + if (of::filesystem::is_directory(currentPath)) { + ofDirectory current(currentPath); + // Found directory: Recursion + if (!current.copyTo(dst, false, overwrite)) { return false; } + } else { + ofFile tmp; + tmp.openFromCWD(file->path(), ofFile::Reference); + tmp.copyTo(dst.string(), false, overwrite); } +} - //our path is bRelativeToData handled from above - so can't open via the constructor approach - ofDirectory dir; - dir.openFromCWD(path); - dir.create(true); - - // Iterate through the source directory - for(of::filesystem::directory_iterator file(myDir); file != of::filesystem::directory_iterator(); ++file){ - auto currentPath = of::filesystem::absolute(file->path()); - auto dst = of::filesystem::path(path) / currentPath.filename(); - if(of::filesystem::is_directory(currentPath)){ - ofDirectory current(currentPath); - // Found directory: Recursion - if(!current.copyTo(dst,false,overwrite)){ - return false; - } - }else{ - ofFile tmp; - tmp.openFromCWD(file->path(),ofFile::Reference); - tmp.copyTo(dst.string(),false,overwrite); - } - } - - return true; +return true; } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::moveTo(const of::filesystem::path& path, bool bRelativeToData, bool overwrite){ - if(copyTo(path,bRelativeToData,overwrite)){ - return remove(true); - } +bool ofDirectory::moveTo(const of::filesystem::path & path, bool bRelativeToData, bool overwrite) { +if (copyTo(path, bRelativeToData, overwrite)) { + return remove(true); +} - return false; +return false; } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::renameTo(const of::filesystem::path& path, bool bRelativeToData, bool overwrite){ - return moveTo(path, bRelativeToData, overwrite); +bool ofDirectory::renameTo(const of::filesystem::path & path, bool bRelativeToData, bool overwrite) { +return moveTo(path, bRelativeToData, overwrite); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::remove(bool recursive){ - if(path().empty() || !of::filesystem::exists(myDir)){ - return false; - } +bool ofDirectory::remove(bool recursive) { +if (path().empty() || !of::filesystem::exists(myDir)) { + return false; +} - try{ - if(recursive){ - of::filesystem::remove_all(of::filesystem::canonical(myDir)); - }else{ - of::filesystem::remove(of::filesystem::canonical(myDir)); - } - }catch(std::exception & except){ - ofLogError("ofDirectory") << "remove(): unable to remove file/directory: " << except.what(); - return false; +try { + if (recursive) { + of::filesystem::remove_all(of::filesystem::canonical(myDir)); + } else { + of::filesystem::remove(of::filesystem::canonical(myDir)); } +} catch (std::exception & except) { + ofLogError("ofDirectory") << "remove(): unable to remove file/directory: " << except.what(); + return false; +} - return true; +return true; } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::allowExt(const std::string& extension){ - if(extension == "*"){ - ofLogWarning("ofDirectory") << "allowExt(): wildcard extension * is deprecated"; - } - extensions.push_back(ofToLower(extension)); +void ofDirectory::allowExt(const std::string & extension) { +if (extension == "*") { + ofLogWarning("ofDirectory") << "allowExt(): wildcard extension * is deprecated"; +} +extensions.push_back(ofToLower(extension)); } //------------------------------------------------------------------------------------------------------------ -std::size_t ofDirectory::listDir(const of::filesystem::path & directory){ - open(directory); - return listDir(); +std::size_t ofDirectory::listDir(const of::filesystem::path & directory) { +open(directory); +return listDir(); } //------------------------------------------------------------------------------------------------------------ -std::size_t ofDirectory::listDir(){ - files.clear(); - if(path().empty()){ - ofLogError("ofDirectory") << "listDir(): directory path is empty"; - return 0; - } - if(!of::filesystem::exists(myDir)){ - ofLogError("ofDirectory") << "listDir:() source directory does not exist: \"" << myDir << "\""; - return 0; - } +std::size_t ofDirectory::listDir() { +files.clear(); +if (path().empty()) { + ofLogError("ofDirectory") << "listDir(): directory path is empty"; + return 0; +} +if (!of::filesystem::exists(myDir)) { + ofLogError("ofDirectory") << "listDir:() source directory does not exist: \"" << myDir << "\""; + return 0; +} - of::filesystem::directory_iterator end_iter; - if ( of::filesystem::exists(myDir) && of::filesystem::is_directory(myDir)){ - for( of::filesystem::directory_iterator dir_iter(myDir) ; dir_iter != end_iter ; ++dir_iter){ - files.emplace_back(dir_iter->path().string(), ofFile::Reference); - } - }else{ - ofLogError("ofDirectory") << "listDir:() source directory does not exist: \"" << myDir << "\""; - return 0; +of::filesystem::directory_iterator end_iter; +if (of::filesystem::exists(myDir) && of::filesystem::is_directory(myDir)) { + for (of::filesystem::directory_iterator dir_iter(myDir); dir_iter != end_iter; ++dir_iter) { + files.emplace_back(dir_iter->path().string(), ofFile::Reference); } +} else { + ofLogError("ofDirectory") << "listDir:() source directory does not exist: \"" << myDir << "\""; + return 0; +} - if(!showHidden){ - ofRemove(files, [](ofFile & file){ - return file.isHidden(); - }); - } +if (!showHidden) { + ofRemove(files, [](ofFile & file) { + return file.isHidden(); + }); +} +if (!extensions.empty() && !ofContains(extensions, (string) "*")) { + ofRemove(files, [&](ofFile & file) { + return std::find(extensions.begin(), extensions.end(), ofToLower(file.getExtension())) == extensions.end(); + }); +} - if(!extensions.empty() && !ofContains(extensions, (string)"*")){ - ofRemove(files, [&](ofFile & file){ - return std::find(extensions.begin(), extensions.end(), ofToLower(file.getExtension())) == extensions.end(); - }); - } - - if(ofGetLogLevel() == OF_LOG_VERBOSE){ - for(int i = 0; i < (int)size(); i++){ - ofLogVerbose() << "\t" << getName(i); - } - ofLogVerbose() << "listed " << size() << " files in \"" << originalDirectory << "\""; +if (ofGetLogLevel() == OF_LOG_VERBOSE) { + for (int i = 0; i < (int)size(); i++) { + ofLogVerbose() << "\t" << getName(i); } + ofLogVerbose() << "listed " << size() << " files in \"" << originalDirectory << "\""; +} - return size(); +return size(); } //------------------------------------------------------------------------------------------------------------ string ofDirectory::getOriginalDirectory() const { - return originalDirectory; +return originalDirectory; } //------------------------------------------------------------------------------------------------------------ -string ofDirectory::getName(std::size_t position) const{ - return files.at(position).getFileName(); +string ofDirectory::getName(std::size_t position) const { +return files.at(position).getFileName(); } //------------------------------------------------------------------------------------------------------------ -string ofDirectory::getPath(std::size_t position) const{ - return originalDirectory + getName(position); +string ofDirectory::getPath(std::size_t position) const { +return originalDirectory + getName(position); } //------------------------------------------------------------------------------------------------------------ ofFile ofDirectory::getFile(std::size_t position, ofFile::Mode mode, bool binary) const { - ofFile file = files[position]; - file.changeMode(mode, binary); - return file; +ofFile file = files[position]; +file.changeMode(mode, binary); +return file; } ofFile ofDirectory::operator[](std::size_t position) const { - return getFile(position); +return getFile(position); } //------------------------------------------------------------------------------------------------------------ -const vector & ofDirectory::getFiles() const{ - if(files.empty() && !myDir.empty()){ - const_cast(this)->listDir(); - } - return files; +const vector & ofDirectory::getFiles() const { +if (files.empty() && !myDir.empty()) { + const_cast(this)->listDir(); +} +return files; } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::getShowHidden() const{ - return showHidden; +bool ofDirectory::getShowHidden() const { +return showHidden; } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::reset(){ - close(); +void ofDirectory::reset() { +close(); } //------------------------------------------------------------------------------------------------------------ -static bool natural(const ofFile& a, const ofFile& b) { - string aname = a.getBaseName(), bname = b.getBaseName(); - int aint = ofToInt(aname), bint = ofToInt(bname); - if(ofToString(aint) == aname && ofToString(bint) == bname) { - return aint < bint; - } else { - return a < b; - } +static bool natural(const ofFile & a, const ofFile & b) { +string aname = a.getBaseName(), bname = b.getBaseName(); +int aint = ofToInt(aname), bint = ofToInt(bname); +if (ofToString(aint) == aname && ofToString(bint) == bname) { + return aint < bint; +} else { + return a < b; +} } - //------------------------------------------------------------------------------------------------------------ -struct StringSort{ - of::filesystem::path path; - string basename; - int nameInt; - string stringInt; +struct StringSort { +of::filesystem::path path; +string basename; +int nameInt; +string stringInt; }; //------------------------------------------------------------------------------------------------------------ -static bool naturalStr(const StringSort& a, const StringSort& b) { - if(a.stringInt == a.basename && b.stringInt == b.basename) { - return a.nameInt < b.nameInt; - } else { - return a.path < b.path; - } +static bool naturalStr(const StringSort & a, const StringSort & b) { +if (a.stringInt == a.basename && b.stringInt == b.basename) { + return a.nameInt < b.nameInt; +} else { + return a.path < b.path; +} } //------------------------------------------------------------------------------------------------------------ -static bool byDate(const ofFile& a, const ofFile& b) { - auto ta = of::filesystem::last_write_time(a); - auto tb = of::filesystem::last_write_time(b); - return ta < tb; +static bool byDate(const ofFile & a, const ofFile & b) { +auto ta = of::filesystem::last_write_time(a); +auto tb = of::filesystem::last_write_time(b); +return ta < tb; } //------------------------------------------------------------------------------------------------------------ void ofDirectory::sortByDate() { - if (files.empty() && !myDir.empty()) { - listDir(); - } - ofSort(files, byDate); +if (files.empty() && !myDir.empty()) { + listDir(); +} +ofSort(files, byDate); } //------------------------------------------------------------------------------------------------------------ -void ofDirectory::sort(const SortMode & mode){ - if(files.empty() && !myDir.empty()){ - listDir(); +void ofDirectory::sort(const SortMode & mode) { +if (files.empty() && !myDir.empty()) { + listDir(); +} + +if (mode == ofDirectory::SORT_NATURAL) { + vector sort; + sort.reserve(files.size()); + + for (auto & f : files) { + StringSort ss; + ss.path = f.path(); + ss.basename = f.getBaseName(); + ss.nameInt = ofToInt(ss.basename); + ss.stringInt = ofToString(ss.nameInt); + sort.push_back(ss); } - if( mode == ofDirectory::SORT_NATURAL ){ - vector sort; - sort.reserve(files.size()); + ofSort(sort, naturalStr); + files.clear(); + files.reserve(sort.size()); + for (auto & s : sort) { + files.emplace_back(s.path, ofFile::Reference); + } +} else if (mode == ofDirectory::SORT_FAST) { + std::vector sort; + sort.reserve(files.size()); - for( auto & f : files ){ - StringSort ss; - ss.path = f.path(); - ss.basename = f.getBaseName(); - ss.nameInt = ofToInt(ss.basename); - ss.stringInt = ofToString(ss.nameInt); - sort.push_back(ss); - } - - ofSort(sort, naturalStr); - files.clear(); - files.reserve(sort.size()); - for( auto & s : sort ){ - files.emplace_back( s.path , ofFile::Reference); - } - } - else if(mode == ofDirectory::SORT_FAST){ - std::vector sort; - sort.reserve(files.size()); - - for( auto & f : files ){ - string ss = f.getFileName(); - sort.push_back(ss); - } + for (auto & f : files) { + string ss = f.getFileName(); + sort.push_back(ss); + } - std::sort(sort.begin(), sort.end()); - files.clear(); - files.reserve(sort.size()); - for( auto & s : sort ){ - files.emplace_back( myDir / of::filesystem::path(s), ofFile::Reference); - } - }else if(mode == ofDirectory::SORT_BY_DATE){ - sortByDate(); - } + std::sort(sort.begin(), sort.end()); + files.clear(); + files.reserve(sort.size()); + for (auto & s : sort) { + files.emplace_back(myDir / of::filesystem::path(s), ofFile::Reference); + } +} else if (mode == ofDirectory::SORT_BY_DATE) { + sortByDate(); +} } //------------------------------------------------------------------------------------------------------------ -ofDirectory ofDirectory::getSorted(){ - ofDirectory sorted(*this); - sorted.listDir(); - sorted.sort(); - return sorted; +ofDirectory ofDirectory::getSorted() { +ofDirectory sorted(*this); +sorted.listDir(); +sorted.sort(); +return sorted; } //------------------------------------------------------------------------------------------------------------ -std::size_t ofDirectory::size() const{ - return files.size(); +std::size_t ofDirectory::size() const { +return files.size(); } //------------------------------------------------------------------------------------------------------------ -int ofDirectory::numFiles(){ - return static_cast(size()); +int ofDirectory::numFiles() { +return static_cast(size()); } //------------------------------------------------------------------------------------------------------------ @@ -1589,131 +1576,129 @@ int ofDirectory::numFiles(){ //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::removeDirectory(const of::filesystem::path& _path, bool deleteIfNotEmpty, bool bRelativeToData){ - auto path = _path; +bool ofDirectory::removeDirectory(const of::filesystem::path & _path, bool deleteIfNotEmpty, bool bRelativeToData) { +auto path = _path; - ofFile dirToRemove; - if(bRelativeToData){ - dirToRemove.open(path,ofFile::Reference); - }else{ - dirToRemove.openFromCWD(path,ofFile::Reference); - } +ofFile dirToRemove; +if (bRelativeToData) { + dirToRemove.open(path, ofFile::Reference); +} else { + dirToRemove.openFromCWD(path, ofFile::Reference); +} - return dirToRemove.remove(deleteIfNotEmpty); +return dirToRemove.remove(deleteIfNotEmpty); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::createDirectory(const of::filesystem::path& _dirPath, bool bRelativeToData, bool recursive){ - auto dirPath = _dirPath; +bool ofDirectory::createDirectory(const of::filesystem::path & _dirPath, bool bRelativeToData, bool recursive) { +auto dirPath = _dirPath; - if(bRelativeToData){ - dirPath = ofToDataPath(dirPath); - } - - // on OSX,of::filesystem::create_directories seems to return false *if* the path has folders that already exist - // and true if it doesn't - // so to avoid unnecessary warnings on OSX, we check if it exists here: - - bool bDoesExistAlready = ofDirectory::doesDirectoryExist(dirPath,false); +if (bRelativeToData) { + dirPath = ofToDataPath(dirPath); +} - if (!bDoesExistAlready){ +// on OSX,of::filesystem::create_directories seems to return false *if* the path has folders that already exist +// and true if it doesn't +// so to avoid unnecessary warnings on OSX, we check if it exists here: - bool success = false; - try{ - if(!recursive){ - success = of::filesystem::create_directory(dirPath); - }else{ - success = of::filesystem::create_directories(dirPath); - } - } catch(std::exception & except){ - ofLogError("ofDirectory") << "createDirectory(): couldn't create directory \"" << dirPath << "\": " << except.what(); - return false; - } - return success; - } +bool bDoesExistAlready = ofDirectory::doesDirectoryExist(dirPath, false); - // no need to create it - it already exists. - return true; -} +if (!bDoesExistAlready) { -//------------------------------------------------------------------------------------------------------------ -bool ofDirectory::doesDirectoryExist(const of::filesystem::path& _dirPath, bool bRelativeToData){ - auto dirPath = _dirPath; + bool success = false; try { - if (bRelativeToData) { - dirPath = ofToDataPath(dirPath); + if (!recursive) { + success = of::filesystem::create_directory(dirPath); + } else { + success = of::filesystem::create_directories(dirPath); } - return of::filesystem::exists(dirPath) && of::filesystem::is_directory(dirPath); - } - catch (std::exception & except) { - ofLogError("ofDirectory") << "doesDirectoryExist(): couldn't find directory \"" << dirPath << "\": " << except.what() << std::endl; + } catch (std::exception & except) { + ofLogError("ofDirectory") << "createDirectory(): couldn't create directory \"" << dirPath << "\": " << except.what(); return false; } + return success; +} + +// no need to create it - it already exists. +return true; } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::isDirectoryEmpty(const of::filesystem::path& _dirPath, bool bRelativeToData){ - auto dirPath = _dirPath; - if(bRelativeToData){ +bool ofDirectory::doesDirectoryExist(const of::filesystem::path & _dirPath, bool bRelativeToData) { +auto dirPath = _dirPath; +try { + if (bRelativeToData) { dirPath = ofToDataPath(dirPath); } - - if(!dirPath.empty() && of::filesystem::exists(dirPath) && of::filesystem::is_directory(dirPath)){ - return of::filesystem::directory_iterator(dirPath) == of::filesystem::directory_iterator(); - } + return of::filesystem::exists(dirPath) && of::filesystem::is_directory(dirPath); +} catch (std::exception & except) { + ofLogError("ofDirectory") << "doesDirectoryExist(): couldn't find directory \"" << dirPath << "\": " << except.what() << std::endl; return false; } +} //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::operator==(const ofDirectory & dir) const{ - return getAbsolutePath() == dir.getAbsolutePath(); +bool ofDirectory::isDirectoryEmpty(const of::filesystem::path & _dirPath, bool bRelativeToData) { +auto dirPath = _dirPath; +if (bRelativeToData) { + dirPath = ofToDataPath(dirPath); +} + +if (!dirPath.empty() && of::filesystem::exists(dirPath) && of::filesystem::is_directory(dirPath)) { + return of::filesystem::directory_iterator(dirPath) == of::filesystem::directory_iterator(); +} +return false; } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::operator!=(const ofDirectory & dir) const{ - return getAbsolutePath() != dir.getAbsolutePath(); +bool ofDirectory::operator==(const ofDirectory & dir) const { +return getAbsolutePath() == dir.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::operator<(const ofDirectory & dir) const{ - return getAbsolutePath() < dir.getAbsolutePath(); +bool ofDirectory::operator!=(const ofDirectory & dir) const { +return getAbsolutePath() != dir.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::operator<=(const ofDirectory & dir) const{ - return getAbsolutePath() <= dir.getAbsolutePath(); +bool ofDirectory::operator<(const ofDirectory & dir) const { +return getAbsolutePath() < dir.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::operator>(const ofDirectory & dir) const{ - return getAbsolutePath() > dir.getAbsolutePath(); +bool ofDirectory::operator<=(const ofDirectory & dir) const { +return getAbsolutePath() <= dir.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ -bool ofDirectory::operator>=(const ofDirectory & dir) const{ - return getAbsolutePath() >= dir.getAbsolutePath(); +bool ofDirectory::operator>(const ofDirectory & dir) const { +return getAbsolutePath() > dir.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ -vector::const_iterator ofDirectory::begin() const{ - return getFiles().begin(); +bool ofDirectory::operator>=(const ofDirectory & dir) const { +return getAbsolutePath() >= dir.getAbsolutePath(); } //------------------------------------------------------------------------------------------------------------ -vector::const_iterator ofDirectory::end() const{ - return files.end(); +vector::const_iterator ofDirectory::begin() const { +return getFiles().begin(); } //------------------------------------------------------------------------------------------------------------ -vector::const_reverse_iterator ofDirectory::rbegin() const{ - return getFiles().rbegin(); +vector::const_iterator ofDirectory::end() const { +return files.end(); } //------------------------------------------------------------------------------------------------------------ -vector::const_reverse_iterator ofDirectory::rend() const{ - return files.rend(); +vector::const_reverse_iterator ofDirectory::rbegin() const { +return getFiles().rbegin(); } +//------------------------------------------------------------------------------------------------------------ +vector::const_reverse_iterator ofDirectory::rend() const { +return files.rend(); +} //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ @@ -1721,150 +1706,147 @@ vector::const_reverse_iterator ofDirectory::rend() const{ //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ - //------------------------------------------------------------------------------------------------------------ -string ofFilePath::addLeadingSlash(const of::filesystem::path& _path){ - auto path = _path.string(); - auto sep = of::filesystem::path("/").make_preferred(); - if(!path.empty()){ - if(ofToString(path[0]) != sep.string()){ - path = (sep / path).string(); - } +string ofFilePath::addLeadingSlash(const of::filesystem::path & _path) { +auto path = _path.string(); +auto sep = of::filesystem::path("/").make_preferred(); +if (!path.empty()) { + if (ofToString(path[0]) != sep.string()) { + path = (sep / path).string(); } - return path; +} +return path; } //------------------------------------------------------------------------------------------------------------ // MARK: - near future //of::filesystem::path ofFilePath::addTrailingSlash(const of::filesystem::path & _path){ -std::string ofFilePath::addTrailingSlash(const of::filesystem::path & _path){ +std::string ofFilePath::addTrailingSlash(const of::filesystem::path & _path) { #if OF_USING_STD_FS && !OF_USE_EXPERIMENTAL_FS - if(_path.string().empty()) return ""; - // FIXME: Remove .string() here and following - // return (of::filesystem::path(_path).make_preferred() / ""); - return (of::filesystem::path(_path).make_preferred() / "").string(); +if (_path.string().empty()) return ""; +// FIXME: Remove .string() here and following +// return (of::filesystem::path(_path).make_preferred() / ""); +return (of::filesystem::path(_path).make_preferred() / "").string(); #else - auto path = of::filesystem::path(_path).make_preferred(); - auto sep = of::filesystem::path("/").make_preferred(); - if(!path.empty()){ - if(ofToString(path.string().back()) != sep.string()){ - path = (path / sep); - } +auto path = of::filesystem::path(_path).make_preferred(); +auto sep = of::filesystem::path("/").make_preferred(); +if (!path.empty()) { + if (ofToString(path.string().back()) != sep.string()) { + path = (path / sep); } +} // return path; - return path.string(); +return path.string(); #endif } - //------------------------------------------------------------------------------------------------------------ -string ofFilePath::getFileExt(const of::filesystem::path& filename){ - return ofFile(filename,ofFile::Reference).getExtension(); +string ofFilePath::getFileExt(const of::filesystem::path & filename) { +return ofFile(filename, ofFile::Reference).getExtension(); } //------------------------------------------------------------------------------------------------------------ // FIXME: remove const and copy // MARK: - near future // of::filesystem::path ofFilePath::removeExt(const of::filesystem::path& _filename){ -std::string ofFilePath::removeExt(const of::filesystem::path& _filename){ - auto filename = _filename; +std::string ofFilePath::removeExt(const of::filesystem::path & _filename) { +auto filename = _filename; // return filename.replace_extension(); - return filename.replace_extension().string(); +return filename.replace_extension().string(); } //------------------------------------------------------------------------------------------------------------ -string ofFilePath::getPathForDirectory(const of::filesystem::path& path){ - // if a trailing slash is missing from a path, this will clean it up - // if it's a windows-style "\" path it will add a "\" - // if it's a unix-style "/" path it will add a "/" +string ofFilePath::getPathForDirectory(const of::filesystem::path & path) { +// if a trailing slash is missing from a path, this will clean it up +// if it's a windows-style "\" path it will add a "\" +// if it's a unix-style "/" path it will add a "/" - // FIXME: Remove .string() here and following - // FIXME: this seems over complicated and not useful anymore, using filesystem +// FIXME: Remove .string() here and following +// FIXME: this seems over complicated and not useful anymore, using filesystem #if OF_USING_STD_FS && !OF_USE_EXPERIMENTAL_FS - if(path.string().empty()) return ""; - return (path / "").string(); +if (path.string().empty()) return ""; +return (path / "").string(); #else - auto sep = of::filesystem::path("/").make_preferred(); - if(!path.empty() && ofToString(path.string().back())!=sep.string()){ - return (path / sep).string(); - }else{ - return path.string(); - } +auto sep = of::filesystem::path("/").make_preferred(); +if (!path.empty() && ofToString(path.string().back()) != sep.string()) { + return (path / sep).string(); +} else { + return path.string(); +} #endif } //------------------------------------------------------------------------------------------------------------ // FIXME: convert to of::filesystem::path -string ofFilePath::removeTrailingSlash(const of::filesystem::path& _path){ - auto path = _path.string(); - if(path.length() > 0 && (path[path.length() - 1] == '/' || path[path.length() - 1] == '\\')){ - path = path.substr(0, path.length() - 1); - } - return path; +string ofFilePath::removeTrailingSlash(const of::filesystem::path & _path) { +auto path = _path.string(); +if (path.length() > 0 && (path[path.length() - 1] == '/' || path[path.length() - 1] == '\\')) { + path = path.substr(0, path.length() - 1); +} +return path; } - //------------------------------------------------------------------------------------------------------------ // FIXME: is this still useful? if yes convert to of::filesystem::path -string ofFilePath::getFileName(const of::filesystem::path& _filePath, bool bRelativeToData){ - auto filePath = _filePath; +string ofFilePath::getFileName(const of::filesystem::path & _filePath, bool bRelativeToData) { +auto filePath = _filePath; - if(bRelativeToData){ - filePath = ofToDataPath(filePath); - } +if (bRelativeToData) { + filePath = ofToDataPath(filePath); +} - // FIXME: this is probably over complicated - return of::filesystem::path(filePath).filename().string(); +// FIXME: this is probably over complicated +return of::filesystem::path(filePath).filename().string(); } //------------------------------------------------------------------------------------------------------------ -string ofFilePath::getBaseName(const of::filesystem::path& filePath){ - // FIXME: is this still useful? - return ofFile(filePath,ofFile::Reference).getBaseName(); +string ofFilePath::getBaseName(const of::filesystem::path & filePath) { +// FIXME: is this still useful? +return ofFile(filePath, ofFile::Reference).getBaseName(); } //------------------------------------------------------------------------------------------------------------ // MARK: - near future //of::filesystem::path ofFilePath::getEnclosingDirectory(const of::filesystem::path & _filePath, bool bRelativeToData){ -std::string ofFilePath::getEnclosingDirectory(const of::filesystem::path & _filePath, bool bRelativeToData){ - auto fp = _filePath; - if(bRelativeToData){ - fp = ofToDataPath(fp); - } - return addTrailingSlash(fp.parent_path()); +std::string ofFilePath::getEnclosingDirectory(const of::filesystem::path & _filePath, bool bRelativeToData) { +auto fp = _filePath; +if (bRelativeToData) { + fp = ofToDataPath(fp); +} +return addTrailingSlash(fp.parent_path()); } //------------------------------------------------------------------------------------------------------------ -bool ofFilePath::createEnclosingDirectory(const of::filesystem::path& filePath, bool bRelativeToData, bool bRecursive) { - return ofDirectory::createDirectory(ofFilePath::getEnclosingDirectory(filePath,bRelativeToData), bRelativeToData, bRecursive); +bool ofFilePath::createEnclosingDirectory(const of::filesystem::path & filePath, bool bRelativeToData, bool bRecursive) { +return ofDirectory::createDirectory(ofFilePath::getEnclosingDirectory(filePath, bRelativeToData), bRelativeToData, bRecursive); } //------------------------------------------------------------------------------------------------------------ // FIXME: - near future //of::filesystem::path ofFilePath::getAbsolutePath(const of::filesystem::path& path, bool bRelativeToData){ -std::string ofFilePath::getAbsolutePath(const of::filesystem::path& path, bool bRelativeToData){ - if(bRelativeToData){ - return ofToDataPath(path, true); - }else{ - try{ -// return of::filesystem::canonical(of::filesystem::absolute(path)); - return of::filesystem::canonical(of::filesystem::absolute(path)).string(); - }catch(...){ -// return of::filesystem::absolute(path); - return of::filesystem::absolute(path).string(); - } +std::string ofFilePath::getAbsolutePath(const of::filesystem::path & path, bool bRelativeToData) { +if (bRelativeToData) { + return ofToDataPath(path, true); +} else { + try { + // return of::filesystem::canonical(of::filesystem::absolute(path)); + return of::filesystem::canonical(of::filesystem::absolute(path)).string(); + } catch (...) { + // return of::filesystem::absolute(path); + return of::filesystem::absolute(path).string(); } } +} //------------------------------------------------------------------------------------------------------------ -bool ofFilePath::isAbsolute(const of::filesystem::path& path){ - return of::filesystem::path(path).is_absolute(); +bool ofFilePath::isAbsolute(const of::filesystem::path & path) { +return of::filesystem::path(path).is_absolute(); } //------------------------------------------------------------------------------------------------------------ -string ofFilePath::getCurrentWorkingDirectory(){ - return of::filesystem::current_path().string(); +string ofFilePath::getCurrentWorkingDirectory() { +return of::filesystem::current_path().string(); } //------------------------------------------------------------------------------------------------------------ @@ -1873,207 +1855,205 @@ string ofFilePath::getCurrentWorkingDirectory(){ // // FIXME: deprecate when possible. helper function more complex than actual solution // return (path1 / path2); //} -std::string ofFilePath::join(const of::filesystem::path& path1, const of::filesystem::path& path2){ - // FIXME: deprecate when possible. helper function more complex than actual solution - return (path1 / path2).string(); +std::string ofFilePath::join(const of::filesystem::path & path1, const of::filesystem::path & path2) { +// FIXME: deprecate when possible. helper function more complex than actual solution +return (path1 / path2).string(); +} + +//------------------------------------------------------------------------------------------------------------ +string ofFilePath::getCurrentExePath() { +#if defined(TARGET_LINUX) || defined(TARGET_ANDROID) +char buff[FILENAME_MAX]; +ssize_t size = readlink("/proc/self/exe", buff, sizeof(buff) - 1); +if (size == -1) { + ofLogError("ofFilePath") << "getCurrentExePath(): readlink failed with error " << errno; +} else { + buff[size] = '\0'; + return buff; +} +#elif defined(TARGET_OSX) +char path[FILENAME_MAX]; +uint32_t size = sizeof(path); +if (_NSGetExecutablePath(path, &size) != 0) { + ofLogError("ofFilePath") << "getCurrentExePath(): path buffer too small, need size " << size; +} +return path; +#elif defined(TARGET_WIN32) +vector executablePath(MAX_PATH); +DWORD result = ::GetModuleFileNameA(nullptr, &executablePath[0], static_cast(executablePath.size())); +if (result == 0) { + ofLogError("ofFilePath") << "getCurrentExePath(): couldn't get path, GetModuleFileNameA failed"; +} else { + return string(executablePath.begin(), executablePath.begin() + result); } - -//------------------------------------------------------------------------------------------------------------ -string ofFilePath::getCurrentExePath(){ - #if defined(TARGET_LINUX) || defined(TARGET_ANDROID) - char buff[FILENAME_MAX]; - ssize_t size = readlink("/proc/self/exe", buff, sizeof(buff) - 1); - if (size == -1){ - ofLogError("ofFilePath") << "getCurrentExePath(): readlink failed with error " << errno; - } - else{ - buff[size] = '\0'; - return buff; - } - #elif defined(TARGET_OSX) - char path[FILENAME_MAX]; - uint32_t size = sizeof(path); - if(_NSGetExecutablePath(path, &size) != 0){ - ofLogError("ofFilePath") << "getCurrentExePath(): path buffer too small, need size " << size; - } - return path; - #elif defined(TARGET_WIN32) - vector executablePath(MAX_PATH); - DWORD result = ::GetModuleFileNameA(nullptr, &executablePath[0], static_cast(executablePath.size())); - if(result == 0) { - ofLogError("ofFilePath") << "getCurrentExePath(): couldn't get path, GetModuleFileNameA failed"; - }else{ - return string(executablePath.begin(), executablePath.begin() + result); - } - #endif - return ""; +#endif +return ""; } //------------------------------------------------------------------------------------------------------------ // MARK: - near future //of::filesystem::path ofFilePath::getCurrentExeDir(){ -std::string ofFilePath::getCurrentExeDir(){ - return ofFilePath::getEnclosingDirectory(ofFilePath::getCurrentExePath(), false); +std::string ofFilePath::getCurrentExeDir() { +return ofFilePath::getEnclosingDirectory(ofFilePath::getCurrentExePath(), false); } //------------------------------------------------------------------------------------------------------------ -string ofFilePath::getUserHomeDir(){ - #ifdef TARGET_WIN32 - // getenv will return any Environent Variable on Windows - // USERPROFILE is the key on Windows 7 but it might be HOME - // in other flavours of windows...need to check XP and NT... - return ofGetEnv("USERPROFILE"); - #elif !defined(TARGET_EMSCRIPTEN) - struct passwd * pw = getpwuid(getuid()); - return pw->pw_dir; - #else - return ""; - #endif +string ofFilePath::getUserHomeDir() { +#ifdef TARGET_WIN32 +// getenv will return any Environent Variable on Windows +// USERPROFILE is the key on Windows 7 but it might be HOME +// in other flavours of windows...need to check XP and NT... +return ofGetEnv("USERPROFILE"); +#elif !defined(TARGET_EMSCRIPTEN) +struct passwd * pw = getpwuid(getuid()); +return pw->pw_dir; +#else +return ""; +#endif } // MARK: - near future //of::filesystem::path ofFilePath::makeRelative(const of::filesystem::path & from, const of::filesystem::path & to){ -std::string ofFilePath::makeRelative(const of::filesystem::path & from, const of::filesystem::path & to){ - auto pathFrom = of::filesystem::absolute( from ); - auto pathTo = of::filesystem::absolute( to ); - of::filesystem::path ret; - of::filesystem::path::const_iterator itrFrom( pathFrom.begin() ), itrTo( pathTo.begin() ); - // Find common base - for( of::filesystem::path::const_iterator toEnd( pathTo.end() ), fromEnd( pathFrom.end() ) ; itrFrom != fromEnd && itrTo != toEnd && *itrFrom == *itrTo; ++itrFrom, ++itrTo ); - // Navigate backwards in directory to reach previously found base - for( of::filesystem::path::const_iterator fromEnd( pathFrom.end() ); itrFrom != fromEnd; ++itrFrom ){ - if( (*itrFrom) != "." ){ - ret /= ".."; - } +std::string ofFilePath::makeRelative(const of::filesystem::path & from, const of::filesystem::path & to) { +auto pathFrom = of::filesystem::absolute(from); +auto pathTo = of::filesystem::absolute(to); +of::filesystem::path ret; +of::filesystem::path::const_iterator itrFrom(pathFrom.begin()), itrTo(pathTo.begin()); +// Find common base +for (of::filesystem::path::const_iterator toEnd(pathTo.end()), fromEnd(pathFrom.end()); itrFrom != fromEnd && itrTo != toEnd && *itrFrom == *itrTo; ++itrFrom, ++itrTo) + ; +// Navigate backwards in directory to reach previously found base +for (of::filesystem::path::const_iterator fromEnd(pathFrom.end()); itrFrom != fromEnd; ++itrFrom) { + if ((*itrFrom) != ".") { + ret /= ".."; } - // Now navigate down the directory branch - for( ; itrTo != pathTo.end() ; ++itrTo ){ - if( itrTo->string() != "."){ - ret /= *itrTo; - } +} +// Now navigate down the directory branch +for (; itrTo != pathTo.end(); ++itrTo) { + if (itrTo->string() != ".") { + ret /= *itrTo; } +} // return ret; - return ret.string(); +return ret.string(); } //-------------------------------------------------- -void ofEnableDataPath(){ - enableDataPath = true; +void ofEnableDataPath() { +enableDataPath = true; } //-------------------------------------------------- -void ofDisableDataPath(){ - enableDataPath = false; +void ofDisableDataPath() { +enableDataPath = false; } //-------------------------------------------------- -bool ofRestoreWorkingDirectoryToDefault(){ - try{ - of::filesystem::current_path(defaultWorkingDirectory()); - return true; - }catch(...){ - return false; - } +bool ofRestoreWorkingDirectoryToDefault() { +try { + of::filesystem::current_path(defaultWorkingDirectory()); + return true; +} catch (...) { + return false; +} } //-------------------------------------------------- -void ofSetDataPathRoot(const of::filesystem::path& newRoot){ - dataPathRoot() = newRoot; +void ofSetDataPathRoot(const of::filesystem::path & newRoot) { +dataPathRoot() = newRoot; } //-------------------------------------------------- // MARK: - near future //of::filesystem::path ofToDataPath(const of::filesystem::path & path, bool makeAbsolute){ -std::string ofToDataPath(const of::filesystem::path & path, bool makeAbsolute){ - if (makeAbsolute && path.is_absolute()) { -// return path; - return path.string(); - } +std::string ofToDataPath(const of::filesystem::path & path, bool makeAbsolute) { +if (makeAbsolute && path.is_absolute()) { + // return path; + return path.string(); +} - if (!enableDataPath) { -// return path; - return path.string(); - } +if (!enableDataPath) { + // return path; + return path.string(); +} - bool hasTrailingSlash = !path.empty() && path.generic_string().back()=='/'; +bool hasTrailingSlash = !path.empty() && path.generic_string().back() == '/'; - // if our Current Working Directory has changed (e.g. file open dialog) +// if our Current Working Directory has changed (e.g. file open dialog) #ifdef TARGET_WIN32 - if (defaultWorkingDirectory() != of::filesystem::current_path()) { - // change our cwd back to where it was on app load - bool ret = ofRestoreWorkingDirectoryToDefault(); - if(!ret){ - ofLogWarning("ofUtils") << "ofToDataPath: error while trying to change back to default working directory " << defaultWorkingDirectory(); - } +if (defaultWorkingDirectory() != of::filesystem::current_path()) { + // change our cwd back to where it was on app load + bool ret = ofRestoreWorkingDirectoryToDefault(); + if (!ret) { + ofLogWarning("ofUtils") << "ofToDataPath: error while trying to change back to default working directory " << defaultWorkingDirectory(); } +} #endif - // this could be performed here, or wherever we might think we accidentally change the cwd, e.g. after file dialogs on windows - const auto & dataPath = dataPathRoot(); - of::filesystem::path inputPath(path); - of::filesystem::path outputPath; - - // if path is already absolute, just return it - if (inputPath.is_absolute()) { - try { - auto outpath = of::filesystem::canonical(inputPath).make_preferred(); - if(of::filesystem::is_directory(outpath) && hasTrailingSlash){ - return ofFilePath::addTrailingSlash(outpath); - }else{ - return outpath.string(); - // return outpath; - } - } - catch (...) { - return inputPath.string(); - // return inputPath; +// this could be performed here, or wherever we might think we accidentally change the cwd, e.g. after file dialogs on windows +const auto & dataPath = dataPathRoot(); +of::filesystem::path inputPath(path); +of::filesystem::path outputPath; + +// if path is already absolute, just return it +if (inputPath.is_absolute()) { + try { + auto outpath = of::filesystem::canonical(inputPath).make_preferred(); + if (of::filesystem::is_directory(outpath) && hasTrailingSlash) { + return ofFilePath::addTrailingSlash(outpath); + } else { + return outpath.string(); + // return outpath; } + } catch (...) { + return inputPath.string(); + // return inputPath; } +} - // here we check whether path already refers to the data folder by looking for common elements - // if the path begins with the full contents of dataPathRoot then the data path has already been added - // we compare inputPath.toString() rather that the input var path to ensure common formatting against dataPath.toString() - auto dirDataPath = dataPath; - // also, we strip the trailing slash from dataPath since `path` may be input as a file formatted path even if it is a folder (i.e. missing trailing slash) - dirDataPath = ofFilePath::addTrailingSlash(dataPath); - - auto relativeDirDataPath = ofFilePath::makeRelative(of::filesystem::current_path(), dataPath); - relativeDirDataPath = ofFilePath::addTrailingSlash(relativeDirDataPath); - - // FIXME: this can be simplified without using string conversion - // if (inputPath.string().find(dirDataPath.string()) != 0 && inputPath.string().find(relativeDirDataPath.string())!=0) { - if (inputPath.string().find(dirDataPath.string()) != 0 && inputPath.string().find(relativeDirDataPath)!=0) { - // inputPath doesn't contain data path already, so we build the output path as the inputPath relative to the dataPath - if(makeAbsolute){ - outputPath = dirDataPath / inputPath; - }else{ - outputPath = relativeDirDataPath / inputPath; - } +// here we check whether path already refers to the data folder by looking for common elements +// if the path begins with the full contents of dataPathRoot then the data path has already been added +// we compare inputPath.toString() rather that the input var path to ensure common formatting against dataPath.toString() +auto dirDataPath = dataPath; +// also, we strip the trailing slash from dataPath since `path` may be input as a file formatted path even if it is a folder (i.e. missing trailing slash) +dirDataPath = ofFilePath::addTrailingSlash(dataPath); + +auto relativeDirDataPath = ofFilePath::makeRelative(of::filesystem::current_path(), dataPath); +relativeDirDataPath = ofFilePath::addTrailingSlash(relativeDirDataPath); + +// FIXME: this can be simplified without using string conversion +// if (inputPath.string().find(dirDataPath.string()) != 0 && inputPath.string().find(relativeDirDataPath.string())!=0) { +if (inputPath.string().find(dirDataPath.string()) != 0 && inputPath.string().find(relativeDirDataPath) != 0) { + // inputPath doesn't contain data path already, so we build the output path as the inputPath relative to the dataPath + if (makeAbsolute) { + outputPath = dirDataPath / inputPath; } else { - // inputPath already contains data path, so no need to change - outputPath = inputPath; + outputPath = relativeDirDataPath / inputPath; } +} else { + // inputPath already contains data path, so no need to change + outputPath = inputPath; +} - // finally, if we do want an absolute path and we don't already have one - if(makeAbsolute){ - // then we return the absolute form of the path - try { - auto outpath = of::filesystem::canonical(of::filesystem::absolute(outputPath)).make_preferred(); - if(of::filesystem::is_directory(outpath) && hasTrailingSlash){ - return ofFilePath::addTrailingSlash(outpath); - }else{ -// return outpath; - return outpath.string(); - } - } - catch (std::exception &) { - return of::filesystem::absolute(outputPath).string(); - // return of::filesystem::absolute(outputPath); +// finally, if we do want an absolute path and we don't already have one +if (makeAbsolute) { + // then we return the absolute form of the path + try { + auto outpath = of::filesystem::canonical(of::filesystem::absolute(outputPath)).make_preferred(); + if (of::filesystem::is_directory(outpath) && hasTrailingSlash) { + return ofFilePath::addTrailingSlash(outpath); + } else { + // return outpath; + return outpath.string(); } - }else{ - // or output the relative path -// return outputPath; - return outputPath.string(); + } catch (std::exception &) { + return of::filesystem::absolute(outputPath).string(); + // return of::filesystem::absolute(outputPath); } +} else { + // or output the relative path + // return outputPath; + return outputPath.string(); +} } diff --git a/libs/openFrameworks/utils/ofFileUtils.h b/libs/openFrameworks/utils/ofFileUtils.h index 74aaa509002..8dfb7e7908c 100644 --- a/libs/openFrameworks/utils/ofFileUtils.h +++ b/libs/openFrameworks/utils/ofFileUtils.h @@ -12,254 +12,253 @@ /// /// A buffer of data which can be accessed as simple bytes or text. /// -class ofBuffer{ - +class ofBuffer { + public: - ofBuffer(); - - /// Create a buffer and set its contents from a raw byte pointer. - /// - /// \param buffer pointer to the raw byte buffer to copy data from - /// \param size the number of bytes to read - /// \warning buffer *must* not be NULL - /// \warning size *must* be <= the number of bytes allocated in buffer - ofBuffer(const char * buffer, std::size_t size); - - /// Create a buffer and set its contents from an input stream. - /// - /// \param ioBlockSize the number of bytes to read from the stream in chunks - ofBuffer(std::istream & stream, std::size_t ioBlockSize = 1024); - - /// Set the contents of the buffer from a raw byte pointer. - /// - /// \warning buffer *must* not be NULL - /// \warning size *must* be <= the number of bytes allocated in buffer - /// \param buffer pointer to the raw byte buffer to copy data from - /// \param size the number of bytes to read - void set(const char * buffer, std::size_t size); - - /// Set contents of the buffer from a string. - /// - /// \param text string to copy data from - void set(const std::string & text); - - /// Set contents of the buffer from an input stream. - /// - /// \param stream input stream to copy data from - /// \param ioBlockSize the number of bytes to read from the stream in chunks - bool set(std::istream & stream, std::size_t ioBlockSize = 1024); - - /// Set all bytes in the buffer to a given value. - /// - /// \param mem byte value to set - void setall(char mem); - - /// Append bytes to the end of buffer from a string. - /// - /// \param buffer string to copy bytes from - void append(const std::string& buffer); - - /// Append bytes to the end of the buffer from a raw byte pointer. - /// - /// \warning buffer *must* not be NULL - /// \warning size *must* be <= the number of bytes allocated in buffer - /// \param buffer pointer to the raw byte buffer to copy data from - /// \param size the number of bytes to read - void append(const char * buffer, std::size_t size); - - /// Request that the buffer capacity be at least enough to contain a - /// specified number of bytes. - /// - /// \param size number of bytes to reserve space for - void reserve(std::size_t size); - - /// Write contents of the buffer to an output stream. - bool writeTo(std::ostream & stream) const; - - /// Remove all bytes from the buffer, leaving a size of 0. - void clear(); - - /// Request that the buffer capacity be at least enough to contain a - /// specified number of bytes. - /// - /// \param size number of bytes to reserve space for - void allocate(std::size_t size); - - /// Resize the buffer to contain a specified number of bytes. - /// - /// If size is < the current buffer size, the contents are reduced to size - /// bytes & remaining bytes are removed. If size is > the current buffer - /// size, the buffer's size is increased to size_ bytes. - /// - /// \param size number of bytes to resize the buffer to - void resize(std::size_t size); - - /// Access the buffer's contents using a raw byte pointer. - /// - /// \warning Do not access bytes at indices beyond size()! - /// \returns pointer to internal raw bytes - char * getData(); - - /// access the buffer's contents using a const raw byte pointer. - /// - /// \warning Do not access bytes at indices beyond size()! - /// \returns const pointer to internal raw bytes - const char * getData() const; - OF_DEPRECATED_MSG("Use getData instead",char * getBinaryBuffer()); - OF_DEPRECATED_MSG("Use getData instead",const char * getBinaryBuffer() const); - - /// get the contents of the buffer as a string. - /// - /// \returns buffer contents as a string - std::string getText() const; - - /// Use buffer as a string via cast. - /// - /// \returns buffer contents as a string - operator std::string() const; - - /// set contents of the buffer from a string - ofBuffer & operator=(const std::string & text); - - /// Check the buffer's size. - /// - /// \returns the size of the buffer's content in bytes - std::size_t size() const; - - OF_DEPRECATED_MSG("use a lines iterator instead",std::string getNextLine()); - OF_DEPRECATED_MSG("use a lines iterator instead",std::string getFirstLine()); - OF_DEPRECATED_MSG("use a lines iterator instead",bool isLastLine()); - OF_DEPRECATED_MSG("use a lines iterator instead",void resetLineReader()); - - friend std::ostream & operator<<(std::ostream & ostr, const ofBuffer & buf); - friend std::istream & operator>>(std::istream & istr, ofBuffer & buf); - - std::vector::iterator begin(); - std::vector::iterator end(); - std::vector::const_iterator begin() const; - std::vector::const_iterator end() const; - std::vector::reverse_iterator rbegin(); - std::vector::reverse_iterator rend(); - std::vector::const_reverse_iterator rbegin() const; - std::vector::const_reverse_iterator rend() const; - - /// A line of text in the buffer. - /// - - struct Line { - Line(std::vector::iterator _begin, std::vector::iterator _end); - const std::string & operator*() const; - const std::string * operator->() const; - const std::string & asString() const; - - using value_type = std::string; - using iterator_category = std::forward_iterator_tag; - using difference_type = std::ptrdiff_t; - using pointer = const value_type*; - using reference = const value_type&; - - /// Increment to the next line. - Line& operator++(); - - /// Increment to a number of lines. - Line operator++(int); - - bool operator!=(Line const& rhs) const; - bool operator==(Line const& rhs) const; - - /// Is this line empty? (aka an empty string "") - bool empty() const; - - private: - std::string line; - std::vector::iterator _current, _begin, _end; - }; - - /// A line of text in the buffer. - /// - struct RLine { - RLine(std::vector::reverse_iterator _begin, std::vector::reverse_iterator _end); - const std::string & operator*() const; - const std::string * operator->() const; - const std::string & asString() const; - - using value_type = std::string; - using iterator_category = std::forward_iterator_tag; - using difference_type = std::ptrdiff_t; - using pointer = const value_type*; - using reference = const value_type&; - - /// Increment to the next line. - RLine& operator++(); - - /// Increment to a number of lines. - RLine operator++(int); - - bool operator!=(RLine const& rhs) const; - bool operator==(RLine const& rhs) const; - - /// Is this line empty? (aka an empty string "") - bool empty() const; - - private: - std::string line; - std::vector::reverse_iterator _current, _rbegin, _rend; - }; - - /// A series of text lines in the buffer. - /// - struct Lines{ - Lines(std::vector::iterator begin, std::vector::iterator end); - - /// Get the first line in the buffer. - Line begin(); - - /// Get the last line in the buffer. - Line end(); - - RLine rbegin(); - RLine rend(); - - private: - std::vector::iterator _begin, _end; - }; - - - /// A series of text lines in the buffer. - /// - struct RLines{ - RLines(std::vector::reverse_iterator rbegin, std::vector::reverse_iterator rend); - - /// Get the first line in the buffer. - RLine begin(); - - /// Get the last line in the buffer. - RLine end(); - - private: - std::vector::reverse_iterator _rbegin, _rend; - }; - - /// Access the contents of the buffer as a series of text lines. - /// - /// If the buffer loads a text file with lines separated by an endline - /// char '\n', you can access each line individually using Line structs. - /// - /// \returns buffer text lines - Lines getLines(); - - /// Access the contents of the buffer as a series of text lines in reverse - /// order - /// - /// If the buffer loads a text file with lines separated by an endline - /// char '\n' or '\r\n', you can access each line individually using Line structs. - /// - /// \returns buffer text lines - RLines getReverseLines(); +ofBuffer(); + +/// Create a buffer and set its contents from a raw byte pointer. +/// +/// \param buffer pointer to the raw byte buffer to copy data from +/// \param size the number of bytes to read +/// \warning buffer *must* not be NULL +/// \warning size *must* be <= the number of bytes allocated in buffer +ofBuffer(const char * buffer, std::size_t size); + +/// Create a buffer and set its contents from an input stream. +/// +/// \param ioBlockSize the number of bytes to read from the stream in chunks +ofBuffer(std::istream & stream, std::size_t ioBlockSize = 1024); + +/// Set the contents of the buffer from a raw byte pointer. +/// +/// \warning buffer *must* not be NULL +/// \warning size *must* be <= the number of bytes allocated in buffer +/// \param buffer pointer to the raw byte buffer to copy data from +/// \param size the number of bytes to read +void set(const char * buffer, std::size_t size); + +/// Set contents of the buffer from a string. +/// +/// \param text string to copy data from +void set(const std::string & text); + +/// Set contents of the buffer from an input stream. +/// +/// \param stream input stream to copy data from +/// \param ioBlockSize the number of bytes to read from the stream in chunks +bool set(std::istream & stream, std::size_t ioBlockSize = 1024); + +/// Set all bytes in the buffer to a given value. +/// +/// \param mem byte value to set +void setall(char mem); + +/// Append bytes to the end of buffer from a string. +/// +/// \param buffer string to copy bytes from +void append(const std::string & buffer); + +/// Append bytes to the end of the buffer from a raw byte pointer. +/// +/// \warning buffer *must* not be NULL +/// \warning size *must* be <= the number of bytes allocated in buffer +/// \param buffer pointer to the raw byte buffer to copy data from +/// \param size the number of bytes to read +void append(const char * buffer, std::size_t size); + +/// Request that the buffer capacity be at least enough to contain a +/// specified number of bytes. +/// +/// \param size number of bytes to reserve space for +void reserve(std::size_t size); + +/// Write contents of the buffer to an output stream. +bool writeTo(std::ostream & stream) const; + +/// Remove all bytes from the buffer, leaving a size of 0. +void clear(); + +/// Request that the buffer capacity be at least enough to contain a +/// specified number of bytes. +/// +/// \param size number of bytes to reserve space for +void allocate(std::size_t size); + +/// Resize the buffer to contain a specified number of bytes. +/// +/// If size is < the current buffer size, the contents are reduced to size +/// bytes & remaining bytes are removed. If size is > the current buffer +/// size, the buffer's size is increased to size_ bytes. +/// +/// \param size number of bytes to resize the buffer to +void resize(std::size_t size); + +/// Access the buffer's contents using a raw byte pointer. +/// +/// \warning Do not access bytes at indices beyond size()! +/// \returns pointer to internal raw bytes +char * getData(); + +/// access the buffer's contents using a const raw byte pointer. +/// +/// \warning Do not access bytes at indices beyond size()! +/// \returns const pointer to internal raw bytes +const char * getData() const; +OF_DEPRECATED_MSG("Use getData instead", char * getBinaryBuffer()); +OF_DEPRECATED_MSG("Use getData instead", const char * getBinaryBuffer() const); + +/// get the contents of the buffer as a string. +/// +/// \returns buffer contents as a string +std::string getText() const; + +/// Use buffer as a string via cast. +/// +/// \returns buffer contents as a string +operator std::string() const; + +/// set contents of the buffer from a string +ofBuffer & operator=(const std::string & text); + +/// Check the buffer's size. +/// +/// \returns the size of the buffer's content in bytes +std::size_t size() const; + +OF_DEPRECATED_MSG("use a lines iterator instead", std::string getNextLine()); +OF_DEPRECATED_MSG("use a lines iterator instead", std::string getFirstLine()); +OF_DEPRECATED_MSG("use a lines iterator instead", bool isLastLine()); +OF_DEPRECATED_MSG("use a lines iterator instead", void resetLineReader()); + +friend std::ostream & operator<<(std::ostream & ostr, const ofBuffer & buf); +friend std::istream & operator>>(std::istream & istr, ofBuffer & buf); + +std::vector::iterator begin(); +std::vector::iterator end(); +std::vector::const_iterator begin() const; +std::vector::const_iterator end() const; +std::vector::reverse_iterator rbegin(); +std::vector::reverse_iterator rend(); +std::vector::const_reverse_iterator rbegin() const; +std::vector::const_reverse_iterator rend() const; + +/// A line of text in the buffer. +/// + +struct Line { + Line(std::vector::iterator _begin, std::vector::iterator _end); + const std::string & operator*() const; + const std::string * operator->() const; + const std::string & asString() const; + + using value_type = std::string; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; + using pointer = const value_type *; + using reference = const value_type &; + + /// Increment to the next line. + Line & operator++(); + + /// Increment to a number of lines. + Line operator++(int); + + bool operator!=(Line const & rhs) const; + bool operator==(Line const & rhs) const; + + /// Is this line empty? (aka an empty string "") + bool empty() const; + +private: + std::string line; + std::vector::iterator _current, _begin, _end; +}; + +/// A line of text in the buffer. +/// +struct RLine { + RLine(std::vector::reverse_iterator _begin, std::vector::reverse_iterator _end); + const std::string & operator*() const; + const std::string * operator->() const; + const std::string & asString() const; + + using value_type = std::string; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; + using pointer = const value_type *; + using reference = const value_type &; + + /// Increment to the next line. + RLine & operator++(); + + /// Increment to a number of lines. + RLine operator++(int); + + bool operator!=(RLine const & rhs) const; + bool operator==(RLine const & rhs) const; + + /// Is this line empty? (aka an empty string "") + bool empty() const; + +private: + std::string line; + std::vector::reverse_iterator _current, _rbegin, _rend; +}; + +/// A series of text lines in the buffer. +/// +struct Lines { + Lines(std::vector::iterator begin, std::vector::iterator end); + + /// Get the first line in the buffer. + Line begin(); + + /// Get the last line in the buffer. + Line end(); + + RLine rbegin(); + RLine rend(); private: - std::vector buffer; - Line currentLine; + std::vector::iterator _begin, _end; +}; + +/// A series of text lines in the buffer. +/// +struct RLines { + RLines(std::vector::reverse_iterator rbegin, std::vector::reverse_iterator rend); + + /// Get the first line in the buffer. + RLine begin(); + + /// Get the last line in the buffer. + RLine end(); + +private: + std::vector::reverse_iterator _rbegin, _rend; +}; + +/// Access the contents of the buffer as a series of text lines. +/// +/// If the buffer loads a text file with lines separated by an endline +/// char '\n', you can access each line individually using Line structs. +/// +/// \returns buffer text lines +Lines getLines(); + +/// Access the contents of the buffer as a series of text lines in reverse +/// order +/// +/// If the buffer loads a text file with lines separated by an endline +/// char '\n' or '\r\n', you can access each line individually using Line structs. +/// +/// \returns buffer text lines +RLines getReverseLines(); + +private: +std::vector buffer; +Line currentLine; }; //-------------------------------------------------- @@ -270,7 +269,7 @@ class ofBuffer{ /// \param path file to open /// \param binary set to false if you are reading a text file & want lines /// split at endline characters automatically -ofBuffer ofBufferFromFile(const of::filesystem::path & path, bool binary=true); +ofBuffer ofBufferFromFile(const of::filesystem::path & path, bool binary = true); //-------------------------------------------------- /// Write the contents of a buffer to a file at path. @@ -281,186 +280,185 @@ ofBuffer ofBufferFromFile(const of::filesystem::path & path, bool binary=true); /// \param buffer data source to write from /// \param binary set to false if you are writing a text file & want lines /// split at endline characters automatically -bool ofBufferToFile(const of::filesystem::path & path, const ofBuffer& buffer, bool binary=true); +bool ofBufferToFile(const of::filesystem::path & path, const ofBuffer & buffer, bool binary = true); //-------------------------------------------------- /// \class ofFilePath /// /// Static class for working with file path strings. /// -class ofFilePath{ +class ofFilePath { public: - - /// Get the extension of a filename, ie. "duck.jpg" -> "jpg". - /// - /// \param filename file path - /// \returns filename extension only - static std::string getFileExt(const of::filesystem::path& filename); - - /// Remove extension from a filename, ie. "duck.jpg" ->"duck". - /// - /// \param filename file path - /// \returns filename without extension +/// Get the extension of a filename, ie. "duck.jpg" -> "jpg". +/// +/// \param filename file path +/// \returns filename extension only +static std::string getFileExt(const of::filesystem::path & filename); + +/// Remove extension from a filename, ie. "duck.jpg" ->"duck". +/// +/// \param filename file path +/// \returns filename without extension // MARK: - near future // static of::filesystem::path removeExt(const of::filesystem::path& filename); - static std::string removeExt(const of::filesystem::path& filename); - - /// Prepend path with a slash, ie. "images" -> "/images". - /// - /// \param path file or directory path - /// \returns slah + path - static std::string addLeadingSlash(const of::filesystem::path& path); - - /// Append path with a slash, ie. "images" -> "images/". - /// - /// \param path directory path - /// \returns path + slash +static std::string removeExt(const of::filesystem::path & filename); + +/// Prepend path with a slash, ie. "images" -> "/images". +/// +/// \param path file or directory path +/// \returns slah + path +static std::string addLeadingSlash(const of::filesystem::path & path); + +/// Append path with a slash, ie. "images" -> "images/". +/// +/// \param path directory path +/// \returns path + slash // MARK: - near future // static of::filesystem::path addTrailingSlash(const of::filesystem::path& path); - static std::string addTrailingSlash(const of::filesystem::path& path); - - /// Remove a path's trailing slash (if found), - /// ie. "images/" -> "images". - /// - /// \param path directory path - /// \returns path minus trailing slash - static std::string removeTrailingSlash(const of::filesystem::path& path); - - /// Cleaned up a directory path by adding a trailing slash if needed. - /// - /// For Windows-style path strings using "\", a "\" will be added. - /// For Unix-style path strings using "/", a "/" will be added. - /// - /// \param path directory path - /// \returns cleaned path + trailing slash (if needed) - static std::string getPathForDirectory(const of::filesystem::path& path); - - /// Get the absolute, full path for a given path, - /// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images". - /// - /// \param path file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder and want the direct path without relative - /// "../../" - /// \returns absolute path - // MARK - near future - // static of::filesystem::path getAbsolutePath(const of::filesystem::path& path, bool bRelativeToData = true); - static std::string getAbsolutePath(const of::filesystem::path& path, bool bRelativeToData = true); - - /// Check if a path is an absolute (aka a full path), - /// ie. "images" -> false, - /// "/Users/mickey/of/apps/myApps/Donald/bin/data/images" -> true. - /// - /// \param path file or directory path - /// \returns true if the path is an absolute path - static bool isAbsolute(const of::filesystem::path& path); - - /// Get the filename of a given path by stripping the parent - /// directories ie. "images/duck.jpg" -> "duck.jpg", assumes the path is in - /// the data folder. - /// - /// \param filePath file path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder and want the direct path without relative - /// "../../" - /// \returns filename - /// - // FIXME: Deprecate / Remove this. - static std::string getFileName(const of::filesystem::path& filePath, bool bRelativeToData = true); - - /// Get a file name without its extension, - /// ie. "images/duck.jpg" -> "duck" and - /// "images/some/folder" -> "folder" - /// - /// \param filePath file path - /// \returns basename - static std::string getBaseName(const of::filesystem::path& filePath); - - /// Get the enclosing parent directory of a path, - /// ie. "images/duck.jpg" -> "images", assumes the path is in the data - /// directory. - /// - /// \param filePath file path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder and want the direct path without relative - /// "../../" - ///\returns enclosing directory +static std::string addTrailingSlash(const of::filesystem::path & path); + +/// Remove a path's trailing slash (if found), +/// ie. "images/" -> "images". +/// +/// \param path directory path +/// \returns path minus trailing slash +static std::string removeTrailingSlash(const of::filesystem::path & path); + +/// Cleaned up a directory path by adding a trailing slash if needed. +/// +/// For Windows-style path strings using "\", a "\" will be added. +/// For Unix-style path strings using "/", a "/" will be added. +/// +/// \param path directory path +/// \returns cleaned path + trailing slash (if needed) +static std::string getPathForDirectory(const of::filesystem::path & path); + +/// Get the absolute, full path for a given path, +/// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images". +/// +/// \param path file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder and want the direct path without relative +/// "../../" +/// \returns absolute path +// MARK - near future +// static of::filesystem::path getAbsolutePath(const of::filesystem::path& path, bool bRelativeToData = true); +static std::string getAbsolutePath(const of::filesystem::path & path, bool bRelativeToData = true); + +/// Check if a path is an absolute (aka a full path), +/// ie. "images" -> false, +/// "/Users/mickey/of/apps/myApps/Donald/bin/data/images" -> true. +/// +/// \param path file or directory path +/// \returns true if the path is an absolute path +static bool isAbsolute(const of::filesystem::path & path); + +/// Get the filename of a given path by stripping the parent +/// directories ie. "images/duck.jpg" -> "duck.jpg", assumes the path is in +/// the data folder. +/// +/// \param filePath file path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder and want the direct path without relative +/// "../../" +/// \returns filename +/// +// FIXME: Deprecate / Remove this. +static std::string getFileName(const of::filesystem::path & filePath, bool bRelativeToData = true); + +/// Get a file name without its extension, +/// ie. "images/duck.jpg" -> "duck" and +/// "images/some/folder" -> "folder" +/// +/// \param filePath file path +/// \returns basename +static std::string getBaseName(const of::filesystem::path & filePath); + +/// Get the enclosing parent directory of a path, +/// ie. "images/duck.jpg" -> "images", assumes the path is in the data +/// directory. +/// +/// \param filePath file path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder and want the direct path without relative +/// "../../" +///\returns enclosing directory // MARK: - near future // static of::filesystem::path getEnclosingDirectory(const of::filesystem::path& filePath, bool bRelativeToData = true); - static std::string getEnclosingDirectory(const of::filesystem::path& filePath, bool bRelativeToData = true); - - /// Create the enclosing parent directory of a path, ie. - /// "images" is the enclosing directory of "duck.jpg" = "images/duck.jpg". - /// - /// Assumes the path is in the data folder & automatically creates nested - /// directories as required. - /// - /// \param bRecursive set to false to override automatically nested - /// directory creation - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder and want the direct path without relative - /// "../../" - /// \returns true if the enclosing directory was created - static bool createEnclosingDirectory(const of::filesystem::path& filePath, bool bRelativeToData = true, bool bRecursive = true); - - /// Get the full path to the app's current working directory. - /// - /// This may be the app's parent directory or the location the app was - /// launched from (aka on the commandline). - /// - /// \warning This location *may* change if you or a library calls the cd() - /// std C function. - /// \returns current working directory - static std::string getCurrentWorkingDirectory(); - - /// Create a single path by joining path1 & path2 using a slash, - /// ie. "/hello/world" + "foo/bar" -> "/hello/world/foo/bar". - /// - /// \param path1 left half of the path to join - /// \param path2 right half of the path to join - /// \returns joined path +static std::string getEnclosingDirectory(const of::filesystem::path & filePath, bool bRelativeToData = true); + +/// Create the enclosing parent directory of a path, ie. +/// "images" is the enclosing directory of "duck.jpg" = "images/duck.jpg". +/// +/// Assumes the path is in the data folder & automatically creates nested +/// directories as required. +/// +/// \param bRecursive set to false to override automatically nested +/// directory creation +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder and want the direct path without relative +/// "../../" +/// \returns true if the enclosing directory was created +static bool createEnclosingDirectory(const of::filesystem::path & filePath, bool bRelativeToData = true, bool bRecursive = true); + +/// Get the full path to the app's current working directory. +/// +/// This may be the app's parent directory or the location the app was +/// launched from (aka on the commandline). +/// +/// \warning This location *may* change if you or a library calls the cd() +/// std C function. +/// \returns current working directory +static std::string getCurrentWorkingDirectory(); + +/// Create a single path by joining path1 & path2 using a slash, +/// ie. "/hello/world" + "foo/bar" -> "/hello/world/foo/bar". +/// +/// \param path1 left half of the path to join +/// \param path2 right half of the path to join +/// \returns joined path // MARK: - near future // static of::filesystem::path join(const of::filesystem::path& path1, const of::filesystem::path& path2); - static std::string join(const of::filesystem::path& path1, const of::filesystem::path& path2); - - /// Get the full path to the application's executable file. - /// - /// Mac: the binary within the application's .app bundle Contents/MacOS dir - /// Windows: the .exe - /// Linux: the binary file itself - /// - /// \returns current executable path - static std::string getCurrentExePath(); - - /// Get the full path to the application's parent directory. - /// - /// Windows & Linux: the application's parent directory - /// Mac: the Contents/MacOS folder within the application's .app bundle - /// - /// \returns current executable directory +static std::string join(const of::filesystem::path & path1, const of::filesystem::path & path2); + +/// Get the full path to the application's executable file. +/// +/// Mac: the binary within the application's .app bundle Contents/MacOS dir +/// Windows: the .exe +/// Linux: the binary file itself +/// +/// \returns current executable path +static std::string getCurrentExePath(); + +/// Get the full path to the application's parent directory. +/// +/// Windows & Linux: the application's parent directory +/// Mac: the Contents/MacOS folder within the application's .app bundle +/// +/// \returns current executable directory // MARK: - near future // static of::filesystem::path getCurrentExeDir(); - static std::string getCurrentExeDir(); - - /// Get the absolute path to the user's home directory. - /// - /// Mac OSX: /Users/ - /// Windows: \Users\ - /// Linux: /home/ - /// - /// \returns home directory path - static std::string getUserHomeDir(); - - /// Make one path relative to another, - /// ie. the relative path of "images/felines/lions" to - /// "images/felines/tigers" is "../tigers". - /// - /// \param from starting path - /// \param to destination path - /// \returns relative path - // MARK: - near future +static std::string getCurrentExeDir(); + +/// Get the absolute path to the user's home directory. +/// +/// Mac OSX: /Users/ +/// Windows: \Users\ +/// Linux: /home/ +/// +/// \returns home directory path +static std::string getUserHomeDir(); + +/// Make one path relative to another, +/// ie. the relative path of "images/felines/lions" to +/// "images/felines/tigers" is "../tigers". +/// +/// \param from starting path +/// \param to destination path +/// \returns relative path +// MARK: - near future // static of::filesystem::path makeRelative(const of::filesystem::path & from, const of::filesystem::path & to); - static std::string makeRelative(const of::filesystem::path & from, const of::filesystem::path & to); +static std::string makeRelative(const of::filesystem::path & from, const of::filesystem::path & to); }; /// \class ofFile @@ -469,369 +467,368 @@ class ofFilePath{ /// /// inherits from an fstream so you can read/write using the stream operators /// once a file path has been opened -class ofFile: public std::fstream{ +class ofFile : public std::fstream { public: - - /// file access mode - enum Mode{ - Reference, //< - ReadOnly, //< read only from the file, do not write - WriteOnly, //< write only to the file, do not read - ReadWrite, //< read from and write to the file - Append //< append data to the end of the file, do not overwrite - }; - - /// Create an ofFile instance. - /// - /// Does not refer to a specific file until you either open a file or create - /// a file or directory path. - ofFile(); - - /// Create a new ofFile instance and attempt to open the path as a - /// file. - /// - /// Opens as a binary file with read only access by default. - /// - /// \param path file path - /// \param mode file access mode depending on how you plan to use the file - /// (read only, read write, etc) - /// \param binary set to false if you are working with a text file & want - /// lines split at endline characters automatically - ofFile(const of::filesystem::path & path, Mode mode=ReadOnly, bool binary=true); - - /// Create a new file path using the same path & settings of another - /// file. - /// - /// \param mom ofFile instance source - ofFile(const ofFile & mom); - - /// Copy the path and settings of an ofFile into this instance. - /// - /// \param mom ofFile instance source - ofFile & operator= (const ofFile & mom); - - ~ofFile(); - - /// Open the path as a file. - /// - /// Opens as a text file with read only access by default. - /// - /// \param path file path - /// \param mode file access mode depending on how you plan to use the file - /// (read only, read write, etc) - /// \param binary set to false if you are reading a text file & want lines - /// split at endline characters automatically - /// \returns true if the path was opened +/// file access mode +enum Mode { + Reference, //< + ReadOnly, //< read only from the file, do not write + WriteOnly, //< write only to the file, do not read + ReadWrite, //< read from and write to the file + Append //< append data to the end of the file, do not overwrite +}; + +/// Create an ofFile instance. +/// +/// Does not refer to a specific file until you either open a file or create +/// a file or directory path. +ofFile(); + +/// Create a new ofFile instance and attempt to open the path as a +/// file. +/// +/// Opens as a binary file with read only access by default. +/// +/// \param path file path +/// \param mode file access mode depending on how you plan to use the file +/// (read only, read write, etc) +/// \param binary set to false if you are working with a text file & want +/// lines split at endline characters automatically +ofFile(const of::filesystem::path & path, Mode mode = ReadOnly, bool binary = true); + +/// Create a new file path using the same path & settings of another +/// file. +/// +/// \param mom ofFile instance source +ofFile(const ofFile & mom); + +/// Copy the path and settings of an ofFile into this instance. +/// +/// \param mom ofFile instance source +ofFile & operator=(const ofFile & mom); + +~ofFile(); + +/// Open the path as a file. +/// +/// Opens as a text file with read only access by default. +/// +/// \param path file path +/// \param mode file access mode depending on how you plan to use the file +/// (read only, read write, etc) +/// \param binary set to false if you are reading a text file & want lines +/// split at endline characters automatically +/// \returns true if the path was opened // bool open(of::filesystem::path & path, Mode mode=ReadOnly, bool binary=true); - bool open(const of::filesystem::path & path, Mode mode=ReadOnly, bool binary=true); - - /// Open the path as a file. - /// - /// Opens as a text file with read only access by default from the current working directory without internally calling ofToDataPath. - /// - /// \param path file path - /// \param mode file access mode depending on how you plan to use the file - /// (read only, read write, etc) - /// \param binary set to false if you are reading a text file & want lines - /// split at endline characters automatically - /// \returns true if the path was opened - bool openFromCWD(const of::filesystem::path & path, Mode mode=ReadOnly, bool binary=true); - - /// Reopen the current file path with a different access mode. - /// - /// \param mode file access mode depending on how you plan to use the file - /// (read only, read write, etc) - /// \param binary set to false if you are reading a text file & want lines - /// split at endline characters automatically - /// \returns true if the file was reopened with the new access mode(s). - bool changeMode(Mode mode, bool binary=true); - - /// Close a currently open file. - void close(); - - /// Create a file at the current path. - /// - /// Creates as a write only binary file by default. - /// - /// \returns true if the file was created - bool create(); - - /// Create a file at a given path. - /// - /// Creates as a write only binary file by default. - /// - /// \param path file path - /// \returns true if the file was created - bool create(const of::filesystem::path & path); - - /// Check if a file exists at the current path. - /// - /// \returns true if the file exists - bool exists() const; - - /// Get the current path. - /// - /// \returns current path +bool open(const of::filesystem::path & path, Mode mode = ReadOnly, bool binary = true); + +/// Open the path as a file. +/// +/// Opens as a text file with read only access by default from the current working directory without internally calling ofToDataPath. +/// +/// \param path file path +/// \param mode file access mode depending on how you plan to use the file +/// (read only, read write, etc) +/// \param binary set to false if you are reading a text file & want lines +/// split at endline characters automatically +/// \returns true if the path was opened +bool openFromCWD(const of::filesystem::path & path, Mode mode = ReadOnly, bool binary = true); + +/// Reopen the current file path with a different access mode. +/// +/// \param mode file access mode depending on how you plan to use the file +/// (read only, read write, etc) +/// \param binary set to false if you are reading a text file & want lines +/// split at endline characters automatically +/// \returns true if the file was reopened with the new access mode(s). +bool changeMode(Mode mode, bool binary = true); + +/// Close a currently open file. +void close(); + +/// Create a file at the current path. +/// +/// Creates as a write only binary file by default. +/// +/// \returns true if the file was created +bool create(); + +/// Create a file at a given path. +/// +/// Creates as a write only binary file by default. +/// +/// \param path file path +/// \returns true if the file was created +bool create(const of::filesystem::path & path); + +/// Check if a file exists at the current path. +/// +/// \returns true if the file exists +bool exists() const; + +/// Get the current path. +/// +/// \returns current path // MARK: - near future // of::filesystem::path path() const; - std::string path() const; - - /// Get the current path without its extension, - /// ie. "duck.jpg" ->"duck". - /// - /// \returns current path file extension - std::string getExtension() const; - - /// Get the filename of the current path by stripping the parent - /// directories, ie. "images/duck.jpg" -> "duck.jpg". - /// - /// \returns current path filename - std::string getFileName() const; - - /// \biref Get the current path without its last component, - /// ie. "images/duck.jpg" -> "images" and - /// "images/some/folder" -> "images/some". - /// - /// \returns current path basename - std::string getBaseName() const; - - /// Get the enclosing parent directory of a path, - /// ie. "images/duck.jpg" -> "images", assumes the path is in the data - /// directory. - /// - /// \returns current path's enclosing directory +std::string path() const; + +/// Get the current path without its extension, +/// ie. "duck.jpg" ->"duck". +/// +/// \returns current path file extension +std::string getExtension() const; + +/// Get the filename of the current path by stripping the parent +/// directories, ie. "images/duck.jpg" -> "duck.jpg". +/// +/// \returns current path filename +std::string getFileName() const; + +/// \biref Get the current path without its last component, +/// ie. "images/duck.jpg" -> "images" and +/// "images/some/folder" -> "images/some". +/// +/// \returns current path basename +std::string getBaseName() const; + +/// Get the enclosing parent directory of a path, +/// ie. "images/duck.jpg" -> "images", assumes the path is in the data +/// directory. +/// +/// \returns current path's enclosing directory // MARK: - near future // of::filesystem::path getEnclosingDirectory() const; - std::string getEnclosingDirectory() const; - - /// \biref Get the absolute, full path of the file, - /// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images". - /// - /// \returns current path as an absolute path +std::string getEnclosingDirectory() const; + +/// \biref Get the absolute, full path of the file, +/// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images". +/// +/// \returns current path as an absolute path // MARK: - near future // of::filesystem::path getAbsolutePath() const; - std::string getAbsolutePath() const; - - /// Check if the current path is readable. - /// - /// \returns true if readable - bool canRead() const; - - /// Check if the current path is writable. - /// - /// \returns true if writable - bool canWrite() const; - - /// Check if the current path is executable. - /// - /// \returns true if executable - bool canExecute() const; - - /// Check if the current path is a file and not a directory. - /// - /// \returns true if a file - bool isFile() const; - - /// Check if the current path is a system link to another file or - /// directory. - /// - /// \returns true if a system link - bool isLink() const; - - /// Check if the current path is a directory and not a file. - /// - /// \returns true if a directory - bool isDirectory() const; - - /// Check if the current path is a device file. - /// - /// Works on Mac & Linux which can represent devices as files, however - /// always returns false on Windows. - /// - /// \returns true if a device file - bool isDevice() const; - - /// Check if the current path is hidden. - /// - /// Works on Mac & Linux which denote hidden files by prepending a period - /// to the filename -> ".hello", however always returns false on Windows. - /// - /// \returns true if hidden - bool isHidden() const; - - /// Set the writable flag of the current path. - void setWriteable(bool writeable=true); - - OF_DEPRECATED_MSG("Use ofFile::setWriteable(!flag).", void setReadOnly(bool flag)); - - /// Set the readable flag of the current path. - void setReadable(bool readable=true); - - /// Set the executable flag of the current path. - void setExecutable(bool executable=true); - - /// Copy the current file or directory path to a new path. - /// - /// Copies relative to the data path & does *not* overwrite by default - /// does not change the current path & assumes the new path is in the data - /// folder. - /// - /// \param path destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \returns true if the copy was successful - bool copyTo(const of::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false) const; - - /// Move the current file or directory path to a new path. - /// - /// Moves relative to the data path & does *not* overwrite by default - /// does not change the current path & assumes the new path is in the data - /// folder. - /// - /// \param path destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \returns true if the copy was successful - bool moveTo(const of::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false); - - /// Rename the current file or directory path to a new path. - /// - /// Renames relative to the data path & does *not* overwrite by default - /// does not change the current path & assumes the new path is in the data - /// folder. - /// - /// \param path destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \returns true if the copy was successful - bool renameTo(const of::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false); - - /// Removes the file or directory at the current path. - /// - /// Does not remove non-empty directories by default. - /// - /// \warning Be careful! This deletes a file or folder. :) - /// \param recursive set to true to remove a non-empty directory and its - /// contents - /// \returns true if the path was removed successfully - bool remove(bool recursive=false); - - /// get the size of the file at the current file path - /// - /// \returns size in bytes - uint64_t getSize() const; - - // this allows to compare files by their paths, also provides sorting - // and use as key in stl containers - bool operator==(const ofFile & file) const; - bool operator!=(const ofFile & file) const; - bool operator<(const ofFile & file) const; - bool operator<=(const ofFile & file) const; - bool operator>(const ofFile & file) const; - bool operator>=(const ofFile & file) const; - - //------------------ - // stream operations - //------------------ - - // since this class inherits from fstream it can be used as a r/w stream: - // http://www.cplusplus.com/reference/iostream/fstream/ - - /// Read the contents of a file at the current path into a buffer. - /// - /// \returns buffer with file contents - ofBuffer readToBuffer(); - - /// Write the contents of a buffer into a file at the current path. - /// - /// \param buffer source byte buffer - /// \returns true if buffer's contents written successfully - bool writeFromBuffer(const ofBuffer & buffer); - - /// Read the entire contents of the currently opened file into an - /// output stream. - /// - /// This is basically an easy to use equivalent to rdbuf(): - /// ie. ofLogNotice() << file.getFileBuffer(); - /// write_file << file.getFileBuffer(); - /// - /// \return output stream - std::filebuf * getFileBuffer() const; - - operator of::filesystem::path(){ - return myFile; - } +std::string getAbsolutePath() const; + +/// Check if the current path is readable. +/// +/// \returns true if readable +bool canRead() const; + +/// Check if the current path is writable. +/// +/// \returns true if writable +bool canWrite() const; + +/// Check if the current path is executable. +/// +/// \returns true if executable +bool canExecute() const; + +/// Check if the current path is a file and not a directory. +/// +/// \returns true if a file +bool isFile() const; + +/// Check if the current path is a system link to another file or +/// directory. +/// +/// \returns true if a system link +bool isLink() const; + +/// Check if the current path is a directory and not a file. +/// +/// \returns true if a directory +bool isDirectory() const; + +/// Check if the current path is a device file. +/// +/// Works on Mac & Linux which can represent devices as files, however +/// always returns false on Windows. +/// +/// \returns true if a device file +bool isDevice() const; + +/// Check if the current path is hidden. +/// +/// Works on Mac & Linux which denote hidden files by prepending a period +/// to the filename -> ".hello", however always returns false on Windows. +/// +/// \returns true if hidden +bool isHidden() const; + +/// Set the writable flag of the current path. +void setWriteable(bool writeable = true); + +OF_DEPRECATED_MSG("Use ofFile::setWriteable(!flag).", void setReadOnly(bool flag)); + +/// Set the readable flag of the current path. +void setReadable(bool readable = true); + +/// Set the executable flag of the current path. +void setExecutable(bool executable = true); + +/// Copy the current file or directory path to a new path. +/// +/// Copies relative to the data path & does *not* overwrite by default +/// does not change the current path & assumes the new path is in the data +/// folder. +/// +/// \param path destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \returns true if the copy was successful +bool copyTo(const of::filesystem::path & path, bool bRelativeToData = true, bool overwrite = false) const; + +/// Move the current file or directory path to a new path. +/// +/// Moves relative to the data path & does *not* overwrite by default +/// does not change the current path & assumes the new path is in the data +/// folder. +/// +/// \param path destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \returns true if the copy was successful +bool moveTo(const of::filesystem::path & path, bool bRelativeToData = true, bool overwrite = false); + +/// Rename the current file or directory path to a new path. +/// +/// Renames relative to the data path & does *not* overwrite by default +/// does not change the current path & assumes the new path is in the data +/// folder. +/// +/// \param path destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \returns true if the copy was successful +bool renameTo(const of::filesystem::path & path, bool bRelativeToData = true, bool overwrite = false); + +/// Removes the file or directory at the current path. +/// +/// Does not remove non-empty directories by default. +/// +/// \warning Be careful! This deletes a file or folder. :) +/// \param recursive set to true to remove a non-empty directory and its +/// contents +/// \returns true if the path was removed successfully +bool remove(bool recursive = false); + +/// get the size of the file at the current file path +/// +/// \returns size in bytes +std::uintmax_t getSize() const; + +// this allows to compare files by their paths, also provides sorting +// and use as key in stl containers +bool operator==(const ofFile & file) const; +bool operator!=(const ofFile & file) const; +bool operator<(const ofFile & file) const; +bool operator<=(const ofFile & file) const; +bool operator>(const ofFile & file) const; +bool operator>=(const ofFile & file) const; + +//------------------ +// stream operations +//------------------ + +// since this class inherits from fstream it can be used as a r/w stream: +// http://www.cplusplus.com/reference/iostream/fstream/ + +/// Read the contents of a file at the current path into a buffer. +/// +/// \returns buffer with file contents +ofBuffer readToBuffer(); + +/// Write the contents of a buffer into a file at the current path. +/// +/// \param buffer source byte buffer +/// \returns true if buffer's contents written successfully +bool writeFromBuffer(const ofBuffer & buffer); + +/// Read the entire contents of the currently opened file into an +/// output stream. +/// +/// This is basically an easy to use equivalent to rdbuf(): +/// ie. ofLogNotice() << file.getFileBuffer(); +/// write_file << file.getFileBuffer(); +/// +/// \return output stream +std::filebuf * getFileBuffer() const; + +operator of::filesystem::path() { + return myFile; +} // - operator of::filesystem::path() const{ - return myFile; - } - - //------- - //static helpers - //------- - - /// Copy source path to destination path. - /// - /// Copies relative to the data path & does *not* overwrite by default - /// assumes the source & destination path is in the data directory. - /// - /// \param pathSrc source file or directory path - /// \param pathDst destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data directory - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \returns true if the copy was successful - static bool copyFromTo(const of::filesystem::path& pathSrc, const of::filesystem::path& pathDst, bool bRelativeToData = true, bool overwrite = false); - - /// Move source path to destination path. - /// - /// Moves relative to the data path & does *not* overwrite by default - /// assumes the source & destination path is in the data directory. - /// - /// \param pathSrc source file or directory path - /// \param pathDst destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \warning be careful with slashes here, appending a slash when moving a - /// folder may cause mad headaches in OSX - /// \returns true if the move was successful - static bool moveFromTo(const of::filesystem::path& pathSrc, const of::filesystem::path& pathDst, bool bRelativeToData = true, bool overwrite = false); - - /// Check if a file or directory exists at a given path. - /// - /// \param fPath file path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder and want the direct path without relative - /// "../../" - /// \returns true if a file or directory exists - static bool doesFileExist(const of::filesystem::path& fPath, bool bRelativeToData = true); - - /// Remove a file or directory at a given path. - /// - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder and want the direct path without relative - /// "../../" - /// \returns true if the path was removed successfully - static bool removeFile(const of::filesystem::path& path, bool bRelativeToData = true); +operator of::filesystem::path() const { + return myFile; +} + +//------- +//static helpers +//------- + +/// Copy source path to destination path. +/// +/// Copies relative to the data path & does *not* overwrite by default +/// assumes the source & destination path is in the data directory. +/// +/// \param pathSrc source file or directory path +/// \param pathDst destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data directory +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \returns true if the copy was successful +static bool copyFromTo(const of::filesystem::path & pathSrc, const of::filesystem::path & pathDst, bool bRelativeToData = true, bool overwrite = false); + +/// Move source path to destination path. +/// +/// Moves relative to the data path & does *not* overwrite by default +/// assumes the source & destination path is in the data directory. +/// +/// \param pathSrc source file or directory path +/// \param pathDst destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \warning be careful with slashes here, appending a slash when moving a +/// folder may cause mad headaches in OSX +/// \returns true if the move was successful +static bool moveFromTo(const of::filesystem::path & pathSrc, const of::filesystem::path & pathDst, bool bRelativeToData = true, bool overwrite = false); + +/// Check if a file or directory exists at a given path. +/// +/// \param fPath file path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder and want the direct path without relative +/// "../../" +/// \returns true if a file or directory exists +static bool doesFileExist(const of::filesystem::path & fPath, bool bRelativeToData = true); + +/// Remove a file or directory at a given path. +/// +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder and want the direct path without relative +/// "../../" +/// \returns true if the path was removed successfully +static bool removeFile(const of::filesystem::path & path, bool bRelativeToData = true); private: - bool isWriteMode(); - bool openStream(Mode _mode, bool binary); - void copyFrom(const ofFile & mom); - - of::filesystem::path myFile; - Mode mode; - bool binary; +bool isWriteMode(); +bool openStream(Mode _mode, bool binary); +void copyFrom(const ofFile & mom); + +of::filesystem::path myFile; +Mode mode; +bool binary; }; /// \class ofDirectory @@ -839,376 +836,373 @@ class ofFile: public std::fstream{ /// Path to a directory. Can be used to query file and directory /// contents. /// -class ofDirectory{ +class ofDirectory { public: +/// Create an ofDirectory instance +/// +/// Does not refer to a specific directory until you either open or create +/// a directory path. +ofDirectory(); + +/// Create an ofDirectory instance and attempt to open the path. +/// +/// \param path directory path +ofDirectory(const of::filesystem::path & path); + +/// Open a directory path, clears the current file list. +/// +/// \param path directory path +void open(const of::filesystem::path & path); + +/// Open a directory path relative to the current working directory without calling ofToDataPath internally, clears the current file list. +/// +/// \param path directory path +void openFromCWD(const of::filesystem::path & path); + +/// Close the currently open path. +void close(); + +/// Create a directory at the current path. +/// +/// \param bRecursive set to true to automatically create nested directories +/// as required +bool create(bool recursive = false); + +/// Check if a directory exists at the current path. +/// +/// \returns true if exists +bool exists() const; - /// Create an ofDirectory instance - /// - /// Does not refer to a specific directory until you either open or create - /// a directory path. - ofDirectory(); - - /// Create an ofDirectory instance and attempt to open the path. - /// - /// \param path directory path - ofDirectory(const of::filesystem::path & path); - - /// Open a directory path, clears the current file list. - /// - /// \param path directory path - void open(const of::filesystem::path & path); - - /// Open a directory path relative to the current working directory without calling ofToDataPath internally, clears the current file list. - /// - /// \param path directory path - void openFromCWD(const of::filesystem::path & path); - - /// Close the currently open path. - void close(); - - /// Create a directory at the current path. - /// - /// \param bRecursive set to true to automatically create nested directories - /// as required - bool create(bool recursive = false); - - /// Check if a directory exists at the current path. - /// - /// \returns true if exists - bool exists() const; - - /// Get the current path. - /// - /// \returns current path +/// Get the current path. +/// +/// \returns current path // MARK: - near future // of::filesystem::path path() const; - std::string path() const; +std::string path() const; - /// Get the absolute, full path of the directory, - /// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images". - /// - /// \return current path as an absolute path +/// Get the absolute, full path of the directory, +/// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images". +/// +/// \return current path as an absolute path // MARK: - near future // of::filesystem::path getAbsolutePath() const; - std::string getAbsolutePath() const; - - /// Check if the current path is readable. - /// - /// \returns true if readable - bool canRead() const; - - /// Check if the current path is writeable. - /// - /// \returns true if writable - bool canWrite() const; - - /// Check if the current path is executable. - /// - /// \returns true if executable - bool canExecute() const; - - /// Check if the current path is indeed a directory and not a file. - /// - /// \returns true if a directory - bool isDirectory() const; - - /// Check if the current path is hidden. - /// - /// Works on Mac & Linux which denote hidden directories by prepending - /// a period -> ".hello", however always returns false on Windows. - /// - /// \returns true if hidden - bool isHidden() const; - - /// Set the writable flag of the current path. - /// - /// \param writable set to true to make path writable - void setWriteable(bool writeable=true); - - OF_DEPRECATED_MSG("Use ofDirectory::setWriteable(!flag).", void setReadOnly(bool flag)); - - /// Set the readable flag of the current path. - /// - /// \param readable set to true to make path readable - void setReadable(bool readable=true); - - /// Set the executable flag of the current path. - /// - /// \param executable set to true to make path executable - void setExecutable(bool executable=true); - - /// Show hidden files & directories when listing files? - /// - /// Mac & Linux denote hidden directories by prepending a period - /// -> ".hello". - /// - /// \param showHidden set to true to show hidden files - void setShowHidden(bool showHidden); - - /// Copy the current file or directory path to a new path. - /// - /// Copies relative to the data path & does *not* overwrite by default - /// does not change the current path & assumes the new path is in the data - /// directory. - /// - /// \param path destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data directory - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \returns true if the copy was successful - bool copyTo(const of::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false); - - /// Move the current file or directory path to a new path. - /// - /// Moves relative to the data path & does *not* overwrite by default - /// does not change the current path & assumes the new path is in the data - /// directory. - /// - /// \param path destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data directory - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \returns true if the copy was successful - bool moveTo(const of::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false); - - /// Rename the current file or directory path to a new path. - /// - /// Renames relative to the data path & does *not* overwrite by default - /// does not change the current path & assumes the new path is in the data - /// directory. - /// - /// \param path destination file or directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data folder - /// \param overwrite set to true if you want to overwrite the file or - /// directory at the new path - /// \returns true if the copy was successful - bool renameTo(const of::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false); - - /// Removes the file or directory at the current path. - /// - /// Does not remove non-empty directories by default. - /// - /// \warning Be careful! This deletes a file or folder. :) - /// \param recursive set to true to remove a non-empty directory and its - /// contents - /// \returns true if the path was removed successfully - bool remove(bool recursive); - - //------------------- - // dirList operations - //------------------- - - /// Allow a file extension when listing the contents the current - /// directory path. - /// - /// Setting an allowed extension enables a whitelist mode which only lists - /// extensions which have been explicitly allowed. - /// - /// \param extension file type extension ie. "jpg", "png", "txt", etc - void allowExt(const std::string& extension); - - /// Open and read the contents of a directory. - /// - /// Uses allowed extension whitelist to ignore unwanted file types if - /// allowExt() has been called. - /// - /// \param path directory path - /// \returns number of paths found - std::size_t listDir(const of::filesystem::path & path); - - /// Open and read the contents of the current directory. - /// - /// Uses allowed extension whitelist to ignore unwanted file types if - /// allowExt() has been called. - /// - /// \returns number of paths found - std::size_t listDir(); - - /// \returns the current path - std::string getOriginalDirectory() const; - - /// Get the filename at a given position in the directory contents - /// list, ie. "duck.jpg". - /// - /// \warning Call listDir() before using this function or the directory - /// contents list will be empty. - /// \throws Throws an out of bounds exception if position >= the number of - /// listed directory contents. - /// \param position array index in the directory contents list - /// \returns file or directory name - std::string getName(std::size_t position) const; - - /// Get the full path of the file or directory at a given position in - /// the directory contents list. - /// - /// \warning Call listDir() before using this function or the directory - /// contents list will be empty. - /// \throws Throws an out of bounds exception if position >= the number of - /// listed directory contents. - /// \param position array index in the directory contents list - /// \returns file or directory name including the current path - std::string getPath(std::size_t position) const; - - /// Open an ofFile instance using the path a given position in the - /// directory contents list. - /// - /// Opens as a binary file with readonly access by default. - /// - /// \warning Call listDir() before using this function or the directory - /// contents list will be empty. - /// \throw Throws an out of bounds exception if position >= the number of - /// listed directory contents. - /// \param position array index in the directory contents list - /// \param mode file access mode depending on how you plan to use the file - /// (read only, read write, etc) - /// \param binary set to false if you are working with a text file & want - /// lines split at endline characters automatically - /// \returns ofFile instance - ofFile getFile(std::size_t position, ofFile::Mode mode=ofFile::Reference, bool binary=true) const; - - /// Get files and directories in the directory contents list. - /// - /// Directory contents are automatically listed. - /// - /// \returns vector of files in the directory - const std::vector & getFiles() const; - - /// Access directory contents via th array operator. - /// - /// \warning Call listDir() before using this function or the directory - /// contents list will be empty. - /// \throw Throws an out of bounds exception if position >= the number of - /// listed directory contents. - /// \param position array index in the directory contents list - /// \returns opened ofFile instance - ofFile operator[](std::size_t position) const; - - /// Check whether hidden files & directories are included when - /// listing files. - /// - /// Mac & Linux denote hidden directories by prepending a period - /// -> ".hello". - /// - /// \returns true if hidden files are shown - bool getShowHidden() const; - - /// Closes the directory. - /// - /// This is for backwards compatibility with ofxDirList. - void reset(); - - typedef enum{ - SORT_FAST, - SORT_NATURAL, - SORT_BY_DATE - }SortMode; - - /// Sort the directory contents list alphabetically. - /// - /// \warning Call listDir() before using this function or there will be - /// nothing to sort. - /// \param SortMode options are SORT_FAST, SORT_NATURAL (default) or SORT_BY_DATE - void sort(const SortMode & mode = SORT_NATURAL); - - /// Sort the directory contents list by date. - /// - /// \warning Call listDir() before using this function or there will be - /// nothing to sort. - void sortByDate(); - - /// Get a sorted ofDirectory instance using the current path. - /// - /// \returns sorted ofDirectory instance - ofDirectory getSorted(); - - /// Get the number of paths in the current directory list. - /// - /// \warning Call listDir() before using this function or it will return 0 - /// since the directory list will be empty. - /// \returns number of paths - std::size_t size() const; - - OF_DEPRECATED_MSG("Use size() instead.", int numFiles()); - - // this allows to compare directories by their paths, also provides sorting - // and use as key in stl containers - bool operator==(const ofDirectory & dir) const; - bool operator!=(const ofDirectory & dir) const; - bool operator<(const ofDirectory & dir) const; - bool operator<=(const ofDirectory & dir) const; - bool operator>(const ofDirectory & dir) const; - bool operator>=(const ofDirectory & dir) const; - - operator of::filesystem::path(){ - return myDir; - } - - operator of::filesystem::path() const{ - return myDir; - } - - //------- - // static helpers - //------- - - /// Create a directory at a given path. - /// - /// Creates relative to the data path by default. - /// - /// \param dirPath directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data directory - /// \param bRecursive set to true to automatically create nested directories - /// as required - /// \returns true if directory was created successfully - static bool createDirectory(const of::filesystem::path& dirPath, bool bRelativeToData = true, bool recursive = false); - - /// Check if a directory at a given path is empty. - /// - /// Assumes directory path is relative to the data path by default. - /// - /// \param dirPath directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data directory - /// \returns true if the directory is empty aka contains no files or - /// directories - static bool isDirectoryEmpty(const of::filesystem::path& dirPath, bool bRelativeToData = true ); - - /// Check if a directory exists at a given path. - /// - /// Assumes directory path is relative to the data path by default. - /// - /// \param dirPath directory path - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data directory - /// \returns true if the directory exists - static bool doesDirectoryExist(const of::filesystem::path& dirPath, bool bRelativeToData = true); - - - /// remove a directory at a given path - /// - /// \param deleteIfNotEmpty set to true if you want to recursively delete - /// the directory *and* its contents - /// \param bRelativeToData set to false if you are working with paths that - /// are *not* in the data directory - /// \returns true if the path was removed successfully - static bool removeDirectory(const of::filesystem::path& path, bool deleteIfNotEmpty, bool bRelativeToData = true); - - std::vector::const_iterator begin() const; - std::vector::const_iterator end() const; - std::vector::const_reverse_iterator rbegin() const; - std::vector::const_reverse_iterator rend() const; - - of::filesystem::path myDir; - std::string originalDirectory; - std::vector extensions; - std::vector files; - bool showHidden; +std::string getAbsolutePath() const; + +/// Check if the current path is readable. +/// +/// \returns true if readable +bool canRead() const; + +/// Check if the current path is writeable. +/// +/// \returns true if writable +bool canWrite() const; + +/// Check if the current path is executable. +/// +/// \returns true if executable +bool canExecute() const; + +/// Check if the current path is indeed a directory and not a file. +/// +/// \returns true if a directory +bool isDirectory() const; + +/// Check if the current path is hidden. +/// +/// Works on Mac & Linux which denote hidden directories by prepending +/// a period -> ".hello", however always returns false on Windows. +/// +/// \returns true if hidden +bool isHidden() const; + +/// Set the writable flag of the current path. +/// +/// \param writable set to true to make path writable +void setWriteable(bool writeable = true); + +OF_DEPRECATED_MSG("Use ofDirectory::setWriteable(!flag).", void setReadOnly(bool flag)); + +/// Set the readable flag of the current path. +/// +/// \param readable set to true to make path readable +void setReadable(bool readable = true); + +/// Set the executable flag of the current path. +/// +/// \param executable set to true to make path executable +void setExecutable(bool executable = true); +/// Show hidden files & directories when listing files? +/// +/// Mac & Linux denote hidden directories by prepending a period +/// -> ".hello". +/// +/// \param showHidden set to true to show hidden files +void setShowHidden(bool showHidden); + +/// Copy the current file or directory path to a new path. +/// +/// Copies relative to the data path & does *not* overwrite by default +/// does not change the current path & assumes the new path is in the data +/// directory. +/// +/// \param path destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data directory +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \returns true if the copy was successful +bool copyTo(const of::filesystem::path & path, bool bRelativeToData = true, bool overwrite = false); + +/// Move the current file or directory path to a new path. +/// +/// Moves relative to the data path & does *not* overwrite by default +/// does not change the current path & assumes the new path is in the data +/// directory. +/// +/// \param path destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data directory +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \returns true if the copy was successful +bool moveTo(const of::filesystem::path & path, bool bRelativeToData = true, bool overwrite = false); + +/// Rename the current file or directory path to a new path. +/// +/// Renames relative to the data path & does *not* overwrite by default +/// does not change the current path & assumes the new path is in the data +/// directory. +/// +/// \param path destination file or directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data folder +/// \param overwrite set to true if you want to overwrite the file or +/// directory at the new path +/// \returns true if the copy was successful +bool renameTo(const of::filesystem::path & path, bool bRelativeToData = true, bool overwrite = false); + +/// Removes the file or directory at the current path. +/// +/// Does not remove non-empty directories by default. +/// +/// \warning Be careful! This deletes a file or folder. :) +/// \param recursive set to true to remove a non-empty directory and its +/// contents +/// \returns true if the path was removed successfully +bool remove(bool recursive); + +//------------------- +// dirList operations +//------------------- + +/// Allow a file extension when listing the contents the current +/// directory path. +/// +/// Setting an allowed extension enables a whitelist mode which only lists +/// extensions which have been explicitly allowed. +/// +/// \param extension file type extension ie. "jpg", "png", "txt", etc +void allowExt(const std::string & extension); + +/// Open and read the contents of a directory. +/// +/// Uses allowed extension whitelist to ignore unwanted file types if +/// allowExt() has been called. +/// +/// \param path directory path +/// \returns number of paths found +std::size_t listDir(const of::filesystem::path & path); + +/// Open and read the contents of the current directory. +/// +/// Uses allowed extension whitelist to ignore unwanted file types if +/// allowExt() has been called. +/// +/// \returns number of paths found +std::size_t listDir(); + +/// \returns the current path +std::string getOriginalDirectory() const; + +/// Get the filename at a given position in the directory contents +/// list, ie. "duck.jpg". +/// +/// \warning Call listDir() before using this function or the directory +/// contents list will be empty. +/// \throws Throws an out of bounds exception if position >= the number of +/// listed directory contents. +/// \param position array index in the directory contents list +/// \returns file or directory name +std::string getName(std::size_t position) const; + +/// Get the full path of the file or directory at a given position in +/// the directory contents list. +/// +/// \warning Call listDir() before using this function or the directory +/// contents list will be empty. +/// \throws Throws an out of bounds exception if position >= the number of +/// listed directory contents. +/// \param position array index in the directory contents list +/// \returns file or directory name including the current path +std::string getPath(std::size_t position) const; + +/// Open an ofFile instance using the path a given position in the +/// directory contents list. +/// +/// Opens as a binary file with readonly access by default. +/// +/// \warning Call listDir() before using this function or the directory +/// contents list will be empty. +/// \throw Throws an out of bounds exception if position >= the number of +/// listed directory contents. +/// \param position array index in the directory contents list +/// \param mode file access mode depending on how you plan to use the file +/// (read only, read write, etc) +/// \param binary set to false if you are working with a text file & want +/// lines split at endline characters automatically +/// \returns ofFile instance +ofFile getFile(std::size_t position, ofFile::Mode mode = ofFile::Reference, bool binary = true) const; + +/// Get files and directories in the directory contents list. +/// +/// Directory contents are automatically listed. +/// +/// \returns vector of files in the directory +const std::vector & getFiles() const; + +/// Access directory contents via th array operator. +/// +/// \warning Call listDir() before using this function or the directory +/// contents list will be empty. +/// \throw Throws an out of bounds exception if position >= the number of +/// listed directory contents. +/// \param position array index in the directory contents list +/// \returns opened ofFile instance +ofFile operator[](std::size_t position) const; + +/// Check whether hidden files & directories are included when +/// listing files. +/// +/// Mac & Linux denote hidden directories by prepending a period +/// -> ".hello". +/// +/// \returns true if hidden files are shown +bool getShowHidden() const; + +/// Closes the directory. +/// +/// This is for backwards compatibility with ofxDirList. +void reset(); + +typedef enum { + SORT_FAST, + SORT_NATURAL, + SORT_BY_DATE +} SortMode; + +/// Sort the directory contents list alphabetically. +/// +/// \warning Call listDir() before using this function or there will be +/// nothing to sort. +/// \param SortMode options are SORT_FAST, SORT_NATURAL (default) or SORT_BY_DATE +void sort(const SortMode & mode = SORT_NATURAL); + +/// Sort the directory contents list by date. +/// +/// \warning Call listDir() before using this function or there will be +/// nothing to sort. +void sortByDate(); + +/// Get a sorted ofDirectory instance using the current path. +/// +/// \returns sorted ofDirectory instance +ofDirectory getSorted(); + +/// Get the number of paths in the current directory list. +/// +/// \warning Call listDir() before using this function or it will return 0 +/// since the directory list will be empty. +/// \returns number of paths +std::size_t size() const; + +OF_DEPRECATED_MSG("Use size() instead.", int numFiles()); + +// this allows to compare directories by their paths, also provides sorting +// and use as key in stl containers +bool operator==(const ofDirectory & dir) const; +bool operator!=(const ofDirectory & dir) const; +bool operator<(const ofDirectory & dir) const; +bool operator<=(const ofDirectory & dir) const; +bool operator>(const ofDirectory & dir) const; +bool operator>=(const ofDirectory & dir) const; + +operator of::filesystem::path() { + return myDir; +} + +operator of::filesystem::path() const { + return myDir; +} + +//------- +// static helpers +//------- + +/// Create a directory at a given path. +/// +/// Creates relative to the data path by default. +/// +/// \param dirPath directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data directory +/// \param bRecursive set to true to automatically create nested directories +/// as required +/// \returns true if directory was created successfully +static bool createDirectory(const of::filesystem::path & dirPath, bool bRelativeToData = true, bool recursive = false); + +/// Check if a directory at a given path is empty. +/// +/// Assumes directory path is relative to the data path by default. +/// +/// \param dirPath directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data directory +/// \returns true if the directory is empty aka contains no files or +/// directories +static bool isDirectoryEmpty(const of::filesystem::path & dirPath, bool bRelativeToData = true); + +/// Check if a directory exists at a given path. +/// +/// Assumes directory path is relative to the data path by default. +/// +/// \param dirPath directory path +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data directory +/// \returns true if the directory exists +static bool doesDirectoryExist(const of::filesystem::path & dirPath, bool bRelativeToData = true); + +/// remove a directory at a given path +/// +/// \param deleteIfNotEmpty set to true if you want to recursively delete +/// the directory *and* its contents +/// \param bRelativeToData set to false if you are working with paths that +/// are *not* in the data directory +/// \returns true if the path was removed successfully +static bool removeDirectory(const of::filesystem::path & path, bool deleteIfNotEmpty, bool bRelativeToData = true); + +std::vector::const_iterator begin() const; +std::vector::const_iterator end() const; +std::vector::const_reverse_iterator rbegin() const; +std::vector::const_reverse_iterator rend() const; + +of::filesystem::path myDir; +std::string originalDirectory; +std::vector extensions; +std::vector files; +bool showHidden; }; /// \section Data Path @@ -1237,7 +1231,7 @@ void ofDisableDataPath(); /// \returns the new path, unless paths were disabled with ofDisableDataPath(). // MARK: - near future //of::filesystem::path ofToDataPath(const of::filesystem::path & path, bool absolute=false); -std::string ofToDataPath(const of::filesystem::path & path, bool absolute=false); +std::string ofToDataPath(const of::filesystem::path & path, bool absolute = false); /// \brief Reset the working directory to the platform default. /// @@ -1256,12 +1250,12 @@ bool ofRestoreWorkingDirectoryToDefault(); /// /// \warning The provided path must have a trailing slash (/). /// \param root The path to the data/ folder relative to the app executable. -void ofSetDataPathRoot(const of::filesystem::path& root); +void ofSetDataPathRoot(const of::filesystem::path & root); /*! \cond PRIVATE */ -namespace of{ -namespace priv{ - void initfileutils(); +namespace of { +namespace priv { +void initfileutils(); } } /*! \endcond */