UnitsApi.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifdef __GNUC__
00026 # include <unistd.h>
00027 #endif
00028
00029 #include <QString>
00030 #include "Exception.h"
00031 #include "UnitsApi.h"
00032 #include "UnitsSchemaInternal.h"
00033 #include "UnitsSchemaImperial1.h"
00034 #include "UnitsSchemaMKS.h"
00035
00036
00037 #ifndef M_PI
00038 #define M_PI 3.14159265358979323846
00039 #endif
00040 #ifndef M_E
00041 #define M_E 2.71828182845904523536
00042 #endif
00043 #ifndef DOUBLE_MAX
00044 # define DOUBLE_MAX 1.7976931348623157E+308
00045 #endif
00046 #ifndef DOUBLE_MIN
00047 # define DOUBLE_MIN 2.2250738585072014E-308
00048 #endif
00049
00050 using namespace Base;
00051
00052
00053 #ifdef _MSC_VER
00054 # pragma warning(disable : 4003)
00055 # pragma warning(disable : 4018)
00056 # pragma warning(disable : 4065)
00057 # pragma warning( disable : 4273 )
00058 # pragma warning(disable : 4335) // disable MAC file format warning on VC
00059 #endif
00060
00061
00062
00063 char *QuantityNames[] = {
00064 "length" ,
00065 "area" ,
00066 "volume" ,
00067 "angle" ,
00068 "time span" ,
00069 "velocity" ,
00070 "acceleration",
00071 "mass" ,
00072 "temperature"
00073 };
00074
00075 const QString UnitsApi::getQuantityName(QuantityType t)
00076 {
00077
00078 assert(t<9);
00079
00080 return QString::fromLatin1(QuantityNames[t]);
00081 }
00082
00083
00084 UnitsSchema *UnitsApi::UserPrefSystem = new UnitsSchemaInternal();
00085
00086 double UnitsApi::UserPrefFactor [50];
00087 QString UnitsApi::UserPrefUnit [50];
00088
00089 UnitsApi::UnitsApi(const char* filter)
00090 {
00091 bool temp;
00092 Result = parse(filter,temp);
00093 }
00094
00095 UnitsApi::UnitsApi(const std::string& filter)
00096 {
00097 bool temp;
00098 Result = parse(filter.c_str(),temp);
00099 }
00100
00101 UnitsApi::~UnitsApi()
00102 {
00103 }
00104
00105 void UnitsApi::setSchema(UnitSystem s)
00106 {
00107 delete UserPrefSystem;
00108 switch (s) {
00109 case SI1 : UserPrefSystem = new UnitsSchemaInternal(); break;
00110 case SI2 : UserPrefSystem = new UnitsSchemaMKS(); break;
00111 case Imperial1: UserPrefSystem = new UnitsSchemaImperial1(); break;
00112 }
00113 UserPrefSystem->setSchemaUnits();
00114 }
00115
00116
00117 double UnitsApi::translateUnit(const char* str)
00118 {
00119 bool temp;
00120 return parse(str,temp );
00121 }
00122
00123 double UnitsApi::translateUnit(const QString & str)
00124 {
00125 bool temp;
00126 return parse(str.toUtf8() ,temp);
00127 }
00128
00129
00130
00131
00132 QString UnitsApi::toStrWithUserPrefs(QuantityType t,double Value)
00133 {
00134 return UserPrefSystem->toStrWithUserPrefs(t,Value);
00135
00136
00137 }
00138
00139 void UnitsApi::toStrWithUserPrefs(QuantityType t,double Value,QString &outValue,QString &outUnit)
00140 {
00141 UserPrefSystem->toStrWithUserPrefs(t,Value,outValue,outUnit);
00142 }
00143
00144 PyObject *UnitsApi::toPyWithUserPrefs(QuantityType t,double Value)
00145 {
00146 return PyFloat_FromDouble(Value * UserPrefFactor[t]);
00147 }
00148
00149 double UnitsApi::toDblWithUserPrefs(QuantityType t,const QString & Str)
00150 {
00151 return toDblWithUserPrefs(t,(const char*) Str.toUtf8());
00152 }
00153
00154 double UnitsApi::toDblWithUserPrefs(QuantityType t,const char* Str)
00155 {
00156 bool UsedUnit;
00157 double Value = parse( Str,UsedUnit );
00158
00159 if (UsedUnit)
00160 return Value;
00161 else
00162 return toDblWithUserPrefs(t,Value);
00163 }
00164
00165 double UnitsApi::toDblWithUserPrefs(QuantityType t,double UserVal)
00166 {
00167 return UserVal*UserPrefFactor[t];
00168 }
00169
00170 double UnitsApi::toDblWithUserPrefs(QuantityType t,PyObject *ArgObj)
00171 {
00172 if (PyString_Check(ArgObj))
00173 return toDblWithUserPrefs(t,PyString_AsString(ArgObj));
00174 else if (PyFloat_Check(ArgObj))
00175 return toDblWithUserPrefs(t,PyFloat_AsDouble(ArgObj));
00176 else if (PyInt_Check(ArgObj))
00177 return toDblWithUserPrefs(t,(double)PyInt_AsLong(ArgObj));
00178 else
00179 throw Base::Exception("Wrong parameter type!");
00180 }
00181
00182 void UnitsApi::setPrefOf(QuantityType t,const char* Str)
00183 {
00184 double Factor = translateUnit(Str);
00185 UserPrefUnit[t] = QString::fromLatin1(Str);
00186 UserPrefFactor[t] = Factor;
00187 }
00188
00189 const QString & UnitsApi::getPrefUnitOf(QuantityType t)
00190 {
00191 return UserPrefUnit[t];
00192 }
00193
00194 const double UnitsApi::getPrefFactorOf(QuantityType t)
00195 {
00196 return UserPrefFactor[t];
00197 }
00198
00199 void UnitsApi::setDefaults(void)
00200 {
00201 setPrefOf( Length ,"mm" );
00202 setPrefOf( Area ,"mm^2" );
00203 setPrefOf( Volume ,"mm^3" );
00204 setPrefOf( Angle ,"deg" );
00205 setPrefOf( TimeSpan ,"s" );
00206 setPrefOf( Velocity ,"mm/s" );
00207 setPrefOf( Acceleration ,"mm/s^2" );
00208 setPrefOf( Mass ,"kg" );
00209 setPrefOf( Temperature ,"K" );
00210
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 double ScanResult=0;
00221 bool UU = false;
00222
00223
00224 void Unit_yyerror(char *errorinfo)
00225 { throw Base::Exception(errorinfo); }
00226
00227
00228
00229 #ifdef _MSC_VER
00230 int isatty (int i) {return _isatty(i);}
00231 int fileno(FILE *stream) {return _fileno(stream);}
00232 #endif
00233
00234 namespace UnitParser {
00235
00236
00237 #define yylex UnitsApilex
00238 int UnitsApilex(void);
00239
00240
00241 #include "UnitsApi.tab.c"
00242
00243 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00244
00245 #include "lex.UnitsApi.c"
00246 #endif // DOXYGEN_SHOULD_SKIP_THIS
00247 }
00248
00249 double UnitsApi::parse(const char* buffer,bool &UsedUnit)
00250 {
00251
00252 UnitParser::YY_BUFFER_STATE my_string_buffer = UnitParser::UnitsApi_scan_string (buffer);
00253
00254 ScanResult = DOUBLE_MIN;
00255 UU = false;
00256
00257 UnitParser::Unit_yyparse ();
00258 UsedUnit = UU;
00259 UU=false;
00260
00261 UnitParser::UnitsApi_delete_buffer (my_string_buffer);
00262
00263 if (ScanResult == DOUBLE_MIN)
00264 throw Base::Exception("Unknown error in Unit expression");
00265 return ScanResult;
00266 }