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) {
|
||||
pos = -1;
|
||||
character = 0;
|
||||
T c1 = '\n';
|
||||
T c2 = '\r';
|
||||
size_t c1 = '\n';
|
||||
size_t c2 = '\r';
|
||||
size_t chr;
|
||||
for (size_t i=start;i<end;i++) {
|
||||
T chr = buffer[i];
|
||||
chr = buffer[i];
|
||||
if (chr == c1 || chr == c2) {
|
||||
pos = (int)i;
|
||||
character = chr;
|
||||
character = (T)chr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,28 +37,27 @@
|
|||
#include "gorgonstring.h"
|
||||
#include "tr1.h"
|
||||
|
||||
// Prototypes
|
||||
class wxStringTokenizer;
|
||||
|
||||
namespace Gorgonsub {
|
||||
|
||||
// Tokenizer class
|
||||
class Tokenizer {
|
||||
private:
|
||||
shared_ptr<wxStringTokenizer> tkn;
|
||||
wxChar *str;
|
||||
const String &string;
|
||||
const wxChar token;
|
||||
size_t pos;
|
||||
|
||||
public:
|
||||
Tokenizer(String string,String token);
|
||||
Tokenizer(const String &string,wxChar token,size_t start=0);
|
||||
~Tokenizer();
|
||||
|
||||
bool HasMore();
|
||||
bool HasMoreTokens();
|
||||
int GetPosition();
|
||||
|
||||
String GetTheRest();
|
||||
String GetString(bool trim=false);
|
||||
int GetInt();
|
||||
long GetLong();
|
||||
float GetFloat();
|
||||
double GetDouble();
|
||||
bool GetBool();
|
||||
};
|
||||
|
||||
|
|
|
@ -93,5 +93,7 @@ namespace Gorgonsub {
|
|||
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);
|
||||
bool AsciiStringCompareNoCase(const wxString &str1,const wxChar *str2);
|
||||
};
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace Gorgonsub {
|
|||
public:
|
||||
// Constructors
|
||||
DialogueASS();
|
||||
DialogueASS(String data,int version);
|
||||
DialogueASS(const String &data,int version);
|
||||
|
||||
// Capabilities
|
||||
bool HasText() const { return true; }
|
||||
|
|
|
@ -47,7 +47,7 @@ DialogueASS::DialogueASS()
|
|||
layer = 0;
|
||||
isComment = false;
|
||||
}
|
||||
DialogueASS::DialogueASS(String data,int version)
|
||||
DialogueASS::DialogueASS(const String &data,int version)
|
||||
{
|
||||
// Try parsing with all different versions
|
||||
bool valid = false;
|
||||
|
@ -79,11 +79,11 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
|||
else return false;
|
||||
|
||||
try {
|
||||
Tokenizer tkn(rawData.Mid(pos),_T(","));
|
||||
Tokenizer tkn(rawData,_T(','),pos);
|
||||
|
||||
// Get first token and see if it has "Marked=" in it
|
||||
temp = tkn.GetString(true);
|
||||
if (temp.Lower().StartsWith(_T("marked="))) {
|
||||
if (AsciiStringCompareNoCase(temp,_T("marked="))) {
|
||||
version = 0;
|
||||
layer = 0;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ bool DialogueASS::Parse(wxString rawData, int version)
|
|||
effect = temp;
|
||||
|
||||
// Get text
|
||||
text = rawData.Mid(pos+tkn.GetPosition());
|
||||
text = tkn.GetTheRest();
|
||||
}
|
||||
|
||||
catch (...) {
|
||||
|
|
|
@ -66,7 +66,7 @@ bool StyleASS::Parse(String data,int version)
|
|||
try {
|
||||
// Tokenize
|
||||
wxString temp;
|
||||
Tokenizer tkn(data.Trim(false).Mid(6),_T(","));
|
||||
Tokenizer tkn(data,_T(','),6);
|
||||
|
||||
// Read name, font name and size
|
||||
name = tkn.GetString(true);
|
||||
|
@ -131,7 +131,7 @@ bool StyleASS::Parse(String data,int version)
|
|||
if (version == 2) relativeTo = tkn.GetInt();
|
||||
|
||||
// Read it all?
|
||||
if (tkn.HasMore()) return false;
|
||||
if (tkn.HasMoreTokens()) return false;
|
||||
|
||||
// Done
|
||||
formatVersion = version;
|
||||
|
|
|
@ -197,7 +197,8 @@ Gorgonsub::String TextFileReader::ActuallyReadLine()
|
|||
|
||||
// Trim
|
||||
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)
|
||||
{
|
||||
// Break into an array of values
|
||||
std::vector<size_t> values(4);
|
||||
array<size_t,4> values;
|
||||
size_t last = 0;
|
||||
size_t len = data.Length();
|
||||
size_t curIndex = 0;
|
||||
|
|
|
@ -35,14 +35,16 @@
|
|||
|
||||
#include "tokenizer.h"
|
||||
#include "exception.h"
|
||||
#include "utils.h"
|
||||
#include <wx/tokenzr.h>
|
||||
using namespace Gorgonsub;
|
||||
|
||||
///////////////
|
||||
// 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()
|
||||
{
|
||||
|
@ -51,9 +53,9 @@ Tokenizer::~Tokenizer()
|
|||
|
||||
////////////
|
||||
// Has more
|
||||
bool Tokenizer::HasMore()
|
||||
bool Tokenizer::HasMoreTokens()
|
||||
{
|
||||
return tkn->HasMoreTokens();
|
||||
return pos < string.Length();
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +63,7 @@ bool Tokenizer::HasMore()
|
|||
// Get position
|
||||
int Tokenizer::GetPosition()
|
||||
{
|
||||
return (int)tkn->GetPosition();
|
||||
return (int) pos;
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,44 +71,67 @@ int Tokenizer::GetPosition()
|
|||
// Get token
|
||||
String Tokenizer::GetString(bool trim)
|
||||
{
|
||||
wxString str = tkn->GetNextToken();
|
||||
if (trim) {
|
||||
str.Trim(true).Trim(false);
|
||||
// Has any more?
|
||||
if (!HasMoreTokens()) throw Exception(Exception::Invalid_Token);
|
||||
|
||||
// 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()
|
||||
{
|
||||
long value;
|
||||
wxString temp = tkn->GetNextToken();
|
||||
temp.ToLong(&value);
|
||||
return (int) value;
|
||||
}
|
||||
long Tokenizer::GetLong()
|
||||
{
|
||||
long value;
|
||||
wxString temp = tkn->GetNextToken();
|
||||
temp.ToLong(&value);
|
||||
return value;
|
||||
return StringToInt(GetString());
|
||||
}
|
||||
|
||||
|
||||
////////////////
|
||||
// Get as float
|
||||
float Tokenizer::GetFloat()
|
||||
{
|
||||
double value;
|
||||
wxString temp = tkn->GetNextToken();
|
||||
wxString temp = GetString();
|
||||
temp.ToDouble(&value);
|
||||
return (float) value;
|
||||
}
|
||||
double Tokenizer::GetDouble()
|
||||
{
|
||||
double value;
|
||||
wxString temp = tkn->GetNextToken();
|
||||
temp.ToDouble(&value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Get as boolean
|
||||
bool Tokenizer::GetBool()
|
||||
{
|
||||
long value;
|
||||
wxString temp = tkn->GetNextToken();
|
||||
temp.ToLong(&value);
|
||||
return value != 0;
|
||||
return GetInt() != 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
|
||||
int Gorgonsub::StringToInt(const String &str)
|
||||
{
|
||||
// TODO: optimize
|
||||
if (!str.IsNumber()) return 0;
|
||||
long temp;
|
||||
str.ToLong(&temp);
|
||||
return (int) temp;
|
||||
size_t len = str.Length();
|
||||
int value = 0;
|
||||
int chr;
|
||||
for (size_t i=0;i<len;i++) {
|
||||
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
|
||||
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 end = len;
|
||||
bool isStart = true;
|
||||
bool isEnd = false;
|
||||
wxChar cur;
|
||||
|
||||
// Search for spaces
|
||||
for (size_t i=start;i<len;i++) {
|
||||
cur = str[i];
|
||||
if (isStart)
|
||||
if (cur == ' ') start++;
|
||||
cur = read[i];
|
||||
bool isSpace = (cur == ' ');
|
||||
if (isStart) {
|
||||
if (isSpace) start++;
|
||||
else isStart = false;
|
||||
if (isEnd)
|
||||
if (cur != ' ') isEnd = false;
|
||||
}
|
||||
if (isEnd) {
|
||||
if (!isSpace) isEnd = false;
|
||||
}
|
||||
else {
|
||||
if (cur == ' ') {
|
||||
if (isSpace) {
|
||||
isEnd = true;
|
||||
end = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
startPos = start;
|
||||
if (isEnd) str[end] = 0;
|
||||
return str.c_str() + startPos;
|
||||
|
||||
// Apply changes to pointer
|
||||
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
|
||||
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";
|
||||
|
||||
// Undo
|
||||
|
@ -104,7 +104,7 @@ int main() {
|
|||
// Save subtitles
|
||||
cout << "Saving file... ";
|
||||
timer.Start();
|
||||
control.SaveFile(L"subs_out.ass",L"UTF-8");
|
||||
//control.SaveFile(L"subs_out.ass",L"UTF-8");
|
||||
timer.Pause();
|
||||
cout << "Done in " << timer.Time() << "ms.\n";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue