project64/Source/Common/Log.cpp

197 lines
4.6 KiB
C++

#include "Log.h"
#include "Platform.h"
#include "path.h"
#include <stdarg.h>
#include <stdio.h>
CLog::CLog(void) :
m_FlushOnWrite(false),
m_TruncateFileLog(true),
m_MaxFileSize(MAX_FILE_SIZE),
m_FileChangeSize(0),
m_FileSize(0)
{
}
CLog::~CLog(void)
{
}
bool CLog::Open(const char * FileName, LOG_OPEN_MODE mode /* = Log_New */)
{
if (FileName == nullptr)
{
return false;
}
CPath File(FileName);
if (m_hLogFile.IsOpen())
{
m_hLogFile.Close();
}
uint32_t nOpenFlags = CFile::modeReadWrite | CFile::modeCreate;
if (mode == Log_Append)
{
nOpenFlags |= CFile::modeNoTruncate;
}
if (!m_hLogFile.Open(File, nOpenFlags))
{
return false;
}
m_FileName = (const char *)File;
m_hLogFile.Seek(0, mode == Log_Append ? CFile::end : CFile::begin);
m_FileSize = mode == Log_Append ? (uint32_t)m_hLogFile.GetLength() : 0;
return true;
}
void CLog::Close(void)
{
if (m_hLogFile.IsOpen())
{
m_hLogFile.Close();
}
}
void CLog::LogF(const char * Message, ...)
{
va_list ap;
va_start(ap, Message);
LogArgs(Message, ap);
va_end(ap);
}
void CLog::LogArgs(const char * Message, va_list & args)
{
if (!m_hLogFile.IsOpen())
{
return;
}
try
{
size_t nlen = _vscprintf(Message, args) + 1;
char * Msg = (char *)alloca(nlen * sizeof(char));
Msg[nlen - 1] = 0;
if (Msg != nullptr)
{
vsprintf(Msg, Message, args);
Log(Msg);
}
}
catch (...)
{
Log("Invalid message format");
}
}
void CLog::Log(const char * Message)
{
if (!m_hLogFile.IsOpen())
{
return;
}
uint32_t message_len = (uint32_t)strlen(Message);
m_hLogFile.Write(Message, message_len);
if (m_FlushOnWrite)
{
m_hLogFile.Flush();
}
m_FileSize += message_len;
if (m_TruncateFileLog && m_FileSize > m_MaxFileSize)
{
// Check file size
m_FileSize = (uint32_t)m_hLogFile.GetLength();
// If larger then maximum size then
if (m_FileSize > m_MaxFileSize)
{
if (!m_FlushOnWrite)
{
m_hLogFile.Flush();
m_FileSize = (uint32_t)m_hLogFile.GetLength();
}
uint32_t end = (uint32_t)m_hLogFile.SeekToEnd();
// Move to reduce size
m_hLogFile.Seek((end - m_MaxFileSize) + m_FileChangeSize, CFile::begin);
// Find next end of line
uint32_t NextEnter = 0, dwRead = 0;
do
{
uint8_t Data[300];
dwRead = m_hLogFile.Read(Data, sizeof(Data));
if (dwRead == 0)
{
break;
}
for (int i = 0; i < sizeof(Data); i++)
{
if (Data[i] == '\n')
{
NextEnter += (i + 1);
dwRead = 0;
break;
}
}
NextEnter += dwRead;
} while (dwRead != 0);
// Copy content of log to the new file
uint32_t ReadPos = (end - m_MaxFileSize) + m_FileChangeSize + NextEnter;
uint32_t SizeToRead, WritePos = 0;
do
{
enum
{
fIS_MvSize = 0x5000
};
unsigned char Data[fIS_MvSize + 1];
SizeToRead = end - ReadPos;
if (SizeToRead > fIS_MvSize)
{
SizeToRead = fIS_MvSize;
}
m_hLogFile.Seek(ReadPos, CFile::begin);
dwRead = m_hLogFile.Read(Data, SizeToRead);
m_hLogFile.Seek(WritePos, CFile::begin);
if (!m_hLogFile.Write(Data, dwRead))
{
//BreakPoint(__FILE__,__LINE__);
break;
}
ReadPos += dwRead;
WritePos += dwRead;
} while (SizeToRead > 0);
// Clean up
m_hLogFile.SetEndOfFile();
m_hLogFile.Flush();
m_FileSize = (uint32_t)m_hLogFile.GetLength();
} // end if
}
}
bool CLog::Empty(void)
{
if (!m_hLogFile.IsOpen())
{
return true;
}
if (m_hLogFile.GetLength() == 0)
{
return true;
}
return false;
}