Significantly clean up and simplify AssAttachment

Originally committed to SVN as r6038.
This commit is contained in:
Thomas Goyne 2011-12-22 21:15:28 +00:00
parent eaf436657e
commit 00bc0c7ef8
3 changed files with 50 additions and 218 deletions

View file

@ -34,9 +34,6 @@
/// @ingroup subs_storage /// @ingroup subs_storage
/// ///
////////////
// Includes
#include "config.h" #include "config.h"
#ifndef AGI_PRE #ifndef AGI_PRE
@ -46,87 +43,26 @@
#include "ass_attachment.h" #include "ass_attachment.h"
AssAttachment::AssAttachment(wxString name)
: data(new std::vector<unsigned char>)
/// @brief Constructor , filename(name)
/// @param _name {
/// wxFileName fname(filename);
AssAttachment::AssAttachment(wxString _name) {
// Parse name
filename = _name;
wxFileName fname(GetFileName());
wxString ext = fname.GetExt().Lower(); wxString ext = fname.GetExt().Lower();
wxString name; if (ext == "ttf")
if (ext == "ttf") { filename = fname.GetName() + "_0." + ext;
name = fname.GetName() + "_0." + ext;
}
else name = _name;
// Set data
filename = name;
data = std::tr1::shared_ptr<AttachData> (new AttachData);
} }
/// @brief Destructor
///
AssAttachment::~AssAttachment() {
}
/// @brief Clone
/// @return
///
AssEntry *AssAttachment::Clone() const { AssEntry *AssAttachment::Clone() const {
// New object
AssAttachment *clone = new AssAttachment(filename); AssAttachment *clone = new AssAttachment(filename);
// Copy fields
clone->data = data; clone->data = data;
clone->group = group; clone->group = group;
// Return
return clone; return clone;
} }
/// @brief Get data
/// @return
///
const DataVec &AssAttachment::GetData() {
return data->GetData();
}
/// @brief Add more data
/// @param _data
///
void AssAttachment::AddData(wxString _data) {
data->AddData(_data);
}
/// @brief Finish adding data
///
void AssAttachment::Finish() {
data->Finish();
}
/// @brief Get encoded data to write on file
/// @return
///
const wxString AssAttachment::GetEntryData() const { const wxString AssAttachment::GetEntryData() const {
// Get data
const DataVec &dat = data->GetData();
int pos = 0; int pos = 0;
int size = dat.size(); int size = data->size();
int written = 0; int written = 0;
unsigned char src[3]; unsigned char src[3];
unsigned char dst[4]; unsigned char dst[4];
@ -144,10 +80,10 @@ const wxString AssAttachment::GetEntryData() const {
if (read > 3) read = 3; if (read > 3) read = 3;
// Read source // Read source
src[0] = dat[pos]; src[0] = (*data)[pos];
if (read >= 2) src[1] = dat[pos+1]; if (read >= 2) src[1] = (*data)[pos+1];
else src[1] = 0; else src[1] = 0;
if (read == 3) src[2] = dat[pos+2]; if (read == 3) src[2] = (*data)[pos+2];
else src[2] = 0; else src[2] = 0;
pos += read; pos += read;
@ -173,32 +109,16 @@ const wxString AssAttachment::GetEntryData() const {
} }
} }
// Return
return entryData; return entryData;
} }
/// @brief Extract as a file
/// @param filename
/// @return
///
void AssAttachment::Extract(wxString filename) { void AssAttachment::Extract(wxString filename) {
// Open file
wxFileOutputStream fp(filename); wxFileOutputStream fp(filename);
if (!fp.Ok()) return; if (!fp.Ok()) return;
fp.Write(&data->GetData()[0],data->GetData().size()); fp.Write(&(*data)[0], data->size());
} }
/// @brief Read a file as attachment
/// @param filename
///
void AssAttachment::Import(wxString filename) { void AssAttachment::Import(wxString filename) {
// Data
DataVec &datavec = data->GetData();
// Open file and get size // Open file and get size
wxFileInputStream fp(filename); wxFileInputStream fp(filename);
if (!fp.Ok()) throw "Failed opening file"; if (!fp.Ok()) throw "Failed opening file";
@ -206,102 +126,38 @@ void AssAttachment::Import(wxString filename) {
fp.SeekI(0,wxFromStart); fp.SeekI(0,wxFromStart);
// Set size and read // Set size and read
datavec.resize(size); data->resize(size);
fp.Read(&datavec[0],size); fp.Read(&(*data)[0],size);
} }
/// @brief Get filename
/// @param raw
/// @return
///
wxString AssAttachment::GetFileName(bool raw) { wxString AssAttachment::GetFileName(bool raw) {
// Raw
if (raw || filename.Right(4).Lower() != ".ttf") return filename; if (raw || filename.Right(4).Lower() != ".ttf") return filename;
// Remove stuff after last underscore if it's a font // Remove stuff after last underscore if it's a font
int lastUnder = -1; wxString::size_type last_under = filename.rfind('_');
for (size_t i=0;i<filename.Length();i++) { if (last_under == wxString::npos)
if (filename[i] == '_') lastUnder = i; return filename;
}
// Underline found return filename.Left(last_under) + ".ttf";
wxString final = filename;
if (lastUnder != -1) {
final = filename.Left(lastUnder) + ".ttf";
}
return final;
} }
void AssAttachment::Finish() {
/// @brief Constructor Attachment //////////////////
///
AttachData::AttachData() {
}
/// @brief Destructor
///
AttachData::~AttachData() {
}
/// @brief Get data
/// @return
///
DataVec &AttachData::GetData() {
return data;
}
/// @brief Add data
/// @param data
///
void AttachData::AddData(wxString data) {
buffer += data;
}
/// @brief Finish
///
void AttachData::Finish() {
// Source and dest buffers // Source and dest buffers
unsigned char src[4]; unsigned char src[4];
unsigned char dst[3]; unsigned char dst[3];
int bufPos = 0;
bool ok = true; data->reserve(buffer.size() * 3 / 4);
// Read buffer // Read buffer
while (ok) { for(size_t pos = 0; pos + 1 < buffer.size(); ) {
// Find characters left // Find characters left
int read = buffer.Length() - bufPos; size_t read = std::min<size_t>(buffer.size() - pos, 4);
if (read > 4) read = 4;
int nbytes;
// At least four, proceed normally // Move 4 bytes from buffer to src
if (read >= 2) { for (size_t i = 0; i < read; ++i)
// Move 4 bytes from buffer to src src[i] = (unsigned char)buffer[pos++] - 33;
for (int i=0;i<read;i++) { for (size_t i = read; i < 4; ++i)
src[i] = (unsigned char) buffer[bufPos] - 33; src[i] = 0;
bufPos++;
}
for (int i=read;i<4;i++) src[i] = 0;
ok = true;
nbytes = read-1;
}
// Zero, end
else {
ok = false;
break;
}
// Convert the 4 bytes from source to 3 in dst // Convert the 4 bytes from source to 3 in dst
dst[0] = (src[0] << 2) | (src[1] >> 4); dst[0] = (src[0] << 2) | (src[1] >> 4);
@ -309,14 +165,10 @@ void AttachData::Finish() {
dst[2] = ((src[2] & 0x3) << 6) | (src[3]); dst[2] = ((src[2] & 0x3) << 6) | (src[3]);
// Push into vector // Push into vector
size_t size = data.size(); copy(dst, dst + read - 1, back_inserter(*data));
data.resize(size+nbytes);
for (int i=0;i<nbytes;i++) data[size+i] = dst[i];
} }
// Clear buffer // Clear buffer
buffer.Clear(); buffer.clear();
buffer.Shrink(); buffer.Shrink();
} }

View file

@ -34,9 +34,6 @@
/// @ingroup subs_storage /// @ingroup subs_storage
/// ///
///////////
// Headers
#ifndef AGI_PRE #ifndef AGI_PRE
#include <tr1/memory> #include <tr1/memory>
#include <vector> #include <vector>
@ -44,60 +41,43 @@
#include "ass_entry.h" #include "ass_entry.h"
/// DOCME
typedef std::vector<unsigned char> DataVec;
/// @class AttachData
/// @brief DOCME
class AttachData {
private:
/// DOCME
DataVec data;
/// DOCME
wxString buffer;
public:
AttachData();
~AttachData();
DataVec &GetData();
void AddData(wxString data);
void Finish();
};
/// @class AssAttachment /// @class AssAttachment
/// @brief DOCME /// @brief DOCME
class AssAttachment : public AssEntry { class AssAttachment : public AssEntry {
private: /// Decoded file data
std::tr1::shared_ptr<std::vector<unsigned char> > data;
/// DOCME /// Encoded data which has been read from the script but not yet decoded
std::tr1::shared_ptr<AttachData> data; wxString buffer;
/// DOCME /// Name of the attached file, with SSA font mangling if it is a ttf
wxString filename; wxString filename;
public: public:
const DataVec &GetData(); /// Get the size of the attached file in bytes
size_t GetSize() const { return data->size(); }
void AddData(wxString data); /// Add a line of data (without newline) read from a subtitle file to the
/// buffer waiting to be decoded
void AddData(wxString data) { buffer += data; }
/// Decode all data passed with AddData
void Finish(); void Finish();
/// Extract the contents of this attachment to a file
/// @param filename Path to save the attachment to
void Extract(wxString filename); void Extract(wxString filename);
/// Import the contents of a file as an attachment
/// @param filename Path to import
void Import(wxString filename); void Import(wxString filename);
/// Get the name of the attached file
/// @param raw If false, remove the SSA filename mangling
wxString GetFileName(bool raw=false); wxString GetFileName(bool raw=false);
const wxString GetEntryData() const; const wxString GetEntryData() const;
/// @brief DOCME
///
ASS_EntryType GetType() const { return ENTRY_ATTACHMENT; } ASS_EntryType GetType() const { return ENTRY_ATTACHMENT; }
AssEntry *Clone() const; AssEntry *Clone() const;
AssAttachment(wxString name); AssAttachment(wxString name);
~AssAttachment();
}; };

View file

@ -117,7 +117,7 @@ void DialogAttachments::UpdateList() {
// Add item // Add item
int row = listView->GetItemCount(); int row = listView->GetItemCount();
listView->InsertItem(row,attach->GetFileName(true)); listView->InsertItem(row,attach->GetFileName(true));
listView->SetItem(row,1,PrettySize(attach->GetData().size())); listView->SetItem(row,1,PrettySize(attach->GetSize()));
listView->SetItem(row,2,attach->group); listView->SetItem(row,2,attach->group);
listView->SetItemPtrData(row,wxPtrToUInt(attach)); listView->SetItemPtrData(row,wxPtrToUInt(attach));
} }