From 5764970709f15e85ec30c9cea89c318eb8114c58 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 14 Apr 2014 03:03:35 -0400 Subject: more work on linking file existence and removability --- libs/ardour/ardour/file_source.h | 1 + libs/ardour/coreaudiosource.cc | 15 ++++++++++++++- libs/ardour/file_source.cc | 27 ++++++++++++--------------- libs/ardour/session.cc | 9 +++++++++ libs/ardour/smf_source.cc | 10 ++++++++-- libs/ardour/sndfilesource.cc | 40 ++++++++++++++++++++++++++++------------ 6 files changed, 72 insertions(+), 30 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/file_source.h b/libs/ardour/ardour/file_source.h index 79153f6568..37a7e67d2e 100644 --- a/libs/ardour/ardour/file_source.h +++ b/libs/ardour/ardour/file_source.h @@ -82,6 +82,7 @@ public: static PBD::Signal2 > AmbiguousFileName; + void existence_check (); virtual void prevent_deletion (); protected: diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index 947c66e756..010905d120 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -28,6 +28,8 @@ #include #include +#include + #include "i18n.h" #include @@ -36,21 +38,32 @@ using namespace std; using namespace ARDOUR; using namespace PBD; +/** Create a new CoreAudioSource using session state, which implies that the + * file must already exist. + */ CoreAudioSource::CoreAudioSource (Session& s, const XMLNode& node) : Source (s, node) , AudioFileSource (s, node) { init_cafile (); + + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); } +/** Create a new CoreAudioSource from an existing file. Sources created with this + * method are never writable or removable. + */ CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag flags) - /* files created this way are never writable or removable */ : Source (s, DataType::AUDIO, path, Source::Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))), AudioFileSource (s, path, Source::Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) { _channel = chn; init_cafile (); + + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); } void diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index 709915378d..109539ce2d 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -62,8 +62,6 @@ FileSource::FileSource (Session& session, DataType type, const string& path, con , _open (false) { set_within_session_from_path (path); - - prevent_deletion (); } FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist*/) @@ -77,8 +75,6 @@ FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist _path = _name; _within_session = true; - - prevent_deletion (); } FileSource::~FileSource() @@ -86,20 +82,21 @@ 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)) { - cerr << " ... " << _path << " already exists, marking immutable\n"; + prevent_deletion (); + } +} - if (!(_flags & Destructive)) { - mark_immutable (); - } else { - _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy)); - } - } +void +FileSource::prevent_deletion () +{ + if (!(_flags & Destructive)) { + mark_immutable (); + } else { + _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy)); + } } bool diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 6f93dafd6b..2aef745961 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3470,6 +3470,15 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha break; } + /* it is possible that we have the path already + * assigned to a source that has not yet been written + * (ie. the write source for a diskstream). we have to + * check this in order to make sure that our candidate + * path isn't used again, because that can lead to + * two Sources point to the same file with different + * notions of their removability. + */ + string possible_path = Glib::build_filename (spath, buf); if (source_by_path (possible_path)) { diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index e15bc9a238..812e06c27b 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -63,9 +63,12 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags) { /* note that origin remains empty */ - if (init(_path, false)) { + if (init (_path, false)) { throw failed_constructor (); } + + assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); /* file is not opened until write */ @@ -94,10 +97,13 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist) throw failed_constructor (); } - if (init(_path, true)) { + if (init (_path, true)) { throw failed_constructor (); } + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + if (open(_path)) { throw failed_constructor (); } diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 6bb0e46551..e0851602fc 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -31,6 +31,7 @@ #ifdef PLATFORM_WINDOWS #include #endif +#include #include #include "ardour/sndfilesource.h" @@ -57,9 +58,18 @@ const Source::Flag SndFileSource::default_writable_flags = Source::Flag ( SndFileSource::SndFileSource (Session& s, const XMLNode& node) : Source(s, node) , AudioFileSource (s, node) + , _descriptor (0) + , _broadcast_info (0) + , _capture_start (false) + , _capture_end (false) + , file_pos (0) + , xfade_buf (0) { init_sndfile (); + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + if (open()) { throw failed_constructor (); } @@ -72,11 +82,20 @@ SndFileSource::SndFileSource (Session& s, const string& path, int chn, Flag flag : Source(s, DataType::AUDIO, path, flags) /* note that the origin of an external file is itself */ , AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) + , _descriptor (0) + , _broadcast_info (0) + , _capture_start (false) + , _capture_end (false) + , file_pos (0) + , xfade_buf (0) { _channel = chn; init_sndfile (); + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + if (open()) { throw failed_constructor (); } @@ -89,11 +108,20 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig SampleFormat sfmt, HeaderFormat hf, framecnt_t rate, Flag flags) : Source(s, DataType::AUDIO, path, flags) , AudioFileSource (s, path, origin, flags, sfmt, hf) + , _descriptor (0) + , _broadcast_info (0) + , _capture_start (false) + , _capture_end (false) + , file_pos (0) + , xfade_buf (0) { int fmt = 0; init_sndfile (); + assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + _file_is_new = true; switch (hf) { @@ -160,24 +188,12 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig void SndFileSource::init_sndfile () { - string file; - - _descriptor = 0; - - // lets try to keep the object initalizations here at the top - xfade_buf = 0; - _broadcast_info = 0; - /* although libsndfile says we don't need to set this, valgrind and source code shows us that we do. */ memset (&_info, 0, sizeof(_info)); - _capture_start = false; - _capture_end = false; - file_pos = 0; - if (destructive()) { xfade_buf = new Sample[xfade_frames]; _timeline_position = header_position_offset; -- cgit v1.2.3