青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

重新修訂自用的文件型日志WIN32 C++類

        對于日志 , 一般在工業24小時執行的程序很多見, 通常的用就是法記錄文本信息.。這次提供的C++類命名為CxLog, 提供文本記錄, 多參數格式化文本紀錄, 二進制數據參照常見16進制編輯器紀錄,對常見編譯器的異常提供便捷的記錄接口。本次提供的類支持多線程,本身也是依賴守護線程執行,也采用了簡單的單件模式,一個程序只會有一個實例,且不需要用戶定義。同時支持UNICODE,支持常見的編譯器,記錄文件時同時會向控制臺輸出,也會向調試窗口輸出, 主要目的就是為了方便,其實程序難度很低,高手莫要見笑。
下載地址http://download.csdn.net/source/408048
本文末提供源代碼

文本紀錄: LOG(text);
多參數格式化文本紀錄:
     GNU C++ :LOGN(format, p1, p2...);
     VC6等不支持多參數宏采用LOG1(format, p1);  LOG2(format, p1, p2); .....
CException: LOGE(e);
_com_error: LOGE(e);
std::exception: LOGE(e);

日志內容:
2008-04-10 15:05:26.469 Exception BaseTestLog.cpp(func, 44): test of c ++ exception.

  
二進制數據: LOG_BIN(pData, uDataSize);
日志內容:
2008-04-10 15:05:26.469 Exception BaseTestLog.cpp(func, 44):
00000060: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F `abcdefghijklmno
對于ASCII的控制字符默認替換成_T('.'),你可以定義宏CX_LOG_REPLACE_ASCII來改變他,也可以定義宏CX_LOG_REPLACE_CONTROL選擇是否替換

總的來說功能也就是記錄文件名、函數名、行號、內容,并提供對常見異常自動擴展,
你可以通過定義宏來改變日志文件名
 比如你定義
#define CX_LOG_FILE_NAME  _T("d:\mylog.log")
日志就會記錄在該文件中
系統默認記錄在.\log下,文件名為程序啟動當天日期
提供按一定時間記錄的功能
通過宏CX_LOG_BY_DAY、CX_LOG_BY_WEEK、CX_LOG_BY_MONTH、CX_LOG_BY_YEAR
改變記錄的文件名




初步遺留問題:
1 聽說VC2005支持多參數宏 沒有安裝測試
2 __FUNCTION__ 的UNICODE擴展在GCC中沒有成功但是__FILE__成功了,我都有點糊涂了 ,所以UNICODE下不支持__FUNCTION__

#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)

#define __WFILE__ WIDEN(__FILE__)
#define __WFUNCTION__ WIDEN(__FUNCTION__)//GCC失敗

3 對于不支持多參數宏的采用LOG1~9的擴展宏支持,盡管很難看,暫時我也不會了
4 只支持WIN32 希望有時間考慮開發移植

以下是一個測試用例, 在VC6(sp6)、VC2003、BCB6、GCC3.4.4、GCC4.4.1、Intel C++9下分別在UNICODE和非UNICODE下編譯通過




#define _CONSOLE
#include 
"cxlog.h"

void Test()
{
    LOG(_T(
"Test Log"));
    LOG1(_T(
"Arg:%d"), 1);
    LOG2(_T(
"Arg:%d, %d"), 12);
    LOG3(_T(
"Arg:%d, %d, %d"), 123);
    LOG4(_T(
"Arg:%d, %d, %d, %d"), 1234);
    LOG5(_T(
"Arg:%d, %d, %d, %d, %d"), 12345);
    LOG6(_T(
"Arg:%d, %d, %d, %d, %d, %d"), 123456);
    LOG7(_T(
"Arg:%d, %d, %d, %d, %d, %d, %d"), 1234567);
    LOG8(_T(
"Arg:%d, %d, %d, %d, %d, %d, %d, %d"), 12345678);
    LOG9(_T(
"Arg:%d, %d, %d, %d, %d, %d, %d, %d, %d"), 123456789);

    LOG_WARN(_T(
"Test Log"));
    LOG_WARN1(_T(
"Arg:%d"), 1);
    LOG_WARN2(_T(
"Arg:%d, %d"), 12);
    LOG_WARN3(_T(
"Arg:%d, %d, %d"), 123);
    LOG_WARN4(_T(
"Arg:%d, %d, %d, %d"), 1234);
    LOG_WARN5(_T(
"Arg:%d, %d, %d, %d, %d"), 12345);
    LOG_WARN6(_T(
"Arg:%d, %d, %d, %d, %d, %d"), 123456);
    LOG_WARN7(_T(
"Arg:%d, %d, %d, %d, %d, %d, %d"), 1234567);
    LOG_WARN8(_T(
"Arg:%d, %d, %d, %d, %d, %d, %d, %d"), 12345678);
    LOG_WARN9(_T(
"Arg:%d, %d, %d, %d, %d, %d, %d, %d, %d"), 123456789);

    LOG_LAST_ERROR();

    
try
    {
        
throw std::runtime_error("test of c ++ exception.");
    }
    
catch (const std::exception &e)
    {
        LOGE(e);
    }


    BYTE bin[
256];
    
for(int i = 0; i < 256; i++)
        bin[i] 
= i;

    LOG_BIN(bin, 
256);

    #ifdef __GNUC__ 
        LOGN(_T(
"test for LogN :%d, %d, %d"), 123);
    
#endif
}


int main(int argc, char *argv[])
{
    Test();
    
return 0;
}

      輸出內容:

2008-04-10 15:05:26.468 Message BaseTestLog.cpp(14): Test Log
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(15): Arg:1
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(16): Arg:1, 2
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(17): Arg:1, 2, 3
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(18): Arg:1, 2, 3, 4
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(19): Arg:1, 2, 3, 4, 5
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(20): Arg:1, 2, 3, 4, 5, 6
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(21): Arg:1, 2, 3, 4, 5, 6, 7
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(22): Arg:1, 2, 3, 4, 5, 6, 7, 8
2008-04-10 15:05:26.468 Message BaseTestLog.cpp(23): Arg:1, 2, 3, 4, 5, 6, 7, 8, 9
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(25): Test Log
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(26): Arg:1
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(27): Arg:1, 2
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(28): Arg:1, 2, 3
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(29): Arg:1, 2, 3, 4
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(30): Arg:1, 2, 3, 4, 5
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(31): Arg:1, 2, 3, 4, 5, 6
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(32): Arg:1, 2, 3, 4, 5, 6, 7
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(33): Arg:1, 2, 3, 4, 5, 6, 7, 8
2008-04-10 15:05:26.468 Warning BaseTestLog.cpp(34): Arg:1, 2, 3, 4, 5, 6, 7, 8, 9
2008-04-10 15:05:26.469 Error BaseTestLog.cpp(36): (0):操作成功完成。
2008-04-10 15:05:26.469 Exception BaseTestLog.cpp(44): test of c ++ exception.
2008-04-10 15:05:26.469 Message BaseTestLog.cpp(52):
00000000: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F                
00000010: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F                
00000020: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F  !"#$&'()*+,-./
00000030: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0123456789:;<=>?
00000040: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F @ABCDEFGHIJKLMNO
00000050: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F PQRSTUVWXYZ[\]^_
00000060: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F `abcdefghijklmno
00000070: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F pqrstuvwxyz{|}~
00000080: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F €亗儎厗噲墛媽崕?
00000090: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F 悜挀敃枟槞殯湞灍
000000A0: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF 牎ⅲぅΗī
000000B0: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 氨渤吹斗腹夯冀究
000000C0: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF 懶旅吶魄壬仕掏蝸
000000D0: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF 醒矣哉腫剄譙茌捱
000000E0: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF 噌懺溴驍栝覿祉鉺
000000F0: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 瘃蝮趲鲼?


