⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logger.cpp

📁 机器人程序
💻 CPP
字号:
// Logger.cpp - by Robin Hewitt, 2005
// http://www.robinhewitt.com/mavis
// This is free software. See license at the bottom
// of this file for details.
//

#include "MavisErr.h"
#include "Logger.h"
#include "Params.h"
#include "Mavis.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>


//////////////////////////////////////////////////////////////
// Implementation of the Logger class
//

const char * Logger::DEFAULT_LOGDIR = "./log";
const char * Logger::LOG_FILE = "mavis.log";
const char * Logger::LOG_ENTRY_DELIMITER = "##################################################\n";


//////////////////
//  FUNCTION:   Constructor
//
Logger::Logger(Mavis * pMv)
{
	pMavis = pMv;

	
	Params * pParams = pMavis->getParams();


	// Get and store the path for the log directory
	int nChar;
	const char * tmp = pParams->getStringValue("log", "logDir");
	if(!tmp)
	{
		nChar = strlen(DEFAULT_LOGDIR);
		logDir = new char[nChar+1];
		strcpy(logDir, DEFAULT_LOGDIR);
	}
	else
	{
		nChar = strlen(tmp);
		logDir = new char[nChar+1];
		strcpy(logDir, tmp);
	}
	
	if( '/' == logDir[nChar] || '\\' == logDir[nChar] ) logDir[nChar] = '\0';


	// Find out if the log directory exists
	int fileAttrib = GetFileAttributes(logDir);
	if(0xFFFFFFFF == fileAttrib || !(FILE_ATTRIBUTE_DIRECTORY&fileAttrib) )
	{
		if( ENOENT == GetLastError() )
		{
			// Log directory doesn't exist, so try to create it
			BOOL dirCreated = CreateDirectory (
			logDir,    // directory path string
			NULL       // use default security attributes
			);

			if( !dirCreated )
				throw MavisErr("Can\'t create log directory %s.", logDir);
		}
	}


	// Open the log file and save file pointer
	char * logFilename = new char [2 + strlen(logDir) + strlen(LOG_FILE)];
	sprintf(logFilename, "%s/%s", logDir, LOG_FILE);
	pLogFile = fopen(logFilename, "a+");

	// Make sure the logfile pointer is valid
	if( !pLogFile )
	{
		MavisErr e (
			"Can't open Mavis logfile, \"%s\".",
			logFilename
		);
		delete[] logFilename;
		throw e;
	}	


	// Limit number of Mavis-run cycles in the log.
	// This keeps the log file from getting too big.
	bool isValid;
	int nMaxRuns = pParams->getIntValue("log", "nRunsToKeep", &isValid);
	if(nMaxRuns < 1) nMaxRuns = 10;  // use default value
	int nRuns = 0;
	char buf[10000];
	buf[0] = '\0';

	rewind(pLogFile);
	while( fgets(buf, 10000, pLogFile) )
		if( !strcmp(buf, LOG_ENTRY_DELIMITER) )
			++nRuns;

	if( (nRuns > nMaxRuns-1) && (nMaxRuns>1) )
	{
		// calculate how many to lop off the front
		int nDelete = 1 + nRuns - nMaxRuns;

		// position file pointer just after the last run to delete
		nRuns = 0;
		rewind(pLogFile);
		while( fgets(buf, 10000, pLogFile) )
		{
			if( !strcmp(buf, LOG_ENTRY_DELIMITER) )
				++nRuns;

			if(nRuns >= nDelete) break;
		}

		// find first non-blank line
		char * p;
		while( p = fgets(buf, 10000, pLogFile) )
			if(buf[1]) break;

		if(p)
		{
			// open a temp file
			char * tmpFilename = new char [100];
			sprintf(tmpFilename, "__tmplog2__");
			FILE * pTmpFile = fopen(tmpFilename, "w");
			

			// copy current buffer plus remainder of log
			fputs(buf, pTmpFile);
			while( fgets(buf, 10000, pLogFile) )
				fputs(buf, pTmpFile);


			// replace the log file with the temp file
			fclose(pLogFile);
			fclose(pTmpFile);
			remove(logFilename);
			rename(tmpFilename, logFilename);
			pLogFile = fopen(logFilename, "a+");

			delete[] tmpFilename;
		}
	}
	else if(nMaxRuns <= 1)
	{
		fclose(pLogFile);
		pLogFile = fopen(logFilename, "w+");
	}
	

	delete[] logFilename;
}


//////////////////
//  FUNCTION:   Destructor
//
Logger::~Logger()
{
	if(pLogFile)
	{
		writelnToLog(LOG_ENTRY_DELIMITER);
		fclose(pLogFile);
	}
	delete[] logDir;
}


