aboutsummaryrefslogtreecommitdiffstats
path: root/CommonLibs/Utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CommonLibs/Utils.cpp')
-rw-r--r--CommonLibs/Utils.cpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/CommonLibs/Utils.cpp b/CommonLibs/Utils.cpp
new file mode 100644
index 0000000..1da95fa
--- /dev/null
+++ b/CommonLibs/Utils.cpp
@@ -0,0 +1,211 @@
+/*
+* Copyright 2011 Range Networks, Inc.
+* All Rights Reserved.
+*
+* This software is distributed under multiple licenses;
+* see the COPYING file in the main directory for licensing
+* information for this specific distribuion.
+*
+* This use of this software may be subject to additional restrictions.
+* See the LEGAL file in the main directory for details.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+*/
+
+#include <unistd.h> // For usleep
+#include <sys/time.h> // For gettimeofday
+#include <stdio.h> // For vsnprintf
+#include <ostream> // For ostream
+#include <sstream> // For ostringstream
+#include <string.h> // For strcpy
+//#include "GSMCommon.h"
+#include "Utils.h"
+#include "MemoryLeak.h"
+
+namespace Utils {
+
+MemStats gMemStats;
+int gMemLeakDebug = 0;
+
+MemStats::MemStats()
+{
+ memset(mMemNow,0,sizeof(mMemNow));
+ memset(mMemTotal,0,sizeof(mMemTotal));
+ memset(mMemName,0,sizeof(mMemName));
+}
+
+void MemStats::text(std::ostream &os)
+{
+ os << "Structs current total:\n";
+ for (int i = 0; i < mMax; i++) {
+ os << "\t" << (mMemName[i] ? mMemName[i] : "unknown") << " " << mMemNow[i] << " " << mMemTotal[i] << "\n";
+ }
+}
+
+void MemStats::memChkNew(MemoryNames memIndex, const char *id)
+{
+ /*std::cout << "new " #type "\n";*/
+ mMemNow[memIndex]++;
+ mMemTotal[memIndex]++;
+ mMemName[memIndex] = id;
+}
+
+void MemStats::memChkDel(MemoryNames memIndex, const char *id)
+{
+ /*std::cout << "del " #type "\n";*/
+ mMemNow[memIndex]--;
+ if (mMemNow[memIndex] < 0) {
+ LOG(ERR) << "Memory underflow on type "<<id;
+ if (gMemLeakDebug) assert(0);
+ mMemNow[memIndex] += 100; // Prevent another message for a while.
+ }
+}
+
+std::ostream& operator<<(std::ostream& os, std::ostringstream& ss)
+{
+ return os << ss.str();
+}
+
+std::ostream &osprintf(std::ostream &os, const char *fmt, ...)
+{
+ va_list ap;
+ char buf[300];
+ va_start(ap,fmt);
+ int n = vsnprintf(buf,300,fmt,ap);
+ va_end(ap);
+ if (n >= (300-4)) { strcpy(&buf[(300-4)],"..."); }
+ os << buf;
+ return os;
+}
+
+std::string format(const char *fmt, ...)
+{
+ va_list ap;
+ char buf[300];
+ va_start(ap,fmt);
+ int n = vsnprintf(buf,300,fmt,ap);
+ va_end(ap);
+ if (n >= (300-4)) { strcpy(&buf[(300-4)],"..."); }
+ return std::string(buf);
+}
+
+// Return time in seconds with high resolution.
+// Note: In the past I found this to be a surprisingly expensive system call in linux.
+double timef()
+{
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
+ return tv.tv_usec / 1000000.0 + tv.tv_sec;
+}
+
+const std::string timestr()
+{
+ struct timeval tv;
+ struct tm tm;
+ gettimeofday(&tv,NULL);
+ localtime_r(&tv.tv_sec,&tm);
+ unsigned tenths = tv.tv_usec / 100000; // Rounding down is ok.
+ return format(" %02d:%02d:%02d.%1d",tm.tm_hour,tm.tm_min,tm.tm_sec,tenths);
+}
+
+// High resolution sleep for the specified time.
+// Return FALSE if time is already past.
+void sleepf(double howlong)
+{
+ if (howlong <= 0.00001) return; // Less than 10 usecs, forget it.
+ usleep((useconds_t) (1000000.0 * howlong));
+}
+
+//bool sleepuntil(double untilwhen)
+//{
+ //double now = timef();
+ //double howlong = untilwhen - now; // Fractional time in seconds.
+ // We are not worrying about overflow because all times should be in the near future.
+ //if (howlong <= 0.00001) return false; // Less than 10 usecs, forget it.
+ //sleepf(sleeptime);
+//}
+
+std::string Text2Str::str() const
+{
+ std::ostringstream ss;
+ text(ss);
+ return ss.str();
+}
+
+std::ostream& operator<<(std::ostream& os, const Text2Str *val)
+{
+ std::ostringstream ss;
+ if (val) {
+ val->text(ss);
+ os << ss.str();
+ } else {
+ os << "(null)";
+ }
+ return os;
+}
+
+// Greatest Common Denominator.
+// This is by Doug Brown.
+int gcd(int x, int y)
+{
+ if (x > y) {
+ return x % y == 0 ? y : gcd(y, x % y);
+ } else {
+ return y % x == 0 ? x : gcd(x, y % x);
+ }
+}
+
+
+// Split a C string into an argc,argv array in place; the input string is modified.
+// Returns argc, and places results in argv, up to maxargc elements.
+// The final argv receives the rest of the input string from maxargc on,
+// even if it contains additional splitchars.
+// The correct idiom for use is to make a copy of your string, like this:
+// char *copy = strcpy((char*)alloca(the_string.length()+1),the_string.c_str());
+// char *argv[2];
+// int argc = cstrSplit(copy,argv,2,NULL);
+// If you want to detect the error of too many arguments, add 1 to argv, like this:
+// char *argv[3];
+// int argc = cstrSplit(copy,argv,3,NULL);
+// if (argc == 3) { error("too many arguments"; }
+int cstrSplit(char *in, char **pargv,int maxargc, const char *splitchars)
+{
+ if (splitchars == NULL) { splitchars = " \t\r\n"; } // Default is any space.
+ int argc = 0;
+ while (argc < maxargc) {
+ while (*in && strchr(splitchars,*in)) {in++;} // scan past any splitchars
+ if (! *in) return argc; // return if finished.
+ pargv[argc++] = in; // save ptr to start of arg.
+ in = strpbrk(in,splitchars); // go to end of arg.
+ if (!in) return argc; // return if finished.
+ *in++ = 0; // zero terminate this arg.
+ }
+ return argc;
+}
+
+std::ostream& operator<<(std::ostream& os, const Statistic<int> &stat) { stat.text(os); return os; }
+std::ostream& operator<<(std::ostream& os, const Statistic<unsigned> &stat) { stat.text(os); return os; }
+std::ostream& operator<<(std::ostream& os, const Statistic<float> &stat) { stat.text(os); return os; }
+std::ostream& operator<<(std::ostream& os, const Statistic<double> &stat) { stat.text(os); return os; }
+
+std::string replaceAll(const std::string input, const std::string search, const std::string replace)
+{
+ std::string output = input;
+ int index = 0;
+
+ while (true) {
+ index = output.find(search, index);
+ if (index == std::string::npos) {
+ break;
+ }
+
+ output.replace(index, replace.length(), replace);
+ index += replace.length();
+ }
+
+ return output;
+}
+
+};