blob: 0bc738e8dcdfd442e044b8e606260befb051828a [file] [log] [blame]
kurtis.heimerl5a872472013-05-31 21:47:25 +00001/*
2* Copyright 2011 Range Networks, Inc.
3* All Rights Reserved.
4*
5* This software is distributed under multiple licenses;
6* see the COPYING file in the main directory for licensing
7* information for this specific distribuion.
8*
9* This use of this software may be subject to additional restrictions.
10* See the LEGAL file in the main directory for details.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15*/
16
17#ifndef GPRSUTILS_H
18#define GPRSUTILS_H
19#include <stdint.h>
20#include <stdarg.h>
21#include <string>
22#include <string.h>
23#include <math.h> // for sqrtf
24#include "Logger.h"
25
26
27namespace Utils {
28
29extern double timef(); // high resolution time
30extern const std::string timestr(); // A timestamp to print in messages.
31extern void sleepf(double howlong); // high resolution sleep
32extern int gcd(int x, int y);
33
34// It is irritating to create a string just to interface to the brain-damaged
35// C++ stream class, but this is only used for debug messages.
36std::string format(const char *fmt, ...) __attribute__((format (printf,1,2)));
37
38int cstrSplit(char *in, char **pargv,int maxargc, const char *splitchars=NULL);
39
40// For classes with a text() function, provide a function to return a String,
41// and also a standard << stream function that takes a pointer to the object.
42// We dont provide the function that takes a reference to the object
43// because it is too highly overloaded and generally doesnt work.
44class Text2Str {
45 public:
46 virtual void text(std::ostream &os) const = 0;
47 std::string str() const;
48};
49std::ostream& operator<<(std::ostream& os, const Text2Str *val);
50
51#if 0
52// Generic Activity Timer. Lots of controls to make everybody happy.
53class ATimer {
54 double mStart;
55 //bool mActive;
56 double mLimitTime;
57 public:
58 ATimer() : mStart(0), mLimitTime(0) { }
59 ATimer(double wLimitTime) : mStart(0), mLimitTime(wLimitTime) { }
60 void start() { mStart=timef(); }
61 void stop() { mStart=0; }
62 bool active() { return !!mStart; }
63 double elapsed() { return timef() - mStart; }
64 bool expired() { return elapsed() > mLimitTime; }
65};
66#endif
67
68
69struct BitSet {
70 unsigned mBits;
71 void setBit(unsigned whichbit) { mBits |= 1<<whichbit; }
72 void clearBit(unsigned whichbit) { mBits &= ~(1<<whichbit); }
73 unsigned getBit(unsigned whichbit) const { return mBits & (1<<whichbit); }
74 bool isSet(unsigned whichbit) const { return mBits & (1<<whichbit); }
75 unsigned bits() const { return mBits; }
76 operator int(void) const { return mBits; }
77 BitSet() { mBits = 0; }
78};
79
80// Store current, min, max and compute running average and standard deviation.
81template<class Type> struct Statistic {
82 Type mCurrent, mMin, mMax; // min,max optional initialization so you can print before adding any values.
83 unsigned mCnt;
84 double mSum;
85 //double mSum2; // sum of squares.
86 // (Type) cast needed in case Type is an enum, stupid language.
87 Statistic() : mCurrent((Type)0), mMin((Type)0), mMax((Type)0), mCnt(0), mSum(0) /*,mSum2(0)*/ {}
88 // Set the current value and add a statisical point.
89 void addPoint(Type val) {
90 mCurrent = val;
91 if (mCnt == 0 || val < mMin) {mMin = val;}
92 if (mCnt == 0 || val > mMax) {mMax = val;}
93 mCnt++;
94 mSum += val;
95 //mSum2 += val * val;
96 }
97 Type getCurrent() const { // Return current value.
98 return mCnt ? mCurrent : 0;
99 }
100 double getAvg() const { // Return average.
101 return mCnt==0 ? 0 : mSum/mCnt;
102 };
103 //float getSD() const { // Return standard deviation. Use low precision square root function.
104 // return mCnt==0 ? 0 : sqrtf(mCnt * mSum2 - mSum*mSum) / mCnt;
105 //}
106
107 void text(std::ostream &os) const { // Print everything in parens.
108 os << "("<<mCurrent;
109 if (mMin != mMax) { // Not point in printing all this stuff if min == max.
110 os <<LOGVAR2("min",mMin)<<LOGVAR2("max",mMax)<<LOGVAR2("avg",getAvg());
111 if (mCnt <= 999999) {
112 os <<LOGVAR2("N",mCnt);
113 } else { // Shorten this up:
114 char buf[10], *ep;
115 sprintf(buf,"%.3g",round(mCnt));
116 if ((ep = strchr(buf,'e')) && ep[1] == '+') { strcpy(ep+1,ep+2); }
117 os << LOGVAR2("N",buf);
118 }
119 // os<<LOGVAR2("sd",getSD()) standard deviation not interesting
120 }
121 os << ")";
122 // " min="<<mMin <<" max="<<mMax <<format(" avg=%4g sd=%3g)",getAvg(),getSD());
123 }
124 // Not sure if this works:
125 //std::string statStr() const {
126 // return (std::string)mCurrent + " min=" + (std::string) mMin +" max="+(string)mMax+ format(" avg=%4g sd=%3g",getAvg(),getSD());
127 //}
128};
129
130// This I/O mechanism is so dumb:
131std::ostream& operator<<(std::ostream& os, const Statistic<int> &stat);
132std::ostream& operator<<(std::ostream& os, const Statistic<unsigned> &stat);
133std::ostream& operator<<(std::ostream& os, const Statistic<float> &stat);
134std::ostream& operator<<(std::ostream& os, const Statistic<double> &stat);
135
136
137// Yes, they botched and left this out:
138std::ostream& operator<<(std::ostream& os, std::ostringstream& ss);
139
140std::ostream &osprintf(std::ostream &os, const char *fmt, ...) __attribute__((format (printf,2,3)));
141
142std::string replaceAll(const std::string input, const std::string search, const std::string replace);
143
144}; // namespace
145
146using namespace Utils;
147
148#endif