void CLogFile::TrimFile(DWORD maxLines) const
{
if (!PathFileExists(m_logFile.GetWinPath()))
{
CTraceToOutputDebugString::Instance()(L"SVNlog::TrimFile: Log file does not exist.");
return;
}
try
{
CMappedInFile file(m_logFile.GetWinPath(), true);
unsigned char* begin = file.GetWritableBuffer();
unsigned char* end = begin + file.GetSize();
CTraceToOutputDebugString::Instance()(L"SVNlog::TrimFile: File path = %s", m_logFile.GetWinPath());
CTraceToOutputDebugString::Instance()(L"SVNlog::TrimFile: File size = %d bytes", file.GetSize());
CTraceToOutputDebugString::Instance()(L"SVNlog::TrimFile: begin = 0x%p, end = 0x%p", begin, end);
CTraceToOutputDebugString::Instance()(L"SVNlog::TrimFile: Number of bytes between begin and end = %d", end - begin);
if (begin <= (end - 2))
{
CTraceToOutputDebugString::Instance()(L"SVNlog::TrimFile: File is too small to trim.");
return;
}
unsigned char* trimPos = begin;
for (unsigned char* s = end; s != begin; --s)
{
if (*(s - 1) == '\n')
{
if (maxLines == 0)
{
trimPos = s;
break;
}
else
--maxLines;
}
}
if (trimPos == begin)
{
CTraceToOutputDebugString::Instance()(L"SVNlog::TrimFile: No lines need to be trimmed.");
return;
}
CString trimPosStr;
trimPosStr.Format(L"SVNlog::trimPos: %p", trimPos);
CTraceToOutputDebugString::Instance()(trimPosStr);
CString endStr;
endStr.Format(L"SVNlog::endPos: %p", end);
CTraceToOutputDebugString::Instance()(endStr);
size_t newSize = end - trimPos;
memmove(begin, trimPos, newSize);
file.Close(newSize);
}
catch (CStreamException& e)
{
CString errorMsg;
errorMsg.Format(L"SVNlog::TrimFile: CStreamException while trimming log file: %s", e.what());
CTraceToOutputDebugString::Instance()(errorMsg);
}
}