X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ffile_source.cc;h=0aec49e6bdd74899dbfafa28d903d0aa6047fc75;hb=6c50971eba37d879f1b8690ee231bb412ee1cda6;hp=f4f3c40d9d6d6f76e64c93ef22b6ec942db2206f;hpb=7eb8a33910bfdab21b98d794dc731bc8e8557cb9;p=ardour.git diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index f4f3c40d9d..0aec49e6bd 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -28,16 +28,15 @@ #include "pbd/convert.h" #include "pbd/basename.h" -#include "pbd/mountpoint.h" #include "pbd/stl_delete.h" #include "pbd/strsplit.h" #include "pbd/shortpath.h" #include "pbd/enumwriter.h" -#include "pbd/filesystem.h" +#include "pbd/file_utils.h" #include #include -#include +#include #include "ardour/data_type.h" #include "ardour/file_source.h" @@ -52,24 +51,22 @@ using namespace ARDOUR; using namespace PBD; using namespace Glib; -PBD::Signal3 > FileSource::AmbiguousFileName; +PBD::Signal2 > FileSource::AmbiguousFileName; FileSource::FileSource (Session& session, DataType type, const string& path, const string& origin, Source::Flag flag) : Source(session, type, path, flag) - , _path(path) - , _file_is_new(true) + , _path (path) + , _file_is_new (!origin.empty()) // if origin is left unspecified (empty string) then file must exist , _channel (0) , _origin (origin) - , _open (false) { set_within_session_from_path (path); - - prevent_deletion (); } FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist*/) : Source (session, node) , _file_is_new (false) + , _channel (0) { /* this setting of _path is temporary - we expect derived classes to call ::init() which will actually locate the file @@ -78,23 +75,28 @@ FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist _path = _name; _within_session = true; +} - prevent_deletion (); +FileSource::~FileSource() +{ } void -FileSource::prevent_deletion () +FileSource::existence_check () { - /* if this file already exists, it cannot be removed, ever - */ - if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) { - if (!(_flags & Destructive)) { - mark_immutable (); - } else { - _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy)); - } - } + prevent_deletion (); + } +} + +void +FileSource::prevent_deletion () +{ + if (!(_flags & Destructive)) { + mark_immutable (); + } else { + _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy)); + } } bool @@ -102,7 +104,7 @@ FileSource::removable () const { bool r = ((_flags & Removable) && ((_flags & RemoveAtDestroy) || - ((_flags & RemovableIfEmpty) && empty() == 0))); + ((_flags & RemovableIfEmpty) && empty()))); return r; } @@ -112,22 +114,24 @@ FileSource::init (const string& pathstr, bool must_exist) { _timeline_position = 0; - if (Stateful::loading_state_version < 3000) { - if (!find_2X (_session, _type, pathstr, must_exist, _file_is_new, _channel, _path)) { - throw MissingSource (pathstr, _type); - } - } else { - if (!find (_session, _type, pathstr, must_exist, _file_is_new, _channel, _path)) { - throw MissingSource (pathstr, _type); - } - } + if (Stateful::loading_state_version < 3000) { + if (!find_2X (_session, _type, pathstr, must_exist, _file_is_new, _channel, _path)) { + throw MissingSource (pathstr, _type); + } + } else { + if (!find (_session, _type, pathstr, must_exist, _file_is_new, _channel, _path)) { + throw MissingSource (pathstr, _type); + } + } set_within_session_from_path (_path); - + _name = Glib::path_get_basename (_path); - if (_file_is_new && must_exist) { - return -1; + if (must_exist) { + if (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) { + throw MissingSource (pathstr, _type); + } } return 0; @@ -210,7 +214,7 @@ FileSource::move_to_trash (const string& trash_dir_name) if (move_dependents_to_trash() != 0) { /* try to back out */ - rename (newpath.c_str(), _path.c_str()); + ::rename (newpath.c_str(), _path.c_str()); return -1; } @@ -239,21 +243,15 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist isnew = false; if (!Glib::path_is_absolute (path)) { - vector dirs; vector hits; string fullpath; + std::vector dirs = s.source_search_path (type); - string search_path = s.source_search_path (type); - - if (search_path.length() == 0) { + if (dirs.size() == 0) { error << _("FileSource: search path not set") << endmsg; goto out; } - split (search_path, dirs, ':'); - - hits.clear (); - for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { fullpath = Glib::build_filename (*i, path); @@ -278,7 +276,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist ++j; while (j != hits.end()) { - if (PBD::sys::inodes_same (*i, *j)) { + if (PBD::equivalent_paths (*i, *j)) { /* *i and *j are the same file; break out of the loop early */ break; } @@ -295,7 +293,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist /* more than one match: ask the user */ - int which = FileSource::AmbiguousFileName (path, search_path, de_duped_hits).get_value_or (-1); + int which = FileSource::AmbiguousFileName (path, de_duped_hits).get_value_or (-1); if (which < 0) { goto out; @@ -308,9 +306,9 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist /* no match: error */ if (must_exist) { - error << string_compose( - _("Filesource: cannot find required file (%1): while searching %2"), - path, search_path) << endmsg; + /* do not generate an error here, leave that to + whoever deals with the false return value. + */ goto out; } else { isnew = true; @@ -321,16 +319,17 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist keeppath = de_duped_hits[0]; } - - } else { + + } else { keeppath = path; } /* Current find() is unable to parse relative path names to yet non-existant sources. QuickFix(tm) */ - if (keeppath == "") { - if (must_exist) { + + if (keeppath.empty()) { + if (must_exist) { error << "FileSource::find(), keeppath = \"\", but the file must exist" << endl; } else { keeppath = path; @@ -356,8 +355,6 @@ bool FileSource::find_2X (Session& s, DataType type, const string& path, bool must_exist, bool& isnew, uint16_t& chan, string& found_path) { - string search_path = s.source_search_path (type); - string pathstr = path; string::size_type pos; bool ret = false; @@ -368,18 +365,17 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex /* non-absolute pathname: find pathstr in search path */ - vector dirs; + vector dirs = s.source_search_path (type); + int cnt; string fullpath; string keeppath; - if (search_path.length() == 0) { + if (dirs.size() == 0) { error << _("FileSource: search path not set") << endmsg; goto out; } - split (search_path, dirs, ':'); - cnt = 0; for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { @@ -436,16 +432,14 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex if (cnt > 1) { error << string_compose ( - _("FileSource: \"%1\" is ambigous when searching %2\n\t"), - pathstr, search_path) << endmsg; + _("FileSource: \"%1\" is ambigous when searching\n\t"), pathstr) << endmsg; goto out; } else if (cnt == 0) { if (must_exist) { error << string_compose( - _("Filesource: cannot find required file (%1): while searching %2"), - pathstr, search_path) << endmsg; + _("Filesource: cannot find required file (%1)"), pathstr) << endmsg; goto out; } else { isnew = true; @@ -495,13 +489,14 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex goto out; } +#ifndef PLATFORM_WINDOWS if (errno != ENOENT) { error << string_compose( _("Filesource: cannot check for existing file (%1): %2"), path, strerror (errno)) << endmsg; goto out; } - +#endif /* a new file */ isnew = true; ret = true; @@ -517,41 +512,21 @@ out: return ret; } -int -FileSource::set_source_name (const string& newname, bool destructive) +void +FileSource::mark_immutable () { - Glib::Mutex::Lock lm (_lock); - string oldpath = _path; - string newpath = _session.change_source_path_by_name (oldpath, _name, newname, destructive); - - if (newpath.empty()) { - error << string_compose (_("programming error: %1"), "cannot generate a changed file path") << endmsg; - return -1; - } - - // Test whether newpath exists, if yes notify the user but continue. - if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) { - error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg; - return -1; + /* destructive sources stay writable, and their other flags don't change. */ + if (!(_flags & Destructive)) { + _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); } - - if (::rename (oldpath.c_str(), newpath.c_str()) != 0) { - error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg; - return -1; - } - - _name = Glib::path_get_basename (newpath); - _path = newpath; - - return 0; } void -FileSource::mark_immutable () +FileSource::mark_immutable_except_write () { /* destructive sources stay writable, and their other flags don't change. */ if (!(_flags & Destructive)) { - _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); + _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); } } @@ -571,6 +546,12 @@ void FileSource::set_path (const std::string& newpath) { _path = newpath; + set_within_session_from_path (newpath); + if (_within_session) { + _origin = Glib::path_get_basename (newpath); + } else { + _origin = newpath; + } } void @@ -579,3 +560,48 @@ FileSource::inc_use_count () Source::inc_use_count (); } +bool +FileSource::is_stub () const +{ + if (!empty()) { + return false; + } + + if (!removable()) { + return false; + } + + if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) { + return false; + } + + return true; +} + +int +FileSource::rename (const string& newpath) +{ + Glib::Threads::Mutex::Lock lm (_lock); + string oldpath = _path; + + // Test whether newpath exists, if yes notify the user but continue. + if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) { + error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg; + return -1; + } + + if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) { + /* rename only needed if file exists on disk */ + if (::rename (oldpath.c_str(), newpath.c_str()) != 0) { + error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg; + return -1; + } + } + + _name = Glib::path_get_basename (newpath); + _path = newpath; + + return 0; +} + +