TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ofx/attribute/OfxhParamChoice.cpp
Go to the documentation of this file.
00001 #include "OfxhParamChoice.hpp"
00002 
00003 #include <boost/numeric/conversion/cast.hpp>
00004 #include <boost/algorithm/string/join.hpp>
00005 #include <boost/functional/hash.hpp>
00006 
00007 namespace tuttle {
00008 namespace host {
00009 namespace ofx {
00010 namespace attribute {
00011 
00012 int OfxhParamChoice::getIndexFor( const std::string& key ) const
00013 {
00014         typedef std::vector<std::string> StringVector;
00015         const StringVector& values = getChoiceKeys();
00016         
00017         if( key.empty() )
00018         {
00019                 BOOST_THROW_EXCEPTION( OfxhException(
00020                         "Empty key value for choice param \"" + this->getName() + "\".\n" +
00021                         "Possible values are : [\n\"" + boost::algorithm::join( values, "\",\n\"" ) + "\" ]"
00022                         ) );
00023         }
00024         if( values.empty() )
00025         {
00026                 BOOST_THROW_EXCEPTION( OfxhException(
00027                         "The key \"" + key + "\" doesn't exist for choice param \"" + this->getName() + "\".\n" +
00028                         "The choice parameter is empty."
00029                         ) );
00030         }
00031         
00032         StringVector partialMatches;
00033         StringVector::const_iterator strictMatch = values.end();
00034         StringVector::const_iterator partialMatch = values.end();
00035         for( StringVector::const_iterator it = values.begin(), itEnd = values.end();
00036                  it != itEnd;
00037                  ++it )
00038         {
00039                 if( it->size() == key.size() ) // exact match
00040                 {
00041                         if( it->compare( key ) == 0 )
00042                         {
00043                                 strictMatch = it;
00044                                 break; // don't need to keep searching
00045                         }
00046                 }
00047                 else if( it->size() > key.size() ) // partial key, the user only set the beginning of the choice value
00048                 {
00049                         if( it->compare( 0, key.size(), key ) == 0 )
00050                         {
00051                                 partialMatch = it;
00052                                 partialMatches.push_back( *it );
00053                         }
00054                 }
00055         }
00056         if( strictMatch != values.end() )
00057         {
00058                 return boost::numeric_cast<int>( std::distance( values.begin(), strictMatch ) );
00059         }
00060         if( partialMatch != values.end() )
00061         {
00062                 if( partialMatches.size() > 1 )
00063                 {
00064                         BOOST_THROW_EXCEPTION( OfxhException(
00065                                 "The key \"" + key + "\" has multiple matches for choice param \"" + this->getName() + "\".\n" +
00066                                 "Possible matches are : [\n\"" + boost::algorithm::join( partialMatches, "\",\n\"" ) + "\" ]"
00067                                 ) );
00068                 }
00069                 return boost::numeric_cast<int>( std::distance( values.begin(), partialMatch ) );
00070         }
00071         BOOST_THROW_EXCEPTION( OfxhException(
00072                 "The key \"" + key + "\" doesn't exist for choice param \"" + this->getName() + "\".\n" +
00073                 "Possible values are : [\n\"" + boost::algorithm::join( values, "\",\n\"" ) + "\" ]"
00074                 ) );
00075 }
00076 
00077 const std::string& OfxhParamChoice::getChoiceKeyAt( const int index ) const
00078 {
00079         const std::vector<std::string>& keys = getChoiceKeys();
00080         if( index < 0 || index >= keys.size() )
00081         {
00082                 BOOST_THROW_EXCEPTION( OfxhException(kOfxStatErrBadIndex)
00083                         << exception::user() + "The index value \"" + index + "\" is out of kays range.\n" +
00084                         "Choice keys are : [\n\"" + boost::algorithm::join( keys, "\",\n\"" ) + "\" ]"
00085                         );
00086         }
00087         return keys[index];
00088 }
00089 
00090 void OfxhParamChoice::getValue( std::string& outKey ) const OFX_EXCEPTION_SPEC
00091 {
00092         int index = 0;
00093         getValue( index );
00094         outKey = getChoiceKeyAt(index);
00095 }
00096 
00097 void OfxhParamChoice::getValueAtTime( const OfxTime time, std::string& outKey ) const OFX_EXCEPTION_SPEC
00098 {
00099         int index = 0;
00100         getValueAtTime( time, index );
00101         outKey = getChoiceKeyAt(index);
00102 }
00103 
00104 /**
00105  * implementation of var args function
00106  */
00107 void OfxhParamChoice::getV( va_list arg ) const OFX_EXCEPTION_SPEC
00108 {
00109         int* value = va_arg( arg, int* );
00110 
00111         return getValue( *value );
00112 }
00113 
00114 /**
00115  * implementation of var args function
00116  */
00117 void OfxhParamChoice::getV( const OfxTime time, va_list arg ) const OFX_EXCEPTION_SPEC
00118 {
00119         int* value = va_arg( arg, int* );
00120 
00121         return getValueAtTime( time, *value );
00122 }
00123 
00124 /**
00125  * implementation of var args function
00126  */
00127 void OfxhParamChoice::setV( va_list arg, const EChange change ) OFX_EXCEPTION_SPEC
00128 {
00129         int value = va_arg( arg, int );
00130 
00131         return setValue( value, change );
00132 }
00133 
00134 /**
00135  * implementation of var args function
00136  */
00137 void OfxhParamChoice::setV( const OfxTime time, va_list arg, const EChange change ) OFX_EXCEPTION_SPEC
00138 {
00139         int value = va_arg( arg, int );
00140 
00141         return setValueAtTime( time, value, change );
00142 }
00143         
00144 std::size_t OfxhParamChoice::getHashAtTime( const OfxTime time ) const
00145 {
00146         std::string value; // don't use the index here. The plugin could change the order of choices values in a minor version change.
00147         getValueAtTime( time, value );
00148         return boost::hash_value( value );
00149 }
00150 
00151 }
00152 }
00153 }
00154 }
00155