00001 /*!@file Util/SimTime.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/SimTime.C $ 00035 // $Id: SimTime.C 12074 2009-11-24 07:51:51Z itti $ 00036 // 00037 00038 #ifndef UTIL_SIMTIME_C_DEFINED 00039 #define UTIL_SIMTIME_C_DEFINED 00040 00041 #include "Util/SimTime.H" 00042 00043 #include "Util/StringConversions.H" 00044 #include "Util/log.H" 00045 #include "Util/sformat.H" 00046 00047 #include <cstdio> // for sscanf() 00048 00049 00050 // ###################################################################### 00051 std::string SimTime::toString(bool with_suffix) const 00052 { 00053 if (with_suffix) 00054 return sformat("%g", this->secs()); 00055 else 00056 return sformat("%gs", this->secs()); 00057 } 00058 00059 // ###################################################################### 00060 SimTime SimTime::fromString(const std::string& str, 00061 const char* default_suffix) 00062 { 00063 // handle special magic words 00064 if (str.compare("max") == 0 || str.compare("MAX") == 0 || 00065 str.compare("forever") == 0 || str.compare("FOREVER") == 0 || 00066 str.compare("unlimited") == 0 || str.compare("UNLIMITED") == 0) 00067 return SimTime::MAX(); 00068 00069 std::string::size_type last_digit = str.find_last_of("0123456789"); 00070 00071 const std::string num = str.substr(0, last_digit+1); 00072 00073 double value; char junk[2]; 00074 // make an attempt to scan extra characters after the floating-point 00075 // number; we expect that there should be none, otherwise the input 00076 // is trashy (this way we can reject input like "3.x43"): 00077 if (sscanf(num.c_str(), "%lf%1s", &value, &junk[0]) != 1) 00078 LFATAL("while parsing SimTime string '%s':\n" 00079 "\tnumeric conversion failed from '%s'", 00080 str.c_str(), num.c_str()); 00081 00082 if (default_suffix==0 && last_digit+1 >= str.length()) 00083 LFATAL("while parsing SimTime string '%s':\n" 00084 "\tno suffix found in '%s' and no default suffix was given\n" 00085 "\tin the code -- to avoid this error, either add a 's' or\n" 00086 "\t'ms' suffix (i.e., '%ss' or '%sms'), or change the code\n" 00087 "\tto specify a default suffix", 00088 str.c_str(), str.c_str(), str.c_str(), str.c_str()); 00089 00090 const std::string suffix = 00091 last_digit+1 < str.length() 00092 ? str.substr(last_digit+1, str.npos) 00093 : default_suffix; 00094 00095 // now, parse the suffix and convert so that we have a number of 00096 // nanoseconds: 00097 00098 if (suffix == "s" || 00099 suffix == "sec" || 00100 suffix == "secs" || 00101 suffix == "seconds") 00102 { 00103 value *= 1000000000.0; // was seconds, now is nanoseconds 00104 } 00105 else if (suffix == "ms" || 00106 suffix == "msec" || 00107 suffix == "msecs" || 00108 suffix == "milliseconds") 00109 { 00110 value *= 1000000.0; // was milliseconds, now is nanoseconds 00111 } 00112 else if (suffix == "us" || 00113 suffix == "usec" || 00114 suffix == "usecs" || 00115 suffix == "microseconds") 00116 { 00117 value *= 1000.0; // was microseconds, now is nanoseconds 00118 } 00119 else if (suffix == "ns" || 00120 suffix == "nsec" || 00121 suffix == "nsecs" || 00122 suffix == "nanoseconds") 00123 { 00124 /* do nothing, value is already in nanoseconds */ 00125 } 00126 else if (suffix == "Hz") 00127 { 00128 value = 1.0/value; // was seconds^-1, now is seconds 00129 value *= 1000000000.0; // was seconds, now is nanoseconds 00130 } 00131 else if (suffix == "kHz") 00132 { 00133 value = 1.0/value; // was kiloseconds^-1, now is milliseconds 00134 value *= 1000000.0; // was milliseconds, now is nanoseconds 00135 } 00136 else if (suffix == "MHz") 00137 { 00138 value = 1.0/value; // was megaseconds^-1, now is microseconds 00139 value *= 1000.0; // was microseconds, now is nanoseconds 00140 } 00141 else 00142 { 00143 LFATAL("while parsing SimTime string '%s':\n" 00144 "\tunknown units suffix '%s'", 00145 str.c_str(), suffix.c_str()); 00146 } 00147 00148 const double int64min = double(std::numeric_limits<int64>::min()); 00149 const double int64max = double(std::numeric_limits<int64>::max()); 00150 00151 if (value < int64min) 00152 { 00153 LFATAL("time value '%s' (%.2ens) is too small to be represented " 00154 "(min value is %.2ens)", 00155 str.c_str(), value, int64min); 00156 } 00157 else if (value > int64max) 00158 { 00159 LFATAL("time value '%s' (%.2ens) is too large to be represented " 00160 "(max value is %.2ens)", 00161 str.c_str(), value, int64max); 00162 } 00163 00164 return SimTime::NSECS(int64(value)); 00165 } 00166 00167 // ###################################################################### 00168 /* So things look consistent in everyone's emacs... */ 00169 /* Local Variables: */ 00170 /* indent-tabs-mode: nil */ 00171 /* End: */ 00172 00173 #endif // UTIL_SIMTIME_C_DEFINED