頭文件CxLog.h 下載地址 http://download.csdn.net/source/408048

直接拷貝也行,只要一個頭文件就好

/*
CxLog (WIN32) free version 0.1
Compiled by: C++ BUILDER 6, X; VC++ 6, 7, 8;  GCC 3.4.5, 4.2.1; Intel C++ 9
Writer: llbird
Mail  : wushaojian@21cn.com 
Blog  : http:///blog.csdn.net/wujian53
Copyright(c) 2005.5 - 2008.3
void Test()
{
 LOG(_T("Test Log"));
 LOG1(_T("Arg:%d"), 1);
 LOG2(_T("Arg:%d, %d"), 1, 2);

 LOG_WARN(_T("Test Log"));
 LOG_WARN1(_T("Arg:%d"), 1);

 LOG_LAST_ERROR();

 try
 {
  throw std::runtime_error("test of c ++ exception.");
 }
 catch (const std::exception &e)
 {
  LOGE(e);
 }

 BYTE bin[256];
 for(int i = 0; i < 256; i++)
  bin[i] = i;

 LOG_BIN(bin, 256);

 #ifdef __GNUC__
  LOGN(_T("test for LogN :%d, %d, %d"), 1, 2, 3);
 #endif
}
*/

#ifndef _CX_LOG_H_
#define _CX_LOG_H_

#if defined(_MSC_VER)
 #pragma warning(disable: 4530)
#endif

#include <stdio.h>
#include <time.h>
#include <assert.h>

#include <list>
#include <iterator>
#include <stdexcept>
#include <exception>

#if defined(_MSC_VER) || defined(__INTEL_COMPILER) 
 #include <comdef.h>
#endif

#include <tchar.h>
#include <process.h>
#include <windows.h>


//////////////////////////////////////////////////////////////////////////
///文件型多線程日志類 class for log file

#ifndef CX_LOG_DEFAULT_FORMAT
 #if (defined(_MSC_VER) && _MSC_VER<=1310) || defined(__BORLANDC__)  || (defined(__GNUC__) && defined(_UNICODE))
  #define CX_LOG_DEFAULT_FORMAT _T("%s %s %s(%d): %s\r\n")
 #else
  #define CX_LOG_DEFAULT_FORMAT _T("%s %s %s(%s, %d): %s\r\n")
 #endif
#endif

