1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-25 00:48:10 +02:00

Rewrite DirManager::EnsureSafeFileName without downcasts...

... weakening but not yet eliminating dependency on BlockFile subclasses
This commit is contained in:
Paul Licameli 2019-05-14 12:58:20 -04:00
parent d46bb29e3a
commit 81d4c217e6
5 changed files with 50 additions and 27 deletions

View File

@ -133,6 +133,16 @@ void BlockFile::SetFileName(wxFileNameWrapper &&name)
mFileName=std::move(name);
}
const wxFileNameWrapper &BlockFile::GetExternalFileName() const
{
static wxFileNameWrapper empty;
return empty;
}
void BlockFile::SetExternalFileName( wxFileNameWrapper && )
{
wxASSERT( false );
}
/// Marks this BlockFile as "locked." A locked BlockFile may not
/// be moved or deleted, only copied. Locking a BlockFile prevents
@ -724,6 +734,16 @@ AliasBlockFile::~AliasBlockFile()
{
}
const wxFileNameWrapper &AliasBlockFile::GetExternalFileName() const
{
return GetAliasedFileName();
}
void AliasBlockFile::SetExternalFileName( wxFileNameWrapper &&newName )
{
ChangeAliasedFileName( std::move( newName ) );
}
/// Read the summary of this alias block from disk. Since the audio data
/// is elsewhere, this consists of reading the entire summary file.
/// Fill with zeroes and return false if data are unavailable for any reason.

View File

@ -114,6 +114,12 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
virtual GetFileNameResult GetFileName() const;
virtual void SetFileName(wxFileNameWrapper &&name);
// Managing an external file dependency
// Default always returns empty
virtual const wxFileNameWrapper &GetExternalFileName() const;
// Default does nothing (and gives assertion violation in debug)
virtual void SetExternalFileName( wxFileNameWrapper &&newName );
size_t GetLength() const { return mLen; }
void SetLength(size_t newLen) { mLen = newLen; }
@ -278,10 +284,13 @@ class AliasBlockFile /* not final */ : public BlockFile
//
// These methods are for advanced use only!
//
const wxFileName &GetAliasedFileName() const { return mAliasedFileName; }
const wxFileNameWrapper &GetAliasedFileName() const { return mAliasedFileName; }
void ChangeAliasedFileName(wxFileNameWrapper &&newAliasedFile);
bool IsAlias() const override { return true; }
const wxFileNameWrapper &GetExternalFileName() const override;
void SetExternalFileName( wxFileNameWrapper &&newName ) override;
protected:
// Introduce a NEW virtual.
/// Write the summary to disk, using the derived ReadData() to get the data

View File

@ -1581,25 +1581,11 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
{
BlockFilePtr b = iter->second.lock();
if (b) {
// don't worry, we don't rely on this cast unless IsAlias is true
auto ab = static_cast< AliasBlockFile * > ( &*b );
// don't worry, we don't rely on this cast unless ISDataAvailable is false
// which means that it still needs to access the file.
auto db = static_cast< ODDecodeBlockFile * > ( &*b );
if (b->IsAlias() && ab->GetAliasedFileName() == fName) {
if (fName.IsOk() && b->GetExternalFileName() == fName) {
needToRename = true;
//ODBlocks access the aliased file on another thread, so we need to pause them before this continues.
readLocks.push_back( ab->LockForRead() );
}
//now for encoded OD blocks (e.g. flac)
else if (!b->IsDataAvailable() && db->GetEncodedAudioFilename() == fName) {
needToRename = true;
//ODBlocks access the aliased file on another thread, so we need to pause them before this continues.
readLocks.push_back( db->LockForRead() );
readLocks.push_back( b->LockForRead() );
}
}
++iter;
@ -1631,19 +1617,12 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
{
BlockFilePtr b = iter2->second.lock();
if (b) {
auto ab = static_cast< AliasBlockFile * > ( &*b );
auto db = static_cast< ODDecodeBlockFile * > ( &*b );
if (b->IsAlias() && ab->GetAliasedFileName() == fName)
{
ab->ChangeAliasedFileName(wxFileNameWrapper{ renamedFileName });
if (fName.IsOk() && b->GetExternalFileName() == fName) {
b->SetExternalFileName(wxFileNameWrapper{ renamedFileName });
wxPrintf(_("Changed block %s to new alias name\n"),
b->GetFileName().name.GetFullName());
}
else if (!b->IsDataAvailable() && db->GetEncodedAudioFilename() == fName) {
db->ChangeAudioFile(wxFileNameWrapper{ renamedFileName });
}
}
++iter2;
}

View File

@ -502,6 +502,18 @@ void ODDecodeBlockFile::UnlockRead() const
mReadDataMutex.Unlock();
}
const wxFileNameWrapper &ODDecodeBlockFile::GetExternalFileName() const
{
if ( !IsDataAvailable() )
return GetEncodedAudioFilename();
return SimpleBlockFile::GetExternalFileName();
}
void ODDecodeBlockFile::SetExternalFileName( wxFileNameWrapper &&newName )
{
ChangeAudioFile( std::move( newName ) );
}
/// Modify this block to point at a different file. This is generally
/// looked down on, but it is necessary in one case: see
/// DirManager::EnsureSafeFilename().

View File

@ -56,6 +56,9 @@ class ODDecodeBlockFile final : public SimpleBlockFile
/// Returns TRUE if the summary has not yet been written, but is actively being computed and written to disk
bool IsSummaryBeingComputed() override { return false; }
const wxFileNameWrapper &GetExternalFileName() const override;
void SetExternalFileName( wxFileNameWrapper &&newName ) override;
//Calls that rely on summary files need to be overidden
DiskByteCount GetSpaceUsage() const override;
/// Gets extreme values for the specified region
@ -138,7 +141,7 @@ class ODDecodeBlockFile final : public SimpleBlockFile
///// Get the name of the file where the audio data for this block is
/// stored.
const wxFileName &GetEncodedAudioFilename()
const wxFileNameWrapper &GetEncodedAudioFilename() const
{
return mAudioFileName;
}