mirror of https://github.com/odrling/Aegisub
Now loading 4.5 MB in 220 ms! :D
Originally committed to SVN as r2062.
This commit is contained in:
parent
e31b424064
commit
16bcf0c942
|
@ -89,13 +89,14 @@ namespace Gorgonsub {
|
||||||
void FindLineBreak(size_t start,size_t end,int &pos,T &character) {
|
void FindLineBreak(size_t start,size_t end,int &pos,T &character) {
|
||||||
pos = -1;
|
pos = -1;
|
||||||
character = 0;
|
character = 0;
|
||||||
T c1 = '\n';
|
size_t c1 = '\n';
|
||||||
T c2 = '\r';
|
size_t c2 = '\r';
|
||||||
|
size_t chr;
|
||||||
for (size_t i=start;i<end;i++) {
|
for (size_t i=start;i<end;i++) {
|
||||||
T chr = buffer[i];
|
chr = buffer[i];
|
||||||
if (chr == c1 || chr == c2) {
|
if (chr == c1 || chr == c2) {
|
||||||
pos = (int)i;
|
pos = (int)i;
|
||||||
character = chr;
|
character = (T)chr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,28 +37,27 @@
|
||||||
#include "gorgonstring.h"
|
#include "gorgonstring.h"
|
||||||
#include "tr1.h"
|
#include "tr1.h"
|
||||||
|
|
||||||
// Prototypes
|
|
||||||
class wxStringTokenizer;
|
|
||||||
|
|
||||||
namespace Gorgonsub {
|
namespace Gorgonsub {
|
||||||
|
|
||||||
// Tokenizer class
|
// Tokenizer class
|
||||||
class Tokenizer {
|
class Tokenizer {
|
||||||
private:
|
private:
|
||||||
shared_ptr<wxStringTokenizer> tkn;
|
wxChar *str;
|
||||||
|
const String &string;
|
||||||
|
const wxChar token;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Tokenizer(String string,String token);
|
Tokenizer(const String &string,wxChar token,size_t start=0);
|
||||||
~Tokenizer();
|
~Tokenizer();
|
||||||
|
|
||||||
bool HasMore();
|
bool HasMoreTokens();
|
||||||
int GetPosition();
|
int GetPosition();
|
||||||
|
|
||||||
|
String GetTheRest();
|
||||||
String GetString(bool trim=false);
|
String GetString(bool trim=false);
|
||||||
int GetInt();
|
int GetInt();
|
||||||
long GetLong();
|
|
||||||
float GetFloat();
|
float GetFloat();
|
||||||
double GetDouble();
|
|
||||||
bool GetBool();
|
bool GetBool();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -93,5 +93,7 @@ namespace Gorgonsub {
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
void WriteNumber(wxChar *&dst,wxChar *temp,int number,int pad,size_t &pos);
|
void WriteNumber(wxChar *&dst,wxChar *temp,int number,int pad,size_t &pos);
|
||||||
|
const wxChar *StringPtrTrim(wxChar *str,size_t len,size_t start);
|
||||||
const wxChar *StringTrim(wxString &str,size_t start);
|
const wxChar *StringTrim(wxString &str,size_t start);
|
||||||
|
bool AsciiStringCompareNoCase(const wxString &str1,const wxChar *str2);
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace Gorgonsub {
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
DialogueASS();
|
DialogueASS();
|
||||||
DialogueASS(String data,int version);
|
DialogueASS(const String &data,int version);
|
||||||
|
|
||||||
// Capabilities
|
// Capabilities
|
||||||
bool HasText() const { return true; }
|
bool HasText() const { return true; }
|
||||||
|
|
|
@ -47,7 +47,7 @@ DialogueASS::DialogueASS()
|
||||||
layer = 0;
|
layer = 0;
|
||||||
isComment = false;
|
isComment = false;
|
||||||
}
|
}
|
||||||
DialogueASS::DialogueASS(String data,int version)
|
DialogueASS::DialogueASS(const String &data,int version)
|
||||||
{
|
{
|
||||||
// Try parsing with all different versions
|
// Try parsing with all different versions
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
@ -79,11 +79,11 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
||||||
else return false;
|
else return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Tokenizer tkn(rawData.Mid(pos),_T(","));
|
Tokenizer tkn(rawData,_T(','),pos);
|
||||||
|
|
||||||
// Get first token and see if it has "Marked=" in it
|
// Get first token and see if it has "Marked=" in it
|
||||||
temp = tkn.GetString(true);
|
temp = tkn.GetString(true);
|
||||||
if (temp.Lower().StartsWith(_T("marked="))) {
|
if (AsciiStringCompareNoCase(temp,_T("marked="))) {
|
||||||
version = 0;
|
version = 0;
|
||||||
layer = 0;
|
layer = 0;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
||||||
effect = temp;
|
effect = temp;
|
||||||
|
|
||||||
// Get text
|
// Get text
|
||||||
text = rawData.Mid(pos+tkn.GetPosition());
|
text = tkn.GetTheRest();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (...) {
|
catch (...) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ bool StyleASS::Parse(String data,int version)
|
||||||
try {
|
try {
|
||||||
// Tokenize
|
// Tokenize
|
||||||
wxString temp;
|
wxString temp;
|
||||||
Tokenizer tkn(data.Trim(false).Mid(6),_T(","));
|
Tokenizer tkn(data,_T(','),6);
|
||||||
|
|
||||||
// Read name, font name and size
|
// Read name, font name and size
|
||||||
name = tkn.GetString(true);
|
name = tkn.GetString(true);
|
||||||
|
@ -131,7 +131,7 @@ bool StyleASS::Parse(String data,int version)
|
||||||
if (version == 2) relativeTo = tkn.GetInt();
|
if (version == 2) relativeTo = tkn.GetInt();
|
||||||
|
|
||||||
// Read it all?
|
// Read it all?
|
||||||
if (tkn.HasMore()) return false;
|
if (tkn.HasMoreTokens()) return false;
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
formatVersion = version;
|
formatVersion = version;
|
||||||
|
|
|
@ -197,7 +197,8 @@ Gorgonsub::String TextFileReader::ActuallyReadLine()
|
||||||
|
|
||||||
// Trim
|
// Trim
|
||||||
if (trim) return String(StringTrim(stringBuffer,startPos));
|
if (trim) return String(StringTrim(stringBuffer,startPos));
|
||||||
return String(stringBuffer.c_str() + startPos);
|
if (startPos) return String(stringBuffer.c_str() + startPos);
|
||||||
|
return stringBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ String Time::GetString(int ms_precision,int h_precision) const
|
||||||
void Time::Parse(const String &data)
|
void Time::Parse(const String &data)
|
||||||
{
|
{
|
||||||
// Break into an array of values
|
// Break into an array of values
|
||||||
std::vector<size_t> values(4);
|
array<size_t,4> values;
|
||||||
size_t last = 0;
|
size_t last = 0;
|
||||||
size_t len = data.Length();
|
size_t len = data.Length();
|
||||||
size_t curIndex = 0;
|
size_t curIndex = 0;
|
||||||
|
|
|
@ -35,14 +35,16 @@
|
||||||
|
|
||||||
#include "tokenizer.h"
|
#include "tokenizer.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
#include "utils.h"
|
||||||
#include <wx/tokenzr.h>
|
#include <wx/tokenzr.h>
|
||||||
using namespace Gorgonsub;
|
using namespace Gorgonsub;
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
Tokenizer::Tokenizer(String string,String token)
|
Tokenizer::Tokenizer(const String &_string,wxChar _token,size_t start)
|
||||||
|
: string(_string), pos(start), token(_token)
|
||||||
{
|
{
|
||||||
tkn = shared_ptr<wxStringTokenizer> (new wxStringTokenizer(string,token,wxTOKEN_RET_EMPTY_ALL));
|
str = const_cast<wxChar*> (string.c_str());
|
||||||
}
|
}
|
||||||
Tokenizer::~Tokenizer()
|
Tokenizer::~Tokenizer()
|
||||||
{
|
{
|
||||||
|
@ -51,9 +53,9 @@ Tokenizer::~Tokenizer()
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
// Has more
|
// Has more
|
||||||
bool Tokenizer::HasMore()
|
bool Tokenizer::HasMoreTokens()
|
||||||
{
|
{
|
||||||
return tkn->HasMoreTokens();
|
return pos < string.Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +63,7 @@ bool Tokenizer::HasMore()
|
||||||
// Get position
|
// Get position
|
||||||
int Tokenizer::GetPosition()
|
int Tokenizer::GetPosition()
|
||||||
{
|
{
|
||||||
return (int)tkn->GetPosition();
|
return (int) pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,44 +71,67 @@ int Tokenizer::GetPosition()
|
||||||
// Get token
|
// Get token
|
||||||
String Tokenizer::GetString(bool trim)
|
String Tokenizer::GetString(bool trim)
|
||||||
{
|
{
|
||||||
wxString str = tkn->GetNextToken();
|
// Has any more?
|
||||||
if (trim) {
|
if (!HasMoreTokens()) throw Exception(Exception::Invalid_Token);
|
||||||
str.Trim(true).Trim(false);
|
|
||||||
|
// Find token
|
||||||
|
size_t len = string.Length();
|
||||||
|
size_t oldPos = pos;
|
||||||
|
bool found = false;
|
||||||
|
for (size_t i=pos;i<len;i++) {
|
||||||
|
if (str[i] == token) {
|
||||||
|
found = true;
|
||||||
|
str[i] = 0;
|
||||||
|
pos = i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return str;
|
if (!found) pos = len;
|
||||||
|
|
||||||
|
// Trimmed
|
||||||
|
if (trim) {
|
||||||
|
return StringPtrTrim(str+oldPos,pos-oldPos-1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Untrimmed
|
||||||
|
return wxString(str+oldPos,pos-oldPos-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
// Get as integer
|
||||||
int Tokenizer::GetInt()
|
int Tokenizer::GetInt()
|
||||||
{
|
{
|
||||||
long value;
|
return StringToInt(GetString());
|
||||||
wxString temp = tkn->GetNextToken();
|
|
||||||
temp.ToLong(&value);
|
|
||||||
return (int) value;
|
|
||||||
}
|
|
||||||
long Tokenizer::GetLong()
|
|
||||||
{
|
|
||||||
long value;
|
|
||||||
wxString temp = tkn->GetNextToken();
|
|
||||||
temp.ToLong(&value);
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
// Get as float
|
||||||
float Tokenizer::GetFloat()
|
float Tokenizer::GetFloat()
|
||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
wxString temp = tkn->GetNextToken();
|
wxString temp = GetString();
|
||||||
temp.ToDouble(&value);
|
temp.ToDouble(&value);
|
||||||
return (float) value;
|
return (float) value;
|
||||||
}
|
}
|
||||||
double Tokenizer::GetDouble()
|
|
||||||
{
|
|
||||||
double value;
|
//////////////////
|
||||||
wxString temp = tkn->GetNextToken();
|
// Get as boolean
|
||||||
temp.ToDouble(&value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
bool Tokenizer::GetBool()
|
bool Tokenizer::GetBool()
|
||||||
{
|
{
|
||||||
long value;
|
return GetInt() != 0;
|
||||||
wxString temp = tkn->GetNextToken();
|
}
|
||||||
temp.ToLong(&value);
|
|
||||||
return value != 0;
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Gets all remaining string data
|
||||||
|
String Tokenizer::GetTheRest()
|
||||||
|
{
|
||||||
|
// Make string
|
||||||
|
size_t size = string.Length()-pos;
|
||||||
|
size_t oldPos = pos;
|
||||||
|
pos += size;
|
||||||
|
return String(str+oldPos,size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,11 +42,14 @@ using namespace Gorgonsub;
|
||||||
// Convert a string to an integer
|
// Convert a string to an integer
|
||||||
int Gorgonsub::StringToInt(const String &str)
|
int Gorgonsub::StringToInt(const String &str)
|
||||||
{
|
{
|
||||||
// TODO: optimize
|
size_t len = str.Length();
|
||||||
if (!str.IsNumber()) return 0;
|
int value = 0;
|
||||||
long temp;
|
int chr;
|
||||||
str.ToLong(&temp);
|
for (size_t i=0;i<len;i++) {
|
||||||
return (int) temp;
|
chr = (int)str[i]-(int)'0';
|
||||||
|
if (chr >= 0 && chr <= 9) value = 10*value+chr;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,29 +134,69 @@ void Gorgonsub::WriteNumber(wxChar *&dst,wxChar *temp,int number,int pad,size_t
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
// Trim a string
|
// Trim a string
|
||||||
const wxChar *Gorgonsub::StringTrim(wxString &str,size_t startPos)
|
const wxChar *Gorgonsub::StringPtrTrim(wxChar *chr,size_t len,size_t startPos)
|
||||||
{
|
{
|
||||||
size_t len = str.Length();
|
// String metrics
|
||||||
|
wxChar *read = chr;
|
||||||
size_t start = startPos;
|
size_t start = startPos;
|
||||||
size_t end = len;
|
size_t end = len;
|
||||||
bool isStart = true;
|
bool isStart = true;
|
||||||
bool isEnd = false;
|
bool isEnd = false;
|
||||||
wxChar cur;
|
wxChar cur;
|
||||||
|
|
||||||
|
// Search for spaces
|
||||||
for (size_t i=start;i<len;i++) {
|
for (size_t i=start;i<len;i++) {
|
||||||
cur = str[i];
|
cur = read[i];
|
||||||
if (isStart)
|
bool isSpace = (cur == ' ');
|
||||||
if (cur == ' ') start++;
|
if (isStart) {
|
||||||
|
if (isSpace) start++;
|
||||||
else isStart = false;
|
else isStart = false;
|
||||||
if (isEnd)
|
}
|
||||||
if (cur != ' ') isEnd = false;
|
if (isEnd) {
|
||||||
|
if (!isSpace) isEnd = false;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (cur == ' ') {
|
if (isSpace) {
|
||||||
isEnd = true;
|
isEnd = true;
|
||||||
end = i;
|
end = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startPos = start;
|
|
||||||
if (isEnd) str[end] = 0;
|
// Apply changes to pointer
|
||||||
return str.c_str() + startPos;
|
if (isEnd) chr[end] = 0;
|
||||||
|
return chr + start;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxChar *Gorgonsub::StringTrim(wxString &str,size_t startPos)
|
||||||
|
{
|
||||||
|
// Get a pointer to the string data
|
||||||
|
wxChar *chr = const_cast<wxChar*> (str.c_str());
|
||||||
|
return StringPtrTrim(chr,str.Length(),startPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// Compares a string to a constant, ignoring case
|
||||||
|
bool Gorgonsub::AsciiStringCompareNoCase(const wxString &str1,const wxChar *str2)
|
||||||
|
{
|
||||||
|
const wxChar *src = str1.c_str();
|
||||||
|
wxChar c1,c2;
|
||||||
|
wxChar mask = 0xFFDF;
|
||||||
|
size_t len = str1.Length();
|
||||||
|
for (size_t i=0;i<len;i++) {
|
||||||
|
// Abort on end of string 2
|
||||||
|
c2 = str2[i];
|
||||||
|
if (!c2) return false;
|
||||||
|
|
||||||
|
// Upper case both, this ONLY WORKS FOR ASCII
|
||||||
|
c1 = src[i] & mask;
|
||||||
|
c2 = c2 & mask;
|
||||||
|
|
||||||
|
// Check them
|
||||||
|
if (c1 != c2) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal strings
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ int main() {
|
||||||
|
|
||||||
// Save subtitles
|
// Save subtitles
|
||||||
cout << "Saving file... ";
|
cout << "Saving file... ";
|
||||||
control.SaveFile(L"subs_out_mid1.ass",L"UTF-8");
|
//control.SaveFile(L"subs_out_mid1.ass",L"UTF-8");
|
||||||
cout << "Done.\n";
|
cout << "Done.\n";
|
||||||
|
|
||||||
// Undo
|
// Undo
|
||||||
|
@ -104,7 +104,7 @@ int main() {
|
||||||
// Save subtitles
|
// Save subtitles
|
||||||
cout << "Saving file... ";
|
cout << "Saving file... ";
|
||||||
timer.Start();
|
timer.Start();
|
||||||
control.SaveFile(L"subs_out.ass",L"UTF-8");
|
//control.SaveFile(L"subs_out.ass",L"UTF-8");
|
||||||
timer.Pause();
|
timer.Pause();
|
||||||
cout << "Done in " << timer.Time() << "ms.\n";
|
cout << "Done in " << timer.Time() << "ms.\n";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue