#include "stdafx.h"
#include "srtcut.h"
#include "SrtReader.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CSrtReader::CSrtReader()
{
}
CSrtReader::~CSrtReader()
{
for( int nTitle = 0; nTitle < m_vpTitles.size(); nTitle++ )
{
struct _tagTitle* pTitle = m_vpTitles[nTitle];
delete pTitle;
}
}
BOOL CSrtReader::ReadFromFile(LPCTSTR lpszFileName)
{
if( lpszFileName == NULL )
return FALSE;
if( _tcslen(lpszFileName) == 0 )
return FALSE;
CStdioFile file;
TRY
{
if( !file.Open(lpszFileName, CFile::modeRead | CFile::typeText) )
return FALSE;
_tagTitle* pTitle = NULL;
CString strLine;
int iLineIndex = 0;
while( file.ReadString(strLine) )
{
strLine.TrimLeft();
strLine.TrimRight();
if( !strLine.IsEmpty() )
{
if( iLineIndex % 3 == 0 )
{
if( pTitle != NULL )
delete pTitle;
pTitle = new _tagTitle;
if( !_TryToReadIndex(strLine, pTitle->iIndex) )
{
}
}
else if( iLineIndex % 3 == 1 )
{
if( !_TryToReadTimestamp(strLine, pTitle->tsStart, pTitle->tsEnd) )
{
}
}
else
{
if( !_TryToReadText(strLine, pTitle->szText) )
{
}
m_vpTitles.push_back(pTitle);
pTitle = NULL;
}
iLineIndex++;
}
}
if( pTitle != NULL )
delete pTitle;
}
CATCH(CFileException, e)
{
}
END_CATCH
return TRUE;
}
int CSrtReader::Cut(short sHour, short sMinute, short sSecond, short sMillsecond)
{
struct _tagTimestamp tsSeparator;
tsSeparator.sHour = sHour;
tsSeparator.sMinute = sMinute;
tsSeparator.sSecond = sSecond;
tsSeparator.sMillsecond = sMillsecond;
if( !m_vtsSeparators.empty() )
{
struct _tagTimestamp& tsReferenceSeparator = m_vtsSeparators[m_vtsSeparators.size() - 1];
if( _LessThan(tsSeparator, tsReferenceSeparator) )
return -1;
}
m_vtsSeparators.push_back(tsSeparator);
return m_vtsSeparators.size();
}
BOOL CSrtReader::SaveToFiles(LPCTSTR lpszFileNameFormat) const
{
if( lpszFileNameFormat == NULL )
return FALSE;
if( _tcslen(lpszFileNameFormat) == 0 )
return FALSE;
if( m_vtsSeparators.empty() )
return FALSE;
TRY
{
CString strTest;
strTest.Format(lpszFileNameFormat, 0);
}
CATCH(CException, e)
{
return FALSE;
}
END_CATCH
struct _tagTimestamp tsOffset;
CString strFileName;
int nTitle = 0;
int nOffset = 0;
tsOffset.sHour = 0;
tsOffset.sMinute = 0;
tsOffset.sSecond = 0;
tsOffset.sMillsecond = 0;
for( int nSeparator = 0; nSeparator < m_vtsSeparators.size(); nSeparator++ )
{
const struct _tagTimestamp& tsSeparator = m_vtsSeparators[nSeparator];
for( ; nTitle < m_vpTitles.size(); nTitle++ )
{
struct _tagTitle* pTitle = m_vpTitles[nTitle];
if( _LessThan(tsSeparator, pTitle->tsStart) )
break;
}
strFileName.Format(lpszFileNameFormat, nSeparator);
_SaveToFile(nOffset, tsOffset, nTitle, strFileName);
nOffset = nTitle;
tsOffset.sHour = tsSeparator.sHour;
tsOffset.sMinute = tsSeparator.sMinute;
tsOffset.sSecond = tsSeparator.sSecond;
tsOffset.sMillsecond = tsSeparator.sMillsecond;
}
strFileName.Format(lpszFileNameFormat, nSeparator);
_SaveToFile(nOffset, tsOffset, m_vpTitles.size(), strFileName);
return TRUE;
}
inline BOOL CSrtReader::_TryToReadIndex(LPCTSTR lpszLine, int &iIndex) const
{
iIndex = _ttoi(lpszLine);
return TRUE;
}
inline BOOL CSrtReader::_TryToReadTimestamp(LPCTSTR lpszLine, _tagTimestamp &tsStart, _tagTimestamp &tsEnd) const
{
_stscanf(lpszLine, _T("%d:%d:%d,%d --> %d:%d:%d,%d"), &tsStart.sHour, &tsStart.sMinute,
&tsStart.sSecond, &tsStart.sMillsecond, &tsEnd.sHour, &tsEnd.sMinute,
&tsEnd.sSecond, &tsEnd.sMillsecond);
return TRUE;
}
inline BOOL CSrtReader::_TryToReadText(LPCTSTR lpszLine, LPTSTR lpszText) const
{
_tcsncpy(lpszText, lpszLine, 1024);
return TRUE;
}
inline BOOL CSrtReader::_LessThan(const struct _tagTimestamp &ts1, const struct _tagTimestamp &ts2) const
{
if( ts2.sHour > ts1.sHour )
return TRUE;
else if( ts2.sHour == ts1.sHour )
{
if( ts2.sMinute > ts1.sMinute )
return TRUE;
else if( ts2.sMinute == ts1.sMinute )
{
if( ts2.sSecond > ts1.sSecond )
return TRUE;
else if( ts2.sSecond == ts1.sSecond )
{
if( ts2.sMillsecond > ts1.sMillsecond )
return TRUE;
}
}
}
return FALSE;
}
inline BOOL CSrtReader::_SaveToFile(int iStartTitle, const _tagTimestamp &tsOffset, int iStopTitle, LPCTSTR lpszFileName) const
{
CStdioFile file;
TRY
{
if( !file.Open(lpszFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText) )
return FALSE;
for( int nTitle = iStartTitle; nTitle < iStopTitle; nTitle++ )
{
const struct _tagTitle* pTitle = m_vpTitles[nTitle];
struct _tagTimestamp tsStart;
struct _tagTimestamp tsEnd;
CString strLine;
_WriteIndex(pTitle->iIndex - iStartTitle, strLine);
file.WriteString(strLine);
file.WriteString(_T("\r\n"));
_TimeSpan(tsStart, pTitle->tsStart, tsOffset);
_TimeSpan(tsEnd, pTitle->tsEnd, tsOffset);
_WriteTimestamp(tsStart, tsEnd, strLine);
file.WriteString(strLine);
file.WriteString(_T("\r\n"));
_WriteText(pTitle->szText, strLine);
file.WriteString(strLine);
file.WriteString(_T("\r\n"));
file.WriteString(_T("\r\n"));
}
file.Close();
}
CATCH(CFileException, e)
{
}
END_CATCH
return TRUE;
}
inline void CSrtReader::_WriteIndex(int iIndex, CString &strLine) const
{
strLine.Format(_T("%d"), iIndex);
}
inline void CSrtReader::_WriteTimestamp(const _tagTimestamp &tsStart, const _tagTimestamp &tsEnd, CString &strLine) const
{
strLine.Format(_T("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d"), tsStart.sHour, tsStart.sMinute,
tsStart.sSecond, tsStart.sMillsecond, tsEnd.sHour, tsEnd.sMinute, tsEnd.sSecond, tsEnd.sMillsecond);
}
inline void CSrtReader::_WriteText(LPCTSTR lpszText, CString &strLine) const
{
strLine = lpszText;
}
inline BOOL CSrtReader::_TimeSpan(_tagTimestamp &ts, const _tagTimestamp &ts1, const _tagTimestamp &ts2) const
{
__int64 i641 = ts1.sHour * 60 * 60 * 1000 + ts1.sMinute * 60 * 1000 + ts1.sSecond * 1000 + ts1.sMillsecond;
__int64 i642 = ts2.sHour * 60 * 60 * 1000 + ts2.sMinute * 60 * 1000 + ts2.sSecond * 1000 + ts2.sMillsecond;
__int64 i64 = i641 - i642;
ts.sHour = i64 / (60 * 60 * 1000);
i64 -= ts.sHour * 60 * 60 * 1000;
ts.sMinute = i64 / (60 * 1000);
i64 -= ts.sMinute * 60 * 1000;
ts.sSecond = i64 / 1000;
i64 -= ts.sSecond * 1000;
ts.sMillsecond = i64;
return TRUE;
}