source: s10k/CommonLibs/plog/Util.h@ 1077

Last change on this file since 1077 was 1073, checked in by s10k, 7 years ago

added XML Tools latest version (2.0d) and s10k's common libs

File size: 9.9 KB
Line 
1#pragma once
2#include <cassert>
3#include <cstring>
4#include <cstdio>
5#include <sstream>
6#include <fcntl.h>
7#include <sys/stat.h>
8
9#ifndef PLOG_ENABLE_WCHAR_INPUT
10# ifdef _WIN32
11# define PLOG_ENABLE_WCHAR_INPUT 1
12# else
13# define PLOG_ENABLE_WCHAR_INPUT 0
14# endif
15#endif
16
17#ifdef _WIN32
18# include <plog/WinApi.h>
19# include <time.h>
20# include <sys/timeb.h>
21# include <io.h>
22# include <share.h>
23#else
24# include <unistd.h>
25# include <sys/syscall.h>
26# include <sys/time.h>
27# include <pthread.h>
28# if PLOG_ENABLE_WCHAR_INPUT
29# include <iconv.h>
30# endif
31#endif
32
33#ifdef _WIN32
34# define _PLOG_NSTR(x) L##x
35# define PLOG_NSTR(x) _PLOG_NSTR(x)
36#else
37# define PLOG_NSTR(x) x
38#endif
39
40namespace plog
41{
42 namespace util
43 {
44#ifdef _WIN32
45 typedef std::wstring nstring;
46 typedef std::wstringstream nstringstream;
47 typedef wchar_t nchar;
48#else
49 typedef std::string nstring;
50 typedef std::stringstream nstringstream;
51 typedef char nchar;
52#endif
53
54 inline void localtime_s(struct tm* t, const time_t* time)
55 {
56#if defined(_WIN32) && defined(__BORLANDC__)
57 ::localtime_s(time, t);
58#elif defined(_WIN32) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
59 *t = *::localtime(time);
60#elif defined(_WIN32)
61 ::localtime_s(t, time);
62#else
63 ::localtime_r(time, t);
64#endif
65 }
66
67#ifdef _WIN32
68 typedef timeb Time;
69
70 inline void ftime(Time* t)
71 {
72 ::ftime(t);
73 }
74#else
75 struct Time
76 {
77 time_t time;
78 unsigned short millitm;
79 };
80
81 inline void ftime(Time* t)
82 {
83 timeval tv;
84 ::gettimeofday(&tv, NULL);
85
86 t->time = tv.tv_sec;
87 t->millitm = static_cast<unsigned short>(tv.tv_usec / 1000);
88 }
89#endif
90
91 inline unsigned int gettid()
92 {
93#ifdef _WIN32
94 return GetCurrentThreadId();
95#elif defined(__unix__)
96 return static_cast<unsigned int>(::syscall(__NR_gettid));
97#elif defined(__APPLE__)
98 uint64_t tid64;
99 pthread_threadid_np(NULL, &tid64);
100 return static_cast<unsigned int>(tid64);
101#endif
102 }
103
104#if PLOG_ENABLE_WCHAR_INPUT && !defined(_WIN32)
105 inline std::string toNarrow(const wchar_t* wstr)
106 {
107 size_t wlen = ::wcslen(wstr);
108 std::string str(wlen * sizeof(wchar_t), 0);
109
110 if (!str.empty())
111 {
112 const char* in = reinterpret_cast<const char*>(&wstr[0]);
113 char* out = &str[0];
114 size_t inBytes = wlen * sizeof(wchar_t);
115 size_t outBytes = str.size();
116
117 iconv_t cd = ::iconv_open("UTF-8", "WCHAR_T");
118 ::iconv(cd, const_cast<char**>(&in), &inBytes, &out, &outBytes);
119 ::iconv_close(cd);
120
121 str.resize(str.size() - outBytes);
122 }
123
124 return str;
125 }
126#endif
127
128#ifdef _WIN32
129 inline std::wstring toWide(const char* str)
130 {
131 size_t len = ::strlen(str);
132 std::wstring wstr(len, 0);
133
134 if (!wstr.empty())
135 {
136 int wlen = MultiByteToWideChar(codePage::kActive, 0, str, static_cast<int>(len), &wstr[0], static_cast<int>(wstr.size()));
137 wstr.resize(wlen);
138 }
139
140 return wstr;
141 }
142
143 inline std::string toUTF8(const std::wstring& wstr)
144 {
145 std::string str(wstr.size() * sizeof(wchar_t), 0);
146
147 if (!str.empty())
148 {
149 int len = WideCharToMultiByte(codePage::kUTF8, 0, wstr.c_str(), static_cast<int>(wstr.size()), &str[0], static_cast<int>(str.size()), 0, 0);
150 str.resize(len);
151 }
152
153 return str;
154 }
155#endif
156
157 inline std::string processFuncName(const char* func)
158 {
159#if (defined(_WIN32) && !defined(__MINGW32__)) || defined(__OBJC__)
160 return std::string(func);
161#else
162 const char* funcBegin = func;
163 const char* funcEnd = ::strchr(funcBegin, '(');
164
165 if (!funcEnd)
166 {
167 return std::string(func);
168 }
169
170 for (const char* i = funcEnd - 1; i >= funcBegin; --i) // search backwards for the first space char
171 {
172 if (*i == ' ')
173 {
174 funcBegin = i + 1;
175 break;
176 }
177 }
178
179 return std::string(funcBegin, funcEnd);
180#endif
181 }
182
183 inline const nchar* findExtensionDot(const nchar* fileName)
184 {
185#ifdef _WIN32
186 return std::wcsrchr(fileName, L'.');
187#else
188 return std::strrchr(fileName, '.');
189#endif
190 }
191
192 inline void splitFileName(const nchar* fileName, nstring& fileNameNoExt, nstring& fileExt)
193 {
194 const nchar* dot = findExtensionDot(fileName);
195
196 if (dot)
197 {
198 fileNameNoExt.assign(fileName, dot);
199 fileExt.assign(dot + 1);
200 }
201 else
202 {
203 fileNameNoExt.assign(fileName);
204 fileExt.clear();
205 }
206 }
207
208 class NonCopyable
209 {
210 protected:
211 NonCopyable()
212 {
213 }
214
215 private:
216 NonCopyable(const NonCopyable&);
217 NonCopyable& operator=(const NonCopyable&);
218 };
219
220 class File : NonCopyable
221 {
222 public:
223 File() : m_file(-1)
224 {
225 }
226
227 File(const nchar* fileName) : m_file(-1)
228 {
229 open(fileName);
230 }
231
232 ~File()
233 {
234 close();
235 }
236
237 off_t open(const nchar* fileName)
238 {
239#if defined(_WIN32) && (defined(__BORLANDC__) || defined(__MINGW32__))
240 m_file = ::_wsopen(fileName, _O_CREAT | _O_WRONLY | _O_BINARY, SH_DENYWR, _S_IREAD | _S_IWRITE);
241#elif defined(_WIN32)
242 ::_wsopen_s(&m_file, fileName, _O_CREAT | _O_WRONLY | _O_BINARY, _SH_DENYWR, _S_IREAD | _S_IWRITE);
243#else
244 m_file = ::open(fileName, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
245#endif
246 return seek(0, SEEK_END);
247 }
248
249 int write(const void* buf, size_t count)
250 {
251#ifdef _WIN32
252 return m_file != -1 ? ::_write(m_file, buf, static_cast<unsigned int>(count)) : -1;
253#else
254 return m_file != -1 ? static_cast<int>(::write(m_file, buf, count)) : -1;
255#endif
256 }
257
258 template<class CharType>
259 int write(const std::basic_string<CharType>& str)
260 {
261 return write(str.data(), str.size() * sizeof(CharType));
262 }
263
264 off_t seek(off_t offset, int whence)
265 {
266#ifdef _WIN32
267 return m_file != -1 ? ::_lseek(m_file, offset, whence) : -1;
268#else
269 return m_file != -1 ? ::lseek(m_file, offset, whence) : -1;
270#endif
271 }
272
273 void close()
274 {
275 if (m_file != -1)
276 {
277#ifdef _WIN32
278 ::_close(m_file);
279#else
280 ::close(m_file);
281#endif
282 m_file = -1;
283 }
284 }
285
286 static int unlink(const nchar* fileName)
287 {
288#ifdef _WIN32
289 return ::_wunlink(fileName);
290#else
291 return ::unlink(fileName);
292#endif
293 }
294
295 static int rename(const nchar* oldFilename, const nchar* newFilename)
296 {
297#ifdef _WIN32
298 return MoveFileW(oldFilename, newFilename);
299#else
300 return ::rename(oldFilename, newFilename);
301#endif
302 }
303
304 private:
305 int m_file;
306 };
307
308 class Mutex : NonCopyable
309 {
310 public:
311 Mutex()
312 {
313#ifdef _WIN32
314 InitializeCriticalSection(&m_sync);
315#else
316 ::pthread_mutex_init(&m_sync, 0);
317#endif
318 }
319
320 ~Mutex()
321 {
322#ifdef _WIN32
323 DeleteCriticalSection(&m_sync);
324#else
325 ::pthread_mutex_destroy(&m_sync);
326#endif
327 }
328
329 friend class MutexLock;
330
331 private:
332 void lock()
333 {
334#ifdef _WIN32
335 EnterCriticalSection(&m_sync);
336#else
337 ::pthread_mutex_lock(&m_sync);
338#endif
339 }
340
341 void unlock()
342 {
343#ifdef _WIN32
344 LeaveCriticalSection(&m_sync);
345#else
346 ::pthread_mutex_unlock(&m_sync);
347#endif
348 }
349
350 private:
351#ifdef _WIN32
352 CRITICAL_SECTION m_sync;
353#else
354 pthread_mutex_t m_sync;
355#endif
356 };
357
358 class MutexLock : NonCopyable
359 {
360 public:
361 MutexLock(Mutex& mutex) : m_mutex(mutex)
362 {
363 m_mutex.lock();
364 }
365
366 ~MutexLock()
367 {
368 m_mutex.unlock();
369 }
370
371 private:
372 Mutex& m_mutex;
373 };
374
375 template<class T>
376 class Singleton : NonCopyable
377 {
378 public:
379 Singleton()
380 {
381 assert(!m_instance);
382 m_instance = static_cast<T*>(this);
383 }
384
385 ~Singleton()
386 {
387 assert(m_instance);
388 m_instance = 0;
389 }
390
391 static T* getInstance()
392 {
393 return m_instance;
394 }
395
396 private:
397 static T* m_instance;
398 };
399
400 template<class T>
401 T* Singleton<T>::m_instance = NULL;
402 }
403}
Note: See TracBrowser for help on using the repository browser.