From 83f0c945452002892a10d408e4c8a3f09db682f0 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Fri, 20 Apr 2007 22:17:42 +0000 Subject: [PATCH] Optimizations to AssTime::ParseASS() Originally committed to SVN as r1102. --- aegisub/ass_time.cpp | 38 +++++++------------ aegisub/text_file_reader.cpp | 8 ++-- aegisub/utils.cpp | 72 ++++++++++++++++++++++++++++++++++++ aegisub/utils.h | 5 ++- 4 files changed, 94 insertions(+), 29 deletions(-) diff --git a/aegisub/ass_time.cpp b/aegisub/ass_time.cpp index ad4d955b6..c7ad3f8b0 100644 --- a/aegisub/ass_time.cpp +++ b/aegisub/ass_time.cpp @@ -36,10 +36,11 @@ //////////// // Includes -#include "ass_time.h" -#include "vfr.h" #include #include +#include "ass_time.h" +#include "vfr.h" +#include "utils.h" @@ -54,37 +55,26 @@ AssTime::AssTime () { // Parses from ASS // --------------- // Note that this function is atomic, it won't touch the values if it's invalid. -void AssTime::ParseASS (const wxString _text) { +void AssTime::ParseASS (const wxString text) { // Prepare - wxString text = _text; - text.Trim(true); - text.Trim(false); - wxString temp; size_t pos = 0; size_t end = 0; - long th,tm,ts,tms; - double ts_raw; + long th,tm,tms; try { // Hours end = text.Find(_T(':')); - temp = text.Left(end); - if (!temp.ToLong(&th)) throw 0; - pos = end+1; - text[end] = _T(' '); + th = StringToInt(text,0,end); // Minutes - end = text.Find(_T(':')); - temp = text.Mid(pos,end-pos); - if (!temp.ToLong(&tm)) throw 0; + pos = end+1; + while (text[++end] != _T(':')); + tm = StringToInt(text,pos,end); - // Seconds - temp = text.Mid(end+1); - if (!temp.ToDouble(&ts_raw)) throw 0; - - // Split into seconds and fraction - ts = (long int)(ts_raw); - tms = (long int)((ts_raw-ts)*1000+0.5); + // Miliseconds (includes seconds) + pos = end+1; + end = text.Length(); + tms = StringToFix(text,3,pos,end); } // Something went wrong, don't change anything @@ -93,7 +83,7 @@ void AssTime::ParseASS (const wxString _text) { } // OK, set values - time = tms + ts*1000 + tm*60000 + th*3600000; + time = tms + tm*60000 + th*3600000; } diff --git a/aegisub/text_file_reader.cpp b/aegisub/text_file_reader.cpp index 3bee3f7d7..7a68991db 100644 --- a/aegisub/text_file_reader.cpp +++ b/aegisub/text_file_reader.cpp @@ -198,9 +198,9 @@ wxString TextFileReader::ReadLineFromFile() { if (Is16) { char charbuffer[3]; charbuffer[2] = 0; - char aux; wchar_t ch = 0; int n = 0; + size_t len = 0; #ifdef TEXT_READER_USE_STDIO while (ch != L'\n' && !feof(file)) { // Read two chars from file @@ -213,19 +213,19 @@ wxString TextFileReader::ReadLineFromFile() { // Swap bytes for big endian if (swap) { - aux = charbuffer[0]; + register char aux = charbuffer[0]; charbuffer[0] = charbuffer[1]; charbuffer[1] = aux; } // Convert two chars into a widechar and append to string ch = *((wchar_t*)charbuffer); - if (wxbuffer.Length() == bufAlloc) { + if (len >= bufAlloc - 1) { bufAlloc *= 2; wxbuffer.Alloc(bufAlloc); } wxbuffer += ch; - n++; + len++; } } diff --git a/aegisub/utils.cpp b/aegisub/utils.cpp index a8978e6a9..d5ad6e1c2 100644 --- a/aegisub/utils.cpp +++ b/aegisub/utils.cpp @@ -283,3 +283,75 @@ void GetWordBoundaries(const wxString text,IntPairVector &results,int start,int } } } + + +///////////////////// +// String to integer +// wxString::ToLong() is slow and not as flexible +int StringToInt(const wxString &str,size_t start,size_t end) { + // Initialize to zero and get length if end set to -1 + int sign = 1; + int value = 0; + if (end == -1) end = str.Length(); + + for (size_t pos=start;pos _T('9')) break; + + // Shift value to next decimal place and increment the value just read + value = value * 10 + (val - _T('0')); + } + + return value*sign; +} + + + +///////////////////////// +// String to fixed point +int StringToFix(const wxString &str,size_t decimalPlaces,size_t start,size_t end) { + // Parts of the number + int sign = 1; + int major = 0; + int minor = 0; + if (end == -1) end = str.Length(); + bool inMinor = false; + int *dst = &major; + size_t mCount = 0; + + for (size_t pos=start;pos _T('9')) break; + *dst = (*dst * 10) + (val - _T('0')); + mCount++; + } + + // Change minor to have the right number of decimal places + while (mCount > decimalPlaces) { + minor /= 10; + mCount--; + } + while (mCount < decimalPlaces) { + minor *= 10; + mCount++; + } + + // Shift major and return + for (size_t i=0;i