#ifndef CX_LOG_DEFAULT_FORMAT_SIZE
 #define CX_LOG_DEFAULT_FORMAT_SIZE 1024
#endif

#ifndef CX_LOG_REPLACE_CONTROL
 #define CX_LOG_REPLACE_CONTROL true
#endif

#ifndef CX_LOG_REPLACE_ASCII
 #define CX_LOG_REPLACE_ASCII _T(' ')
#endif

class CxLog
{
public:
 enum EnumType{
  CX_LOG_MESSAGE = 0,
  CX_LOG_WARNING,
  CX_LOG_EXCEPTION,
  CX_LOG_ERROR
 };

 static CxLog& Instance()
 {
  static bool alive = false;
  static CxLog log(alive);

  if(!alive)
  {
   OutputDebugString(_T("CxLog has destroy!"));
   throw std::runtime_error("CxLog has destroy!");
  }

  return log;
 }

 struct Item
 {
  SYSTEMTIME _Time;//>time stamp
  TCHAR _szTime[24];

  LPTSTR _szSrc;//>source file name
  LPTSTR _szFunc;//>founction name
  ULONG _uLine;//>line number

  EnumType _eType;//
  LPTSTR _szDesc;//>content

  LPBYTE _pBin;//>binary data szBuffer
  ULONG _uBinSize;//>the size of binary data szBuffer

  Item()
  {
   InitItem(NULL, NULL, 0, CX_LOG_MESSAGE, NULL, NULL, 0);
  }

  Item(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, EnumType eType,
   LPCTSTR szDesc, LPVOID pBin = NULL, ULONG uSize = 0)
  {
   InitItem(szSrc, szFunc, uLine, eType, szDesc, pBin, uSize);
  }

  ~Item()
  {
   ReleaseStringBuffer(_szSrc); 
   ReleaseStringBuffer(_szFunc);
   ReleaseStringBuffer(_szDesc);
   
   if(_pBin)
   {
    delete []_pBin;
    _pBin = NULL;
   }
  }

  VOID InitItem(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, EnumType eType,
   LPCTSTR szDesc, LPVOID pBin, ULONG uSize)
  {
   GetLocalTime(&_Time);
   wsprintf(_szTime, _T("%04d-%02d-%02d %02d:%02d:%02d.%03d"),
    _Time.wYear,
    _Time.wMonth,
    _Time.wDay,
    _Time.wHour,
    _Time.wMinute,
    _Time.wSecond,
    _Time.wMilliseconds
    );

   _eType = eType;
   _uBinSize = _uLine = 0;
   _szSrc = _szFunc = _szDesc = NULL;
   _pBin = NULL;

   if(szSrc)
   {
    LPCTSTR p = szSrc;

   #ifndef CX_LOG_FULL_SOURCE_NAME
    p = szSrc + _tcslen(szSrc);
    while(p>szSrc && *p!=_T('\\'))
     p--;
    
    if(*p == _T('\\'))
     p++;
   #endif

    AllocStringBuffer(_szSrc, p);
    _uLine = uLine;
   }
   
   AllocStringBuffer(_szFunc, szFunc);
   AllocStringBuffer(_szDesc, szDesc);

   if(pBin && uSize)
   {
    _pBin = new BYTE[uSize];
    assert(_pBin);
    memcpy(_pBin, pBin, uSize);
    _uBinSize = uSize;
   }
  }

  VOID AllocStringBuffer(LPTSTR& szDest, LPCTSTR& szSrc)
  {
   if(szSrc)
   {
    ULONG uSize = _tcslen(szSrc) + 1;
    szDest = new TCHAR[uSize];
    assert(szDest);
    memcpy(szDest, szSrc, uSize*sizeof(TCHAR));
   }
  }

  VOID ReleaseStringBuffer(LPTSTR& lpDest)
  {
   if(lpDest)
   {
    delete []lpDest;
    lpDest = NULL;
   }
  }
  
  LPTSTR Format(LPTSTR szBuffer, ULONG uSize, ULONG* pSize = NULL)
  {
   static LPCTSTR szType[] = {_T("Message"), _T("Warning"), _T("Exception"), _T("Error")};

   if(!szBuffer)
    return szBuffer;

   int iLen;

   #if (defined(_MSC_VER) && _MSC_VER<=1310) || defined(__BORLANDC__)  || (defined(__GNUC__) && defined(_UNICODE))
    iLen = _sntprintf(szBuffer, uSize,
     CX_LOG_DEFAULT_FORMAT,
     _szTime, szType[_eType],
     _szSrc?_szSrc:_T(""), _uLine,
     _szDesc?_szDesc:_T(""));
   #else
    iLen = _sntprintf(szBuffer, uSize,
     CX_LOG_DEFAULT_FORMAT,
     _szTime, szType[_eType],
     _szSrc?_szSrc:_T(""), _szFunc?_szFunc:_T(""), _uLine,
     _szDesc?_szDesc:_T(""));
   #endif

   if(iLen>4 && !_tcsncmp(szBuffer+iLen-4, _T("\r\n"), 2))
    *(szBuffer+iLen-2) = TCHAR(NULL), iLen -= 2;
   
   if(pSize)
    *pSize = iLen;

   return szBuffer;
  }

  LPTSTR FormatBinary(LPTSTR szBuffer, ULONG uSize, ULONG* pSize = NULL,
   bool bReplace  = CX_LOG_REPLACE_CONTROL,
   TCHAR chReplaceAscii = CX_LOG_REPLACE_ASCII)
  {
   return FormatBinary(_pBin, _uBinSize, szBuffer, uSize,  pSize,
    bReplace, chReplaceAscii);
  }
  
  LPTSTR FormatBinary(LPVOID lpBin, ULONG uBinSize,
   LPTSTR szBuffer, ULONG uSize,  ULONG* pSize = NULL,
   bool bReplace  = CX_LOG_REPLACE_CONTROL,
   TCHAR chReplaceAscii = CX_LOG_REPLACE_ASCII)
  {
   TCHAR temp[8+2+3*16+16+2+1];
   ULONG uActualSize = 0;

   if(!_pBin)
   {
    if(pSize)
     *pSize = uActualSize;
    return szBuffer;
   }

   if(!szBuffer)
   {
    uSize = ((_uBinSize>>4)+1)*(8+2+3*16+16+2)+1;
    szBuffer = new TCHAR[uSize];
    assert(szBuffer);
   }

   for(ULONG p = 0; p<_uBinSize && uActualSize<uSize-1; p += 16)
   {
    wsprintf(temp, _T("%08X: "), p);

    int i;

    for(i = 0; i < 16; i++)
    {
     if(p+i<_uBinSize)
     {
      BYTE x = *(_pBin+p+i), t;

      t = (x&0xF0) >> 4;
      *(temp+8+2+3*i) = t>9 ?  _T('A')+t-10 : _T('0')+t;
      t = x&0x0F;
      *(temp+8+2+3*i+1) = t>9 ? _T('A')+t-10 : _T('0')+t;

      *(temp+8+2+3*i+2) = _T(' ');
     }
     else
      _tcscpy(temp+8+2+3*i, _T("   "));
    }

    for(i = 0; i < 16; i++)
    {
     if(p+i<_uBinSize)
      *(temp+8+2+3*16+i) = (bReplace&&_istcntrl(TCHAR(*(_pBin+p+i)))) ? chReplaceAscii : *(_pBin+p+i);
     else
      *(temp+8+2+3*16+i) = _T(' ');
    }
    
     
    _tcscpy(temp+8+2+3*16+16, _T("\r\n"));

    ULONG uLen = uSize-uActualSize-1>8+2+3*16+16+2? 8+2+3*16+16+2 : uSize-uActualSize-1;
    memcpy(szBuffer+uActualSize, temp, uLen*sizeof(TCHAR));
    uActualSize += uLen;
   }

   if(pSize)
    *pSize = uActualSize;

   szBuffer[uActualSize] = TCHAR(NULL);

   return szBuffer;
  }
 };

 LPTSTR GetLogFileName()
 {
 #if defined(CX_LOG_BY_DAY) || defined(CX_LOG_BY_WEEK) || defined(CX_LOG_BY_MONTH) || defined(CX_LOG_BY_YEAR)
  time_t now = time(NULL);
  #if defined(CX_LOG_BY_DAY)
   _tcsftime(_szFileName, MAX_PATH, _T(".\\Log\\%Y%m%d.log"), localtime(&now));
  #elif defined(CX_LOG_BY_WEEK)
   _tcsftime(_szFileName, MAX_PATH, _T(".\\Log\\%Y%W.log"), localtime(&now));
  #elif defined(CX_LOG_BY_MONTH)
   _tcsftime(_szFileName, MAX_PATH, _T(".\\Log\\%Y%m.log"), localtime(&now));
  #elif defined(CX_LOG_BY_YEAR)
   _tcsftime(_szFileName, MAX_PATH, _T(".\\Log\\%Y.log"), localtime(&now));
  #endif
 #endif
  return _szFileName;
 }

public:
 CxLog(bool &alive) : _bAlive(alive)
 {
  _bAlive = true;

 #ifdef CX_LOG_FILE_NAME
  ULONG uSize = _tcslen(CX_LOG_FILE_NAME) + 1;
  uSize = uSize>MAX_PATH ? MAX_PATH : uSize;
  memcpy(_szFileName, CX_LOG_FILE_NAME, uSize*sizeof(TCHAR));
 #else
  CreateDirectory(_T(".\\Log"), NULL);  //>create log sub dir
  #if !defined(CX_LOG_BY_DAY) && !defined(CX_LOG_BY_WEEK) && !defined(CX_LOG_BY_MONTH) && !defined(CX_LOG_BY_YEAR)
   time_t now = time(NULL);
   _tcsftime(_szFileName, MAX_PATH, _T(".\\Log\\%Y%m%d.log"), localtime(&now));
  #endif
 #endif

  _TerminateEvent = CreateEvent(0, TRUE, FALSE, NULL);
  _LogHandle = CreateEvent(0, FALSE, FALSE, NULL);
  ::InitializeCriticalSection(&_LogMutex);

 #ifdef _MT
  unsigned int id;
  _hThreadHandle = (HANDLE)::_beginthreadex(NULL, 0, StaticThreadProc, this, 0, &id);
 #else
  DWORD id;
  _hThreadHandle = ::CreateThread(NULL, 0, StaticThreadProc, this, 0, &id);
 #endif 
 }

 ~CxLog()
 {
  Destroy(); 
 }

 VOID Destroy()
 {
  _bAlive = false;
  if(_hThreadHandle)
  {
   SetEvent(_TerminateEvent);
   if(::WaitForSingleObject(_hThreadHandle, 500) != WAIT_OBJECT_0)
    ::TerminateThread(_hThreadHandle, 0);
   CloseHandle(_hThreadHandle);
  }
  ::DeleteCriticalSection(&_LogMutex);
 }

 VOID Lock()
 {
  ::EnterCriticalSection(&_LogMutex);
 }

 VOID Unlock()
 {
  ::LeaveCriticalSection(&_LogMutex);
 }

 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, EnumType eType,
   LPCTSTR szDesc, LPVOID pBin = NULL, ULONG uSize = 0)
 {
  Item* p = new Item(szSrc, szFunc, uLine, eType, szDesc, pBin, uSize);

 #if defined(_CONSOLE) || defined(_DEBUG)
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  p->Format(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);

  LPTSTR pBinStr = p->FormatBinary(p->_pBin, p->_uBinSize, NULL, 0,  &uSize);

  #ifdef _CONSOLE
   if(szBuffer)
    _tprintf(szBuffer);

   if(pBinStr)
    _tprintf(pBinStr);
  #endif

  #ifdef _DEBUG
   OutputDebugString(szBuffer);
   OutputDebugString(pBinStr);
  #endif

  delete []pBinStr;
 #endif

  Lock();
  _ItemList.push_back(p);
  Unlock();
  
  SetEvent(_LogHandle);
 }

 VOID LogBin(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, EnumType eType, LPVOID pBin, ULONG uSize)
 {
  Log(szSrc, szFunc, uLine, eType, NULL, pBin, uSize);
 }

 VOID LogN(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, EnumType eType, LPCTSTR szFormat, ...)
 {
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE] = {0};

  va_list va;
  va_start(va, szFormat);
  _vsntprintf(szBuffer, 1024-1, szFormat, va);
  va_end(va);

  Log(szSrc, szFunc, uLine, eType, szBuffer);
 }

#ifdef _INC_COMDEF
 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, _com_error &e)
 {
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE] = {0};
  _sntprintf(szBuffer, 1024, _T("_com_error Code=%08X Meaning=%s Source=%s Description=%s"),
   e.Error(),
   (LPCSTR)_bstr_t(e.ErrorMessage()),
   (LPCSTR)e.Source(),
   (LPCSTR)e.Description());

  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
 }
#endif

 VOID LogLastError(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, DWORD dwError)
 {
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE] = {0};

  int iLen = _stprintf(szBuffer, _T("(%d):"), dwError);
  FormatMessage(
   FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
   NULL,
   dwError,
   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
   szBuffer + iLen,
   CX_LOG_DEFAULT_FORMAT_SIZE - iLen - 3,
   NULL
   );

  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_ERROR, szBuffer);
 }

#if defined(INC_VCL) && defined(__BORLANDC__)
 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, const Exception *e)
 {
 #ifdef _UNICODE
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  e->Message.WideChar(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
 #else
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e->Message.c_str());
 #endif
 }

 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, const Exception &e)
 {
 #ifdef _UNICODE
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  e.Message.WideChar(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
 #else
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e.Message.c_str());
 #endif
 }
#endif

#if (defined(_MFC_VER) && defined(__AFX_H__))
 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, const CException *e)
 {
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  e->GetErrorMessage(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE, NULL);
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
 }

 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, const CException &e)
 {
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  e.GetErrorMessage(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE, NULL);
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
 }
#endif

 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, const std::exception *e)
 {
 #ifdef _UNICODE
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  MultiByteToWideChar(CP_ACP, 0, e->what(), -1, szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
 #else
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e->what());
 #endif
 }

 VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, ULONG uLine, const std::exception &e)
 {
 #ifdef _UNICODE
  TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  MultiByteToWideChar(CP_ACP, 0, e.what(), -1, szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
 #else
  Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e.what());
 #endif
 }

