OSDN Git Service

VP27マージ
[peercast-im/PeerCastIM.git] / PeerCast.root / PeerCast / core / common / sys.h
1 // ------------------------------------------------
2 // File : sys.h
3 // Date: 4-apr-2002
4 // Author: giles
5 // Desc: 
6 //
7 // (c) 2002 peercast.org
8 // ------------------------------------------------
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 // ------------------------------------------------
19
20 #ifndef _SYS_H
21 #define _SYS_H
22
23 #include <string.h>
24 #include "common.h"
25
26 #define RAND(a,b) (((a = 36969 * (a & 65535) + (a >> 16)) << 16) + \
27                     (b = 18000 * (b & 65535) + (b >> 16))  )
28 extern char *stristr(const char *s1, const char *s2);
29 extern char *trimstr(char *s);
30
31
32 #define MAX_CGI_LEN 1024
33 // ------------------------------------
34 class String
35 {
36 public:
37         enum {
38                 MAX_LEN = 256
39         };
40
41         enum TYPE
42         {
43                 T_UNKNOWN,
44                 T_ASCII,
45                 T_HTML,
46                 T_ESC,
47                 T_ESCSAFE,
48                 T_META,
49                 T_METASAFE,
50                 T_BASE64,
51                 T_UNICODE,
52                 T_UNICODESAFE,
53 #ifdef WIN32
54                 T_SJIS, //JP-EX
55 #endif
56         };
57
58         String() {clear();}
59         String(const char *p, TYPE t=T_ASCII) 
60         {
61                 set(p,t);
62         }
63
64         // set from straight null terminated string
65         void set(const char *p, TYPE t=T_ASCII) 
66         {
67                 strncpy(data,p,MAX_LEN-1);
68                 data[MAX_LEN-1] = 0;
69                 type = t;
70         }
71
72         // set from quoted or unquoted null terminated string
73         void setFromString(const char *str, TYPE t=T_ASCII);
74         
75         // set from stopwatch
76         void setFromStopwatch(unsigned int t);
77
78         // set from time
79         void setFromTime(unsigned int t);
80
81
82         // from single word (end at whitespace)
83         void setFromWord(const char *str)
84         {
85                 int i;
86                 for(i=0; i<MAX_LEN-1; i++)
87                 {
88                         data[i] = *str++;
89                         if ((data[i]==0) || (data[i]==' '))
90                                 break;
91                 }
92                 data[i]=0;
93         }
94
95
96         // set from null terminated string, remove first/last chars
97         void setUnquote(const char *p, TYPE t=T_ASCII) 
98         {
99                 size_t slen = strlen(p);
100                 if (slen > 2)
101                 {
102                         if (slen >= MAX_LEN) slen = MAX_LEN;
103                         strncpy(data,p+1,slen-2);
104                         data[slen-2]=0;
105                 }else
106                         clear();
107                 type = t;
108         }
109
110         void clear() 
111         {
112                 memset(data, 0, MAX_LEN);
113                 data[0]=0;
114                 type = T_UNKNOWN;
115         }
116         void ASCII2ESC(const char *,bool);
117         void ASCII2HTML(const char *);
118         void ASCII2META(const char *,bool);
119         void ESC2ASCII(const char *);
120         void HTML2ASCII(const char *);
121         void HTML2UNICODE(const char *);
122         void BASE642ASCII(const char *);
123         void UNKNOWN2UNICODE(const char *,bool);
124 #ifdef WIN32
125         void ASCII2SJIS(const char *); //JP-EX
126 #endif
127
128         static  int     base64WordToChars(char *,const char *);
129
130         static bool isSame(const char *s1, const char *s2) {return strcmp(s1,s2)==0;}
131
132         bool startsWith(const char *s) const {return strncmp(data,s,strlen(s))==0;}
133         bool isValidURL();
134         bool isEmpty() {return data[0]==0;}
135         bool isSame(::String &s) const {return strcmp(data,s.data)==0;}
136         bool isSame(const char *s) const {return strcmp(data,s)==0;}
137         bool contains(::String &s) {return stristr(data,s.data)!=NULL;}
138         bool contains(const char *s) {return stristr(data,s)!=NULL;}
139         void append(const char *s)
140         {
141                 if ((strlen(s)+strlen(data) < (MAX_LEN-1)))
142                         strcat(data,s);
143         }
144         void append(char c)
145         {
146                 char tmp[2];
147                 tmp[0]=c;
148                 tmp[1]=0;
149                 append(tmp);
150         }
151
152         void prepend(const char *s)
153         {
154                 ::String tmp;
155                 tmp.set(s);
156                 tmp.append(data);
157                 tmp.type = type;
158                 *this = tmp;
159         }
160
161         bool operator == (const char *s) const {return isSame(s);}
162         bool operator != (const char *s) const {return !isSame(s);}
163
164         operator const char *() const {return data;}
165
166         void convertTo(TYPE t);
167
168         char    *cstr() {return data;}
169
170         static bool isWhitespace(char c) {return c==' ' || c=='\t';}
171
172         TYPE    type;
173         char    data[MAX_LEN];
174 };
175
176 // ------------------------------------
177 namespace peercast {
178 class Random {
179 public:
180         Random(int s=0x14235465)
181         {
182                 setSeed(s);
183         }
184         
185         unsigned int next()
186         {
187                 return RAND(a[0],a[1]);
188         }
189
190         void setSeed(int s)
191         {
192                 a[0] = a[1] = s;
193         }       
194         
195         unsigned long a[2];
196 };
197 }
198 // ------------------------------------
199 class Sys
200 {
201 public:
202         Sys();
203
204
205
206     virtual class ClientSocket  *createSocket() = 0;
207         virtual bool                    startThread(class ThreadInfo *) = 0;
208         virtual void                    sleep(int) = 0;
209         virtual void                    appMsg(long,long = 0) = 0;
210         virtual unsigned int    getTime() = 0;          
211         virtual double                  getDTime() = 0;         
212         virtual unsigned int    rnd() = 0;
213         virtual void                    getURL(const char *) = 0;
214         virtual void                    exit() = 0;
215         virtual bool                    hasGUI() = 0;
216         virtual void                    callLocalURL(const char *,int)=0;
217         virtual void                    executeFile(const char *) = 0;
218         virtual void                    endThread(ThreadInfo *) {}
219         virtual void                    waitThread(ThreadInfo *, int timeout = 30000) {}
220
221
222
223 #ifdef __BIG_ENDIAN__
224         unsigned short  convertEndian(unsigned short v) { return SWAP2(v); }
225         unsigned int    convertEndian(unsigned int v) { return SWAP4(v); }
226 #else
227         unsigned short  convertEndian(unsigned short v) { return v; }
228         unsigned int    convertEndian(unsigned int v) { return v; }
229 #endif
230
231
232         void    sleepIdle();
233
234         unsigned int idleSleepTime;
235         unsigned int rndSeed;
236         unsigned int numThreads;
237
238         class LogBuffer *logBuf;
239 };
240
241
242 #ifdef WIN32
243 #include <windows.h>
244
245 typedef __int64 int64_t;
246
247 #ifndef _UINTPTR_T_DEFINED
248 typedef unsigned int uintptr_t;
249 #endif
250
251 // ------------------------------------
252 class WEvent
253 {
254 public:
255         WEvent()
256         {
257                  event = ::CreateEvent(NULL, // no security attributes
258                                   TRUE, // manual-reset
259                                   FALSE,// initially non-signaled
260                                   NULL);// anonymous
261         }
262
263         ~WEvent()
264         {
265                 ::CloseHandle(event);
266         }
267
268         void    signal()
269         {
270                 ::SetEvent(event);
271         }
272
273         void    wait(int timeout = 30000)
274         {
275                 switch(::WaitForSingleObject(event, timeout))
276                 {
277           case WAIT_TIMEOUT:
278               throw TimeoutException();
279               break;
280           //case WAIT_OBJECT_0:
281               //break;
282                 }
283         }
284
285         void    reset()
286         {
287                 ::ResetEvent(event);
288         }
289
290
291
292         HANDLE event;
293 };
294
295
296
297 // ------------------------------------
298 typedef int (WINAPI *THREAD_FUNC)(ThreadInfo *);
299 typedef uintptr_t THREAD_HANDLE;
300 #define THREAD_PROC int WINAPI
301 #define vsnprintf _vsnprintf
302
303 // ------------------------------------
304 class WLock
305 {
306 public:
307         WLock()
308         {
309                 InitializeCriticalSection(&cs);
310         }
311
312
313         void    on()
314         {
315                 EnterCriticalSection(&cs);
316         }
317
318         void    off()
319         {
320                 LeaveCriticalSection(&cs);
321         }
322         
323         CRITICAL_SECTION cs;
324 };
325 #endif
326
327
328 #ifdef _UNIX
329 // ------------------------------------
330 #include <pthread.h>
331 #include <errno.h>
332
333 #ifdef __APPLE__
334 #include <sched.h>
335 #define _BIG_ENDIAN 1
336 #endif
337
338 typedef long long int64_t;
339
340 typedef int (*THREAD_FUNC)(ThreadInfo *);
341 #define THREAD_PROC int 
342 typedef pthread_t THREAD_HANDLE;
343
344 // ------------------------------------
345 #define stricmp strcasecmp
346 #define strnicmp strncasecmp
347
348
349 // ------------------------------------
350 class WEvent
351 {
352 public:
353
354         WEvent()
355         {
356         }
357
358         void    signal()
359         {
360         }
361
362         void    wait(int timeout = 30000)
363         {
364         }
365
366         void    reset()
367         {
368         }
369
370 };
371
372 // ------------------------------------
373 class WLock 
374 {
375 private:
376         pthread_mutex_t mutex;
377 public:
378         WLock()
379         {
380             const pthread_mutexattr_t mattr = 
381                 {
382 #ifdef __APPLE__                
383                         PTHREAD_MUTEX_RECURSIVE
384 #else
385                         PTHREAD_MUTEX_RECURSIVE_NP
386 #endif
387                  };
388                  
389         pthread_mutex_init( &mutex, &mattr );
390         }
391
392         ~WLock()
393         {
394         pthread_mutex_destroy( &mutex );
395         }
396
397
398         void    on()
399         {
400                 pthread_mutex_lock(&mutex);
401         }
402
403         void    off()
404         {
405                 pthread_mutex_unlock(&mutex);
406         }
407         
408 };
409 #endif
410
411 class WLockBlock
412 {
413 private:
414         WLock *lock;
415         bool flg;
416 public:
417         WLockBlock(WLock *l){
418                 lock = l;
419                 flg = false;
420         }
421         ~WLockBlock(){
422                 if (flg){
423                         lock->off();
424                         LOG_DEBUG("LOCK OFF by destructor");
425                 }
426         }
427         void on(){
428                 flg = true;
429                 lock->on();
430         }
431         void off(){
432                 flg = false;
433                 lock->off();
434         }
435 };
436
437 // ------------------------------------
438 class ThreadInfo
439 {
440 public:
441         //typedef int  (__stdcall *THREAD_FUNC)(ThreadInfo *);
442
443         ThreadInfo()
444         {
445                 active = false;
446                 finish = false;
447                 id = 0;
448                 func = NULL;
449                 data = NULL;
450         }
451
452         void    shutdown();
453
454         volatile bool   active;
455         volatile bool   finish;
456         int             id;
457         THREAD_FUNC func;
458         THREAD_HANDLE handle;
459         
460
461         void    *data;
462 };
463
464
465 // ------------------------------------
466 class LogBuffer 
467 {
468 public:
469         enum TYPE
470         {
471                 T_NONE,
472                 T_DEBUG,
473                 T_ERROR,
474                 T_NETWORK,
475                 T_CHANNEL,
476         };
477
478         LogBuffer(int i, int l)
479         {
480                 lineLen = l;
481                 maxLines = i;
482                 currLine = 0;
483                 buf = new char[lineLen*maxLines];
484                 times = new unsigned int [maxLines];
485                 types = new TYPE [maxLines];
486         }
487
488         void    clear()
489         {
490                 currLine = 0;
491         }
492         void    write(const char *, TYPE);
493         static const char *getTypeStr(TYPE t) {return logTypes[t];}
494         void    dumpHTML(class Stream &);
495
496         char *buf;
497         unsigned int *times;
498         unsigned int currLine,maxLines,lineLen;
499         TYPE    *types;
500         WLock   lock;
501         static  const char *logTypes[];
502
503 };
504
505 #define RWLOCK_READ_MAX 32
506
507 class LockBlock
508 {
509 public:
510         LockBlock(WLock &l){ flg = false; lock = l; }
511         ~LockBlock(){ if (flg) lock.off(); }
512         void lockon(){ flg = true; lock.on(); }
513         void lockoff(){ flg = false; lock.off(); }
514
515 private:
516         WLock lock;
517         bool flg;
518 };
519
520 // ------------------------------------
521 extern Sys *sys;
522
523 // ------------------------------------
524
525
526 #if _BIG_ENDIAN
527 #define CHECK_ENDIAN2(v) v=SWAP2(v)
528 #define CHECK_ENDIAN3(v) v=SWAP3(v)
529 #define CHECK_ENDIAN4(v) v=SWAP4(v)
530 #else
531 #define CHECK_ENDIAN2
532 #define CHECK_ENDIAN3
533 #define CHECK_ENDIAN4
534 #endif
535
536
537 // ------------------------------------
538 #endif
539