ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/CommonLibs/plog/Util.h
Revision: 1073
Committed: Thu Oct 5 17:48:32 2017 UTC (8 years ago) by s10k
Content type: text/x-chdr
File size: 10154 byte(s)
Log Message:
added XML Tools latest version (2.0d) and s10k's common libs

File Contents

# Content
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
40 namespace 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 }