//////////////////
//  FUNCTION:   writeToLog
//
void Logger::writeToLog(const char * pStr, ...)
{
	va_list args;
	va_start(args, pStr);

	vfprintf(pLogFile, pStr, args);
	fflush(pLogFile);

	va_end(args);
}


//////////////////
//  FUNCTION:   writelnToLog
//
void Logger::writelnToLog(const char * pStr, ...)
{
	va_list args;
	va_start(args, pStr);

	vfprintf(pLogFile, pStr, args);
	fprintf(pLogFile, "\n");
	fflush(pLogFile);

	va_end(args);
}


//////////////////
//  FUNCTION:   writeFrame
//
void Logger::writeFrame(BYTE * frameBuf, const char * filename)
{ writeFrame(frameBuf, (char *)NULL, filename); }


//////////////////
//  FUNCTION:   writeFrame(subdirectory)
//
void Logger::writeFrame(BYTE * frameBuf, const char * subdir, const char * inpFilename)
{
	char szFilename[MAX_PATH];
	char * filename = new char[1+strlen(inpFilename)];
	strcpy(filename, inpFilename);

	// check for .bmp file extension and remove it if found
	char * bmpExtension = strstr(filename, ".bmp");
	if(bmpExtension) *bmpExtension = '\0';


	// create file path
	if(subdir)
	{
		char * pathname = new char[2+ strlen(logDir) + strlen(subdir)];
		sprintf(pathname, "%s/%s", logDir, subdir);

		// does subdirectory exist?
		int fileAttrib = GetFileAttributes(pathname);
		if(0xFFFFFFFF == fileAttrib)
		{
			if( ENOENT == GetLastError() )
			{
				// the subdirectory doesn't exist, so try to create it
				BOOL dirCreated = CreateDirectory (
					pathname,  // directory
					NULL       // use default security attributes
				);

				// error: failed to create subdirectory
				if( !dirCreated )
				{
					writelnToLog(
						"Can\'t create subdirectory %s for bitmap %s",
						subdir, inpFilename
					);
					delete[] filename;
					delete[] pathname;
					return;
				}
			}
		}
		delete[] pathname;

		// full path for file
		sprintf(szFilename, "%s/%s/%s.bmp", logDir, subdir, filename);
	}
	else
		sprintf(szFilename, "%s/%s.bmp", logDir, filename);

	delete[] filename;


	// Create the bitmap file
	HANDLE hf = CreateFile(
		szFilename,
		GENERIC_WRITE,
		FILE_SHARE_READ,
		NULL,
		CREATE_ALWAYS,
		NULL,
		NULL
	);

	if( INVALID_HANDLE_VALUE == hf )
	{
		int err = GetLastError();
		writelnToLog("Can\'t create file %s: %s", szFilename, strerror(err));
		return;
	}

	// Get data for bitmap
	int nBytes = pMavis->getFrameSize();
	int width = pMavis->getImgWidth();
	int height = pMavis->getImgHeight();


	// Write out the bitmap file header
    BITMAPFILEHEADER bfh;
    memset( &bfh, 0, sizeof( bfh ) );
    bfh.bfType    = 'MB';
    bfh.bfSize    = sizeof( bfh ) + nBytes + sizeof( BITMAPINFOHEADER );
    bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );
	DWORD written = 0;
    WriteFile( hf, &bfh, sizeof( bfh ), &written, NULL );

	// Write the bitmap format information
    BITMAPINFOHEADER bih;
    memset( &bih, 0, sizeof( bih ) );
    bih.biSize     = sizeof( bih );
    bih.biWidth    = width;
    bih.biHeight   = height;
    bih.biPlanes   = 1;
    bih.biBitCount = 24;
    written = 0;
    WriteFile( hf, &bih, sizeof( bih ), &written, NULL );

	// Write the bitmap bits
    written = 0;
    WriteFile( hf, frameBuf, nBytes, &written, NULL );


	// release resources
    CloseHandle( hf );
}

///////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 
//
// By downloading, copying, installing or using the software you agree to this
// license. If you do not agree to this license, do not download, install, copy or
// use the software.
//
//
//                        Mavis License Agreement 
//
// Copyright (c) 2005, Robin Hewitt (http://www.robin-hewitt.com).
// Third party copyrights are property of their respective owners. 
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
// 
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
// 
// This software is provided "as is" and any express or implied warranties, including,
// but not limited to, the implied warranties of merchantability and fitness for a
// particular purpose are disclaimed. In no event shall the authors or contributors be
// liable for any direct, indirect, incidental, special, exemplary, or consequential
// damages (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused and on any
// theory of liability, whether in contract, strict liability, or tort (including
// negligence or otherwise) arising in any way out of the use of this software, even
// if advised of the possibility of such damage. 
///////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -