1 |
#ifndef _YEBISOCKS_LOGGER_H_ |
2 |
#define _YEBISOCKS_LOGGER_H_ |
3 |
|
4 |
#include <YCL/String.h> |
5 |
using namespace yebisuya; |
6 |
|
7 |
class Logger { |
8 |
private: |
9 |
HANDLE logfile; |
10 |
WString folder_; |
11 |
Logger():logfile(INVALID_HANDLE_VALUE) { |
12 |
} |
13 |
public: |
14 |
~Logger() { |
15 |
if (logfile != INVALID_HANDLE_VALUE) { |
16 |
::CloseHandle(logfile); |
17 |
logfile = INVALID_HANDLE_VALUE; |
18 |
} |
19 |
} |
20 |
private: |
21 |
static Logger& instance() { |
22 |
static Logger instance; |
23 |
return instance; |
24 |
} |
25 |
void debuglog_string(const char* label, const char* data) { |
26 |
if (logfile != INVALID_HANDLE_VALUE) { |
27 |
DWORD written; |
28 |
const char* start = data; |
29 |
WriteFile(logfile, label, strlen(label), &written, NULL); |
30 |
WriteFile(logfile, ": \"", 3, &written, NULL); |
31 |
while (*data != '\0') { |
32 |
char escaped[2] = {'\\'}; |
33 |
switch (*data) { |
34 |
case '\n': |
35 |
escaped[1] = 'n'; |
36 |
break; |
37 |
case '\r': |
38 |
escaped[1] = 'r'; |
39 |
break; |
40 |
case '\t': |
41 |
escaped[1] = 't'; |
42 |
break; |
43 |
case '\\': |
44 |
escaped[1] = '\\'; |
45 |
break; |
46 |
case '\"': |
47 |
escaped[1] = '\"'; |
48 |
break; |
49 |
} |
50 |
if (escaped[1] != '\0') { |
51 |
if (start < data) { |
52 |
WriteFile(logfile, start, data - start, &written, NULL); |
53 |
} |
54 |
WriteFile(logfile, escaped, 2, &written, NULL); |
55 |
start = data + 1; |
56 |
} |
57 |
data++; |
58 |
} |
59 |
if (start < data) { |
60 |
WriteFile(logfile, start, data - start, &written, NULL); |
61 |
} |
62 |
WriteFile(logfile, "\"\r\n", 3, &written, NULL); |
63 |
} |
64 |
} |
65 |
|
66 |
void debuglog_binary(const char* label, const unsigned char* data, int size) { |
67 |
if (logfile != INVALID_HANDLE_VALUE) { |
68 |
DWORD written; |
69 |
char buf[16]; |
70 |
int len; |
71 |
WriteFile(logfile, label, strlen(label), &written, NULL); |
72 |
WriteFile(logfile, ": [", 3, &written, NULL); |
73 |
while (size-- > 0) { |
74 |
len = wsprintf(buf, " %02x", *data++); |
75 |
WriteFile(logfile, buf, 3, &written, NULL); |
76 |
} |
77 |
WriteFile(logfile, " ]\r\n", 4, &written, NULL); |
78 |
} |
79 |
} |
80 |
|
81 |
public: |
82 |
static void open(WString filename) { |
83 |
close(); |
84 |
|
85 |
if (filename == NULL) { |
86 |
return; |
87 |
} |
88 |
|
89 |
WString full_filename; |
90 |
if (IsRelativePathW(filename)) { |
91 |
full_filename = instance().folder_ + L"\\" + filename; |
92 |
} |
93 |
else { |
94 |
full_filename = filename; |
95 |
} |
96 |
|
97 |
HANDLE logfile = ::CreateFileW(full_filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
98 |
if (logfile != INVALID_HANDLE_VALUE) { |
99 |
::SetFilePointer(logfile, 0, NULL, FILE_END); |
100 |
instance().logfile = logfile; |
101 |
} |
102 |
} |
103 |
static void close() { |
104 |
if (instance().logfile != INVALID_HANDLE_VALUE) { |
105 |
::CloseHandle(instance().logfile); |
106 |
instance().logfile = INVALID_HANDLE_VALUE; |
107 |
} |
108 |
} |
109 |
static void log(const char* label, const char* data) { |
110 |
instance().debuglog_string(label, data); |
111 |
} |
112 |
static void log(const char* label, const unsigned char* data, int size) { |
113 |
instance().debuglog_binary(label, data, size); |
114 |
} |
115 |
static void set_folder(const WString &folder) { |
116 |
instance().folder_ = folder; |
117 |
} |
118 |
}; |
119 |
|
120 |
#endif//_YEBISOCKS_LOGGER_H_ |