From 16bcf0c942dcd1a0377ed4197226c677295b1a0e Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Sat, 15 Mar 2008 06:21:11 +0000 Subject: [PATCH] Now loading 4.5 MB in 220 ms! :D Originally committed to SVN as r2062. --- aegilib/include/aegilib/fastbuffer.h | 9 ++- aegilib/include/aegilib/tokenizer.h | 15 ++-- aegilib/include/aegilib/utils.h | 2 + aegilib/src/formats/format_ass.h | 2 +- aegilib/src/formats/format_ass_dialogue.cpp | 8 +- aegilib/src/formats/format_ass_style.cpp | 4 +- aegilib/src/text_file_reader.cpp | 3 +- aegilib/src/time.cpp | 2 +- aegilib/src/tokenizer.cpp | 89 +++++++++++++-------- aegilib/src/utils.cpp | 75 +++++++++++++---- aegilib/test/src/main.cpp | 4 +- 11 files changed, 142 insertions(+), 71 deletions(-) diff --git a/aegilib/include/aegilib/fastbuffer.h b/aegilib/include/aegilib/fastbuffer.h index 83fa6b1f5..f53fc263b 100644 --- a/aegilib/include/aegilib/fastbuffer.h +++ b/aegilib/include/aegilib/fastbuffer.h @@ -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 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(); }; diff --git a/aegilib/include/aegilib/utils.h b/aegilib/include/aegilib/utils.h index 3495c1c49..0d5f3ebd8 100644 --- a/aegilib/include/aegilib/utils.h +++ b/aegilib/include/aegilib/utils.h @@ -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); }; diff --git a/aegilib/src/formats/format_ass.h b/aegilib/src/formats/format_ass.h index 4bbaa59c5..cff5a7c86 100644 --- a/aegilib/src/formats/format_ass.h +++ b/aegilib/src/formats/format_ass.h @@ -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; } diff --git a/aegilib/src/formats/format_ass_dialogue.cpp b/aegilib/src/formats/format_ass_dialogue.cpp index 290f35b36..3b850bed1 100644 --- a/aegilib/src/formats/format_ass_dialogue.cpp +++ b/aegilib/src/formats/format_ass_dialogue.cpp @@ -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 (...) { diff --git a/aegilib/src/formats/format_ass_style.cpp b/aegilib/src/formats/format_ass_style.cpp index e99c9bab1..6572de185 100644 --- a/aegilib/src/formats/format_ass_style.cpp +++ b/aegilib/src/formats/format_ass_style.cpp @@ -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; diff --git a/aegilib/src/text_file_reader.cpp b/aegilib/src/text_file_reader.cpp index 45f981efc..8b97f0aed 100644 --- a/aegilib/src/text_file_reader.cpp +++ b/aegilib/src/text_file_reader.cpp @@ -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; } diff --git a/aegilib/src/time.cpp b/aegilib/src/time.cpp index e30de2578..e1749ebeb 100644 --- a/aegilib/src/time.cpp +++ b/aegilib/src/time.cpp @@ -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 values(4); + array values; size_t last = 0; size_t len = data.Length(); size_t curIndex = 0; diff --git a/aegilib/src/tokenizer.cpp b/aegilib/src/tokenizer.cpp index b00e13541..24a2fa2d5 100644 --- a/aegilib/src/tokenizer.cpp +++ b/aegilib/src/tokenizer.cpp @@ -35,14 +35,16 @@ #include "tokenizer.h" #include "exception.h" +#include "utils.h" #include 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 (new wxStringTokenizer(string,token,wxTOKEN_RET_EMPTY_ALL)); + str = const_cast (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;iGetNextToken(); - 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); } diff --git a/aegilib/src/utils.cpp b/aegilib/src/utils.cpp index 1e4e280a5..1ca413943 100644 --- a/aegilib/src/utils.cpp +++ b/aegilib/src/utils.cpp @@ -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= 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 (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