mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-08 08:01:19 +02:00
AUP3: Mostly rework of CopyTo()
It now uses VACUUM INTO instead of the SQLite backup API in hopes that the copies will be smaller. And VACUUM INTO is "supposed" to be faster, but time will tell. It's easy to put the backup API usage back in. This also fixes a bit I missed with redoing the orphan block handling that was reported by Paul. And finally, it renames the AutoRecovery.cpp/.h files and AutoSaveFile class to ProjectSerializer since the AutoSaveFile class is being used for regular project documents now and it doesn't write to a file anymore. If anyone has a better idea for a name other than ProjectSerializer feel free to change it. I hate naming things.
This commit is contained in:
parent
7ad8849d32
commit
5b41115bd0
@ -28,7 +28,6 @@ list( APPEND DEFINES
|
|||||||
SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||||
SQLITE_MAX_EXPR_DEPTH=0
|
SQLITE_MAX_EXPR_DEPTH=0
|
||||||
SQLITE_OMIT_DEPRECATED
|
SQLITE_OMIT_DEPRECATED
|
||||||
SQLITE_OMIT_PROGRESS_CALLBACK
|
|
||||||
SQLITE_OMIT_SHARED_CACHE
|
SQLITE_OMIT_SHARED_CACHE
|
||||||
SQLITE_USE_ALLOCA
|
SQLITE_USE_ALLOCA
|
||||||
SQLITE_OMIT_AUTOINIT
|
SQLITE_OMIT_AUTOINIT
|
||||||
|
@ -99,7 +99,6 @@ It handles initialization and termination by subclassing wxApp.
|
|||||||
#include "Theme.h"
|
#include "Theme.h"
|
||||||
#include "PlatformCompatibility.h"
|
#include "PlatformCompatibility.h"
|
||||||
#include "FileNames.h"
|
#include "FileNames.h"
|
||||||
#include "AutoRecovery.h"
|
|
||||||
#include "AutoRecoveryDialog.h"
|
#include "AutoRecoveryDialog.h"
|
||||||
#include "SplashDialog.h"
|
#include "SplashDialog.h"
|
||||||
#include "FFT.h"
|
#include "FFT.h"
|
||||||
|
@ -14,10 +14,10 @@ Paul Licameli split from AudacityProject.cpp
|
|||||||
#include <wx/crt.h>
|
#include <wx/crt.h>
|
||||||
#include <wx/frame.h>
|
#include <wx/frame.h>
|
||||||
|
|
||||||
#include "AutoRecovery.h"
|
|
||||||
#include "FileNames.h"
|
#include "FileNames.h"
|
||||||
#include "Project.h"
|
#include "Project.h"
|
||||||
#include "ProjectFileIORegistry.h"
|
#include "ProjectFileIORegistry.h"
|
||||||
|
#include "ProjectSerializer.h"
|
||||||
#include "ProjectSettings.h"
|
#include "ProjectSettings.h"
|
||||||
#include "Tags.h"
|
#include "Tags.h"
|
||||||
#include "ViewInfo.h"
|
#include "ViewInfo.h"
|
||||||
@ -727,88 +727,94 @@ bool ProjectFileIO::CheckForOrphans(BlockIDs &blockids)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int progress_callback(void *data)
|
||||||
|
{
|
||||||
|
ProgressDialog *progress = (ProgressDialog *) data;
|
||||||
|
|
||||||
|
// No way to know how much time will be spent, so turn the
|
||||||
|
// ProgressDialog in to an elapsed timer.
|
||||||
|
//
|
||||||
|
// Would be nice if our ProgressDialog has a Cylon mode.
|
||||||
|
if (progress->Update(100000) != ProgressResult::Success)
|
||||||
|
{
|
||||||
|
return SQLITE_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath)
|
sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath)
|
||||||
{
|
{
|
||||||
auto db = DB();
|
auto db = DB();
|
||||||
int rc;
|
int rc;
|
||||||
ProgressResult res = ProgressResult::Success;
|
ProgressResult res = ProgressResult::Success;
|
||||||
|
|
||||||
sqlite3 *destdb = nullptr;
|
sqlite3_stmt *stmt = nullptr;
|
||||||
|
auto cleanup = finally([&]
|
||||||
/* Open the database file identified by zFilename. */
|
|
||||||
rc = sqlite3_open(destpath, &destdb);
|
|
||||||
if (rc == SQLITE_OK)
|
|
||||||
{
|
{
|
||||||
bool success = true;
|
if (stmt)
|
||||||
sqlite3_backup *backup = sqlite3_backup_init(destdb, "main", db, "main");
|
{
|
||||||
if (backup)
|
sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db, "VACUUM INTO ?;", -1, &stmt, 0);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
SetDBError(
|
||||||
|
XO("Unable to prepare project file command")
|
||||||
|
);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_bind_text(stmt, 1, destpath.mb_str().data(), destpath.mb_str().length(), SQLITE_STATIC);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
/* i18n-hint: This title appears on a dialog that indicates the progress
|
/* i18n-hint: This title appears on a dialog that indicates the progress
|
||||||
in doing something.*/
|
in doing something.*/
|
||||||
ProgressDialog progress(XO("Progress"), XO("Saving project"));
|
ProgressDialog progress(XO("Progress"), XO("Saving project"));
|
||||||
|
|
||||||
do
|
sqlite3_progress_handler(db, 10, progress_callback, &progress);
|
||||||
{
|
|
||||||
// These two calls always return zero before any sqlite3_backup_step
|
|
||||||
// but that doesn't matter
|
|
||||||
int remaining = sqlite3_backup_remaining(backup);
|
|
||||||
int total = sqlite3_backup_pagecount(backup);
|
|
||||||
|
|
||||||
if (progress.Update(total - remaining, total) != ProgressResult::Success)
|
rc = sqlite3_step(stmt);
|
||||||
{
|
|
||||||
SetError(
|
sqlite3_progress_handler(db, 0, nullptr, nullptr);
|
||||||
XO("Copy process cancelled.")
|
|
||||||
);
|
|
||||||
success = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sqlite3_backup_step(backup, 12);
|
sqlite3_finalize(stmt);
|
||||||
} while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
|
stmt = nullptr;
|
||||||
|
|
||||||
// The return code from finish() will reflect errors from step()
|
// VACUUMing failed
|
||||||
rc = sqlite3_backup_finish(backup);
|
if (rc != SQLITE_DONE)
|
||||||
if (rc != SQLITE_OK)
|
|
||||||
{
|
{
|
||||||
SetDBError(
|
SetDBError(
|
||||||
XO("The copy process failed for:\n\n%s").Format(destpath)
|
XO("Project file copy failed")
|
||||||
);
|
);
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDBError(
|
|
||||||
XO("Unable to initiate the backup process.")
|
|
||||||
);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
// Don't give this DB connection back to the caller
|
|
||||||
rc = sqlite3_close(destdb);
|
|
||||||
if (rc != SQLITE_OK)
|
|
||||||
{
|
|
||||||
SetDBError(
|
|
||||||
XO("Failed to successfully close the destination project file:\n\n%s")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
wxRemoveFile(destpath);
|
wxRemoveFile(destpath);
|
||||||
return nullptr;
|
|
||||||
}
|
return nullptr;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
sqlite3 *destdb = nullptr;
|
||||||
// sqlite3 docs say you should close anyway to avoid leaks
|
rc = sqlite3_open(destpath, &destdb);
|
||||||
sqlite3_close( destdb );
|
if (rc != SQLITE_OK)
|
||||||
SetDBError(
|
{
|
||||||
XO("Unable to open the destination project file:\n\n%s").Format(destpath)
|
SetDBError(
|
||||||
);
|
XO("Failed to open copy of project file")
|
||||||
|
);
|
||||||
|
|
||||||
|
sqlite3_close(destdb);
|
||||||
|
|
||||||
|
wxRemoveFile(destpath);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the caller use this connection and close it later
|
|
||||||
return destdb;
|
return destdb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1108,7 +1114,7 @@ void ProjectFileIO::WriteXML(XMLWriter &xmlFile, const WaveTrackArray *tracks)
|
|||||||
|
|
||||||
bool ProjectFileIO::AutoSave(const WaveTrackArray *tracks)
|
bool ProjectFileIO::AutoSave(const WaveTrackArray *tracks)
|
||||||
{
|
{
|
||||||
AutoSaveFile autosave;
|
ProjectSerializer autosave;
|
||||||
WriteXMLHeader(autosave);
|
WriteXMLHeader(autosave);
|
||||||
WriteXML(autosave, tracks);
|
WriteXML(autosave, tracks);
|
||||||
|
|
||||||
@ -1121,11 +1127,15 @@ bool ProjectFileIO::AutoSave(const WaveTrackArray *tracks)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectFileIO::AutoSaveDelete()
|
bool ProjectFileIO::AutoSaveDelete(sqlite3 *db /* = nullptr */)
|
||||||
{
|
{
|
||||||
auto db = DB();
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!db)
|
||||||
|
{
|
||||||
|
db = DB();
|
||||||
|
}
|
||||||
|
|
||||||
rc = sqlite3_exec(db, "DELETE FROM autosave;", nullptr, nullptr, nullptr);
|
rc = sqlite3_exec(db, "DELETE FROM autosave;", nullptr, nullptr, nullptr);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_OK)
|
||||||
{
|
{
|
||||||
@ -1138,20 +1148,25 @@ bool ProjectFileIO::AutoSaveDelete()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectFileIO::WriteDoc(const char *table, const AutoSaveFile &autosave)
|
bool ProjectFileIO::WriteDoc(const char *table,
|
||||||
|
const ProjectSerializer &autosave,
|
||||||
|
sqlite3 *db /* = nullptr */)
|
||||||
{
|
{
|
||||||
auto db = DB();
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!db)
|
||||||
|
{
|
||||||
|
db = DB();
|
||||||
|
}
|
||||||
|
|
||||||
// For now, we always use an ID of 1. This will replace the previously
|
// For now, we always use an ID of 1. This will replace the previously
|
||||||
// writen row every time.
|
// writen row every time.
|
||||||
char sql[256];
|
char sql[256];
|
||||||
sqlite3_snprintf(sizeof(sql),
|
sqlite3_snprintf(sizeof(sql),
|
||||||
sql,
|
sql,
|
||||||
"INSERT INTO %s(id, dict, doc) VALUES(1, ?1, ?2)"
|
"INSERT INTO %s(id, dict, doc) VALUES(1, ?1, ?2)"
|
||||||
" ON CONFLICT(id) DO UPDATE SET %sdoc = ?2;",
|
" ON CONFLICT(id) DO UPDATE SET dict = ?1, doc = ?2;",
|
||||||
table,
|
table);
|
||||||
autosave.DictChanged() ? "dict = ?1, " : "");
|
|
||||||
|
|
||||||
sqlite3_stmt *stmt = nullptr;
|
sqlite3_stmt *stmt = nullptr;
|
||||||
auto cleanup = finally([&]
|
auto cleanup = finally([&]
|
||||||
@ -1233,7 +1248,7 @@ bool ProjectFileIO::LoadProject(const FilePath &fileName)
|
|||||||
}
|
}
|
||||||
if (buffer.GetDataLen() > 0)
|
if (buffer.GetDataLen() > 0)
|
||||||
{
|
{
|
||||||
project = AutoSaveFile::Decode(buffer, blockids);
|
project = ProjectSerializer::Decode(buffer, blockids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetBlob("SELECT dict || doc FROM autosave WHERE id = 1;", buffer))
|
if (!GetBlob("SELECT dict || doc FROM autosave WHERE id = 1;", buffer))
|
||||||
@ -1243,7 +1258,7 @@ bool ProjectFileIO::LoadProject(const FilePath &fileName)
|
|||||||
}
|
}
|
||||||
if (buffer.GetDataLen() > 0)
|
if (buffer.GetDataLen() > 0)
|
||||||
{
|
{
|
||||||
autosave = AutoSaveFile::Decode(buffer, blockids);
|
autosave = ProjectSerializer::Decode(buffer, blockids);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should this be an error???
|
// Should this be an error???
|
||||||
@ -1362,10 +1377,7 @@ bool ProjectFileIO::SaveProject(const FilePath &fileName)
|
|||||||
UseConnection( newDB, fileName );
|
UseConnection( newDB, fileName );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto db = DB();
|
ProjectSerializer doc;
|
||||||
int rc;
|
|
||||||
|
|
||||||
AutoSaveFile doc;
|
|
||||||
WriteXMLHeader(doc);
|
WriteXMLHeader(doc);
|
||||||
WriteXML(doc);
|
WriteXML(doc);
|
||||||
|
|
||||||
@ -1411,7 +1423,6 @@ bool ProjectFileIO::SaveCopy(const FilePath& fileName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc;
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
auto cleanup = finally([&]
|
auto cleanup = finally([&]
|
||||||
@ -1427,64 +1438,21 @@ bool ProjectFileIO::SaveCopy(const FilePath& fileName)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
XMLStringWriter doc;
|
ProjectSerializer doc;
|
||||||
WriteXMLHeader(doc);
|
WriteXMLHeader(doc);
|
||||||
WriteXML(doc);
|
WriteXML(doc);
|
||||||
|
|
||||||
// Always use an ID of 1. This will replace any existing row.
|
// Write the project doc to the new DB
|
||||||
char sql[256];
|
if (!WriteDoc("project", doc, db))
|
||||||
sqlite3_snprintf(sizeof(sql),
|
|
||||||
sql,
|
|
||||||
"INSERT INTO project(id, doc) VALUES(1, ?1)"
|
|
||||||
" ON CONFLICT(id) DO UPDATE SET doc = ?1;");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
sqlite3_stmt* stmt = nullptr;
|
|
||||||
|
|
||||||
auto finalize = finally([&]
|
|
||||||
{
|
|
||||||
if (stmt)
|
|
||||||
{
|
|
||||||
// This will free the statement
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
|
||||||
if (rc != SQLITE_OK)
|
|
||||||
{
|
|
||||||
SetDBError(
|
|
||||||
XO("Unable to prepare project file command:\n\n%s").Format(sql)
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BIND SQL project
|
// We need to remove the autosave info from the new DB since it is now
|
||||||
rc = sqlite3_bind_text(stmt, 1, doc, -1, SQLITE_STATIC);
|
// clean and unmodified. Otherwise, it would be considered "recovered"
|
||||||
if (rc != SQLITE_OK)
|
// when next opened.
|
||||||
|
if (!AutoSaveDelete(db))
|
||||||
{
|
{
|
||||||
SetDBError(
|
|
||||||
XO("Unable to bind to project file document.")
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = sqlite3_step(stmt);
|
|
||||||
if (rc != SQLITE_DONE)
|
|
||||||
{
|
|
||||||
SetDBError(
|
|
||||||
XO("Failed to save project file information.")
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = sqlite3_exec(db, "DELETE FROM autosave;", nullptr, nullptr, nullptr);
|
|
||||||
if (rc != SQLITE_OK)
|
|
||||||
{
|
|
||||||
SetDBError(
|
|
||||||
XO("Failed to remove the autosave information from the project file.")
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ struct sqlite3_value;
|
|||||||
|
|
||||||
class AudacityProject;
|
class AudacityProject;
|
||||||
class AutoCommitTransaction;
|
class AutoCommitTransaction;
|
||||||
class AutoSaveFile;
|
class ProjectSerializer;
|
||||||
class SqliteSampleBlock;
|
class SqliteSampleBlock;
|
||||||
class WaveTrack;
|
class WaveTrack;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ public:
|
|||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
bool AutoSave(const WaveTrackArray *tracks = nullptr);
|
bool AutoSave(const WaveTrackArray *tracks = nullptr);
|
||||||
bool AutoSaveDelete();
|
bool AutoSaveDelete(sqlite3 *db = nullptr);
|
||||||
|
|
||||||
bool LoadProject(const FilePath &fileName);
|
bool LoadProject(const FilePath &fileName);
|
||||||
bool SaveProject(const FilePath &fileName);
|
bool SaveProject(const FilePath &fileName);
|
||||||
@ -118,6 +118,8 @@ private:
|
|||||||
static int ExecCallback(void *data, int cols, char **vals, char **names);
|
static int ExecCallback(void *data, int cols, char **vals, char **names);
|
||||||
int Exec(const char *query, ExecCB callback, wxString *result);
|
int Exec(const char *query, ExecCB callback, wxString *result);
|
||||||
|
|
||||||
|
static int ProgressCallback(void *data);
|
||||||
|
|
||||||
// The opening of the database may be delayed until demanded.
|
// The opening of the database may be delayed until demanded.
|
||||||
// Returns a non-null pointer to an open database, or throws an exception
|
// Returns a non-null pointer to an open database, or throws an exception
|
||||||
// if opening fails.
|
// if opening fails.
|
||||||
@ -152,7 +154,7 @@ private:
|
|||||||
bool UpgradeSchema();
|
bool UpgradeSchema();
|
||||||
|
|
||||||
// Write project or autosave XML (binary) documents
|
// Write project or autosave XML (binary) documents
|
||||||
bool WriteDoc(const char *table, const AutoSaveFile &autosave);
|
bool WriteDoc(const char *table, const ProjectSerializer &autosave, sqlite3 *db = nullptr);
|
||||||
|
|
||||||
// Checks for orphan blocks. This will go away at a future date
|
// Checks for orphan blocks. This will go away at a future date
|
||||||
using BlockIDs = std::set<SampleBlockID>;
|
using BlockIDs = std::set<SampleBlockID>;
|
||||||
|
@ -4,26 +4,25 @@
|
|||||||
Audacity(R) is copyright (c) 1999-2010 Audacity Team.
|
Audacity(R) is copyright (c) 1999-2010 Audacity Team.
|
||||||
License: GPL v2. See License.txt.
|
License: GPL v2. See License.txt.
|
||||||
|
|
||||||
AutoRecovery.cpp
|
ProjectSerializer.cpp
|
||||||
|
|
||||||
*******************************************************************//**
|
*******************************************************************//**
|
||||||
|
|
||||||
\class AutoSaveFile
|
\class ProjectSerializer
|
||||||
\brief a class wrapping reading and writing of arbitrary data in
|
\brief a class used to (de)serialize the project catalog
|
||||||
text or binary format to a file.
|
|
||||||
|
|
||||||
*//********************************************************************/
|
*//********************************************************************/
|
||||||
|
|
||||||
#include "Audacity.h"
|
#include "Audacity.h"
|
||||||
#include "AutoRecovery.h"
|
#include "ProjectSerializer.h"
|
||||||
|
|
||||||
#include <wx/ustring.h>
|
#include <wx/ustring.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// AutoSaveFile class
|
/// ProjectSerializer class
|
||||||
///
|
///
|
||||||
|
|
||||||
// Simple "binary xml" format used exclusively for autosave documents.
|
// Simple "binary xml" format used exclusively for project documents.
|
||||||
//
|
//
|
||||||
// It is not intended that the user view or modify the file.
|
// It is not intended that the user view or modify the file.
|
||||||
//
|
//
|
||||||
@ -75,17 +74,17 @@ enum FieldTypes
|
|||||||
// is writen and then the envelope is later removed, the dict will still
|
// is writen and then the envelope is later removed, the dict will still
|
||||||
// contain the envelope name, but that's not a problem.
|
// contain the envelope name, but that's not a problem.
|
||||||
|
|
||||||
NameMap AutoSaveFile::mNames;
|
NameMap ProjectSerializer::mNames;
|
||||||
wxMemoryBuffer AutoSaveFile::mDict;
|
wxMemoryBuffer ProjectSerializer::mDict;
|
||||||
|
|
||||||
TranslatableString AutoSaveFile::FailureMessage( const FilePath &/*filePath*/ )
|
TranslatableString ProjectSerializer::FailureMessage( const FilePath &/*filePath*/ )
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
XO("This recovery file was saved by Audacity 2.3.0 or before.\n"
|
XO("This recovery file was saved by Audacity 2.3.0 or before.\n"
|
||||||
"You need to run that version of Audacity to recover the project." );
|
"You need to run that version of Audacity to recover the project." );
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoSaveFile::AutoSaveFile(size_t allocSize)
|
ProjectSerializer::ProjectSerializer(size_t allocSize)
|
||||||
{
|
{
|
||||||
mDict.SetBufSize(allocSize);
|
mDict.SetBufSize(allocSize);
|
||||||
mBuffer.SetBufSize(allocSize);
|
mBuffer.SetBufSize(allocSize);
|
||||||
@ -99,28 +98,28 @@ AutoSaveFile::AutoSaveFile(size_t allocSize)
|
|||||||
mDictChanged = false;
|
mDictChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoSaveFile::~AutoSaveFile()
|
ProjectSerializer::~ProjectSerializer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::StartTag(const wxString & name)
|
void ProjectSerializer::StartTag(const wxString & name)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_StartTag);
|
mBuffer.AppendByte(FT_StartTag);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::EndTag(const wxString & name)
|
void ProjectSerializer::EndTag(const wxString & name)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_EndTag);
|
mBuffer.AppendByte(FT_EndTag);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, const wxChar *value)
|
void ProjectSerializer::WriteAttr(const wxString & name, const wxChar *value)
|
||||||
{
|
{
|
||||||
WriteAttr(name, wxString(value));
|
WriteAttr(name, wxString(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, const wxString & value)
|
void ProjectSerializer::WriteAttr(const wxString & name, const wxString & value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_String);
|
mBuffer.AppendByte(FT_String);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -131,7 +130,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, const wxString & value)
|
|||||||
mBuffer.AppendData(value.wx_str(), len);
|
mBuffer.AppendData(value.wx_str(), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, int value)
|
void ProjectSerializer::WriteAttr(const wxString & name, int value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Int);
|
mBuffer.AppendByte(FT_Int);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -139,7 +138,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, int value)
|
|||||||
mBuffer.AppendData(&value, sizeof(value));
|
mBuffer.AppendData(&value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, bool value)
|
void ProjectSerializer::WriteAttr(const wxString & name, bool value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Bool);
|
mBuffer.AppendByte(FT_Bool);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -147,7 +146,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, bool value)
|
|||||||
mBuffer.AppendData(&value, sizeof(value));
|
mBuffer.AppendData(&value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, long value)
|
void ProjectSerializer::WriteAttr(const wxString & name, long value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Long);
|
mBuffer.AppendByte(FT_Long);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -155,7 +154,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, long value)
|
|||||||
mBuffer.AppendData(&value, sizeof(value));
|
mBuffer.AppendData(&value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, long long value)
|
void ProjectSerializer::WriteAttr(const wxString & name, long long value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_LongLong);
|
mBuffer.AppendByte(FT_LongLong);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -163,7 +162,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, long long value)
|
|||||||
mBuffer.AppendData(&value, sizeof(value));
|
mBuffer.AppendData(&value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, size_t value)
|
void ProjectSerializer::WriteAttr(const wxString & name, size_t value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_SizeT);
|
mBuffer.AppendByte(FT_SizeT);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -171,7 +170,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, size_t value)
|
|||||||
mBuffer.AppendData(&value, sizeof(value));
|
mBuffer.AppendData(&value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, float value, int digits)
|
void ProjectSerializer::WriteAttr(const wxString & name, float value, int digits)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Float);
|
mBuffer.AppendByte(FT_Float);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -180,7 +179,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, float value, int digits)
|
|||||||
mBuffer.AppendData(&digits, sizeof(digits));
|
mBuffer.AppendData(&digits, sizeof(digits));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteAttr(const wxString & name, double value, int digits)
|
void ProjectSerializer::WriteAttr(const wxString & name, double value, int digits)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Double);
|
mBuffer.AppendByte(FT_Double);
|
||||||
WriteName(name);
|
WriteName(name);
|
||||||
@ -189,7 +188,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, double value, int digits)
|
|||||||
mBuffer.AppendData(&digits, sizeof(digits));
|
mBuffer.AppendData(&digits, sizeof(digits));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteData(const wxString & value)
|
void ProjectSerializer::WriteData(const wxString & value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Data);
|
mBuffer.AppendByte(FT_Data);
|
||||||
|
|
||||||
@ -199,7 +198,7 @@ void AutoSaveFile::WriteData(const wxString & value)
|
|||||||
mBuffer.AppendData(value.wx_str(), len);
|
mBuffer.AppendData(value.wx_str(), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::Write(const wxString & value)
|
void ProjectSerializer::Write(const wxString & value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Raw);
|
mBuffer.AppendByte(FT_Raw);
|
||||||
|
|
||||||
@ -209,7 +208,7 @@ void AutoSaveFile::Write(const wxString & value)
|
|||||||
mBuffer.AppendData(value.wx_str(), len);
|
mBuffer.AppendData(value.wx_str(), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteSubTree(const AutoSaveFile & value)
|
void ProjectSerializer::WriteSubTree(const ProjectSerializer & value)
|
||||||
{
|
{
|
||||||
mBuffer.AppendByte(FT_Push);
|
mBuffer.AppendByte(FT_Push);
|
||||||
|
|
||||||
@ -219,7 +218,7 @@ void AutoSaveFile::WriteSubTree(const AutoSaveFile & value)
|
|||||||
mBuffer.AppendByte(FT_Pop);
|
mBuffer.AppendByte(FT_Pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSaveFile::WriteName(const wxString & name)
|
void ProjectSerializer::WriteName(const wxString & name)
|
||||||
{
|
{
|
||||||
wxASSERT(name.length() * sizeof(wxChar) <= SHRT_MAX);
|
wxASSERT(name.length() * sizeof(wxChar) <= SHRT_MAX);
|
||||||
short id;
|
short id;
|
||||||
@ -247,28 +246,28 @@ void AutoSaveFile::WriteName(const wxString & name)
|
|||||||
mBuffer.AppendData(&id, sizeof(id));
|
mBuffer.AppendData(&id, sizeof(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxMemoryBuffer &AutoSaveFile::GetDict() const
|
const wxMemoryBuffer &ProjectSerializer::GetDict() const
|
||||||
{
|
{
|
||||||
return mDict;
|
return mDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxMemoryBuffer &AutoSaveFile::GetData() const
|
const wxMemoryBuffer &ProjectSerializer::GetData() const
|
||||||
{
|
{
|
||||||
return mBuffer;
|
return mBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AutoSaveFile::IsEmpty() const
|
bool ProjectSerializer::IsEmpty() const
|
||||||
{
|
{
|
||||||
return mBuffer.GetDataLen() == 0;
|
return mBuffer.GetDataLen() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AutoSaveFile::DictChanged() const
|
bool ProjectSerializer::DictChanged() const
|
||||||
{
|
{
|
||||||
return mDictChanged;
|
return mDictChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See ProjectFileIO::CheckForOrphans() for explanation of the blockids arg
|
// See ProjectFileIO::CheckForOrphans() for explanation of the blockids arg
|
||||||
wxString AutoSaveFile::Decode(const wxMemoryBuffer &buffer, BlockIDs &blockids)
|
wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &blockids)
|
||||||
{
|
{
|
||||||
wxMemoryInputStream in(buffer.GetData(), buffer.GetDataLen());
|
wxMemoryInputStream in(buffer.GetData(), buffer.GetDataLen());
|
||||||
|
|
||||||
@ -449,8 +448,8 @@ wxString AutoSaveFile::Decode(const wxMemoryBuffer &buffer, BlockIDs &blockids)
|
|||||||
in.Read(&val, sizeof(val));
|
in.Read(&val, sizeof(val));
|
||||||
|
|
||||||
// Look for and save the "blockid" values to support orphan
|
// Look for and save the "blockid" values to support orphan
|
||||||
// block checking. This should be removed once autosave and
|
// block checking. This should be removed once serialization
|
||||||
// related blocks become part of the same transaction.
|
// and related blocks become part of the same transaction.
|
||||||
const wxString &name = Lookup(id);
|
const wxString &name = Lookup(id);
|
||||||
if (name.IsSameAs(wxT("blockid")))
|
if (name.IsSameAs(wxT("blockid")))
|
||||||
{
|
{
|
||||||
@ -510,7 +509,7 @@ wxString AutoSaveFile::Decode(const wxMemoryBuffer &buffer, BlockIDs &blockids)
|
|||||||
}
|
}
|
||||||
catch( const Error& )
|
catch( const Error& )
|
||||||
{
|
{
|
||||||
// Autosave was corrupt, or platform differences in size or endianness
|
// Document was corrupt, or platform differences in size or endianness
|
||||||
// were not well canonicalized
|
// were not well canonicalized
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
@ -4,12 +4,12 @@
|
|||||||
Audacity(R) is copyright (c) 1999-2010 Audacity Team.
|
Audacity(R) is copyright (c) 1999-2010 Audacity Team.
|
||||||
License: GPL v2. See License.txt.
|
License: GPL v2. See License.txt.
|
||||||
|
|
||||||
AutoRecovery.h
|
ProjectSerializer.h
|
||||||
|
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
|
||||||
#ifndef __AUDACITY_AUTORECOVERY__
|
#ifndef __AUDACITY_PROJECTSERIALIZER__
|
||||||
#define __AUDACITY_AUTORECOVERY__
|
#define __AUDACITY_PROJECTSERIALIZER__
|
||||||
|
|
||||||
#include "xml/XMLTagHandler.h"
|
#include "xml/XMLTagHandler.h"
|
||||||
|
|
||||||
@ -26,21 +26,21 @@ using SampleBlockID = long long;
|
|||||||
using BlockIDs = std::set<SampleBlockID>;
|
using BlockIDs = std::set<SampleBlockID>;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// AutoSaveFile
|
/// ProjectSerializer
|
||||||
///
|
///
|
||||||
|
|
||||||
using NameMap = std::unordered_map<wxString, short>;
|
using NameMap = std::unordered_map<wxString, short>;
|
||||||
using IdMap = std::unordered_map<short, wxString>;
|
using IdMap = std::unordered_map<short, wxString>;
|
||||||
|
|
||||||
// This class's overrides do NOT throw AudacityException.
|
// This class's overrides do NOT throw AudacityException.
|
||||||
class AUDACITY_DLL_API AutoSaveFile final : public XMLWriter
|
class AUDACITY_DLL_API ProjectSerializer final : public XMLWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static TranslatableString FailureMessage( const FilePath &filePath );
|
static TranslatableString FailureMessage( const FilePath &filePath );
|
||||||
|
|
||||||
AutoSaveFile(size_t allocSize = 1024 * 1024);
|
ProjectSerializer(size_t allocSize = 1024 * 1024);
|
||||||
virtual ~AutoSaveFile();
|
virtual ~ProjectSerializer();
|
||||||
|
|
||||||
void StartTag(const wxString & name) override;
|
void StartTag(const wxString & name) override;
|
||||||
void EndTag(const wxString & name) override;
|
void EndTag(const wxString & name) override;
|
||||||
@ -60,7 +60,7 @@ public:
|
|||||||
void Write(const wxString & data) override;
|
void Write(const wxString & data) override;
|
||||||
|
|
||||||
// Non-override functions
|
// Non-override functions
|
||||||
void WriteSubTree(const AutoSaveFile & value);
|
void WriteSubTree(const ProjectSerializer & value);
|
||||||
|
|
||||||
const wxMemoryBuffer &GetDict() const;
|
const wxMemoryBuffer &GetDict() const;
|
||||||
const wxMemoryBuffer &GetData() const;
|
const wxMemoryBuffer &GetData() const;
|
@ -31,6 +31,7 @@
|
|||||||
#include "../Mix.h"
|
#include "../Mix.h"
|
||||||
#include "../PluginManager.h"
|
#include "../PluginManager.h"
|
||||||
#include "../ProjectAudioManager.h"
|
#include "../ProjectAudioManager.h"
|
||||||
|
#include "../ProjectFileIO.h"
|
||||||
#include "../ProjectSettings.h"
|
#include "../ProjectSettings.h"
|
||||||
#include "../ShuttleGui.h"
|
#include "../ShuttleGui.h"
|
||||||
#include "../Shuttle.h"
|
#include "../Shuttle.h"
|
||||||
@ -1316,7 +1317,21 @@ bool Effect::DoEffect(double projectRate,
|
|||||||
};
|
};
|
||||||
auto vr = valueRestorer( mProgress, &progress );
|
auto vr = valueRestorer( mProgress, &progress );
|
||||||
|
|
||||||
|
{
|
||||||
|
// This is for performance purposes only.
|
||||||
|
#if 0
|
||||||
|
auto &pProject = *const_cast<AudacityProject*>(FindProject()); // how to remove this const_cast?
|
||||||
|
auto &pIO = ProjectFileIO::Get(pProject);
|
||||||
|
AutoCommitTransaction trans(pIO, "Effect");
|
||||||
|
#endif
|
||||||
returnVal = Process();
|
returnVal = Process();
|
||||||
|
#if 0
|
||||||
|
if (!returnVal)
|
||||||
|
{
|
||||||
|
trans.Rollback();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnVal && (mT1 >= mT0 ))
|
if (returnVal && (mT1 >= mT0 ))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user