Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ariaUtil.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
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    Takes a string and splits it into a list of words. It appends the words
00109    to the outList. If there is nothing found, it will not touch the outList.
00110    @param inString the input string to split
00111    @param outList the list in which to store the words that are found
00112 */
00113 /*
00114 AREXPORT void ArUtil::splitString(std::string inString,
00115                   std::list<std::string> &outList)
00116 {
00117   const char *start, *end;
00118 
00119   // Strip off leading white space
00120   for (end=inString.c_str(); *end && isspace(*end); ++end)
00121     ;
00122   while (*end)
00123   {
00124     // Mark start of the word then find end
00125     for (start=end; *end && !isspace(*end); ++end)
00126       ;
00127     // Store the word
00128     if (*start && ((*end && isspace(*end)) || !*end))
00129       outList.push_back(std::string(start, (int)(end-start)));
00130     for (; *end && isspace(*end); ++end)
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 // WIN32
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    Works for \ and /. Returns true if something was actualy done. Sets
00231    fileOut to be what ever the answer is.
00232    @return true if the path contains a file
00233    @param fileIn input path/fileName
00234    @param fileOut output fileName
00235 */
00236 /*AREXPORT bool ArUtil::stripDir(std::string fileIn, std::string &fileOut)
00237 {
00238   const char *ptr;
00239 
00240   for (ptr=fileIn.c_str(); *ptr; ++ptr)
00241     ;
00242   for (--ptr; (ptr > fileIn.c_str()) && (*ptr != '/') && (*ptr != '\\'); --ptr)
00243     ;
00244   if ((*ptr == '/') || (*ptr == '\\'))
00245   {
00246     fileOut=ptr+1;
00247     return(true);
00248   }
00249   else
00250   {
00251     fileOut=fileIn;
00252     return(false);
00253   }
00254 }
00255 */
00256 /*
00257    Works for \ and /. Returns true if something was actualy done. Sets
00258    fileOut to be what ever the answer is.
00259    @return true if the file contains a path
00260    @param fileIn input path/fileName
00261    @param fileOut output path
00262 */
00263 /*
00264 AREXPORT bool ArUtil::stripFile(std::string fileIn, std::string &fileOut)
00265 {
00266   const char *start, *end;
00267 
00268   for (start=end=fileIn.c_str(); *end; ++end)
00269   {
00270     if ((*end == '/') || (*end == '\\'))
00271     {
00272       start=end;
00273       for (; *end && ((*end == '/') || (*end == '\\')); ++end)
00274         ;
00275     }
00276   }
00277 
00278   if (start < end)
00279   {
00280     fileOut.assign(fileIn, 0, start-fileIn.c_str());
00281     return(true);
00282   }
00283 
00284   fileOut=fileIn;
00285   return(false);
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   // if there are no quotes to strip just copy and return
00297   if (srcLen < 2 || 
00298       (src[0] != '"' || src[srcLen - 1] != '"'))
00299   {
00300     strcpy(dest, src);
00301     return true;
00302   }
00303   // we have quotes so chop of the first and last char
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   // first check boundary
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   // start it off
00392   strncpy(dest, baseDir, destLength - 1);
00393   // make sure we have a null term
00394   dest[destLength - 1] = '\0';
00395   // toss on that slash
00396   appendSlash(dest, destLength);
00397   // put on the inside dir
00398   strncat(dest, insideDir, destLength - strlen(dest) - 1);
00399   // now toss on that slash
00400   appendSlash(dest, destLength);
00401   // and now fix up all the slashes
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   // walk it, when we find one toss in the slash and incr adj so the
00526   // next characters go in the right space
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   // make sure its null terminated
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 } // end method isStrEmpty
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     //printf("Got a key\n");
00729     if (RegQueryInfoKey(hkey, NULL, NULL, NULL, &numKeys, &longestKey, NULL, 
00730             &numValues, &longestValue, &longestDataLength, NULL, NULL) == ERROR_SUCCESS)
00731     {
00732     /*
00733       printf("Have %d keys longest is %d, have %d values longest name is %d, longest data is %d\n",
00734          numKeys, longestKey, numValues, longestValue, longestDataLength);
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         //printf("Enumed value %d, name is %s, value is %s\n", i, valueName, data);
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     else
00763         printf("Couldn't enum value %d cause %d\n",i,  err);
00764         */
00765         }
00766       delete data;
00767       delete valueName;
00768     }
00769     /*
00770     else
00771       printf("QueryInfoKey failed\n");
00772       */
00773   }
00774   /*
00775   else
00776     printf("No key %d\n", err);
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: // child process just return
00872       myIsDaemonized = true;
00873       fclose(stdout);
00874       fclose(stderr);
00875       return true;
00876     case -1: // error.... fail
00877       printf("Can't fork");
00878       ArLog::log(ArLog::Terse, "ArDaemonizer: Can't fork");
00879       return false;
00880     default: // parent process
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   // TODO make this threadsafe
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 }

Generated on Tue Feb 20 10:51:40 2007 for Aria by  doxygen 1.4.0