protected:
 bool& _bAlive;
 CRITICAL_SECTION _LogMutex;
 std::list<Item*> _ItemList;
 TCHAR _szFileName[MAX_PATH];
 HANDLE _hThreadHandle, _LogHandle, _TerminateEvent;

 virtual VOID Run()
 {
  HANDLE HandleArray[2];
  HandleArray[0] = _LogHandle;
  HandleArray[1] = _TerminateEvent;

  for(;;)
  {
   DWORD ret = ::WaitForMultipleObjects(2, HandleArray, false, INFINITE);
   if(ret == WAIT_OBJECT_0)
   {
    HANDLE hHandle = ::CreateFile(
     GetLogFileName(),
     GENERIC_READ | GENERIC_WRITE ,
     FILE_SHARE_READ,
     NULL,
     OPEN_ALWAYS,
     FILE_ATTRIBUTE_NORMAL,
     NULL
     );

    if(!hHandle)
     return;
    
    DWORD NumberOfBytesWritten;

    SetFilePointer(hHandle, 0, 0, FILE_END);

    try
    {
     Lock();
     while(_ItemList.size())
     {
      Item *p = _ItemList.front();

      TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
      ULONG uSize = 0;
      p->Format(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE, &uSize);
      WriteFile(hHandle, szBuffer, uSize*sizeof(TCHAR), &NumberOfBytesWritten, NULL);

      if(p->_pBin && p->_uBinSize)
      {
       ULONG uSize = 0;
       LPTSTR t = p->FormatBinary(p->_pBin, p->_uBinSize, NULL, 0,  &uSize);
       WriteFile(hHandle, t, uSize*sizeof(TCHAR), &NumberOfBytesWritten, NULL);
       delete []t;
      }

      _ItemList.pop_front();
      delete p;
     }
     Unlock();
    }
    catch (...)
    {
     Unlock();
    }
        
    SetEndOfFile(hHandle);
    CloseHandle(hHandle);
   }

            if(ret == WAIT_OBJECT_0 + 1)
    break;
  } 
 }

private:
 CxLog(const CxLog&);
 CxLog& operator=(CxLog&);

#ifdef _MT
 static UINT APIENTRY StaticThreadProc(LPVOID lpPara) //允許C多線程運行庫
#else
 static DWORD WINAPI StaticThreadProc(LPVOID lpPara)
#endif
 {
  ((CxLog*)(lpPara))->Run();

 #ifdef _MT
  ::_endthreadex(0);
 #endif
  return 0;
 }
};

#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)

#define __WFILE__ WIDEN(__FILE__)
#ifdef _UNICODE
 #define __TFILE__ __WFILE__
#else
 #define __TFILE__ __FILE__
#endif

#if (_MSC_VER && _MSC_VER<=1200) || (__BORLANDC__)
 #define __FUNCTION__ NULL
 #define __WFUNCTION__ NULL
#else //_MSC_VER>1200 __GNUC__ __INTEL_COMPILER
 #define __WFUNCTION__ WIDEN(__FUNCTION__)
#endif

#ifdef _UNICODE
 #ifdef __GNUC__
  #define __TFUNCTION__ NULL
 #else
  #define __TFUNCTION__ __WFUNCTION__
 #endif
#else
 #define __TFUNCTION__ __FUNCTION__
#endif

#define BASE_LOG(type, msg) CxLog::Instance().Log(__TFILE__, __TFUNCTION__, __LINE__, (type), (msg))
#define LOG(msg) BASE_LOG(CxLog::CX_LOG_MESSAGE, (msg))
#define LOG_WARN(msg) BASE_LOG(CxLog::CX_LOG_WARNING, (msg))
#define LOGE(e) CxLog::Instance().Log(__TFILE__, __TFUNCTION__, __LINE__, (e))
#define LOG_ERR(msg) BASE_LOG(CxLog::CX_LOG_ERROR, (msg))

#define BASE_LOG_BIN(type, bin, size) CxLog::Instance().LogBin(__TFILE__, __TFUNCTION__, __LINE__, (type), (bin), (size))
#define LOG_BIN(bin, size) BASE_LOG_BIN(CxLog::CX_LOG_MESSAGE, (bin), (size))
#define LOG_WARN_BIN(bin, size) BASE_LOG_BIN(CxLog::CX_LOG_WARNING, (bin), (size))
#define LOG_ERR_BIN(bin, size) BASE_LOG_BIN(CxLog::CX_LOG_ERROR, (bin), (size))

#if __GNUC__ || __INTEL_COMPILER || _MSC_VER>1310
 #define BASE_LOGN(type, msg, ...) CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, (type), (msg), ##__VA_ARGS__)
 #define LOGN(msg, ...) BASE_LOGN(CxLog::CX_LOG_MESSAGE, (msg), ##__VA_ARGS__)
 #define LOGN_WARNN(msg, ...) BASE_LOGN(CxLog::CX_LOG_WARNING, (msg), ##__VA_ARGS__)
 #define LOGN_ERRN(msg, ...) BASE_LOGN(CxLog::CX_LOG_ERROR, (msg), ##__VA_ARGS__)
#endif


#define PRE_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_MESSAGE,
#define LOG1(str, p1) PRE_LOG (str), (p1))
#define LOG2(str, p1, p2) PRE_LOG (str), (p1), (p2))
#define LOG3(str, p1, p2, p3) PRE_LOG (str), (p1), (p2), (p3))
#define LOG4(str, p1, p2, p3, p4) PRE_LOG (str), (p1), (p2), (p3), (p4))
#define LOG5(str, p1, p2, p3, p4, p5) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5))
#define LOG6(str, p1, p2, p3, p4, p5, p6) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
#define LOG7(str, p1, p2, p3, p4, p5, p6, p7) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
#define LOG8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
#define LOG9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))

