//************************************************************************************************** // UnitsBase.cpp * // --------------- * // Started : 2014-03-08 * // Last Update : 2015-01-18 * // Copyright : (C) 2014-2016 MSWaters * //************************************************************************************************** //************************************************************************************************** // * // This program is free software; you can redistribute it and/or modify it under the * // terms of the GNU General Public License as published by the Free Software Foundation; * // either version 3 of the License, or (at your option) any later version. * // * //************************************************************************************************** #include "UnitsBase.hpp" //************************************************************************************************** // Constructor. UnitsBase::UnitsBase( void ) { } //************************************************************************************************** // Destructor. UnitsBase::~UnitsBase( ) { } //************************************************************************************************** // Combine a value with it's units to produce the equivalent long value. // // Argument List : // dfValue - The float value // // Return Values : // Success - The value combined with the units as a long // Failure - NOVAL_LONG long UnitsBase::liGetValue( double dfValue ) { double df1; long li1; df1 = dfGetValue( dfValue ); if( df1 == NOVAL_DBL ) return( NOVAL_LNG ); if( df1<(double)-LONG_MAX || df1>(double)LONG_MAX ) return( NOVAL_LNG ); li1 = lround( df1 ); return( li1 ); } //************************************************************************************************** // Combine a value with it's units to produce a single value. // // Argument List : // dfValue - The float value // // Return Values : // Success - The value combined with the units as a double // Failure - NOVAL_DBL double UnitsBase::dfGetValue( double dfValue ) { wxString os1; double df1; int i1; if( ! bIsCreated( ) ) return( NOVAL_DBL ); if( dfValue == 0.0 ) return( 0.0 ); i1 = iGetUnits( ); if( i1 == NOVAL_INT ) return( NOVAL_DBL ); df1 = dfValue; if( i1 != 0 ) df1 *= EXP10( (double) i1 ); return( df1 ); } //************************************************************************************************** // Combine a value with it's units to produce the equivalent string value. // // Argument List : // dfValue - The float value // iRes - The resolution (ie. how many digits after the decimal point) // // Return Values : // Success - The string containing the engineering format // Failure - An empty string const wxString & UnitsBase::rosGetValue( double dfValue, int iRes ) { static wxString osValue; wxString osFmt, os1; wxChar oc1; int i1; osValue.Empty( ); if( ! bIsCreated( ) ) return( osValue ); // Create the format string and convert fValue to a string osFmt = wxString::Format( wxT("%%#.%if"), iRes ); if( os1.Printf( osFmt, dfValue ) < 0 ) return( osValue ); osValue = os1; // Add the units to the float value os1 = rosGetUnits( ); if( ! os1.IsEmpty( ) ) { oc1 = os1.GetChar( 0 ); os1.MakeLower( ); if( os1.StartsWith( wxT("micro") ) ) osValue << wxT('u'); else if( os1.StartsWith( wxT("x 1") ) ) { i1 = iGetUnits( ); if( CnvtType::bUnitExpToPfx( i1, &oc1 ) ) osValue << oc1; } else if( os1.StartsWith( wxT("metre") ) ) ; // Do nothing else { if( CnvtType::bUnitPfxToExp( oc1, &i1 ) ) osValue << oc1; if( oc1 == wxT('M') ) osValue << wxT("EG"); } } return( osValue ); } //************************************************************************************************** // Return the units string associated with a units enumerated type specifier. // // (Eg. eUNITS_RES returns "Ohm".) // // Argument List : // eUType - the units enumerated type // rosUnits - the units string // // Return Values : // true - Success // false - Failure bool UnitsBase::bGetUnitsType( eTypeUnits eUType, wxString & rosUnits ) { switch( eUType ) { case eUNITS_CAP : // Capacitance rosUnits = wxT("F"); break; case eUNITS_IND : // Inductance rosUnits = wxT("H"); break; case eUNITS_RES : // Resistance rosUnits = wxT("Ohm"); break; case eUNITS_COND : // Conductance rosUnits = wxT("S"); break; case eUNITS_VOLT : // Voltage rosUnits = wxT("V"); break; case eUNITS_CURR : // Current rosUnits = wxT("A"); break; case eUNITS_TIME : // Time rosUnits = wxT("Sec"); break; case eUNITS_FREQ : // Frequency rosUnits = wxT("Hz"); break; case eUNITS_CHRG : // Charge rosUnits = wxT("C"); break; case eUNITS_PHAD : // Phase / angle in Degree rosUnits = wxT("Degree"); break; case eUNITS_PHAR : // Phase / angle in Radian rosUnits = wxT("Radian"); break; case eUNITS_TMPC : // Temperature in Celcius rosUnits = wxT("Deg.C"); break; case eUNITS_TMPF : // Temperature in Fahrenheit rosUnits = wxT("Deg.F"); break; case eUNITS_EXP : // Dimensionless (append an exponent) case eUNITS_NONE : // No units specified rosUnits = wxT(""); break; default : // No associated units return( false ); } return( true ); } //************************************************************************************************** // Attempt to determine the units type from a string. // // Eg. 34.0mVolt produces the units type of eUNITS_VOLT. // // Note : This function will not cope multi-character units prefixes eg. milliVolt would fail. // // Argument List : // rosUnits - the string containing a units specifier // peUType - the returned enumerated units type // // Return Values : // true - Success // false - Failure bool UnitsBase::bGetUnitsType( const wxString & rosUnits, eTypeUnits * peUType ) { wxString os1, os2; wxChar oc1, oc2; size_t sz1; int i1; // Set the default units type value *peUType = eUNITS_NONE; // Extract everything after the numeric value including any units prefix sz1 = rosUnits.find_first_not_of( wxT(" .-+0123456789Ee") ); if( sz1 == std::string::npos ) return( false ); if( CnvtType::bUnitPfxToExp( rosUnits[ sz1 ], &i1 ) ) sz1++; if( sz1 >= rosUnits.length( ) ) return( false ); os1 = rosUnits.Mid( sz1 ).Upper( ); // Now attempt to determine the units type switch( (char) os1.GetChar( 0 ) ) { case wxT('A') : if( os1.length( ) > 1 ) if( ! os1.StartsWith( wxT("AMP") ) ) return( false ); *peUType = eUNITS_CURR; // Current (A or Amp) break; case wxT('C') : if( os1.length( ) > 1 ) if( ! os1.StartsWith( wxT("COULOMB") ) ) return( false ); *peUType = eUNITS_CHRG; // Current (A or Amp) break; case wxT('D') : if( ! os1.StartsWith( wxT("DEG") ) ) return( false ); oc1 = oc2 = 0; if( os1.length( ) >= 4 ) oc1 = os1.GetChar( 3 ); if( os1.length( ) >= 5 ) oc2 = os1.GetChar( 4 ); if( oc1==wxT('C') || oc2==wxT('C') ) *peUType = eUNITS_TMPC; // Temperature (DegC or Deg C or Deg.C) else if( oc1==wxT('F') || oc2==wxT('F') ) *peUType = eUNITS_TMPF; // Temperature (DegF or Deg F or Deg.F) else *peUType = eUNITS_PHAD; // Phase / angle (Deg) break; case wxT('F') : if( os1.length( ) > 1 ) if( ! os1.StartsWith( wxT("FARAD") ) ) return( false ); *peUType = eUNITS_CAP; // Capacitance (F or Farad) break; case wxT('H') : // Inductance (H or Henry) or Frequency (Hz or Hertz) if( os1.length( )==1 || os1.StartsWith( wxT("HENRY") ) ) *peUType = eUNITS_IND; else if( os1.GetChar( 1 )==wxT('Z') || os1.StartsWith( wxT("HERTZ") ) ) *peUType = eUNITS_FREQ; else return( false ); break; case wxT('O') : if( os1.StartsWith( wxT("OHM") ) ) *peUType = eUNITS_RES; // Resistance (Ohm) else return( false ); break; case wxT('S') : // Conductance (S or Siemen) or Time (s or Sec) if( os1.length( ) == 1 ) { if( rosUnits.GetChar( sz1 ) == wxT('s') ) *peUType = eUNITS_TIME; else *peUType = eUNITS_COND; } else if( os1.StartsWith( wxT("SEC") ) ) *peUType = eUNITS_TIME; else if( os1.StartsWith( wxT("SIEMEN") ) ) *peUType = eUNITS_COND; else return( false ); break; case wxT('R') : if( ! os1.StartsWith( wxT("RAD") ) ) return( false ); *peUType = eUNITS_PHAR; // Phase / angle (Rad) case wxT('V') : if( os1.length( ) > 1 ) if( ! os1.StartsWith( wxT("VOLT") ) ) return( false ); *peUType = eUNITS_VOLT; // Voltage (V or Volt) break; default : return( false ); } return( true ); } //**************************************************************************************************