Optimizations to AssTime::ParseASS()

Originally committed to SVN as r1102.
This commit is contained in:
Rodrigo Braz Monteiro 2007-04-20 22:17:42 +00:00
parent 168d08acc2
commit 83f0c94545
4 changed files with 94 additions and 29 deletions

View file

@ -36,10 +36,11 @@
////////////
// Includes
#include "ass_time.h"
#include "vfr.h"
#include <fstream>
#include <algorithm>
#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;
}

View file

@ -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++;
}
}

View file

@ -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<end;pos++) {
// Get value and check if it's a number
int val = (int)(str[pos]);
if (val == _T(' ') || val == _T('\t')) continue;
if (val == _T('-')) sign = -1;
if (val < _T('0') || val > _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<end;pos++) {
// Get value and check if it's a number
int val = (int)(str[pos]);
if (val == _T(' ') || val == _T('\t')) continue;
if (val == _T('-')) sign = -1;
// Switch to minor
if (val == _T('.') || val == _T(',')) {
if (inMinor) break;
inMinor = true;
dst = &minor;
mCount = 0;
continue;
}
if (val < _T('0') || val > _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<decimalPlaces;i++) major *= 10;
return (major + minor)*sign;
}

View file

@ -67,6 +67,8 @@ wxString PrettySize(int bytes);
wxMenuItem *AppendBitmapMenuItem (wxMenu* parentMenu,int id,wxString text,wxString help,wxBitmap bmp,int pos=-1);
int SmallestPowerOf2(int x);
void GetWordBoundaries(const wxString text,IntPairVector &results,int start=0,int end=-1);
int StringToInt(const wxString &str,size_t start=0,size_t end=-1);
int StringToFix(const wxString &str,size_t decimalPlaces,size_t start=0,size_t end=-1);
//////////
@ -87,7 +89,8 @@ void GetWordBoundaries(const wxString text,IntPairVector &results,int start=0,in
#ifdef __VISUALC__
#define FORCEINLINE __forceinline
#else
#define FORCEINLINE inline // __attribute__((always_inline)) gives me errors on g++ ~amz
#define FORCEINLINE inline
// __attribute__((always_inline)) gives me errors on g++ ~amz
#endif
#endif