1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-19 14:17:41 +02:00

Complete the exception handling project, enable the throws

This commit is contained in:
Paul Licameli 2017-04-03 23:33:19 -04:00
commit d417acd5c6
12 changed files with 99 additions and 119 deletions

View File

@ -616,8 +616,7 @@ size_t BlockFile::CommonReadData(
if ( framesRead < len ) { if ( framesRead < len ) {
if (mayThrow) if (mayThrow)
//throw FileException{ FileException::Cause::Read, fileName } throw FileException{ FileException::Cause::Read, fileName };
;
ClearSamples(data, format, framesRead, len - framesRead); ClearSamples(data, format, framesRead, len - framesRead);
} }

View File

@ -90,6 +90,7 @@
#include "AudacityApp.h" #include "AudacityApp.h"
#include "AudacityException.h" #include "AudacityException.h"
#include "BlockFile.h" #include "BlockFile.h"
#include "FileException.h"
#include "blockfile/LegacyBlockFile.h" #include "blockfile/LegacyBlockFile.h"
#include "blockfile/LegacyAliasBlockFile.h" #include "blockfile/LegacyAliasBlockFile.h"
#include "blockfile/SimpleBlockFile.h" #include "blockfile/SimpleBlockFile.h"
@ -97,6 +98,7 @@
#include "blockfile/PCMAliasBlockFile.h" #include "blockfile/PCMAliasBlockFile.h"
#include "blockfile/ODPCMAliasBlockFile.h" #include "blockfile/ODPCMAliasBlockFile.h"
#include "blockfile/ODDecodeBlockFile.h" #include "blockfile/ODDecodeBlockFile.h"
#include "InconsistencyException.h"
#include "Internat.h" #include "Internat.h"
#include "Project.h" #include "Project.h"
#include "Prefs.h" #include "Prefs.h"
@ -1110,8 +1112,12 @@ bool DirManager::ContainsBlockFile(const wxString &filepath) const
// Adds one to the reference count of the block file, // Adds one to the reference count of the block file,
// UNLESS it is "locked", then it makes a NEW copy of // UNLESS it is "locked", then it makes a NEW copy of
// the BlockFile. // the BlockFile.
// This function returns non-NULL, or else throws
BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b) BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
{ {
if (!b)
THROW_INCONSISTENCY_EXCEPTION;
auto result = b->GetFileName(); auto result = b->GetFileName();
const auto &fn = result.name; const auto &fn = result.name;
@ -1122,7 +1128,7 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
// //
// LLL: Except for silent block files which have uninitialized filename. // LLL: Except for silent block files which have uninitialized filename.
if (fn.IsOk()) if (fn.IsOk())
mBlockFileHash[fn.GetName()]=b; mBlockFileHash[fn.GetName()] = b;
return b; return b;
} }
@ -1148,7 +1154,9 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
{ {
if( !wxCopyFile(fn.GetFullPath(), if( !wxCopyFile(fn.GetFullPath(),
newFile.GetFullPath()) ) newFile.GetFullPath()) )
return {}; // Disk space exhaustion, maybe
throw FileException{
FileException::Cause::Write, newFile };
} }
// Done with fn // Done with fn
@ -1156,13 +1164,13 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
b2 = b->Copy(std::move(newFile)); b2 = b->Copy(std::move(newFile));
if (b2 == NULL) mBlockFileHash[newName] = b2;
return {};
mBlockFileHash[newName]=b2;
aliasList.Add(newPath); aliasList.Add(newPath);
} }
if (!b2)
THROW_INCONSISTENCY_EXCEPTION;
return b2; return b2;
} }

View File

@ -95,6 +95,8 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
// Adds one to the reference count of the block file, // Adds one to the reference count of the block file,
// UNLESS it is "locked", then it makes a NEW copy of // UNLESS it is "locked", then it makes a NEW copy of
// the BlockFile. // the BlockFile.
// May throw an exception in case of disk space exhaustion, otherwise
// returns non-null.
BlockFilePtr CopyBlockFile(const BlockFilePtr &b); BlockFilePtr CopyBlockFile(const BlockFilePtr &b);
BlockFile *LoadBlockFile(const wxChar **attrs, sampleFormat format); BlockFile *LoadBlockFile(const wxChar **attrs, sampleFormat format);

View File

