Main Page | Namespace List | Alphabetical List | Class List | Directories | File List | Class Members | File Members

Utilities.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   SpikeStream Library                                                   *
00003  *   Copyright (C) 2007 by David Gamez                                     *
00004  *   david@davidgamez.eu                                                   *
00005  *   Version 0.1                                                           *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 
00023 //SpikeStream includes
00024 #include "Utilities.h"
00025 
00026 //Other includes
00027 #include <math.h>
00028 #include <iostream>
00029 using namespace std;
00030 
00031 //Testing debug variables
00032 //#define TEST_ROUND
00033 
00034 
00035 /*! The maximum value of a short. */
00036 #define MAX_SHORT_VALUE 32768
00037 
00038 /*! The minimum value of a short. */
00039 #define MIN_SHORT_VALUE -32768
00040 
00041 /*! The maximum value of an unsigned short. */
00042 #define MAX_USHORT_VALUE 65536
00043 
00044 
00045 /*! Exception thrown when there is a number conversion error. */
00046 class NumConversionException : public exception{
00047 
00048   virtual const char* what() const throw(){
00049     return "Number conversion error";
00050   }
00051 } numConversionException;
00052 
00053 
00054 
00055 /*! Exception thrown when there is a different kind of utilities error. */
00056 class UtilitiesException : public exception{
00057 
00058   virtual const char* what() const throw(){
00059     return "Utilities error";
00060   }
00061 } genUtilitiesException;
00062 
00063 
00064 //-------------------------------------------------------------------------
00065 //---------------------- PUBLIC STATIC METHODS ----------------------------
00066 //-------------------------------------------------------------------------
00067 
00068 /*! Returns the absolute value of the number.*/
00069 int Utilities::absVal(const int& num){
00070         if(num < 0)
00071                 return num * -1;
00072         return num;
00073 }
00074 
00075 
00076 /*! Returns the absolute value of the number.*/
00077 double Utilities::absVal(const double& num){
00078         if(num < 0.0)
00079                 return num * -1.0;
00080         return num;
00081 }
00082 
00083 
00084 /*! Returns true if string1 = string2 without the possibility of a 
00085         buffer overflow. */
00086 bool Utilities::cStringEquals(const char *cString1, const char *cString2, int length){
00087         for(int i=0; i<length; ++i){
00088                 if(cString1[i] != cString2[i]){
00089                         return false;
00090                 }
00091                 //Both strings are shorter than length, but equal so return true
00092                 else if(cString1[i] == '\0')
00093                         return true;
00094         }
00095         //Have not returned so far, so strings must be equal over the specified length
00096         return true;
00097 }
00098 
00099 
00100 /*! Converts cstring to double. */
00101 double Utilities::getDouble(const char *cString){
00102         int pointCount = 0;//Records the number of points in the double
00103         int eCount = 0;//Records the number of 'e's in the double for floating point stuff
00104         int dashCount =0;//Records the number of '-'s in the double excluding the first one
00105         int plusCount = 0;//Records the number of '+'s in the double
00106 
00107         //First check to see if first character is a negative sign or a digit
00108         if((cString[0] == '-') || isdigit(cString[0])){
00109                 //Work through rest of characters to check they are digits or the letter E or e and there is not more than 1 point
00110                 for(int i=1; i<strlen(cString); i++){
00111                         if(cString[i] == '.'){
00112                                 ++pointCount;
00113                                 if(pointCount > 1){
00114                                         cerr<<"Utilities: ERROR IN CSTRING TO DOUBLE CONVERSION. TOO MANY POINTS IN CSTRING: \""<<cString<<"\""<<endl;
00115                                         throw numConversionException;
00116                                 }
00117                         }
00118                         else if(cString[i] == 'E' || cString[i] == 'e'){
00119                                 ++eCount;
00120                                 if(eCount > 1){
00121                                         cerr<<"Utilities: ERROR IN CSTRING TO DOUBLE CONVERSION. TOO MANY 'e's IN CSTRING: \""<<cString<<"\""<<endl;
00122                                         throw numConversionException;
00123                                 }
00124                         }
00125                         else if(cString[i] == '-'){
00126                                 ++dashCount;
00127                                 if(dashCount > 1){
00128                                         cerr<<"Utilities: ERROR IN CSTRING TO DOUBLE CONVERSION. TOO MANY '-'s IN CSTRING: \""<<cString<<"\""<<endl;
00129                                         throw numConversionException;
00130                                 }
00131                         }
00132                         else if(cString[i] == '+'){
00133                                 ++plusCount;
00134                                 if(plusCount > 1){
00135                                         cerr<<"Utilities: ERROR IN CSTRING TO DOUBLE CONVERSION. TOO MANY '+'s IN CSTRING: \""<<cString<<"\""<<endl;
00136                                         throw numConversionException;
00137                                 }
00138                         }
00139                         else if(!isdigit(cString[i])){
00140                                 cerr<<"Utilities: ERROR IN CSTRING TO DOUBLE CONVERSION. CSTRING CONTAINS NON DIGITS: \""<<cString<<"\""<<endl;
00141                                 throw numConversionException;
00142                         }
00143                 }
00144                 //Convert and return the new double.
00145                 return atof(cString);
00146         }
00147         else {
00148                 cerr<<"Utilities: ERROR IN CSTRING TO DOUBLE CONVERSION. FIRST CHARACTER IN CSTRING CONTAINS NON DIGITS: \""<<cString<<"\""<<endl;
00149                 throw numConversionException;
00150         }
00151 }
00152 
00153 
00154 /*! Converts string to double. */
00155 double Utilities::getDouble(string s){
00156         return Utilities::getDouble(s.data());
00157 }
00158 
00159 
00160 /*! Converts cstring to signed integer. */
00161 int Utilities::getInt(const char *cString){
00162         //First check to see if first character is a negative sign or a digit
00163         if((cString[0] == '-') || isdigit(cString[0])){
00164                 for(int i=1; i<strlen(cString); i++){//Work through rest of characters to check they are digits
00165                         if(!isdigit(cString[i])){
00166                                 cerr<<"Utilities: ERROR IN CSTRING TO INT CONVERSION. CSTRING CONTAINS NON DIGITS: \""<<cString<<"\""<<endl;
00167                                 throw numConversionException;
00168                         }
00169                 }
00170                 //Create and return the new integer.
00171                 int newInt = atoi(cString);
00172                 return newInt;
00173         }
00174         else {
00175                 cerr<<"Utilities: ERROR IN CSTRING TO INT CONVERSION. CSTRING CONTAINS NON DIGITS: \""<<cString<<"\""<<endl;
00176                 throw numConversionException;
00177         }
00178 }
00179 
00180 
00181 /*! Converts string to integer. */
00182 int Utilities::getInt(string s){
00183         return Utilities::getInt(s.data());
00184 }
00185 
00186 
00187 /*! Extracts NeuronGrpID from string of the form "layerName[NeuronGrpID]". */
00188 unsigned int Utilities::getNeuronGrpID(string neurGrpStr){
00189          //Chop off the first part of the string up to the bracket: string should equal "NeuronGrpID]"
00190     neurGrpStr = neurGrpStr.substr( neurGrpStr.find('[') + 1);
00191         string uIntStr  = "";
00192         int counter = 0;
00193         while(neurGrpStr[counter] != ']'){
00194                 uIntStr += neurGrpStr[counter];
00195                 ++counter;
00196                 if(counter == 100){
00197                         cerr<<"Utilities: ERROR EXTRACTING NEURON GROUP ID FROM STRING: "<<neurGrpStr<<endl;
00198                         throw genUtilitiesException;
00199                 }
00200         }
00201         return getUInt(uIntStr);
00202 }
00203 
00204 
00205 /*! Returns a random unsigned integer betwen 0 and rangeHigh.
00206         rand() returns a number between 0 and RANGE_MAX, so dividing
00207         this by RANGE MAX gives a number between 0 and 1.0 */
00208 unsigned int Utilities::getRandomUInt(unsigned int rangeHigh){
00209         return (unsigned int)rint( (double)rangeHigh * ( (double)rand() / (double)RAND_MAX ));
00210 }
00211 
00212 
00213 /*! Converts cstring to short. */
00214 short Utilities::getShort(const char *cString){
00215         int tempInt = getInt(cString);
00216         if((tempInt > MAX_SHORT_VALUE) || (tempInt < MIN_SHORT_VALUE)){//Check it is in range for short
00217                 cerr<<"Utilities: UNSIGNED SHORT IS OUTSIDE OF SPECIFIED RANGE: "<<tempInt<<endl;
00218                 throw numConversionException;
00219         }
00220         return (short)tempInt;
00221 }
00222 
00223 
00224 /*! Converts string to short. */
00225 short Utilities::getShort(string str){
00226         return getShort(str.data());
00227 }
00228 
00229 
00230 /*! Converts cstring to unsigned integer. */
00231 unsigned int Utilities::getUInt(const char *cString){
00232         //First check that all characters are digits. Unsigned int so no negative sign allowed
00233         for(int i=0; i<strlen(cString); i++){
00234                 if(!isdigit(cString[i])){
00235                         cerr<<"Utilities: ERROR IN CSTRING TO UINT CONVERSION. CSTRING CONTAINS NON DIGITS: \""<<cString<<"\""<<endl;
00236                         throw numConversionException;
00237                 }
00238         }
00239         int newInt = atoi(cString);
00240         return newInt;
00241 }
00242 
00243 
00244 /*! Converts string to unsigned integer. */
00245 unsigned int Utilities::getUInt(string s){
00246         return Utilities::getUInt(s.data());
00247 }
00248 
00249 
00250 /*! Converts cstring to unsigned short. */
00251 unsigned short Utilities::getUShort(const char *cString){
00252         //First check that all characters are digits. Unsigned int so no negative sign allowed
00253         for(int i=0; i<strlen(cString); i++){
00254                 if(!isdigit(cString[i])){
00255                         cerr<<"Utilities: ERROR IN CSTRING TO UINT CONVERSION. CSTRING CONTAINS NON DIGITS: \""<<cString<<"\""<<endl;
00256                         throw numConversionException;
00257                 }
00258         }
00259         int newInt = atoi(cString);
00260         if(newInt >= 0 && newInt < MAX_USHORT_VALUE)
00261                 return newInt;
00262         cerr<<"Utilities: UNSIGNED SHORT IS OUTSIDE OF SPECIFIED RANGE: "<<newInt<<endl;
00263         throw numConversionException;
00264 }
00265 
00266 
00267 /*! Converts string to unsigned short. */
00268 unsigned short Utilities::getUShort(string s){
00269         return Utilities::getUShort(s.data());
00270 }
00271 
00272 
00273 /*! Rounds the given double to the specified number of decimal places. */
00274 double Utilities::round(double tempDoub, unsigned int numPlaces){
00275         #ifdef TEST_ROUND
00276                 cout<<"Rounding "<<tempDoub<<" to "<<numPlaces<<" decimal places. ";
00277         #endif//TEST_ROUND
00278 
00279         tempDoub = tempDoub * ( pow(10.0, (double)numPlaces) );
00280         tempDoub = rint(tempDoub);
00281         tempDoub = tempDoub / ( pow(10.0, (double)numPlaces) );
00282 
00283         #ifdef TEST_ROUND
00284                 cout<<"Result =  "<<tempDoub<<endl;
00285         #endif//TEST_ROUND
00286 
00287         return tempDoub;
00288 }
00289 
00290 
00291 /*! Rounds the given double to two decimal places. */
00292 void Utilities::roundTwoDecimalPlaces(double &tempDoub){
00293         tempDoub = tempDoub * 100.0;
00294         tempDoub = rint(tempDoub);
00295         tempDoub = tempDoub * 0.01;
00296 }
00297 
00298 
00299 /*! Adds source onto the end of target without potential buffer overflow. */
00300 void Utilities::safeCStringCat(char target[], const char source[], int targetSize){
00301         //Do intitial checks on target size
00302         if(targetSize < 0){
00303                 cerr<<"Utilities: String target size less than 0"<<endl;
00304                 throw genUtilitiesException;
00305         }
00306         else if (targetSize != (int)strlen(target)){
00307                 cerr<<"Utilities: TARGET LENGTH "<<strlen(target)<<" DOES NOT MATCH targetSize "<<targetSize<<endl;
00308                 throw genUtilitiesException;
00309         }
00310         
00311         // Find the position of the null character in target
00312         int endLocation = 0;
00313         for(int i=0; i<targetSize; i++){
00314                 if(target[i] == '\0'){
00315                         endLocation = i;
00316                         break;
00317                 }
00318         }
00319         
00320         //Check that new size of string will fit within target
00321         int newLength = endLocation + strlen(source);
00322         if(newLength > targetSize - 1){
00323                 cerr<<"Utilities: SOURCE CSTRING TOO LARGE FOR DESTINATION CSTRING"<<endl;
00324                 throw genUtilitiesException;
00325         }
00326         
00327         //Add source onto the end of target
00328         int i;
00329         for(i=endLocation; i< newLength; i++) //Copy everything up to newLength-1
00330                 target[i] = source[i];
00331         target[i] = '\0';//Finish string with null character
00332 }
00333 
00334 
00335 /*! Carries out a safe copy of source cstring to target cstring that is no larger than targetSize. */
00336 void Utilities::safeCStringCopy(char target[], const char source[], int targetSize){
00337         int newLength = strlen(source);
00338         if(newLength > targetSize){
00339                 cerr<<"Utilities: SOURCE CSTRING TOO LARGE FOR DESTINATION CSTRING"<<endl;
00340                 throw genUtilitiesException;
00341         }
00342         int i;
00343         for(i=0; i< newLength; ++i) //Copy everything up to newLength-1
00344                 target[i] = source[i];
00345         target[i] = '\0';//Finish string with null character
00346 }
00347 

Generated on Mon Sep 3 22:18:50 2007 for SpikeStream Library by  doxygen 1.4.4