00001 
00002 #ifndef _CKSTREAM_H
00003 #define _CKSTREAM_H
00004 
00005 #include <string.h>
00006 #include <stdio.h>
00007 
00008 #define BUF_MAXLEN  16384
00009 #define TBUF_MAXLEN   128
00010 
00011 #if defined(_WIN32)
00012 #define snprintf _snprintf
00013 #endif
00014 
00015 class _CkOStream {
00016   private:
00017     bool _isErr;
00018     size_t _buflen, _actlen;
00019     char _obuf[BUF_MAXLEN];    
00020     char _tbuf[TBUF_MAXLEN];   
00021     void output(const char *str) {
00022       _actlen += strlen(str);
00023       if(_actlen > _buflen)
00024         CmiAbort("Print Buffer Overflow!!\n");
00025       strcat(_obuf, str); 
00026     }
00027     
00028   public:
00029     _CkOStream(bool isErr=false) {
00030       _buflen=BUF_MAXLEN; 
00031       _actlen=1;
00032       _isErr = isErr; 
00033       _obuf[0] = '\0'; 
00034     }
00035     _CkOStream& endl(void) {
00036       strcat(_obuf, "\n");
00037       if(_isErr)
00038         CkError("%s", _obuf);
00039       else
00040         CkPrintf("%s", _obuf);
00041       _obuf[0] = '\0'; 
00042       _actlen=1;
00043       return *this;
00044     }
00045 
00046     _CkOStream& operator << (_CkOStream& (*f)(_CkOStream &)) {
00047       return f(*this);
00048     }
00049 #define _OPSHIFTLEFT(type, format) \
00050     _CkOStream& operator << (type x) { \
00051       int ret = snprintf(_tbuf, TBUF_MAXLEN, format, (type) x); \
00052       if (ret >= TBUF_MAXLEN) CmiPrintf("Warning: CkStream tbuf overflow!\n"); \
00053       output(_tbuf); \
00054       return *this; \
00055     }
00056 
00057     _OPSHIFTLEFT(int, "%d");
00058     _OPSHIFTLEFT(unsigned int, "%u");
00059     _OPSHIFTLEFT(short, "%hd");
00060     _OPSHIFTLEFT(unsigned short, "%hu");
00061     _OPSHIFTLEFT(long, "%ld");
00062     _OPSHIFTLEFT(unsigned long, "%lu");
00063 #if CMK_LONG_LONG_DEFINED
00064     _OPSHIFTLEFT(long long, "%lld");
00065     _OPSHIFTLEFT(unsigned long long, "%llu");
00066 #endif
00067     _OPSHIFTLEFT(char, "%c");
00068     _OPSHIFTLEFT(unsigned char, "%u");
00069     _OPSHIFTLEFT(float, "%f");
00070     _OPSHIFTLEFT(double, "%f");  
00071     _OPSHIFTLEFT(void*, "%p");
00072 
00073     
00074     _CkOStream& operator << (const char *str) {
00075       output(str);
00076       return *this;
00077     }
00078 };
00079 
00080 static inline _CkOStream& endl(_CkOStream& s)  { return s.endl(); }
00081 
00082 class _CkOutStream : public _CkOStream {
00083   public:
00084     _CkOutStream() : _CkOStream(0) {}
00085 };
00086 
00087 class _CkErrStream : public _CkOStream {
00088   public:
00089     _CkErrStream() : _CkOStream(1) {}
00090 };
00091 
00092 CkpvExtern(_CkOutStream*, _ckout);
00093 CkpvExtern(_CkErrStream*, _ckerr);
00094 
00095 class CkOStream {
00096  public:
00097   virtual ~CkOStream() {}
00098   virtual CkOStream& operator << (_CkOStream& (*f)(_CkOStream &)) = 0;
00099 #define SHIFTLEFT(type) \
00100   virtual CkOStream& operator << (type x) = 0
00101 
00102   SHIFTLEFT(int);
00103   SHIFTLEFT(unsigned int);
00104   SHIFTLEFT(short);
00105   SHIFTLEFT(unsigned short);
00106   SHIFTLEFT(long);
00107   SHIFTLEFT(unsigned long);
00108 #if CMK_LONG_LONG_DEFINED
00109   SHIFTLEFT(long long);
00110   SHIFTLEFT(unsigned long long);
00111 #endif
00112   SHIFTLEFT(char);
00113   SHIFTLEFT(unsigned char);
00114   SHIFTLEFT(float);
00115   SHIFTLEFT(double);
00116   SHIFTLEFT(const char*);
00117   SHIFTLEFT(void*);
00118 };
00119 
00120 class CkOutStream : public CkOStream {
00121   public:
00122   CkOutStream& operator << (_CkOStream& (*f)(_CkOStream &)) {
00123     f(*CkpvAccess(_ckout));
00124     return *this;
00125   }
00126 #define OUTSHIFTLEFT(type) \
00127   CkOutStream& operator << (type x) { \
00128     *CkpvAccess(_ckout) << x; \
00129     return *this; \
00130   }
00131     OUTSHIFTLEFT(int);
00132     OUTSHIFTLEFT(unsigned int);
00133     OUTSHIFTLEFT(short);
00134     OUTSHIFTLEFT(unsigned short);
00135     OUTSHIFTLEFT(long);
00136     OUTSHIFTLEFT(unsigned long);
00137 #if CMK_LONG_LONG_DEFINED
00138     OUTSHIFTLEFT(long long);
00139     OUTSHIFTLEFT(unsigned long long);
00140 #endif
00141     OUTSHIFTLEFT(char);
00142     OUTSHIFTLEFT(unsigned char);
00143     OUTSHIFTLEFT(float);
00144     OUTSHIFTLEFT(double);
00145     OUTSHIFTLEFT(const char*);
00146     OUTSHIFTLEFT(void*);
00147 };
00148 
00149 class CkErrStream : public CkOStream {
00150   public:
00151   CkErrStream& operator << (_CkOStream& (*f)(_CkOStream &)) {
00152     f(*CkpvAccess(_ckerr));
00153     return *this;
00154   }
00155 #define ERRSHIFTLEFT(type) \
00156   CkErrStream& operator << (type x) { \
00157     *CkpvAccess(_ckerr) << x; \
00158     return *this; \
00159   }
00160     ERRSHIFTLEFT(int);
00161     ERRSHIFTLEFT(unsigned int);
00162     ERRSHIFTLEFT(short);
00163     ERRSHIFTLEFT(unsigned short);
00164     ERRSHIFTLEFT(long);
00165     ERRSHIFTLEFT(unsigned long);
00166 #if CMK_LONG_LONG_DEFINED
00167     ERRSHIFTLEFT(long long);
00168     ERRSHIFTLEFT(unsigned long long);
00169 #endif
00170     ERRSHIFTLEFT(char);
00171     ERRSHIFTLEFT(unsigned char);
00172     ERRSHIFTLEFT(float);
00173     ERRSHIFTLEFT(double);
00174     ERRSHIFTLEFT(const char*);
00175     ERRSHIFTLEFT(void*);
00176 };
00177 
00178 extern CkOutStream ckout;
00179 extern CkErrStream ckerr;
00180 
00181 class CkInStream {
00182   public:
00183 #define OPSHIFTRIGHT(type, format) \
00184     CkInStream& operator >> (type& x) { \
00185       CkScanf(format, (type *)&x); \
00186       return *this; \
00187     }
00188 
00189     OPSHIFTRIGHT(int, "%d");
00190     OPSHIFTRIGHT(unsigned int, "%u");
00191     OPSHIFTRIGHT(short, "%hd");
00192     OPSHIFTRIGHT(unsigned short, "%hu");
00193     OPSHIFTRIGHT(long, "%ld");
00194     OPSHIFTRIGHT(unsigned long, "%lu");
00195 #if CMK_LONG_LONG_DEFINED
00196     OPSHIFTRIGHT(long long, "%lld");
00197     OPSHIFTRIGHT(unsigned long long, "%llu");
00198 #endif
00199     OPSHIFTRIGHT(char, "%c");
00200     OPSHIFTRIGHT(unsigned char, "%c");
00201     OPSHIFTRIGHT(float, "%f");
00202     OPSHIFTRIGHT(double, "%lf");
00203 
00204     CkInStream& operator >> (char* x) {
00205       CkScanf("%s", x);
00206       return *this;
00207     }
00208 };
00209 
00210 extern CkInStream ckin;
00211 
00212 #endif