mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-05 21:57:20 +00:00
Backup document data in a raw format directly on disk
This commit is contained in:
parent
5c3e6e4863
commit
9ca4d15d74
@ -227,6 +227,7 @@ add_library(app-lib
|
||||
context_flags.cpp
|
||||
crash/backup_observer.cpp
|
||||
crash/data_recovery.cpp
|
||||
crash/document_io.cpp
|
||||
crash/session.cpp
|
||||
document.cpp
|
||||
document_api.cpp
|
||||
|
150
src/app/crash/document_io.cpp
Normal file
150
src/app/crash/document_io.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/crash/document_io.h"
|
||||
|
||||
#include "app/document.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/path.h"
|
||||
#include "base/serialization.h"
|
||||
#include "base/string.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/cel_data_io.h"
|
||||
#include "doc/cel_io.h"
|
||||
#include "doc/cels_range.h"
|
||||
#include "doc/frame.h"
|
||||
#include "doc/frame_tag.h"
|
||||
#include "doc/frame_tag_io.h"
|
||||
#include "doc/image_io.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/palette_io.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "doc/string_io.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace app {
|
||||
namespace crash {
|
||||
|
||||
using namespace base::serialization;
|
||||
using namespace base::serialization::little_endian;
|
||||
using namespace doc;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define OFSTREAM(name, fn) \
|
||||
std::ofstream name(base::from_utf8(base::join_path(path, fn)));
|
||||
#else
|
||||
#define OFSTREAM(name, fn) \
|
||||
std::ofstream name(base::join_path(path, fn));
|
||||
#endif
|
||||
|
||||
void write_document(const std::string& path, app::Document* doc)
|
||||
{
|
||||
Sprite* spr = doc->sprite();
|
||||
std::vector<Layer*> layers;
|
||||
|
||||
{
|
||||
OFSTREAM(os, "spr-" + base::convert_to<std::string>(spr->id()));
|
||||
|
||||
write32(os, spr->id());
|
||||
write8(os, spr->pixelFormat());
|
||||
write32(os, spr->width());
|
||||
write32(os, spr->height());
|
||||
write32(os, spr->transparentColor());
|
||||
|
||||
// Frame durations
|
||||
write32(os, spr->totalFrames());
|
||||
for (frame_t fr = 0; fr < spr->totalFrames(); ++fr)
|
||||
write32(os, spr->frameDuration(fr));
|
||||
|
||||
// Palettes
|
||||
write32(os, spr->getPalettes().size());
|
||||
for (Palette* pal : spr->getPalettes())
|
||||
write32(os, pal->id());
|
||||
|
||||
// Frame tags
|
||||
write32(os, spr->frameTags().size());
|
||||
for (FrameTag* tag : spr->frameTags())
|
||||
write32(os, tag->id());
|
||||
|
||||
// Layers
|
||||
spr->getLayersList(layers);
|
||||
write32(os, layers.size());
|
||||
for (Layer* lay : layers)
|
||||
write32(os, lay->id());
|
||||
|
||||
// Cels
|
||||
int celCount = 0;
|
||||
for (Cel* cel : spr->cels())
|
||||
++celCount;
|
||||
write32(os, celCount);
|
||||
for (Cel* cel : spr->cels())
|
||||
write32(os, cel->id());
|
||||
|
||||
// Images (CelData)
|
||||
int uniqueCelCount = 0;
|
||||
for (Cel* cel : spr->uniqueCels())
|
||||
++uniqueCelCount;
|
||||
write32(os, uniqueCelCount);
|
||||
for (Cel* cel : spr->uniqueCels())
|
||||
write32(os, cel->data()->id());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Create one stream for each object
|
||||
|
||||
for (Palette* pal : spr->getPalettes()) {
|
||||
OFSTREAM(subos, "pal-" + base::convert_to<std::string>(pal->id()));
|
||||
write_palette(subos, pal);
|
||||
}
|
||||
|
||||
for (FrameTag* tag : spr->frameTags()) {
|
||||
OFSTREAM(subos, "frtag-" + base::convert_to<std::string>(tag->id()));
|
||||
write_frame_tag(subos, tag);
|
||||
}
|
||||
|
||||
for (Layer* lay : layers) {
|
||||
OFSTREAM(os, "lay-" + base::convert_to<std::string>(lay->id()));
|
||||
write32(os, lay->id());
|
||||
write_string(os, lay->name());
|
||||
|
||||
write32(os, static_cast<int>(lay->flags())); // Flags
|
||||
write16(os, static_cast<int>(lay->type())); // Type
|
||||
|
||||
if (lay->type() == ObjectType::LayerImage) {
|
||||
CelConstIterator it, begin = static_cast<const LayerImage*>(lay)->getCelBegin();
|
||||
CelConstIterator end = static_cast<const LayerImage*>(lay)->getCelEnd();
|
||||
|
||||
// Cels
|
||||
write32(os, static_cast<const LayerImage*>(lay)->getCelsCount());
|
||||
for (it=begin; it != end; ++it) {
|
||||
const Cel* cel = *it;
|
||||
write32(os, cel->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Cel* cel : spr->cels()) {
|
||||
OFSTREAM(os, "cel-" + base::convert_to<std::string>(cel->id()));
|
||||
write_cel(os, cel);
|
||||
}
|
||||
|
||||
// Images (CelData)
|
||||
for (Cel* cel : spr->uniqueCels()) {
|
||||
OFSTREAM(os, "img-" + base::convert_to<std::string>(cel->data()->id()));
|
||||
write_celdata(os, cel->data());
|
||||
write_image(os, cel->image());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace crash
|
||||
} // namespace app
|
23
src/app/crash/document_io.h
Normal file
23
src/app/crash/document_io.h
Normal file
@ -0,0 +1,23 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_CRASH_WRITE_DOCUMENT_H_INCLUDED
|
||||
#define APP_CRASH_WRITE_DOCUMENT_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
class Document;
|
||||
namespace crash {
|
||||
|
||||
void write_document(const std::string& dir, app::Document* doc);
|
||||
|
||||
} // namespace crash
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -12,6 +12,7 @@
|
||||
#include "app/crash/session.h"
|
||||
|
||||
#include "app/context.h"
|
||||
#include "app/crash/document_io.h"
|
||||
#include "app/document.h"
|
||||
#include "app/document_access.h"
|
||||
#include "app/file/file.h"
|
||||
@ -20,6 +21,7 @@
|
||||
#include "base/fs.h"
|
||||
#include "base/path.h"
|
||||
#include "base/process.h"
|
||||
#include "base/string.h"
|
||||
|
||||
namespace app {
|
||||
namespace crash {
|
||||
@ -43,7 +45,7 @@ bool Session::isRunning()
|
||||
bool Session::isEmpty()
|
||||
{
|
||||
for (auto& item : base::list_files(m_path)) {
|
||||
if (base::get_file_extension(item) == "ase")
|
||||
if (base::is_directory(item))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -63,8 +65,15 @@ void Session::create(base::pid pid)
|
||||
|
||||
void Session::removeFromDisk()
|
||||
{
|
||||
base::delete_file(pidFilename());
|
||||
base::remove_directory(m_path);
|
||||
if (base::is_file(pidFilename()))
|
||||
base::delete_file(pidFilename());
|
||||
|
||||
try {
|
||||
base::remove_directory(m_path);
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
// Is not empty
|
||||
}
|
||||
}
|
||||
|
||||
void Session::saveDocumentChanges(app::Document* doc)
|
||||
@ -72,22 +81,15 @@ void Session::saveDocumentChanges(app::Document* doc)
|
||||
DocumentReader reader(doc);
|
||||
DocumentWriter writer(reader);
|
||||
app::Context ctx;
|
||||
std::string fn = base::join_path(m_path,
|
||||
base::convert_to<std::string>(doc->id()) + ".ase");
|
||||
TRACE("DataRecovery: Saving document '%s'...\n", fn.c_str());
|
||||
std::string dir = base::join_path(m_path,
|
||||
base::convert_to<std::string>(doc->id()));
|
||||
TRACE("DataRecovery: Saving document '%s'...\n", dir.c_str());
|
||||
|
||||
FileOp* fop = fop_to_save_document(&ctx,
|
||||
static_cast<app::Document*>(doc), fn.c_str(), "");
|
||||
if (!fop) {
|
||||
TRACE("DataRecovery: Cannot create save file operation\n");
|
||||
return;
|
||||
}
|
||||
if (!base::is_directory(dir))
|
||||
base::make_directory(dir);
|
||||
|
||||
fop_operate(fop, NULL);
|
||||
fop_done(fop);
|
||||
if (fop->has_error())
|
||||
TRACE("DataRecovery: Error saving changes '%s'\n", fop->error.c_str());
|
||||
fop_free(fop);
|
||||
// Save document information
|
||||
write_document(dir, doc);
|
||||
}
|
||||
|
||||
void Session::loadPid()
|
||||
|
Loading…
Reference in New Issue
Block a user