mirror of https://github.com/odrling/Aegisub
Optimizations to AssTime::ParseASS()
Originally committed to SVN as r1102.
This commit is contained in:
parent
168d08acc2
commit
83f0c94545
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue