/*
* CLog.cpp
*
* Created on: 2015年4月22日
* Author:
[email protected]
*/
//#include "stdafx.h"
#include "CLog.h"
#include <errno.h>
#include <iostream>
#include <memory>
#include <algorithm>
#include <sstream>
#include <fstream>
#include <vector>
#include <time.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <syslog.h>
#include <sys/stat.h>
#include <dirent.h>
#include <pwd.h>
#endif //
#ifndef MAX_PATH
#define MAX_PATH 256
#endif //MAX_PATH
///////////////////////////////////////////////////////////////////
namespace detail
{
enum Constant
{
kMaxPath = 256,
kMaxFileSize = 10,
kMaxFileCount = 2
};
#ifndef va_copy
#define va_copy(x,y) x = y
#endif //
#ifdef WIN32
class CriticalSection
{
public:
CriticalSection()
{
InitializeCriticalSection( &m_cs );
}
~CriticalSection()
{
DeleteCriticalSection( &m_cs );
}
void lock()
{
EnterCriticalSection( &m_cs );
}
void unlock()
{
LeaveCriticalSection( &m_cs );
}
CRITICAL_SECTION &getLock()
{
return m_cs;
}
#if(_WIN32_WINNT >= 0x0400)
bool trylock()
{
return ( TryEnterCriticalSection( &m_cs ) != 0 );
}
#endif /* _WIN32_WINNT >= 0x0400 */
private:
CRITICAL_SECTION m_cs;
};
#else
/// cross platform critical section
class CriticalSection
{
public:
CriticalSection()
{
pthread_mutexattr_t attr;
::pthread_mutexattr_init(&attr);
::pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
::pthread_mutex_init(&m_mutex, &attr);
::pthread_mutexattr_destroy(&attr);
}
~CriticalSection()
{
::pthread_mutex_destroy(&m_mutex);
}
void lock()
{
::pthread_mutex_lock(&m_mutex);
}
void unlock()
{
::pthread_mutex_unlock(&m_mutex);
}
bool trylock()
{
return (0 == ::pthread_mutex_trylock(&m_mutex));
}
pthread_mutex_t &getLock()
{
return m_mutex;
}
private:
pthread_mutex_t m_mutex;
};
#endif //WIN32
class AutoLock
{
public:
explicit AutoLock(CriticalSection& cs):
m_cs(cs)
{
m_cs.lock();
}
~AutoLock()
{
m_cs.unlock();
}
private:
CriticalSection& m_cs;
};
#ifdef WIN32
/*
* Number of micro-seconds between the beginning of the Windows epoch
* (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
*
* This assumes all Win32 compilers have 64-bit support.
*/
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__WATCOMC__)
#define DELTA_EPOCH_IN_USEC 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_USEC 11644473600000000ULL
#endif
typedef unsigned __int64 u_int64_t;
static u_int64_t filetime_to_unix_epoch (const FILETIME *ft)
{
u_int64_t res = (u_int64_t) ft->dwHighDateTime << 32;
res |= ft->dwLowDateTime;
res /= 10; /* from 100 nano-sec periods to usec */
res -= DELTA_EPOCH_IN_USEC; /* from Win epoch to Unix epoch */
return (res);
}
int getTimeOfDay(struct timeval *tv, void *tz)
{
FILETIME ft;
u_int64_t tim;
if (!tv) {
//errno = EINVAL;
return (-1);
}
GetSystemTimeAsFileTime (&ft);
tim = filetime_to_unix_epoch (&ft);
tv->tv_sec = (long) (tim / 1000000L);
tv->tv_usec = (long) (tim % 1000000L);
return (0);
}
#else
int getTimeOfDay(struct timeval *tv, void *tz)
{
return ::gettimeofday(tv, (struct timezone*)tz);
}
#endif //win32
int getcurtime(struct tm& t, int& ms)
{
struct timeval tv;
void* tz = NULL;
int rc = detail::getTimeOfDay(&tv, tz);
time_t sec = tv.tv_sec;
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
localtime_s(&t, &sec);
#else
t = *localtime(&sec);
#endif //
ms = tv.tv_usec/1000;
return rc;
}
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4996)
#endif //
int vsprint(char **buf, size_t size, const char *fmt, va_list ap)
{
va_list ap_copy;
int len;
va_copy(ap_copy, ap);
len = vsnprintf(*buf, size, fmt, ap_copy);
va_end(ap_copy);
if (len < 0)
{
// eCos and Windows are not standard-compliant and return -1 when
// the buffer is too small. Keep allocating larger buffers until we
// succeed or out of memory.
*buf = NULL;
while (len < 0)
{
if (*buf)
{
free(*buf);
}
size *= 2;
if ((*buf = (char *)malloc(size)) == NULL)
break;
va_copy(ap_copy, ap);
len = vsnprintf(*buf, size, fmt, ap_copy);
va_end(ap_copy);
}
}
else if (len > (int) size)
{
// Standard-compliant code path. Allocate a buffer that is large enough.
if ((*buf = (char *) malloc(len + 1)) == NULL)
{
len = -1;
}
else
{
va_copy(ap_copy, ap);
len = vsnprintf(*buf, len + 1, fmt, ap_copy);
va_end(ap_copy);
}
}
return len;
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif //
int sprint(char **buf, size_t size, const char *fmt, ...)
{
va_list argList;
va_start(argList, fmt);
return vsprint(buf, size, fmt, argList);
}
///////////////////////////////////////////////////////////////////
/// ini file reader and writer
class IniFile
{
public:
IniFile();
~IniFile();
explicit IniFile(bool ignoreCase);
bool load( const char* filename );
bool save( const char* filename );
size_t getSectionCount();
bool existSection( const char* name );
/// return true if insertion happened
bool insertSection( const char* name );
void removeSection( const char* name );
/// remove comment in the section
void removeComment( const char* sectionName );
/// remove all comment in the file
void removeComment();
/// insert comment before key
void setComment( const char* sectionName, const char* keyName,
const char* comment );
/// return empty if comment does not exist
std::string getComment( const char* sectionName, const char* keyName );
size_t getKeyCount( const char* sectionName );
bool existKey( const char* sectionName, const char* keyName );
void removeKey( const char* sectionName, const char* keyName );
std::string getValue( const char* sectionName, const char* keyName,
const std::string& defaultValue );
std::string getValue( const char* sectionName, const char* keyName,
const char* defaultValue = "");
void setValue( const char* sectionName, const char* keyName,
const char* value );
void setValue( const char* sectionName, const char* keyName,
const std::string& value );
template < class T >
bool queryValue(const char* sectionName, const char* keyName, T& value)
{
bool found = false;
iterator it = findIterator( sectionName );
if ( it != m_sections.end() )
{
IniSection& sec = *it;
IniEntryIterator pos = sec.findIterator( keyName );
if ( pos != sec.entryArray.end() )
{
std::istringstream iss(pos->value);
iss >> value;
found = true;
}
}
return found;
}
bool queryValue(const char* sectionName, const char* keyName, bool& value)
{
std::string str;
if (!queryValue(sectionName, keyName, str))
{
return false;
}
value = (str == "true") || (str == "1");
return true;
}
template < class T >
T getValue( const char* sectionName, const char* keyName, T defaultValue )
{
iterator it = findIterator( sectionName );
if ( it != m_sections.end() )
{
IniSectio
评论0