#define PRE_T_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__,
#define LOG_T1(t, str, p1) PRE_T_LOG (t), (str), (p1))
#define LOG_T2(t, str, p1, p2) PRE_T_LOG (t), (str), (p1), (p2))
#define LOG_T3(t, str, p1, p2, p3) PRE_T_LOG (t), (str), (p1), (p2), (p3))
#define LOG_T4(t, str, p1, p2, p3, p4) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4))
#define LOG_T5(t, str, p1, p2, p3, p4, p5) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5))
#define LOG_T6(t, str, p1, p2, p3, p4, p5, p6) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6))
#define LOG_T7(t, str, p1, p2, p3, p4, p5, p6, p7) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
#define LOG_T8(t, str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
#define LOG_T9(t, str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))

#define PRE_WARN_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_WARNING,
#define LOG_WARN1(str, p1) PRE_WARN_LOG (str), (p1))
#define LOG_WARN2(str, p1, p2) PRE_WARN_LOG (str), (p1), (p2))
#define LOG_WARN3(str, p1, p2, p3) PRE_WARN_LOG (str), (p1), (p2), (p3))
#define LOG_WARN4(str, p1, p2, p3, p4) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4))
#define LOG_WARN5(str, p1, p2, p3, p4, p5) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5))
#define LOG_WARN6(str, p1, p2, p3, p4, p5, p6) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
#define LOG_WARN7(str, p1, p2, p3, p4, p5, p6, p7) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
#define LOG_WARN8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
#define LOG_WARN9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))

#define PRE_EXCEPTION_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_EXCEPTION,
#define LOG_EXCEPTION1(str, p1) PRE_EXCEPTION_LOG (str), (p1))
#define LOG_EXCEPTION2(str, p1, p2) PRE_EXCEPTION_LOG (str), (p1), (p2))
#define LOG_EXCEPTION3(str, p1, p2, p3) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3))
#define LOG_EXCEPTION4(str, p1, p2, p3, p4) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4))
#define LOG_EXCEPTION5(str, p1, p2, p3, p4, p5) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5))
#define LOG_EXCEPTION6(str, p1, p2, p3, p4, p5, p6) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
#define LOG_EXCEPTION7(str, p1, p2, p3, p4, p5, p6, p7) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
#define LOG_EXCEPTION8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
#define LOG_EXCEPTION9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))

#define PRE_ERR_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_ERROR,
#define LOG_ERR1(str, p1) PRE_ERR_LOG (str), (p1))
#define LOG_ERR2(str, p1, p2) PRE_ERR_LOG (str), (p1), (p2))
#define LOG_ERR3(str, p1, p2, p3) PRE_ERR_LOG (str), (p1), (p2), (p3))
#define LOG_ERR4(str, p1, p2, p3, p4) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4))
#define LOG_ERR5(str, p1, p2, p3, p4, p5) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5))
#define LOG_ERR6(str, p1, p2, p3, p4, p5, p6) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
#define LOG_ERR7(str, p1, p2, p3, p4, p5, p6, p7) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
#define LOG_ERR8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
#define LOG_ERR9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))

#define LOG_LAST_ERROR() CxLog::Instance().LogLastError(__TFILE__, __TFUNCTION__, __LINE__, GetLastError())

#endif //_CX_LOG_H_



posted on 2008-04-10 21:00 llbird 閱讀(3219) 評論(2)  編輯 收藏 引用

評論

# re: 重新修訂自用的文件型日志WIN32 C++類 2008-04-11 08:46 夢在天涯

強!  回復  更多評論   

# re: 重新修訂自用的文件型日志WIN32 C++類 2008-04-11 23:54 ood

相當好,收了  回復  更多評論   

<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

導航

統計

常用鏈接

留言簿(8)

