OSDN Git Service

リレー数上限をチャンネル毎に設定出来るように修正。
[peercast-im/PeerCastIM.git] / c: / 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                 int 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                 data[0]=0;
113                 type = T_UNKNOWN;
114         }
115         void ASCII2ESC(const char *,bool);
116         void ASCII2HTML(const char *);
117         void ASCII2META(const char *,bool);
118         void ESC2ASCII(const char *);
119         void HTML2ASCII(const char *);
120         void HTML2UNICODE(const char *);
121         void BASE642ASCII(const char *);
122         void UNKNOWN2UNICODE(const char *,bool);
123 #ifdef WIN32
124         void ASCII2SJIS(const char *); //JP-EX
125 #endif
126
127         static  int     base64WordToChars(char *,const char *);
128
129         static bool isSame(const char *s1, const char *s2) {return strcmp(s1,s2)==0;}
130
131         bool startsWith(const char *s) const {return strncmp(data,s,strlen(s))==0;}
132         bool isValidURL();
133         bool isEmpty() {return data[0]==0;}
134         bool isSame(::String &s) const {return strcmp(data,s.data)==0;}
135         bool isSame(const char *s) const {return strcmp(data,s)==0;}
136         bool contains(::String &s) {return stristr(data,s.data)!=NULL;}
137         bool contains(const char *s) {return stristr(data,s)!=NULL;}
138         void append(const char *s)
139         {
140                 if ((strlen(s)+strlen(data) < (MAX_LEN-1)))
141                         strcat(data,s);
142         }
143         void append(char c)
144         {
145                 char tmp[2];
146                 tmp[0]=c;
147                 tmp[1]=0;
148                 append(tmp);
149         }
150
151         void prepend(const char *s)
152         {
153                 ::String tmp;
154                 tmp.set(s);
155                 tmp.append(data);
156                 tmp.type = type;
157                 *this = tmp;
158         }
159
160         bool operator == (const char *s) const {return isSame(s);}
161         bool operator != (const char *s) const {return !isSame(s);}
162
163         operator const char *() const {return data;}
164
165         void convertTo(TYPE t);
166
167         char    *cstr() {return data;}
168
169         static bool isWhitespace(char c) {return c==' ' || c=='\t';}
170
171         TYPE    type;
172         char    data[MAX_LEN];
173 };
174
175 // ------------------------------------
176 namespace peercast {
177 class Random {
178 public:
179         Random(int s=0x14235465)
180         {
181                 setSeed(s);
182         }
183         
184         unsigned int next()
185         {
186                 return RAND(a[0],a[1]);
187         }
188
189         void setSeed(int s)
190         {
191                 a[0] = a[1] = s;
192         }       
193         
194         unsigned long a[2];
195 };
196 }
197 // ------------------------------------
198 class Sys
199 {
200 public:
201         Sys();
202
203
204
205     virtual class ClientSocket  *createSocket() = 0;
206         virtual bool                    startThread(class ThreadInfo *) = 0;
207         virtual void                    sleep(int) = 0;
208         virtual void                    appMsg(long,long = 0) = 0;
209         virtual unsigned int    getTime() = 0;          
210         virtual double                  getDTime() = 0;         
211         virtual unsigned int    rnd() = 0;
212         virtual void                    getURL(const char *) = 0;
213         virtual void                    exit() = 0;
214         virtual bool                    hasGUI() = 0;
215         virtual void                    callLocalURL(const char *,int)=0;
216         virtual void                    executeFile(const char *) = 0;
217         virtual void                    endThread(ThreadInfo *) {}
218         virtual void                    waitThread(ThreadInfo *, int timeout = 30000) {}
219
220
221
222 #ifdef __BIG_ENDIAN__
223         unsigned short  convertEndian(unsigned short v) { return SWAP2(v); }
224         unsigned int    convertEndian(unsigned int v) { return SWAP4(v); }
225 #else
226         unsigned short  convertEndian(unsigned short v) { return v; }
227         unsigned int    convertEndian(unsigned int v) { return v; }
228 #endif
229
230
231         void    sleepIdle();
232
233         unsigned int idleSleepTime;
234         unsigned int rndSeed;
235         unsigned int numThreads;
236
237         class LogBuffer *logBuf;
238 };
239
240
241 #ifdef WIN32
242 #include <windows.h>
243
244 typedef __int64 int64_t;
245
246
247 // ------------------------------------
248 class WEvent
249 {
250 public:
251         WEvent()
252         {
253                  event = ::CreateEvent(NULL, // no security attributes
254                                   TRUE, // manual-reset
255                                   FALSE,// initially non-signaled
256                                   NULL);// anonymous
257         }
258
259         ~WEvent()
260         {
261                 ::CloseHandle(event);
262         }
263
264         void    signal()
265         {
266                 ::SetEvent(event);
267         }
268
269         void    wait(int timeout = 30000)
270         {
271                 switch(::WaitForSingleObject(event, timeout))
272                 {
273           case WAIT_TIMEOUT:
274               throw TimeoutException();
275               break;
276           //case WAIT_OBJECT_0:
277               //break;
278                 }
279         }
280
281         void    reset()
282         {
283                 ::ResetEvent(event);
284         }
285
286
287
288         HANDLE event;
289 };
290
291
292
293 // ------------------------------------
294 typedef int (WINAPI *THREAD_FUNC)(ThreadInfo *);
295 typedef unsigned int THREAD_HANDLE;
296 #define THREAD_PROC int WINAPI
297 #define vsnprintf _vsnprintf
298
299 // ------------------------------------
300 class WLock
301 {
302 public:
303         WLock()
304         {
305                 InitializeCriticalSection(&cs);
306         }
307
308
309         void    on()
310         {
311                 EnterCriticalSection(&cs);
312         }
313
314         void    off()
315         {
316                 LeaveCriticalSection(&cs);
317         }
318         
319         CRITICAL_SECTION cs;
320 };
321 #endif
322
323
324 #ifdef _UNIX
325 // ------------------------------------
326 #include <pthread.h>
327 #include <errno.h>
328
329 #ifdef __APPLE__
330 #include <sched.h>
331 #define _BIG_ENDIAN 1
332 #endif
333
334 typedef long long int64_t;
335
336 typedef int (*THREAD_FUNC)(ThreadInfo *);
337 #define THREAD_PROC int 
338 typedef pthread_t THREAD_HANDLE;
339
340 // ------------------------------------
341 #define stricmp strcasecmp
342 #define strnicmp strncasecmp
343
344
345 // ------------------------------------
346 class WEvent
347 {
348 public:
349
350         WEvent()
351         {
352         }
353
354         void    signal()
355         {
356         }
357
358         void    wait(int timeout = 30000)
359         {
360         }
361
362         void    reset()
363         {
364         }
365
366 };
367
368 // ------------------------------------
369 class WLock 
370 {
371 private:
372         pthread_mutex_t mutex;
373 public:
374         WLock()
375         {
376             const pthread_mutexattr_t mattr = 
377                 {
378 #ifdef __APPLE__                
379                         PTHREAD_MUTEX_RECURSIVE
380 #else
381                         PTHREAD_MUTEX_RECURSIVE_NP
382 #endif
383                  };
384                  
385         pthread_mutex_init( &mutex, &mattr );
386         }
387
388         ~WLock()
389         {
390         pthread_mutex_destroy( &mutex );
391         }
392
393
394         void    on()
395         {
396                 pthread_mutex_lock(&mutex);
397         }
398
399         void    off()
400         {
401                 pthread_mutex_unlock(&mutex);
402         }
403         
404 };
405 #endif
406
407 class WLockBlock
408 {
409 private:
410         WLock *lock;
411         bool flg;
412 public:
413         WLockBlock(WLock *l){
414                 lock = l;
415                 flg = false;
416         }
417         ~WLockBlock(){
418                 if (flg){
419                         lock->off();
420                         LOG_DEBUG("LOCK OFF by destructor");
421                 }
422         }
423         void on(){
424                 flg = true;
425                 lock->on();
426         }
427         void off(){
428                 flg = false;
429                 lock->off();
430         }
431 };
432
433 // ------------------------------------
434 class ThreadInfo
435 {
436 public:
437         //typedef int  (__stdcall *THREAD_FUNC)(ThreadInfo *);
438
439         ThreadInfo()
440         {
441                 active = false;
442                 finish = false;
443                 id = 0;
444                 func = NULL;
445                 data = NULL;
446         }
447
448         void    shutdown();
449
450         volatile bool   active;
451         volatile bool   finish;
452         int             id;
453         THREAD_FUNC func;
454         THREAD_HANDLE handle;
455         
456
457         void    *data;
458 };
459
460
461 // ------------------------------------
462 class LogBuffer 
463 {
464 public:
465         enum TYPE
466         {
467                 T_NONE,
468                 T_DEBUG,
469                 T_ERROR,
470                 T_NETWORK,
471                 T_CHANNEL,
472         };
473
474         LogBuffer(int i, int l)
475         {
476                 lineLen = l;
477                 maxLines = i;
478                 currLine = 0;
479                 buf = new char[lineLen*maxLines];
480                 times = new unsigned int [maxLines];
481                 types = new TYPE [maxLines];
482         }
483
484         void    clear()
485         {
486                 currLine = 0;
487         }
488         void    write(const char *, TYPE);
489         static const char *getTypeStr(TYPE t) {return logTypes[t];}
490         void    dumpHTML(class Stream &);
491
492         char *buf;
493         unsigned int *times;
494         unsigned int currLine,maxLines,lineLen;
495         TYPE    *types;
496         WLock   lock;
497         static  const char *logTypes[];
498
499 };
500
501 #define RWLOCK_READ_MAX 32
502
503 class LockBlock
504 {
505 public:
506         LockBlock(WLock &l){ flg = false; lock = l; }
507         ~LockBlock(){ if (flg) lock.off(); }
508         void lockon(){ flg = true; lock.on(); }
509         void lockoff(){ flg = false; lock.off(); }
510
511 private:
512         WLock lock;
513         bool flg;
514 };
515
516 // ------------------------------------
517 extern Sys *sys;
518
519 // ------------------------------------
520
521
522 #if _BIG_ENDIAN
523 #define CHECK_ENDIAN2(v) v=SWAP2(v)
524 #define CHECK_ENDIAN3(v) v=SWAP3(v)
525 #define CHECK_ENDIAN4(v) v=SWAP4(v)
526 #else
527 #define CHECK_ENDIAN2
528 #define CHECK_ENDIAN3
529 #define CHECK_ENDIAN4
530 #endif
531
532
533 // ------------------------------------
534 #endif
535