00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <math.h>
00033 #include <ctype.h>
00034 #ifndef WIN32
00035 #include <sys/time.h>
00036 #include <stdarg.h>
00037 #include <unistd.h>
00038 #endif
00039
00040 #include "ariaInternal.h"
00041 #include "ariaTypedefs.h"
00042 #include "ariaUtil.h"
00043
00044 #ifdef WIN32
00045 AREXPORT const char *ArUtil::COM1 = "COM1";
00046 AREXPORT const char *ArUtil::COM2 = "COM2";
00047 AREXPORT const char *ArUtil::COM3 = "COM3";
00048 AREXPORT const char *ArUtil::COM4 = "COM4";
00049 #else // ifndef WIN32
00050 const char *ArUtil::COM1 = "/dev/ttyS0";
00051 const char *ArUtil::COM2 = "/dev/ttyS1";
00052 const char *ArUtil::COM3 = "/dev/ttyS2";
00053 const char *ArUtil::COM4 = "/dev/ttyS3";
00054 #endif // WIN32
00055
00056 AREXPORT const char *ArUtil::TRUESTRING = "true";
00057 AREXPORT const char *ArUtil::FALSESTRING = "false";
00058
00076 AREXPORT void ArUtil::sleep(unsigned int ms)
00077 {
00078 #ifdef WIN32
00079 Sleep(ms);
00080 #endif // WIN32
00081 #ifdef linux
00082 if (ms > 10)
00083 ms -= 10;
00084 usleep(ms * 1000);
00085 #endif // linux
00086
00087 }
00088
00094 AREXPORT unsigned int ArUtil::getTime(void)
00095 {
00096 #ifdef WIN32
00097 return timeGetTime();
00098 #endif // WIN32
00099
00100 #ifndef WIN32
00101 struct timeval tv;
00102 gettimeofday(&tv,NULL);
00103 return tv.tv_usec/1000 + (tv.tv_sec % 1000000)*1000;
00104 #endif
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 #ifdef WIN32
00136
00141 AREXPORT long ArUtil::sizeFile(std::string fileName)
00142 {
00143 struct _stat buf;
00144
00145 if (_stat(fileName.c_str(), &buf) < 0)
00146 return(-1);
00147
00148 if (!(buf.st_mode | _S_IFREG))
00149 return(-1);
00150
00151 return(buf.st_size);
00152 }
00153
00158 AREXPORT long ArUtil::sizeFile(const char * fileName)
00159 {
00160 struct _stat buf;
00161
00162 if (_stat(fileName, &buf) < 0)
00163 return(-1);
00164
00165 if (!(buf.st_mode | _S_IFREG))
00166 return(-1);
00167
00168 return(buf.st_size);
00169 }
00170
00171 #else
00172
00173 AREXPORT long ArUtil::sizeFile(std::string fileName)
00174 {
00175 struct stat buf;
00176
00177 if (stat(fileName.c_str(), &buf) < 0)
00178 {
00179 perror("stat");
00180 return(-1);
00181 }
00182
00183 if (!S_ISREG(buf.st_mode))
00184 return(-1);
00185
00186 return(buf.st_size);
00187 }
00188
00189
00194 AREXPORT long ArUtil::sizeFile(const char * fileName)
00195 {
00196 struct stat buf;
00197
00198 if (stat(fileName, &buf) < 0)
00199 {
00200 perror("stat");
00201 return(-1);
00202 }
00203
00204 if (!S_ISREG(buf.st_mode))
00205 return(-1);
00206
00207 return(buf.st_size);
00208 }
00209
00210 #endif // WIN32
00211
00216 AREXPORT bool ArUtil::findFile(const char *fileName)
00217 {
00218 FILE *fp;
00219
00220 if ((fp=fopen(fileName, "r")))
00221 {
00222 fclose(fp);
00223 return(true);
00224 }
00225 else
00226 return(false);
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 AREXPORT bool ArUtil::stripQuotes(char *dest, const char *src, size_t destLen)
00289 {
00290 size_t srcLen = strlen(src);
00291 if (destLen < srcLen + 1)
00292 {
00293 ArLog::log(ArLog::Normal, "ArUtil::stripQuotes: destLen isn't long enough to fit copy its %d should be %d", destLen, srcLen + 1);
00294 return false;
00295 }
00296
00297 if (srcLen < 2 ||
00298 (src[0] != '"' || src[srcLen - 1] != '"'))
00299 {
00300 strcpy(dest, src);
00301 return true;
00302 }
00303
00304 strncpy(dest, &src[1], srcLen - 1);
00305 dest[srcLen - 2] = '\0';
00306 return true;
00307 }
00308
00316 AREXPORT void ArUtil::appendSlash(char *path, size_t pathLength)
00317 {
00318
00319 size_t len;
00320 len = strlen(path);
00321 if (len > pathLength - 2)
00322 return;
00323
00324 if (len == 0 || (path[len - 1] != '\\' && path[len - 1] != '/'))
00325 {
00326 #ifdef WIN32
00327 path[len] = '\\';
00328 #else
00329 path[len] = '/';
00330 #endif
00331 path[len + 1] = '\0';
00332 }
00333 }
00334
00339 AREXPORT void ArUtil::fixSlashes(char *path, size_t pathLength)
00340 {
00341 #ifdef WIN32
00342 fixSlashesBackward(path, pathLength);
00343 #else
00344 fixSlashesForward(path, pathLength);
00345 #endif
00346 }
00347
00352 AREXPORT void ArUtil::fixSlashesBackward(char *path, size_t pathLength)
00353 {
00354 for (size_t i=0; path[i] != '\0' && i < pathLength; i++)
00355 {
00356 if (path[i] == '/')
00357 path[i]='\\';
00358 }
00359 }
00360
00365 AREXPORT void ArUtil::fixSlashesForward(char *path, size_t pathLength)
00366 {
00367
00368 for (size_t i=0; path[i] != '\0' && i < pathLength; i++)
00369 {
00370 if (path[i] == '\\')
00371 path[i]='/';
00372 }
00373 }
00374
00387 AREXPORT void ArUtil::addDirectories(char *dest, size_t destLength,
00388 const char *baseDir,
00389 const char *insideDir)
00390 {
00391
00392 strncpy(dest, baseDir, destLength - 1);
00393
00394 dest[destLength - 1] = '\0';
00395
00396 appendSlash(dest, destLength);
00397
00398 strncat(dest, insideDir, destLength - strlen(dest) - 1);
00399
00400 appendSlash(dest, destLength);
00401
00402 fixSlashes(dest, destLength);
00403 }
00404
00414 AREXPORT int ArUtil::strcmp(std::string str, std::string str2)
00415 {
00416 return ::strcmp(str.c_str(), str2.c_str());
00417 }
00418
00428 AREXPORT int ArUtil::strcmp(std::string str, const char *str2)
00429 {
00430 return ::strcmp(str.c_str(), str2);
00431 }
00432
00442 AREXPORT int ArUtil::strcmp(const char *str, std::string str2)
00443 {
00444 return ::strcmp(str, str2.c_str());
00445 }
00446
00456 AREXPORT int ArUtil::strcmp(const char *str, const char *str2)
00457 {
00458 return ::strcmp(str, str2);
00459 }
00460
00461
00470 AREXPORT int ArUtil::strcasecmp(std::string str, std::string str2)
00471 {
00472 return ::strcasecmp(str.c_str(), str2.c_str());
00473 }
00474
00483 AREXPORT int ArUtil::strcasecmp(std::string str, const char *str2)
00484 {
00485 return ::strcasecmp(str.c_str(), str2);
00486 }
00487
00496 AREXPORT int ArUtil::strcasecmp(const char *str, std::string str2)
00497 {
00498 return ::strcasecmp(str, str2.c_str());
00499 }
00500
00509 AREXPORT int ArUtil::strcasecmp(const char *str, const char *str2)
00510 {
00511 return ::strcasecmp(str, str2);
00512 }
00513
00520 AREXPORT void ArUtil::escapeSpaces(char *dest, const char *src, size_t maxLen)
00521 {
00522 size_t i, adj, len;
00523
00524 len = strlen(src);
00525
00526
00527 for (i = 0, adj = 0; i < len && i + adj < maxLen; i++)
00528 {
00529 if (src[i] == ' ')
00530 {
00531 dest[i+adj] = '\\';
00532 adj++;
00533 }
00534 dest[i+adj] = src[i];
00535 }
00536
00537 dest[i+adj] = '\0';
00538 }
00539
00545 AREXPORT void ArUtil::lower(char *dest, const char *src, size_t maxLen)
00546 {
00547 size_t i;
00548 size_t len;
00549
00550 len = strlen(src);
00551 for (i = 0; i < len && i < maxLen; i++)
00552 dest[i] = tolower(src[i]);
00553 dest[i] = '\0';
00554
00555 }
00556
00557
00558 AREXPORT bool ArUtil::isOnlyAlphaNumeric(const char *str)
00559 {
00560 unsigned int ui;
00561 unsigned int len;
00562 if (str == NULL)
00563 return true;
00564 for (ui = 0, len = sizeof(str); ui < len; ui++)
00565 {
00566 if (!isalpha(str[ui]) && !isdigit(str[ui]) && str[ui] != '\0')
00567 return false;
00568 }
00569 return true;
00570 }
00571
00572 AREXPORT bool ArUtil::isStrEmpty(const char *str)
00573 {
00574 if (str == NULL) {
00575 return true;
00576 }
00577 if (str[0] == '\0') {
00578 return true;
00579 }
00580 return false;
00581
00582 }
00583
00584
00585 AREXPORT const char *ArUtil::convertBool(int val)
00586 {
00587 if (val)
00588 return TRUESTRING;
00589 else
00590 return FALSESTRING;
00591 }
00592
00593 AREXPORT double ArUtil::atof(const char *nptr)
00594 {
00595 if (strcasecmp(nptr, "inf") == 0)
00596 return HUGE_VAL;
00597 else if (strcasecmp(nptr, "-inf") == 0)
00598 return -HUGE_VAL;
00599 else
00600 return ::atof(nptr);
00601 }
00602
00603 AREXPORT void ArUtil::functorPrintf(ArFunctor1<const char *> *functor,
00604 char *str, ...)
00605 {
00606 char buf[2048];
00607 va_list ptr;
00608 va_start(ptr, str);
00609 vsprintf(buf, str, ptr);
00610 functor->invoke(buf);
00611 va_end(ptr);
00612 }
00613
00614 AREXPORT void ArUtil::writeToFile(const char *str, FILE *file)
00615 {
00616 fprintf(file, str);
00617 }
00618
00619
00632 AREXPORT bool ArUtil::getStringFromFile(const char *fileName,
00633 char *str, size_t strLen)
00634 {
00635 FILE *strFile;
00636 unsigned int i;
00637
00638 if ((strFile = fopen(fileName, "r")) != NULL)
00639 {
00640 fgets(str, strLen, strFile);
00641 for (i = 0; i < strLen; i++)
00642 {
00643 if (str[i] == '\r' || str[i] == '\n' || str[i] == '\0')
00644 {
00645 str[i] = '\0';
00646 break;
00647 }
00648 }
00649 }
00650 else
00651 {
00652 str[0] = '\0';
00653 return false;
00654 }
00655 return true;
00656 }
00657
00676 AREXPORT bool ArUtil::getStringFromRegistry(REGKEY root,
00677 const char *key,
00678 const char *value,
00679 char *str,
00680 int len)
00681 {
00682 #ifndef WIN32
00683 return false;
00684 #else // WIN32
00685
00686 HKEY hkey;
00687 int err;
00688 int i;
00689 unsigned long numKeys;
00690 unsigned long longestKey;
00691 unsigned long numValues;
00692 unsigned long longestValue;
00693 unsigned long longestDataLength;
00694 char *valueName;
00695 unsigned long valueLength;
00696 unsigned long type;
00697 char *data;
00698 unsigned long dataLength;
00699 HKEY rootKey;
00700
00701
00702 switch (root)
00703 {
00704 case REGKEY_CLASSES_ROOT:
00705 rootKey = HKEY_CLASSES_ROOT;
00706 break;
00707 case REGKEY_CURRENT_CONFIG:
00708 rootKey = HKEY_CURRENT_CONFIG;
00709 break;
00710 case REGKEY_CURRENT_USER:
00711 rootKey = HKEY_CURRENT_USER;
00712 break;
00713 case REGKEY_LOCAL_MACHINE:
00714 rootKey = HKEY_LOCAL_MACHINE;
00715 break;
00716 case REGKEY_USERS:
00717 rootKey=HKEY_USERS;
00718 break;
00719 default:
00720 ArLog::log(ArLog::Terse,
00721 "ArUtil::getStringFromRegistry: Bad root key given.");
00722 return false;
00723 }
00724
00725
00726 if ((err = RegOpenKeyEx(rootKey, key, 0, KEY_READ, &hkey)) == ERROR_SUCCESS)
00727 {
00728
00729 if (RegQueryInfoKey(hkey, NULL, NULL, NULL, &numKeys, &longestKey, NULL,
00730 &numValues, &longestValue, &longestDataLength, NULL, NULL) == ERROR_SUCCESS)
00731 {
00732
00733
00734
00735
00736 data = new char[longestDataLength+2];
00737 valueName = new char[longestValue+2];
00738 for (i = 0; i < numValues; ++i)
00739 {
00740 dataLength = longestDataLength+1;
00741 valueLength = longestValue+1;
00742 if ((err = RegEnumValue(hkey, i, valueName, &valueLength, NULL,
00743 &type, (unsigned char *)data, &dataLength)) == ERROR_SUCCESS)
00744 {
00745
00746 if (strcmp(value, valueName) == 0)
00747 {
00748 if (len < dataLength)
00749 {
00750 ArLog::log(ArLog::Terse,"ArUtil::getStringFromRegistry: str passed in not long enough for data.");
00751 delete data;
00752 delete valueName;
00753 return false;
00754 }
00755 strncpy(str, data, len);
00756 delete data;
00757 delete valueName;
00758 return true;
00759 }
00760 }
00761
00762
00763
00764
00765 }
00766 delete data;
00767 delete valueName;
00768 }
00769
00770
00771
00772
00773 }
00774
00775
00776
00777
00778 return false;
00779 #endif
00780 }
00781
00782 AREXPORT ArRunningAverage::ArRunningAverage(size_t numToAverage)
00783 {
00784 myNumToAverage = numToAverage;
00785 myTotal = 0;
00786 myNum = 0;
00787 }
00788
00789 AREXPORT ArRunningAverage::~ArRunningAverage()
00790 {
00791
00792 }
00793
00794 AREXPORT double ArRunningAverage::getAverage(void) const
00795 {
00796 return myTotal / myNum;
00797 }
00798
00799 AREXPORT void ArRunningAverage::add(double val)
00800 {
00801 myTotal += val;
00802 myNum++;
00803 myVals.push_front(val);
00804 if (myVals.size() > myNumToAverage || myNum > myNumToAverage)
00805 {
00806 myTotal -= myVals.back();
00807 myNum--;
00808 myVals.pop_back();
00809 }
00810 }
00811
00812 AREXPORT void ArRunningAverage::clear(void)
00813 {
00814 while (myVals.size() > 0)
00815 myVals.pop_back();
00816 myNum = 0;
00817 myTotal = 0;
00818 }
00819
00820 AREXPORT size_t ArRunningAverage::getNumToAverage(void) const
00821 {
00822 return myNumToAverage;
00823 }
00824
00825 AREXPORT void ArRunningAverage::setNumToAverage(size_t numToAverage)
00826 {
00827 myNumToAverage = numToAverage;
00828 while (myVals.size() > myNumToAverage)
00829 {
00830 myTotal -= myVals.back();
00831 myNum--;
00832 myVals.pop_back();
00833 }
00834 }
00835
00836 #ifndef WIN32
00837
00838 AREXPORT ArDaemonizer::ArDaemonizer(int *argc, char **argv) :
00839 myParser(argc, argv),
00840 myLogOptionsCB(this, &ArDaemonizer::logOptions)
00841 {
00842 myIsDaemonized = false;
00843 Aria::addLogOptionsCB(&myLogOptionsCB);
00844 }
00845
00846 AREXPORT ArDaemonizer::~ArDaemonizer()
00847 {
00848
00849 }
00850
00851 AREXPORT bool ArDaemonizer::daemonize(void)
00852 {
00853 if (myParser.checkArgument("-daemonize") ||
00854 myParser.checkArgument("-d"))
00855 {
00856 return forceDaemonize();
00857 }
00858 else
00859 return true;
00860
00861 }
00862
00867 AREXPORT bool ArDaemonizer::forceDaemonize(void)
00868 {
00869 switch (fork())
00870 {
00871 case 0:
00872 myIsDaemonized = true;
00873 fclose(stdout);
00874 fclose(stderr);
00875 return true;
00876 case -1:
00877 printf("Can't fork");
00878 ArLog::log(ArLog::Terse, "ArDaemonizer: Can't fork");
00879 return false;
00880 default:
00881 printf("Daemon started\n");
00882 exit(0);
00883 }
00884 }
00885
00886 AREXPORT void ArDaemonizer::logOptions(void) const
00887 {
00888 ArLog::log(ArLog::Terse, "Options for Daemonizing:");
00889 ArLog::log(ArLog::Terse, "-daemonize");
00890 ArLog::log(ArLog::Terse, "-d");
00891 ArLog::log(ArLog::Terse, "");
00892 }
00893
00894 #endif // WIN32
00895
00896
00897 std::map<ArPriority::Priority, std::string> ArPriority::ourPriorityNames;
00898 std::string ArPriority::ourUnknownPriorityName;
00899 bool ArPriority::ourStringsInited = false;
00900
00901 AREXPORT const char *ArPriority::getPriorityName(Priority priority)
00902 {
00903
00904 if (!ourStringsInited)
00905 {
00906 ourPriorityNames[IMPORTANT] = "Important";
00907 ourPriorityNames[NORMAL] = "Normal";
00908 ourPriorityNames[TRIVIAL] = "Detailed";
00909 ourPriorityNames[DETAILED] = "Detailed";
00910 ourUnknownPriorityName = "Unknown";
00911 ourStringsInited = true;
00912 }
00913 return ourPriorityNames[priority].c_str();
00914 }
00915
00916 AREXPORT void ArUtil::putCurrentYearInString(char* s, size_t len)
00917 {
00918 struct tm t;
00919 ArUtil::localtime(&t);
00920 snprintf(s, len, "%4d", 1900 + t.tm_year);
00921 s[len-1] = '\0';
00922 }
00923 AREXPORT void ArUtil::putCurrentMonthInString(char* s, size_t len)
00924 {
00925
00926 struct tm t;
00927 ArUtil::localtime(&t);
00928 snprintf(s, len, "%02d", t.tm_mon);
00929 s[len-1] = '\0';
00930 }
00931 AREXPORT void ArUtil::putCurrentDayInString(char* s, size_t len)
00932 {
00933 struct tm t;
00934 ArUtil::localtime(&t);
00935 snprintf(s, len, "%02d", t.tm_mday);
00936 s[len-1] = '\0';
00937 }
00938 AREXPORT void ArUtil::putCurrentHourInString(char* s, size_t len)
00939 {
00940 struct tm t;
00941 ArUtil::localtime(&t);
00942 snprintf(s, len, "%02d", t.tm_hour);
00943 s[len-1] = '\0';
00944 }
00945 AREXPORT void ArUtil::putCurrentMinuteInString(char* s, size_t len)
00946 {
00947 struct tm t;
00948 ArUtil::localtime(&t);
00949 snprintf(s, len, "%02d", t.tm_min);
00950 s[len-1] = '\0';
00951 }
00952 AREXPORT void ArUtil::putCurrentSecondInString(char* s, size_t len)
00953 {
00954 struct tm t;
00955 ArUtil::localtime(&t);
00956 snprintf(s, len, "%02d", t.tm_sec);
00957 s[len-1] = '\0';
00958 }
00959
00960
00961 AREXPORT bool ArUtil::localtime(const time_t *timep, struct tm *result)
00962 {
00963
00964 #ifdef WIN32
00965 struct tm *r = ::localtime(timep);
00966 if(r == NULL) return false;
00967 *result = *r;
00968 return true;
00969 #else
00970 return (::localtime_r(timep, result) != NULL);
00971 #endif
00972 }
00973
00974
00979 AREXPORT bool ArUtil::localtime(struct tm *result)
00980 {
00981 time_t now = time(NULL);
00982 return ArUtil::localtime(&now, result);
00983 }
00984
00985 AREXPORT ArCallbackList::ArCallbackList(const char *name,
00986 ArLog::LogLevel logLevel)
00987 {
00988 myName = name;
00989 setLogLevel(logLevel);
00990 }
00991
00992 AREXPORT ArCallbackList::~ArCallbackList()
00993 {
00994
00995 }
00996
00997 AREXPORT void ArCallbackList::addCallback(
00998 ArFunctor *functor, int position)
00999 {
01000 myDataMutex.lock();
01001 myList.insert(
01002 std::pair<int, ArFunctor *>(-position,
01003 functor));
01004 myDataMutex.unlock();
01005 }
01006
01007 AREXPORT void ArCallbackList::remCallback(ArFunctor *functor)
01008 {
01009 myDataMutex.lock();
01010 std::map<int, ArFunctor *>::iterator it;
01011
01012 for (it = myList.begin(); it != myList.end(); it++)
01013 {
01014 if ((*it).second == functor)
01015 {
01016 myList.erase(it);
01017 myDataMutex.unlock();
01018 remCallback(functor);
01019 return;
01020 }
01021 }
01022 myDataMutex.unlock();
01023 }
01024
01025
01026 AREXPORT void ArCallbackList::setName(const char *name)
01027 {
01028 myDataMutex.lock();
01029 myName = name;
01030 myDataMutex.unlock();
01031 }
01032
01033 AREXPORT void ArCallbackList::setLogLevel(ArLog::LogLevel logLevel)
01034 {
01035 myDataMutex.lock();
01036 myLogLevel = logLevel;
01037 myDataMutex.unlock();
01038 }
01039
01040 AREXPORT void ArCallbackList::invoke(void)
01041 {
01042 myDataMutex.lock();
01043
01044 std::map<int, ArFunctor *>::iterator it;
01045 ArFunctor *functor;
01046
01047 ArLog::log(myLogLevel, "%s: Starting calls", myName.c_str());
01048
01049 for (it = myList.begin();
01050 it != myList.end();
01051 it++)
01052 {
01053 functor = (*it).second;
01054 if (functor == NULL)
01055 continue;
01056
01057 if (functor->getName() != NULL && functor->getName()[0] != '\0')
01058 ArLog::log(myLogLevel, "%s: Calling functor '%s' at %d",
01059 myName, functor->getName(), -(*it).first);
01060 else
01061 ArLog::log(myLogLevel, "%s: Calling unnamed functor at %d",
01062 myName.c_str(), -(*it).first);
01063 functor->invoke();
01064 }
01065
01066 ArLog::log(myLogLevel, "%s: Ended calls", myName.c_str());
01067 myDataMutex.unlock();
01068 }