隨筆檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            奶水喷射视频一区| 亚洲综合色丁香婷婷六月图片| 午夜精品福利一区二区蜜股av| 欧美午夜寂寞影院| 午夜久久久久久| 国产亚洲第一区| 亚洲一区二区高清视频| 亚洲日本乱码在线观看| 久久琪琪电影院| 亚洲精品欧美精品| 亚洲午夜av电影| 国内精品国产成人| 亚洲成色777777在线观看影院| 欧美高清视频在线观看| 亚洲欧美国产三级| 久久久久久久综合狠狠综合| 亚洲伦理在线免费看| 一本高清dvd不卡在线观看| 国产精品永久| 欧美激情在线有限公司| 国产精品www网站| 久久蜜桃资源一区二区老牛 | 一区二区激情视频| 黄色日韩网站| 亚洲精品国产视频| 国产一区亚洲| 日韩午夜在线观看视频| 国产一区二区三区最好精华液| 欧美不卡视频| 国产精品久久久久久av福利软件| 久久嫩草精品久久久精品| 欧美精品v日韩精品v国产精品| 欧美影院视频| 欧美美女bb生活片| 麻豆精品视频在线观看| 国产精品xvideos88| 欧美激情1区| 国内精品国产成人| 亚洲欧美日韩系列| 亚洲午夜视频| 欧美精品 国产精品| 久久天堂av综合合色| 国产精品国产三级国产aⅴ无密码| 蜜桃av一区二区在线观看| 欧美日韩另类字幕中文| 欧美激情va永久在线播放| 国产日韩精品在线观看| 亚洲视频综合| 夜夜爽夜夜爽精品视频| 老司机一区二区| 久久另类ts人妖一区二区| 国产精品久久久久久久久免费桃花 | 最新国产成人av网站网址麻豆 | 狂野欧美性猛交xxxx巴西| 国产精品久久97| 亚洲精品小视频| 亚洲欧洲一区二区在线播放| 久久躁狠狠躁夜夜爽| 久久久久在线观看| 国产一在线精品一区在线观看| 亚洲永久在线观看| 午夜国产精品影院在线观看 | 红桃av永久久久| 亚洲综合国产精品| 夜夜嗨av色综合久久久综合网| 久久久久久亚洲精品不卡4k岛国| 欧美在线观看一区二区| 国产欧美日韩三级| 欧美一区二区网站| 久久久久久网址| 好吊妞**欧美| 久久人人97超碰人人澡爱香蕉| 久久综合网络一区二区| 在线观看欧美日本| 欧美成人a∨高清免费观看| 亚洲国产精品专区久久| 一本色道久久综合亚洲精品不| 欧美日韩福利视频| 一区二区三区福利| 久久不射中文字幕| 韩国女主播一区| 免费亚洲婷婷| 一本色道久久综合亚洲精品按摩| 亚洲欧美激情一区| 国模私拍视频一区| 你懂的亚洲视频| 一本久久知道综合久久| 欧美在线观看视频| 亚洲国产激情| 欧美视频免费| 久久精品中文字幕一区| 亚洲激情在线| 欧美一区=区| 亚洲第一在线综合网站| 欧美片第1页综合| 亚洲欧美成人在线| 欧美激情网站在线观看| 亚洲欧美成人精品| 亚洲福利视频一区| 国产精品国产精品国产专区不蜜| 欧美一区激情视频在线观看| 亚洲国产婷婷综合在线精品 | 精久久久久久| 欧美三级电影一区| 久久av一区二区三区| 亚洲精品精选| 久久天天综合| 亚洲午夜激情在线| 亚洲电影一级黄| 国产精品日韩精品欧美在线| 蜜臀av一级做a爰片久久| 亚洲午夜激情免费视频| 亚洲电影第三页| 久久国内精品自在自线400部| 日韩午夜三级在线| 玉米视频成人免费看| 国产精品综合| 欧美日韩天堂| 欧美 日韩 国产精品免费观看| 亚洲欧美国产一区二区三区| 亚洲人成亚洲人成在线观看| 久久网站热最新地址| 性欧美超级视频| 艳女tv在线观看国产一区| 在线观看欧美日韩国产| 国模私拍视频一区| 国产亚洲精品7777| 国产精品久久久久久久app| 欧美猛交免费看| 欧美高清视频一区二区三区在线观看 | 尤物精品国产第一福利三区| 国产精品久久久久久久久借妻 | 中文有码久久| 亚洲美女视频网| 亚洲国产天堂久久综合| 永久域名在线精品| 在线观看亚洲视频| 在线观看日韩专区| 狠狠操狠狠色综合网| 国产日韩欧美制服另类| 国产精品永久| 国产偷自视频区视频一区二区| 国产精品三级久久久久久电影| 欧美色中文字幕| 欧美午夜在线视频| 国产精品久久国产精麻豆99网站| 欧美日韩亚洲综合| 国产精品v亚洲精品v日韩精品| 欧美色图一区二区三区| 国产精品播放| 国产欧美一区二区精品婷婷| 国产午夜精品在线观看| 国内精品久久久久久久影视麻豆| 狠狠色综合色区| 亚洲国产日韩精品| 一区二区三区产品免费精品久久75| 亚洲狼人综合| 亚洲综合久久久久| 久久精品国产96久久久香蕉| 久久另类ts人妖一区二区| 欧美成人在线网站| 999亚洲国产精| 午夜视频在线观看一区二区| 久久精品国产96久久久香蕉| 麻豆精品视频在线观看| 欧美片在线播放| 国产人成精品一区二区三| 精品91在线| 一区二区三区偷拍| 久久精品国产免费观看| 欧美激情精品久久久久久蜜臀| 亚洲激情视频在线观看| 亚洲视频专区在线| 老司机一区二区| 国产精品一级久久久| 亚洲国产精品ⅴa在线观看| 亚洲视频成人| 玖玖国产精品视频| 日韩视频在线观看免费| 久久成人免费电影| 欧美精品日韩| 国产综合香蕉五月婷在线| 一区二区三区高清在线| 久久久亚洲一区| 日韩系列欧美系列| 久久夜色精品一区| 国产欧美精品一区二区三区介绍| 亚洲国产美女久久久久| 午夜久久tv| 亚洲乱码国产乱码精品精天堂 | 亚洲天堂激情| 欧美高清自拍一区| 韩国精品一区二区三区| 午夜精品久久久久久久白皮肤| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美日韩国产成人| 国产乱码精品一区二区三区五月婷| 最新国产精品拍自在线播放| 久久全球大尺度高清视频| 99精品国产在热久久|