00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __CIO_H__
00013 #define __CIO_H__
00014
00015 #include <time.h>
00016 #include <stdio.h>
00017 #include <stdarg.h>
00018 #include <string.h>
00019 #include <dirent.h>
00020 #include <unistd.h>
00021
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024
00025 #include "lib/common.h"
00026 #include "base/init.h"
00027
00028 class CIO;
00029
00030 extern CIO* sg_io;
00031
00036 enum EMessageType
00037 {
00038 M_DEBUG,
00039 M_INFO,
00040 M_NOTICE,
00041 M_WARN,
00042 M_ERROR,
00043 M_CRITICAL,
00044 M_ALERT,
00045 M_EMERGENCY,
00046 M_MESSAGEONLY
00047 };
00048
00049
00050 #define NUM_LOG_LEVELS 9
00051 #define FBUFSIZE 4096
00052
00053 #ifdef DARWIN
00054 #define CONST_DIRENT_T struct dirent
00055 #else //DARWIN
00056 #define CONST_DIRENT_T const struct dirent
00057 #endif //DARWIN
00058
00059 class CIO;
00060
00061
00062
00063 #define SG_DEBUG(...) io->message(M_DEBUG, __VA_ARGS__)
00064 #define SG_INFO(...) io->message(M_INFO, __VA_ARGS__)
00065 #define SG_WARNING(...) io->message(M_WARN, __VA_ARGS__)
00066 #define SG_ERROR(...) io->message(M_ERROR, __VA_ARGS__)
00067 #define SG_PRINT(...) io->message(M_MESSAGEONLY, __VA_ARGS__)
00068 #define SG_NOTIMPLEMENTED io->not_implemented()
00069
00070 #define SG_PROGRESS(...) io->progress(__VA_ARGS__)
00071 #define SG_ABS_PROGRESS(...) io->absolute_progress(__VA_ARGS__)
00072 #define SG_DONE() io->done()
00073
00074
00075 #define SG_SDEBUG(...) sg_io->message(M_DEBUG,__VA_ARGS__)
00076 #define SG_SINFO(...) sg_io->message(M_INFO,__VA_ARGS__)
00077 #define SG_SWARNING(...) sg_io->message(M_WARN,__VA_ARGS__)
00078 #define SG_SERROR(...) sg_io->message(M_ERROR,__VA_ARGS__)
00079 #define SG_SPRINT(...) sg_io->message(M_MESSAGEONLY,__VA_ARGS__)
00080 #define SG_SPROGRESS(...) sg_io->progress(__VA_ARGS__)
00081 #define SG_SABS_PROGRESS(...) sg_io->absolute_progress(__VA_ARGS__)
00082 #define SG_SDONE() sg_io->done()
00083 #define SG_SNOTIMPLEMENTED sg_io->not_implemented()
00084
00085 #define ASSERT(x) { if (!(x)) SG_SERROR("assertion %s failed in file %s line %d\n",#x, __FILE__, __LINE__);}
00086
00087
00094 class CIO
00095 {
00096 public:
00098 CIO();
00100 CIO(const CIO& orig);
00101
00106 void set_loglevel(EMessageType level);
00107
00112 EMessageType get_loglevel() const;
00113
00118 bool get_show_progress() const;
00119
00125 void message(EMessageType prio, const char *fmt, ... ) const;
00126
00135 void progress(
00136 float64_t current_val,
00137 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00138 const char* prefix="PROGRESS:\t");
00139
00149 void absolute_progress(
00150 float64_t current_val, float64_t val,
00151 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00152 const char* prefix="PROGRESS:\t");
00153
00158 void done();
00159
00161 inline void not_implemented() const
00162 {
00163 message(M_ERROR, "Sorry, not yet implemented\n");
00164 }
00165
00171 void buffered_message(EMessageType prio, const char *fmt, ... ) const;
00172
00178 static char* skip_spaces(char* str);
00179
00185 static char* skip_blanks(char* str);
00186
00191 inline FILE* get_target() const
00192 {
00193 return target;
00194 }
00195
00200 void set_target(FILE* target);
00201
00203 inline void set_target_to_stderr() { set_target(stderr); }
00204
00206 inline void set_target_to_stdout() { set_target(stdout); }
00207
00209 inline void enable_progress()
00210 {
00211 show_progress=true;
00212
00213
00214 if (sg_io!=this)
00215 sg_io->enable_progress();
00216 }
00217
00219 inline void disable_progress()
00220 {
00221 show_progress=false;
00222
00223
00224 if (sg_io!=this)
00225 sg_io->disable_progress();
00226 }
00227
00232 static inline void set_dirname(const char* dirname)
00233 {
00234 strncpy(directory_name, dirname, FBUFSIZE);
00235 }
00236
00243 static inline char* concat_filename(const char* filename)
00244 {
00245 if (snprintf(file_buffer, FBUFSIZE, "%s/%s", directory_name, filename) > FBUFSIZE)
00246 SG_SERROR("filename too long");
00247 SG_SDEBUG("filename=\"%s\"\n", file_buffer);
00248 return file_buffer;
00249 }
00250
00256 static inline int filter(CONST_DIRENT_T* d)
00257 {
00258 if (d)
00259 {
00260 char* fname=concat_filename(d->d_name);
00261
00262 if (!access(fname, R_OK))
00263 {
00264 struct stat s;
00265 if (!stat(fname, &s) && S_ISREG(s.st_mode))
00266 return 1;
00267 }
00268 }
00269
00270 return 0;
00271 }
00272
00277 inline int32_t ref()
00278 {
00279 ++refcount;
00280 return refcount;
00281 }
00282
00287 inline int32_t ref_count() const
00288 {
00289 return refcount;
00290 }
00291
00297 inline int32_t unref()
00298 {
00299 if (refcount==0 || --refcount==0)
00300 {
00301 delete this;
00302 return 0;
00303 }
00304 else
00305 return refcount;
00306 }
00307
00309 inline const char* get_name() { return "IO"; }
00310
00311 protected:
00318 const char* get_msg_intro(EMessageType prio) const;
00319
00320 protected:
00322 FILE* target;
00324 int64_t last_progress_time;
00326 int64_t progress_start_time;
00328 float64_t last_progress;
00330 bool show_progress;
00331
00333 EMessageType loglevel;
00335 static const EMessageType levels[NUM_LOG_LEVELS];
00337 static const char* message_strings[NUM_LOG_LEVELS];
00338
00340 static char file_buffer[FBUFSIZE];
00342 static char directory_name[FBUFSIZE];
00343
00344 private:
00345 int32_t refcount;
00346 };
00347
00348 #endif // __CIO_H__