Some MORE refactoring of Athenasub (-_-), which includes breaking loading of files.

Originally committed to SVN as r2472.
This commit is contained in:
Rodrigo Braz Monteiro 2008-11-21 04:13:33 +00:00
parent ad4a9daf75
commit 248dbddfdf
18 changed files with 361 additions and 41 deletions

View file

@ -328,7 +328,7 @@
>
</File>
<File
RelativePath=".\include\aegilib\format_manager.h"
RelativePath=".\src\format_manager.h"
>
</File>
<Filter
@ -447,6 +447,14 @@
<Filter
Name="File IO"
>
<File
RelativePath=".\src\reader.cpp"
>
</File>
<File
RelativePath=".\src\reader.h"
>
</File>
<File
RelativePath=".\src\text_file_reader.cpp"
>
@ -487,6 +495,14 @@
RelativePath=".\src\text_writer.h"
>
</File>
<File
RelativePath=".\src\writer.cpp"
>
</File>
<File
RelativePath=".\src\writer.h"
>
</File>
</Filter>
</Files>
<Globals>

View file

@ -49,6 +49,8 @@ namespace Athenasub {
// Prototypes
class Range;
class Reader;
class Writer;
class ISelection;
class IController;
class IView;
@ -113,7 +115,7 @@ namespace Athenasub {
virtual void DispatchNotifications(Notification notification) const = 0;
virtual void Clear() = 0;
virtual void Load(wxInputStream &input,Format format=Format(),const String encoding="") = 0;
virtual void Load(Reader &input,Format format=Format()) = 0;
virtual Section AddSection(String name) = 0;
virtual Section GetMutableSection(String name) = 0;
@ -125,7 +127,7 @@ namespace Athenasub {
virtual Controller CreateController() = 0;
virtual void AddListener(View listener) = 0;
virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") const = 0;
virtual void Save(Writer &output,Format format=Format()) const = 0;
virtual String GetUndoMessage(const String owner="") const = 0;
virtual String GetRedoMessage(const String owner="") const = 0;
@ -316,6 +318,9 @@ namespace Athenasub {
virtual Dialogue CreateDialogue() const = 0;
virtual Style CreateStyle() const = 0;
virtual bool IsBinary() const = 0;
virtual float CanReadFile(Reader &reader) const = 0; // Should return a float from 0.0f to 1.0f indicating how certain it is that it can read it
};
@ -324,8 +329,8 @@ namespace Athenasub {
public:
virtual ~IFormatHandler() {}
virtual void Load(IModel &model,wxInputStream &file,const String encoding) = 0;
virtual void Save(const IModel &model,wxOutputStream &file,const String encoding) const = 0;
virtual void Load(IModel &model,Reader &file) = 0;
virtual void Save(const IModel &model,Writer &file) const = 0;
};

View file

@ -38,6 +38,8 @@
#include "actionlist.h"
#include "format_manager.h"
#include "selection.h"
#include "reader.h"
#include "writer.h"
using namespace Athenasub;
@ -61,9 +63,24 @@ ActionList CController::CreateActionList(const String title,const String owner,b
// Load a file
void CController::LoadFile(const String filename,const String encoding)
{
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
wxFFileInputStream stream(filename.GetWxString());
model->Load(stream,handler,encoding);
Reader reader(filename,encoding);
std::vector<Format> handlers = FormatManager::GetCompatibleFormatList(reader);
size_t len = handlers.size();
bool success = false;
for (size_t i=0;i<len;i++) {
try {
model->Load(reader,handlers[i]);
success = true;
break;
} catch (Athenasub::Exception &e) {
// Ignore exception
(void) e;
}
}
if (!success) {
THROW_ATHENA_EXCEPTION_MSG(Exception::No_Format_Handler,"Could not locate a suitable format handler.");
}
}
@ -71,9 +88,9 @@ void CController::LoadFile(const String filename,const String encoding)
// Save a file
void CController::SaveFile(const String filename,const String encoding)
{
const Format handler = FormatManager::GetFormatFromFilename(filename,true);
wxFFileOutputStream stream(filename.GetWxString());
model->Save(stream,handler,encoding);
Format handler = FormatManager::GetFormatFromFilename(filename,true);
Writer writer(filename,encoding);
model->Save(writer,handler);
}

View file

@ -55,8 +55,8 @@ namespace Athenasub {
public:
//CFormatHandler(IModel& _model) : model(_model) {}
virtual void Load(IModel &model,wxInputStream &file,const String encoding) = 0;
virtual void Save(const IModel &model,wxOutputStream &file,const String encoding) const = 0;
virtual void Load(IModel &model,Reader &file) = 0;
virtual void Save(const IModel &model,Writer &file) const = 0;
};
}

View file

@ -35,6 +35,8 @@
#include "format_manager.h"
#include "formats/format_ass.h"
#include "reader.h"
#include "text_reader.h"
#include <wx/string.h>
using namespace Athenasub;
@ -56,9 +58,9 @@ void FormatManager::AddFormat(const Format format)
// Initialize all built-in formats
void FormatManager::InitializeFormats()
{
formats.push_back(Format(new FormatASS()));
formats.push_back(Format(new FormatSSA()));
formats.push_back(Format(new FormatASS2()));
AddFormat(Format(new FormatASS()));
AddFormat(Format(new FormatSSA()));
AddFormat(Format(new FormatASS2()));
}
@ -80,7 +82,7 @@ int FormatManager::GetFormatCount()
////////////
// By index
const Format FormatManager::GetFormatByIndex(const int index)
Format FormatManager::GetFormatByIndex(const int index)
{
try {
return formats.at(index);
@ -93,7 +95,7 @@ const Format FormatManager::GetFormatByIndex(const int index)
///////////////
// By filename
const Format FormatManager::GetFormatFromFilename(const String &filename,bool read)
Format FormatManager::GetFormatFromFilename(const String &filename,bool read)
{
size_t len = formats.size();
for (size_t i=0;i<len;i++) {
@ -111,7 +113,7 @@ const Format FormatManager::GetFormatFromFilename(const String &filename,bool re
//////////////////
// By format name
const Format FormatManager::GetFormatFromName(const String &name)
Format FormatManager::GetFormatFromName(const String &name)
{
size_t len = formats.size();
for (size_t i=0;i<len;i++) {
@ -120,3 +122,35 @@ const Format FormatManager::GetFormatFromName(const String &name)
return Format();
}
///////////////////////////////////////////////////////
// Get a list of all formats compatible with this file
std::vector<Format> FormatManager::GetCompatibleFormatList(Reader &reader)
{
// Find all compatible formats and store them with their certainty
std::vector<std::pair<float,Format> > results;
size_t len = formats.size();
for (size_t i=0;i<len;i++) {
reader.Rewind();
float certainty = formats[i]->CanReadFile(reader);
if (certainty > 0.0f) {
results.push_back(std::pair<float,Format>(certainty,formats[i]));
}
}
// Functor to sort them
struct Comp {
bool operator() (const std::pair<float,Format> &p1,const std::pair<float,Format> &p2) {
return p1.first > p2.first;
}
};
// Sort results and store them
sort(results.begin(),results.end(),Comp());
len = results.size();
std::vector<Format> finalResults;
for (size_t i=0;i<len;i++) {
finalResults.push_back(results[i].second);
}
return finalResults;
}

View file

@ -38,6 +38,8 @@
namespace Athenasub {
class Reader;
// Format manager class
class FormatManager {
private:
@ -50,9 +52,10 @@ namespace Athenasub {
static void ClearFormats();
static int GetFormatCount();
static const Format GetFormatByIndex(const int index);
static const Format GetFormatFromFilename(const String &filename,bool read);
static const Format GetFormatFromName(const String &name);
static Format GetFormatByIndex(const int index);
static Format GetFormatFromFilename(const String &filename,bool read);
static Format GetFormatFromName(const String &name);
static std::vector<Format> GetCompatibleFormatList(Reader &reader);
};
}

View file

@ -39,7 +39,9 @@
#include "format_ass_plain.h"
#include "version.h"
#include "../text_reader.h"
#include "../reader.h"
#include "../text_writer.h"
#include "../writer.h"
#include <iostream>
#include <algorithm>
#include <wx/tokenzr.h>
@ -88,6 +90,19 @@ StringArray FormatASS2::GetWriteExtensions() const
}
//////////////////////////////////
// Check if it can read this file
float FormatASSFamily::CanReadFile(Reader &reader) const
{
shared_ptr<TextReader> file = reader.GetTextReader();
if (!file->HasMoreLines()) return 0;
String line = file->ReadLineFromFile();
if (line == "[Script Info]") return 1;
return 0;
}
///////////////
// Constructor
FormatHandlerASS::FormatHandlerASS(int version)
@ -105,10 +120,10 @@ FormatHandlerASS::~FormatHandlerASS()
///////////////
// Load a file
void FormatHandlerASS::Load(IModel &model,wxInputStream &file,const String encoding)
void FormatHandlerASS::Load(IModel &model,Reader &file)
{
// Make text file reader
shared_ptr<TextReader> reader = TextReader::GetReader(file,encoding);
// Get text file reader
shared_ptr<TextReader> reader = file.GetTextReader();
// Variables
int version = 1;
@ -148,10 +163,10 @@ void FormatHandlerASS::Load(IModel &model,wxInputStream &file,const String encod
/////////////////////
// Save file to disc
void FormatHandlerASS::Save(const IModel& model,wxOutputStream &file,const String encoding) const
void FormatHandlerASS::Save(const IModel& model,Writer &file) const
{
// Make text file writer
shared_ptr<TextWriter> writer = TextWriter::GetWriter(file,encoding);
shared_ptr<TextWriter> writer = file.GetTextWriter();
// Set up list of sections to write
StringArray sections;

View file

@ -62,8 +62,8 @@ namespace Athenasub {
FormatHandlerASS(int version);
~FormatHandlerASS();
void Load(IModel &model,wxInputStream &file,const String encoding);
void Save(const IModel &model,wxOutputStream &file,const String encoding) const;
void Load(IModel &model,Reader &file);
void Save(const IModel &model,Writer &file) const;
};
// Advanced Substation Alpha format base class
@ -84,9 +84,11 @@ namespace Athenasub {
virtual int GetTimingPrecision() const { return 10; }
virtual int GetMaxTime() const { return 35999990; }
bool IsBinary() const { return false; }
Dialogue CreateDialogue() const { return Dialogue(new DialogueASS()); }
Style CreateStyle() const { return Style(new StyleASS()); }
float CanReadFile(Reader &reader) const;
};
// Substation Alpha

View file

@ -109,7 +109,7 @@ void CModel::ProcessActionList(CActionList &_actionList,int type)
//////////////////
// Load subtitles
void CModel::Load(wxInputStream &input,const Format _format,const String encoding)
void CModel::Load(Reader &input,const Format _format)
{
// Autodetect format
if (!_format) {
@ -127,7 +127,7 @@ void CModel::Load(wxInputStream &input,const Format _format,const String encodin
Clear();
// Load
handler->Load(*this,input,encoding);
handler->Load(*this,input);
// Set the format
format = _format;
@ -136,7 +136,7 @@ void CModel::Load(wxInputStream &input,const Format _format,const String encodin
//////////////////
// Save subtitles
void CModel::Save(wxOutputStream &output,const Format _format,const String encoding) const
void CModel::Save(Writer &output,const Format _format) const
{
// Use another format
if (_format && _format != format) {
@ -149,7 +149,7 @@ void CModel::Save(wxOutputStream &output,const Format _format,const String encod
if (!handler) THROW_ATHENA_EXCEPTION(Exception::No_Format_Handler);
// Load
handler->Save(*this,output,encoding);
handler->Save(*this,output);
}

View file

@ -36,7 +36,6 @@
#pragma once
#include <list>
#include <vector>
#include <wx/wfstream.h>
#include "athenasub.h"
#include "actionlist.h"
#include "section.h"
@ -80,7 +79,7 @@ namespace Athenasub {
void DispatchNotifications(Notification notification) const;
void Clear();
void Load(wxInputStream &input,Format format=Format(),const String encoding="");
void Load(Reader &input,Format format=Format());
Section AddSection(String name);
Section GetMutableSection(String name);
@ -94,7 +93,7 @@ namespace Athenasub {
Format GetFormat() const { return format; }
void AddListener(View listener);
void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") const;
void Save(Writer &output,Format format=Format()) const;
ConstSection GetSection(String name) const;
ConstSection GetSectionByIndex(size_t index) const;

57
athenasub/src/reader.cpp Normal file
View file

@ -0,0 +1,57 @@
// Copyright (c) 2008, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#include "reader.h"
#include "text_reader.h"
#include <wx/wfstream.h>
using namespace Athenasub;
Reader::Reader(String filename,String encoding)
{
stream = shared_ptr<wxFFileInputStream>(new wxFFileInputStream(filename.GetWxString()));
text = TextReader::GetReader(*stream,encoding);
}
shared_ptr<TextReader> Athenasub::Reader::GetTextReader()
{
return text;
}
void Reader::Rewind()
{
text->Rewind();
}

60
athenasub/src/reader.h Normal file
View file

@ -0,0 +1,60 @@
// Copyright (c) 2008, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
// Headers
#include "athenasub.h"
class wxFFileInputStream;
namespace Athenasub {
class TextReader;
class Reader {
private:
shared_ptr<TextReader> text;
String filename;
shared_ptr<wxFFileInputStream> stream;
public:
Reader(String filename,String encoding="");
shared_ptr<TextReader> GetTextReader();
String GetFileName();
void Rewind();
};
}

View file

@ -44,8 +44,7 @@ namespace Athenasub {
// Dialogue class
class CDialogue : public IDialogue {
private:
static const bool dodgeWarning = true;
void ThrowUnsupported() const { if (dodgeWarning) THROW_ATHENA_EXCEPTION(Exception::Unsupported_Format_Feature); }
#define ThrowUnsupported() THROW_ATHENA_EXCEPTION(Exception::Unsupported_Format_Feature)
static const String& EmptyString();
public:

View file

@ -44,8 +44,7 @@ namespace Athenasub {
// Style class
class CStyle : public IStyle {
private:
static const bool dodgeWarning = true;
void ThrowUnsupported() const { if (dodgeWarning) THROW_ATHENA_EXCEPTION(Exception::Unsupported_Format_Feature); }
#define ThrowUnsupported() THROW_ATHENA_EXCEPTION(Exception::Unsupported_Format_Feature)
public:
// Destructor

View file

@ -48,7 +48,7 @@ Athenasub::TextReaderCache::TextReaderCache(shared_ptr<TextReader> src)
String TextReaderCache::ReadLineFromFile()
{
if (bufferPos == buffer.size()) {
LoadMore(1);
LoadMore(1000000);
}
if (bufferPos == buffer.size()) {
return "";

53
athenasub/src/writer.cpp Normal file
View file

@ -0,0 +1,53 @@
// Copyright (c) 2008, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#include "writer.h"
#include "text_writer.h"
#include <wx/wfstream.h>
using namespace Athenasub;
Writer::Writer(String filename,String encoding)
{
stream = shared_ptr<wxFFileOutputStream>(new wxFFileOutputStream(filename.GetWxString()));
text = TextWriter::GetWriter(*stream,encoding);
}
shared_ptr<TextWriter> Writer::GetTextWriter()
{
return text;
}

58
athenasub/src/writer.h Normal file
View file

@ -0,0 +1,58 @@
// Copyright (c) 2008, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
// Headers
#include "athenasub.h"
class wxFFileOutputStream;
namespace Athenasub {
class TextWriter;
class Writer {
private:
shared_ptr<TextWriter> text;
shared_ptr<wxFFileOutputStream> stream;
public:
Writer(String filename,String encoding="");
shared_ptr<TextWriter> GetTextWriter();
};
}

View file

@ -61,6 +61,7 @@
/>
<Tool
Name="VCLinkerTool"
OutputFile="../../bin/unit_test_d.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
@ -134,6 +135,7 @@
/>
<Tool
Name="VCLinkerTool"
OutputFile="../../bin/unit_test.exe"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
@ -161,6 +163,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine=""
/>
</Configuration>
</Configurations>