@ -16,6 +16,7 @@
#include "Audacity.h" #include "Audacity.h"
#include "NoteTrack.h" #include "NoteTrack.h"
#include "Experimental.h"
#include <wx/dc.h> #include <wx/dc.h>
#include <wx/brush.h> #include <wx/brush.h>
@ -33,7 +34,7 @@
#include "Prefs.h" #include "Prefs.h"
#include "effects/TimeWarper.h" #include "effects/TimeWarper.h"
#include "Experimental.h" #include "InconsistencyException.h"
#ifdef SONIFY #ifdef SONIFY
#include "portmidi.h" #include "portmidi.h"
@ -435,8 +436,8 @@ int NoteTrack::GetVisibleChannels()
Track::Holder NoteTrack::Cut(double t0, double t1) Track::Holder NoteTrack::Cut(double t0, double t1)
{ {
if (t1 <= t0) if (t1 <= t0)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
double len = t1-t0; double len = t1-t0;
auto newTrack = std::make_unique<NoteTrack>(mDirManager); auto newTrack = std::make_unique<NoteTrack>(mDirManager);
@ -458,8 +459,8 @@ Track::Holder NoteTrack::Cut(double t0, double t1)
Track::Holder NoteTrack::Copy(double t0, double t1, bool) const Track::Holder NoteTrack::Copy(double t0, double t1, bool) const
{ {
if (t1 <= t0) if (t1 <= t0)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
double len = t1-t0; double len = t1-t0;
auto newTrack = std::make_unique<NoteTrack>(mDirManager); auto newTrack = std::make_unique<NoteTrack>(mDirManager);
@ -494,10 +495,9 @@ bool NoteTrack::Trim(double t0, double t1)
void NoteTrack::Clear(double t0, double t1) void NoteTrack::Clear(double t0, double t1)
{ {
// If t1 = t0, should Clear return true?
if (t1 <= t0) if (t1 <= t0)
// THROW_INCONSISTENCY_EXCEPTION; ? THROW_INCONSISTENCY_EXCEPTION;
return;
double len = t1-t0; double len = t1-t0;
if (mSeq) if (mSeq)

View File

@ -441,8 +441,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
// PRL: Why bother with Internat when the above is just wxT? // PRL: Why bother with Internat when the above is just wxT?
Internat::ToString(s.as_double(), 0).c_str(), Internat::ToString(s.as_double(), 0).c_str(),
Internat::ToString(mNumSamples.as_double(), 0).c_str()); Internat::ToString(mNumSamples.as_double(), 0).c_str());
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
} }
// Quick check to make sure that it doesn't overflow // Quick check to make sure that it doesn't overflow
@ -453,8 +452,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
// PRL: Why bother with Internat when the above is just wxT? // PRL: Why bother with Internat when the above is just wxT?
Internat::ToString(mNumSamples.as_double(), 0).c_str(), Internat::ToString(mNumSamples.as_double(), 0).c_str(),
Internat::ToString(src->mNumSamples.as_double(), 0).c_str()); Internat::ToString(src->mNumSamples.as_double(), 0).c_str());
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
} }
if (src->mSampleFormat != mSampleFormat) if (src->mSampleFormat != mSampleFormat)
@ -462,8 +460,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
wxLogError( wxLogError(
wxT("Sequence::Paste: Sample format to be pasted, %s, does not match destination format, %s."), wxT("Sequence::Paste: Sample format to be pasted, %s, does not match destination format, %s."),
GetSampleFormatStr(src->mSampleFormat), GetSampleFormatStr(src->mSampleFormat)); GetSampleFormatStr(src->mSampleFormat), GetSampleFormatStr(src->mSampleFormat));
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
} }
const BlockArray &srcBlock = src->mBlock; const BlockArray &srcBlock = src->mBlock;
@ -607,11 +604,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
for (i = 2; i < srcNumBlocks - 2; i++) { for (i = 2; i < srcNumBlocks - 2; i++) {
const SeqBlock &block = srcBlock[i]; const SeqBlock &block = srcBlock[i];
auto file = mDirManager->CopyBlockFile(block.f); auto file = mDirManager->CopyBlockFile(block.f);
if (!file) { // We can assume file is not null
wxASSERT(false); // TODO: Handle this better, alert the user of failure.
return;
}
newBlock.push_back(SeqBlock(file, block.start + s)); newBlock.push_back(SeqBlock(file, block.start + s));
} }
@ -645,8 +638,7 @@ void Sequence::InsertSilence(sampleCount s0, sampleCount len)
{ {
// Quick check to make sure that it doesn't overflow // Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + (len.as_double()))) if (Overflows((mNumSamples.as_double()) + (len.as_double())))
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
if (len <= 0) if (len <= 0)
return; return;
@ -696,8 +688,7 @@ void Sequence::AppendAlias(const wxString &fullPath,
{ {
// Quick check to make sure that it doesn't overflow // Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)len))) if (Overflows((mNumSamples.as_double()) + ((double)len)))
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
SeqBlock newBlock( SeqBlock newBlock(
useOD? useOD?
@ -715,8 +706,7 @@ void Sequence::AppendCoded(const wxString &fName, sampleCount start,
{ {
// Quick check to make sure that it doesn't overflow // Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)len))) if (Overflows((mNumSamples.as_double()) + ((double)len)))
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
SeqBlock newBlock( SeqBlock newBlock(
mDirManager->NewODDecodeBlockFile(fName, start, len, channel, decodeType), mDirManager->NewODDecodeBlockFile(fName, start, len, channel, decodeType),
@ -732,19 +722,13 @@ void Sequence::AppendBlock
{ {
// Quick check to make sure that it doesn't overflow // Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)b.f->GetLength()))) if (Overflows((mNumSamples.as_double()) + ((double)b.f->GetLength())))
// THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
return
;
SeqBlock newBlock( SeqBlock newBlock(
mDirManager.CopyBlockFile(b.f), // Bump ref count if not locked, else copy mDirManager.CopyBlockFile(b.f), // Bump ref count if not locked, else copy
mNumSamples mNumSamples
); );
if (!newBlock.f) { // We can assume newBlock.f is not null
/// \todo Error Could not paste! (Out of disk space?)
wxASSERT(false); // TODO: Handle this better, alert the user of failure.
return;
}
mBlock.push_back(newBlock); mBlock.push_back(newBlock);
mNumSamples += newBlock.f->GetLength(); mNumSamples += newBlock.f->GetLength();
@ -1137,8 +1121,7 @@ bool Sequence::Get(samplePtr buffer, sampleFormat format,
if (start < 0 || start > mNumSamples || if (start < 0 || start > mNumSamples ||
start + len > mNumSamples) { start + len > mNumSamples) {
if (mayThrow) if (mayThrow)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
ClearSamples( buffer, floatSample, 0, len ); ClearSamples( buffer, floatSample, 0, len );
return false; return false;
} }
@ -1176,8 +1159,7 @@ void Sequence::SetSamples(samplePtr buffer, sampleFormat format,
{ {
if (start < 0 || start >= mNumSamples || if (start < 0 || start >= mNumSamples ||
start + len > mNumSamples) start + len > mNumSamples)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
SampleBuffer scratch(mMaxSamples, mSampleFormat); SampleBuffer scratch(mMaxSamples, mSampleFormat);
@ -1213,9 +1195,7 @@ void Sequence::SetSamples(samplePtr buffer, sampleFormat format,
if (!(fileLength <= mMaxSamples && if (!(fileLength <= mMaxSamples &&
bstart + blen <= fileLength)) bstart + blen <= fileLength))
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
wxASSERT(false)
;
if ( bstart > 0 || blen < fileLength ) { if ( bstart > 0 || blen < fileLength ) {
Read(scratch.ptr(), mSampleFormat, block, 0, fileLength, true); Read(scratch.ptr(), mSampleFormat, block, 0, fileLength, true);
@ -1527,8 +1507,7 @@ void Sequence::Append(samplePtr buffer, sampleFormat format,
// Quick check to make sure that it doesn't overflow // Quick check to make sure that it doesn't overflow
if (Overflows(mNumSamples.as_double() + ((double)len))) if (Overflows(mNumSamples.as_double() + ((double)len)))
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
BlockArray newBlock; BlockArray newBlock;
sampleCount newNumSamples = mNumSamples; sampleCount newNumSamples = mNumSamples;
@ -1644,8 +1623,7 @@ void Sequence::Delete(sampleCount start, sampleCount len)
return; return;
if (len < 0 || start < 0 || start >= mNumSamples) if (len < 0 || start < 0 || start >= mNumSamples)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
//TODO: add a ref-deref mechanism to SeqBlock/BlockArray so we don't have to make this a critical section. //TODO: add a ref-deref mechanism to SeqBlock/BlockArray so we don't have to make this a critical section.
//On-demand threads iterate over the mBlocks and the GUI thread deletes them, so for now put a mutex here over //On-demand threads iterate over the mBlocks and the GUI thread deletes them, so for now put a mutex here over
@ -1858,8 +1836,7 @@ void Sequence::ConsistencyCheck
wxT("Undo the failed operation(s), then export or save your work and quit.")); wxT("Undo the failed operation(s), then export or save your work and quit."));
if (mayThrow) if (mayThrow)
//throw ex throw ex;
;
else else
wxASSERT(false); wxASSERT(false);
} }

View File

@ -103,6 +103,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
bool GetWaveDisplay(float *min, float *max, float *rms, int* bl, bool GetWaveDisplay(float *min, float *max, float *rms, int* bl,
size_t len, const sampleCount *where) const; size_t len, const sampleCount *where) const;
// Return non-null, or else throw!
std::unique_ptr<Sequence> Copy(sampleCount s0, sampleCount s1) const; std::unique_ptr<Sequence> Copy(sampleCount s0, sampleCount s1) const;
void Paste(sampleCount s0, const Sequence *src); void Paste(sampleCount s0, const Sequence *src);

View File

@ -1298,8 +1298,7 @@ std::pair<float, float> WaveClip::GetMinMax(
{ {
if (t0 > t1) { if (t0 > t1) {
if (mayThrow) if (mayThrow)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
return { return {
0.f, // harmless, but unused since Sequence::GetMinMax does not use these values 0.f, // harmless, but unused since Sequence::GetMinMax does not use these values
0.f // harmless, but unused since Sequence::GetMinMax does not use these values 0.f // harmless, but unused since Sequence::GetMinMax does not use these values
@ -1321,8 +1320,7 @@ float WaveClip::GetRMS(double t0, double t1, bool mayThrow) const
{ {
if (t0 > t1) { if (t0 > t1) {
if (mayThrow) if (mayThrow)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
return 0.f; return 0.f;
} }
@ -1783,10 +1781,8 @@ void WaveClip::ExpandCutLine(double cutLinePosition)
[=](const WaveClipHolder &p) { return p.get() == cutline; }); [=](const WaveClipHolder &p) { return p.get() == cutline; });
if (it != end) if (it != end)
mCutLines.erase(it); // deletes cutline! mCutLines.erase(it); // deletes cutline!
else { else
// THROW_INCONSISTENCY_EXCEPTION; THROW_INCONSISTENCY_EXCEPTION;
wxASSERT(false);
}
} }
} }
@ -1906,13 +1902,14 @@ void WaveClip::Resample(int rate, ProgressDialog *progress)
); );
error = (updateResult != ProgressResult::Success); error = (updateResult != ProgressResult::Success);
if (error) if (error)
break; throw UserException{};
//throw UserException{};
} }
} }
if (error) if (error)
; throw SimpleMessageBoxException{
_("Resampling failed.")
};
else else
{ {
// Use NOFAIL-GUARANTEE in these steps // Use NOFAIL-GUARANTEE in these steps

View File

@ -555,8 +555,7 @@ bool WaveTrack::IsEmpty(double t0, double t1) const
Track::Holder WaveTrack::Cut(double t0, double t1) Track::Holder WaveTrack::Cut(double t0, double t1)
{ {
if (t1 < t0) if (t1 < t0)
// THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
auto tmp = Copy(t0, t1); auto tmp = Copy(t0, t1);
@ -569,8 +568,7 @@ Track::Holder WaveTrack::SplitCut(double t0, double t1)
// STRONG-GUARANTEE // STRONG-GUARANTEE
{ {
if (t1 < t0) if (t1 < t0)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
// SplitCut is the same as 'Copy', then 'SplitDelete' // SplitCut is the same as 'Copy', then 'SplitDelete'
auto tmp = Copy(t0, t1); auto tmp = Copy(t0, t1);
@ -584,15 +582,12 @@ Track::Holder WaveTrack::SplitCut(double t0, double t1)
Track::Holder WaveTrack::CutAndAddCutLine(double t0, double t1) Track::Holder WaveTrack::CutAndAddCutLine(double t0, double t1)
{ {
if (t1 < t0) if (t1 < t0)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
// Cut is the same as 'Copy', then 'Delete' // Cut is the same as 'Copy', then 'Delete'
auto tmp = Copy(t0, t1); auto tmp = Copy(t0, t1);
if (!ClearAndAddCutLine(t0, t1)) ClearAndAddCutLine(t0, t1);
//THROW_INCONSISTENCY_EXCEPTION
;
return tmp; return tmp;
} }
@ -648,8 +643,7 @@ void WaveTrack::Trim (double t0, double t1)
Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
{ {
if (t1 <= t0) if (t1 <= t0)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
WaveTrack *newTrack; WaveTrack *newTrack;
Track::Holder result Track::Holder result
@ -1038,8 +1032,7 @@ void WaveTrack::HandleClear(double t0, double t1,
// STRONG-GUARANTEE // STRONG-GUARANTEE
{ {
if (t1 < t0) if (t1 < t0)
// THROW_INCONSISTENCY_EXCEPTION; // ? THROW_INCONSISTENCY_EXCEPTION;
return;
bool editClipCanMove = true; bool editClipCanMove = true;
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove); gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove);
@ -1221,12 +1214,10 @@ void WaveTrack::SyncLockAdjust(double oldT1, double newT1)
// follow EditClipCanMove rules (Paste() does it right) // follow EditClipCanMove rules (Paste() does it right)
AudacityProject *p = GetActiveProject(); AudacityProject *p = GetActiveProject();
if (!p) if (!p)
// THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
TrackFactory *f = p->GetTrackFactory(); TrackFactory *f = p->GetTrackFactory();
if (!f) if (!f)
// THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
auto tmp = f->NewWaveTrack(GetSampleFormat(), GetRate()); auto tmp = f->NewWaveTrack(GetSampleFormat(), GetRate());
tmp->InsertSilence(0.0, newT1 - oldT1); tmp->InsertSilence(0.0, newT1 - oldT1);
@ -1395,8 +1386,7 @@ void WaveTrack::Paste(double t0, const Track *src)
void WaveTrack::Silence(double t0, double t1) void WaveTrack::Silence(double t0, double t1)
{ {
if (t1 < t0) if (t1 < t0)
// THROW_INCONSISTENCY_EXCEPTION; // ? THROW_INCONSISTENCY_EXCEPTION;
return;
auto start = (sampleCount)floor(t0 * mRate + 0.5); auto start = (sampleCount)floor(t0 * mRate + 0.5);
auto len = (sampleCount)floor(t1 * mRate + 0.5) - start; auto len = (sampleCount)floor(t1 * mRate + 0.5) - start;
@ -1432,8 +1422,7 @@ void WaveTrack::InsertSilence(double t, double len)
// STRONG-GUARANTEE // STRONG-GUARANTEE
{ {
if (len <= 0) if (len <= 0)
// THROW_INCONSISTENCY_EXCEPTION; // ? THROW_INCONSISTENCY_EXCEPTION;
return;
if (mClips.empty()) if (mClips.empty())
{ {
@ -1953,8 +1942,7 @@ std::pair<float, float> WaveTrack::GetMinMax(
if (t0 > t1) { if (t0 > t1) {
if (mayThrow) if (mayThrow)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
return results; return results;
} }
@ -1986,8 +1974,7 @@ float WaveTrack::GetRMS(double t0, double t1, bool mayThrow) const
{ {
if (t0 > t1) { if (t0 > t1) {
if (mayThrow) if (mayThrow)
//THROW_INCONSISTENCY_EXCEPTION THROW_INCONSISTENCY_EXCEPTION;
;
return 0.f; return 0.f;
} }

View File

@ -27,6 +27,7 @@ The summary is eventually computed and written to a file in a background thread.
#include <wx/thread.h> #include <wx/thread.h>
#include <sndfile.h> #include <sndfile.h>
#include "../FileException.h"
#include "../FileFormats.h" #include "../FileFormats.h"
#include "../Internat.h" #include "../Internat.h"
#include "NotYetAvailableException.h" #include "NotYetAvailableException.h"
@ -38,8 +39,9 @@ char bheaderTag[bheaderTagLen + 1] = "AudacityBlockFile112";
/// Create a disk file and write summary and sample data to it /// Create a disk file and write summary and sample data to it
ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&audioFileName, sampleCount aliasStart, ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&audioFileName, sampleCount aliasStart,
size_t aliasLen, int aliasChannel,unsigned int decodeType): size_t aliasLen, int aliasChannel,unsigned int decodeType)
SimpleBlockFile{ std::move(baseFileName), try
: SimpleBlockFile{ std::move(baseFileName),
NULL, aliasLen, floatSample, true, true }, NULL, aliasLen, floatSample, true, true },
//floatSample has no effect. last two bools - bypass writing of blockfile and cache //floatSample has no effect. last two bools - bypass writing of blockfile and cache
@ -51,6 +53,14 @@ ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNam
mAudioFileName = std::move(audioFileName); mAudioFileName = std::move(audioFileName);
mFormat = int16Sample; mFormat = int16Sample;
} }
catch ( const FileException & e )
{
// The constructor SimpleBlockFile sometimes throws this,
// but it never will for the arguments that were passed to it here.
// So add a catch for completeness, but just assert that this won't happen.
wxASSERT(false);
throw;
}
/// Create the memory structure to refer to the given block file /// Create the memory structure to refer to the given block file
ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&existingFile, wxFileNameWrapper &&audioFileName, sampleCount aliasStart, ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&existingFile, wxFileNameWrapper &&audioFileName, sampleCount aliasStart,
@ -102,8 +112,7 @@ auto ODDecodeBlockFile::GetMinMaxRMS(
else else
{ {
if (mayThrow) if (mayThrow)
// throw NotYetAvailableException{ mAudioFileName } throw NotYetAvailableException{ mAudioFileName };
;
//fake values. These values are used usually for normalization and amplifying, so we want //fake values. These values are used usually for normalization and amplifying, so we want
//the max to be maximal and the min to be minimal //the max to be maximal and the min to be minimal
@ -123,8 +132,7 @@ auto ODDecodeBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS
else else
{ {
if (mayThrow) if (mayThrow)
// throw NotYetAvailableException{ mAudioFileName } throw NotYetAvailableException{ mAudioFileName };
;
//fake values. These values are used usually for normalization and amplifying, so we want //fake values. These values are used usually for normalization and amplifying, so we want
//the max to be maximal and the min to be minimal //the max to be maximal and the min to be minimal
@ -446,8 +454,7 @@ size_t ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format,
else else
{ {
if (mayThrow) if (mayThrow)
//throw NotYetAvailableException{ mFileName } throw NotYetAvailableException{ mAudioFileName };
;
//we should do an ODRequest to start processing the data here, and wait till it finishes. and just do a SimpleBlockFile //we should do an ODRequest to start processing the data here, and wait till it finishes. and just do a SimpleBlockFile
//ReadData. //ReadData.

View File

@ -133,8 +133,7 @@ auto ODPCMAliasBlockFile::GetMinMaxRMS(
else else
{ {
if (mayThrow) if (mayThrow)
//throw NotYetAvailableException{ GetAliasedFileName() } throw NotYetAvailableException{ GetAliasedFileName() };
;
//fake values. These values are used usually for normalization and amplifying, so we want //fake values. These values are used usually for normalization and amplifying, so we want
//the max to be maximal and the min to be minimal //the max to be maximal and the min to be minimal
@ -156,8 +155,7 @@ auto ODPCMAliasBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS
else else
{ {
if (mayThrow) if (mayThrow)
//throw NotYetAvailableException{ GetAliasedFileName() } throw NotYetAvailableException{ GetAliasedFileName() };
;
//fake values. These values are used usually for normalization and amplifying, so we want //fake values. These values are used usually for normalization and amplifying, so we want
//the max to be maximal and the min to be minimal //the max to be maximal and the min to be minimal
@ -415,9 +413,8 @@ void ODPCMAliasBlockFile::WriteSummary()
//and wxLog calls are not thread safe. //and wxLog calls are not thread safe.
printf("Unable to write summary data to file: %s", fileNameChar.get()); printf("Unable to write summary data to file: %s", fileNameChar.get());
// throw FileException{ throw FileException{
// FileException::Cause::Read, wxFileName{ fileNameChar.get() } }; FileException::Cause::Read, wxFileName{ fileNameChar.get() } };
return;
} }
ArrayOf<char> cleanup; ArrayOf<char> cleanup;

View File

@ -57,15 +57,18 @@ to get its definition, rather than rolling our own.
*//*******************************************************************/ *//*******************************************************************/
#include "../Audacity.h"
#include "SimpleBlockFile.h"
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/filefn.h> #include <wx/filefn.h>
#include <wx/ffile.h> #include <wx/ffile.h>
#include <wx/utils.h> #include <wx/utils.h>
#include <wx/log.h> #include <wx/log.h>
#include "../FileException.h"
#include "../Prefs.h" #include "../Prefs.h"
#include "SimpleBlockFile.h"
#include "../FileFormats.h" #include "../FileFormats.h"
#include "sndfile.h" #include "sndfile.h"
@ -114,8 +117,9 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&baseFileName,
if (!(allowDeferredWrite && useCache) && !bypassCache) if (!(allowDeferredWrite && useCache) && !bypassCache)
{ {
bool bSuccess = WriteSimpleBlockFile(sampleData, sampleLen, format, NULL); bool bSuccess = WriteSimpleBlockFile(sampleData, sampleLen, format, NULL);
wxASSERT(bSuccess); // TODO: Handle failure here by alert to user and undo partial op. if (!bSuccess)
wxUnusedVar(bSuccess); throw FileException{
FileException::Cause::Write, GetFileName().name };
} }
if (useCache) { if (useCache) {
@ -404,8 +408,7 @@ size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format,
if ( framesRead < len ) { if ( framesRead < len ) {
if (mayThrow) if (mayThrow)
// Not the best exception class? // Not the best exception class?
//throw FileException{ FileException::Cause::Read, mFileName } throw FileException{ FileException::Cause::Read, mFileName };
;
ClearSamples(data, format, framesRead, len - framesRead); ClearSamples(data, format, framesRead, len - framesRead);
} }

View File

@ -27,10 +27,12 @@ and sample size to help you importing data of an unknown format.
#include "Import.h" #include "Import.h"
#include "../DirManager.h" #include "../DirManager.h"
#include "../FileException.h"
#include "../FileFormats.h" #include "../FileFormats.h"
#include "../Internat.h" #include "../Internat.h"
#include "../Prefs.h" #include "../Prefs.h"
#include "../ShuttleGui.h" #include "../ShuttleGui.h"
#include "../UserException.h"
#include "../WaveTrack.h" #include "../WaveTrack.h"
#include <cmath> #include <cmath>
@ -92,6 +94,9 @@ class ImportRawDialog final : public wxDialogWrapper {
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
// This function leaves outTracks empty as an indication of error,
// but may also throw FileException to make use of the application's
// user visible error reporting.
void ImportRaw(wxWindow *parent, const wxString &fileName, void ImportRaw(wxWindow *parent, const wxString &fileName,
TrackFactory *trackFactory, TrackHolders &outTracks) TrackFactory *trackFactory, TrackHolders &outTracks)
{ {
@ -158,12 +163,11 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
} }
if (!sndFile){ if (!sndFile){
// TODO: Handle error
char str[1000]; char str[1000];
sf_error_str((SNDFILE *)NULL, str, 1000); sf_error_str((SNDFILE *)NULL, str, 1000);
printf("%s\n", str); printf("%s\n", str);
return; throw FileException{ FileException::Cause::Open, fileName };
} }
result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset)); result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset));
@ -171,6 +175,8 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
char str[1000]; char str[1000];
sf_error_str(sndFile.get(), str, 1000); sf_error_str(sndFile.get(), str, 1000);
printf("%s\n", str); printf("%s\n", str);
throw FileException{ FileException::Cause::Read, fileName };
} }
SFCall<sf_count_t>(sf_seek, sndFile.get(), 0, SEEK_SET); SFCall<sf_count_t>(sf_seek, sndFile.get(), 0, SEEK_SET);
@ -254,9 +260,7 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
else { else {
// This is not supposed to happen, sndfile.h says result is always // This is not supposed to happen, sndfile.h says result is always
// a count, not an invalid value for error // a count, not an invalid value for error
wxASSERT(false); throw FileException{ FileException::Cause::Read, fileName };
updateResult = ProgressResult::Failed;
break;
} }
if (block) { if (block) {
@ -288,10 +292,8 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
} while (block > 0 && framescompleted < totalFrames); } while (block > 0 && framescompleted < totalFrames);
} }
if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled) { if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled)
// It's a shame we can't return proper error code throw UserException{};
return;
}
for (const auto &channel : channels) for (const auto &channel : channels)
channel->Flush(); channel->Flush();