1 2 /* Web Polygraph http://www.web-polygraph.org/ 3 * Copyright 2003-2011 The Measurement Factory 4 * Licensed under the Apache License, Version 2.0 */ 5 6 #ifndef POLYGRAPH__BASE_ILOG_H 7 #define POLYGRAPH__BASE_ILOG_H 8 9 #include "xstd/h/iostream.h" 10 11 #include "xstd/Time.h" 12 #include "xstd/Size.h" 13 #include "xstd/NetDouble.h" 14 #include "xstd/BigSize.h" 15 #include "xstd/String.h" 16 #include "xstd/Array.h" 17 #include "xstd/Endian.h" 18 #include "xstd/NetAddr.h" 19 #include "base/Progress.h" 20 21 // some environments do not know better than #define these 22 #ifdef getc 23 #undef getc 24 #endif 25 #ifdef putc 26 #undef putc 27 #endif 28 29 namespace zlib { 30 class IFStream; 31 } 32 33 // every log entry has this prefix 34 class LogEntryPx { 35 public: LogEntryPx()36 LogEntryPx(): theCat(-1), theTag(-1) {} 37 38 bool good() const; 39 operator void*() const { return theTag > 0 ? (void*)-1 : 0; } 40 41 bool load(const void *const buf); 42 ostream &print(ostream &os) const; 43 44 public: 45 static const int TheLoadSize = 2 * sizeof(int); 46 47 Size theSize; // size, including the header 48 int theCat; // logging category 49 int theTag; // logging tag 50 }; 51 52 inline 53 ostream &operator <<(ostream &os, const LogEntryPx &px) { 54 return px.print(os); 55 } 56 57 58 // binary log, input interface 59 class ILog { 60 public: 61 typedef void (Manip)(class ILog &); 62 63 public: 64 ILog(); 65 ~ILog(); 66 67 void stream(const String &aFileName, istream *aStream); 68 void stream(const ILog &log); fileName()69 const String &fileName() const { return theFileName; } 70 istream::pos_type pos() const; 71 bool fail() const; 72 operator void*() const { return !fail() ? (void*)-1 : 0; } 73 getc()74 char getc() { char c; get(&c, 1); return c; } getb()75 bool getb() { return getc() != 0; } geti()76 int geti() { int x; return(geti(x)); } geti(int & x)77 int geti(int &x) { get(&x, sizeof(x)); return x = ntohl(x); } geti64()78 int64_t geti64() { int64_t x; return geti64(x); } geti64(int64_t & x)79 int64_t geti64(int64_t &x) { get(&x, sizeof(x)); return x = be64toh(x); } 80 int geti(int *&xs, int &count); // returns count geta(struct sockaddr_storage & a)81 sockaddr_storage &geta(struct sockaddr_storage &a) { get(&a, SizeOf(a)); return a; } 82 String &gets(String &s); 83 84 LogEntryPx begEntry(); 85 void endEntry(); 86 progress()87 const Progress &progress() const { return theProgress; } 88 89 protected: 90 void getHeader(); 91 bool get(void *const buf, const int len); 92 void ignore(const int n); 93 94 protected: 95 istream *theStream; 96 zlib::IFStream *theZStream; 97 String theFileName; 98 99 streampos theEntryEnd; // end of the current entry (last+1) 100 LogEntryPx theCurPx; // prefix of the current entry 101 Progress theProgress; // current "local time", #errs, etc. 102 }; 103 104 105 /* logging of common types */ 106 107 inline 108 ILog &operator >>(ILog &il, char &c) { 109 c = il.getc(); 110 return il; 111 } 112 113 inline 114 ILog &operator >>(ILog &il, bool &b) { 115 b = il.getb(); 116 return il; 117 } 118 119 inline 120 ILog &operator >>(ILog &il, int &x) { 121 il.geti(x); 122 return il; 123 } 124 125 inline 126 ILog &operator >>(ILog &il, int64_t &x) { 127 il.geti64(x); 128 return il; 129 } 130 131 inline 132 ILog &operator >>(ILog &il, double &x) { 133 NetDouble nd; 134 il >> nd.mnt >> nd.exp; 135 x = nd; 136 return il; 137 } 138 139 inline 140 ILog &operator >>(ILog &il, String &s) { 141 il.gets(s); 142 return il; 143 } 144 145 inline 146 ILog &operator >>(ILog &il, Time &t) { 147 t.tv_sec = il.geti(); 148 t.tv_usec = il.geti(); 149 return il; 150 } 151 152 inline 153 ILog &operator >>(ILog &il, BigSize &bs) { 154 return il >> bs.theAcc >> bs.theCnt; 155 } 156 157 inline 158 ILog &operator >>(ILog &il, Size &sz) { 159 return il >> sz.theSize; 160 } 161 162 inline 163 ILog &operator >>(ILog &il, NetAddr &a) { 164 struct sockaddr_storage ss; 165 il.geta(ss); 166 a = NetAddr(ss); 167 return il; 168 } 169 170 inline 171 ILog &operator >>(ILog &il, ILog::Manip m) { 172 m(il); 173 return il; 174 } 175 176 template <class Item> 177 inline 178 ILog &operator >>(ILog &log, Array<Item> &a) { 179 const int cnt = log.geti(); 180 if (!log) 181 return log; 182 a.resize(cnt); 183 for (int i = 0; i < cnt; ++i) 184 log >> a[i]; 185 return log; 186 } 187 188 template <class Item> 189 inline 190 ILog &operator >>(ILog &log, Array<Item *> &a) { 191 const int cnt = log.geti(); 192 if (!log) 193 return log; 194 for (int i = 0; i < a.count(); ++i) 195 delete a[i]; 196 a.clear(); 197 a.resize(cnt); 198 for (int i = log.geti(); log && i >= 0; log >> i) { 199 Must(i < cnt); 200 if (Should(!a[i])) 201 a[i] = new Item; 202 log >> *a[i]; 203 } 204 return log; 205 } 206 207 #endif 208