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