TuttleOFX
1
|
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