1 /* 2 * Copyright (c) 2011-2015, Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation and/or 13 * other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software without 17 * specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include "SelectionCriterionType.h" 31 #include "Tokenizer.h" 32 #include <sstream> 33 #include <climits> 34 35 #define base CElement 36 37 const std::string CSelectionCriterionType::_strDelimiter = "|"; 38 39 CSelectionCriterionType::CSelectionCriterionType(bool bIsInclusive) : _bInclusive(bIsInclusive) 40 { 41 // For inclusive criterion type, appends the pair none,0 by default. 42 if (_bInclusive) { 43 44 _numToLitMap["none"] = 0; 45 } 46 } 47 48 std::string CSelectionCriterionType::getKind() const 49 { 50 return "SelectionCriterionType"; 51 } 52 53 // From ISelectionCriterionTypeInterface 54 bool CSelectionCriterionType::addValuePair(int iValue, const std::string &strValue, 55 std::string &strError) 56 { 57 // Check 1 bit set only for inclusive types 58 if (_bInclusive && (!iValue || (iValue & (iValue - 1)))) { 59 60 std::ostringstream error; 61 error << "Rejecting value pair association: 0x" << std::hex << iValue << " - " << strValue 62 << " for Selection Criterion Type " << getName(); 63 strError = error.str(); 64 65 return false; 66 } 67 68 // Check already inserted 69 if (_numToLitMap.find(strValue) != _numToLitMap.end()) { 70 71 std::ostringstream error; 72 error << "Rejecting value pair association (literal already present): 0x" << std::hex 73 << iValue << " - " << strValue << " for Selection Criterion Type " << getName(); 74 strError = error.str(); 75 76 return false; 77 } 78 for (NumToLitMapConstIt it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) { 79 if (it->second == iValue) { 80 std::ostringstream error; 81 error << "Rejecting value pair association (numerical already present):" 82 << " 0x" << std::hex << iValue << " - " << strValue 83 << " for Selection Criterion Type " << getName(); 84 strError = error.str(); 85 return false; 86 } 87 } 88 _numToLitMap[strValue] = iValue; 89 90 return true; 91 } 92 93 bool CSelectionCriterionType::getNumericalValue(const std::string &strValue, int &iValue) const 94 { 95 if (_bInclusive) { 96 97 Tokenizer tok(strValue, _strDelimiter); 98 std::vector<std::string> astrValues = tok.split(); 99 size_t uiNbValues = astrValues.size(); 100 int iResult = 0; 101 size_t uiValueIndex; 102 iValue = 0; 103 104 // Looping on each std::string delimited by "|" token and adding the associated value 105 for (uiValueIndex = 0; uiValueIndex < uiNbValues; uiValueIndex++) { 106 107 if (!getAtomicNumericalValue(astrValues[uiValueIndex], iResult)) { 108 109 return false; 110 } 111 iValue |= iResult; 112 } 113 return true; 114 } 115 return getAtomicNumericalValue(strValue, iValue); 116 } 117 118 bool CSelectionCriterionType::getAtomicNumericalValue(const std::string &strValue, 119 int &iValue) const 120 { 121 NumToLitMapConstIt it = _numToLitMap.find(strValue); 122 123 if (it != _numToLitMap.end()) { 124 125 iValue = it->second; 126 127 return true; 128 } 129 return false; 130 } 131 132 bool CSelectionCriterionType::getLiteralValue(int iValue, std::string &strValue) const 133 { 134 NumToLitMapConstIt it; 135 136 for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) { 137 138 if (it->second == iValue) { 139 140 strValue = it->first; 141 142 return true; 143 } 144 } 145 return false; 146 } 147 148 bool CSelectionCriterionType::isTypeInclusive() const 149 { 150 return _bInclusive; 151 } 152 153 // Value list 154 std::string CSelectionCriterionType::listPossibleValues() const 155 { 156 std::string strValueList = "{"; 157 158 // Get comma seprated list of values 159 NumToLitMapConstIt it; 160 bool bFirst = true; 161 162 for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) { 163 164 if (bFirst) { 165 166 bFirst = false; 167 } else { 168 strValueList += ", "; 169 } 170 strValueList += it->first; 171 } 172 173 strValueList += "}"; 174 175 return strValueList; 176 } 177 178 // Formatted state 179 std::string CSelectionCriterionType::getFormattedState(int iValue) const 180 { 181 std::string strFormattedState; 182 183 if (_bInclusive) { 184 185 // Need to go through all set bit 186 bool bFirst = true; 187 188 for (size_t bit = 0; bit < sizeof(iValue) * CHAR_BIT; bit++) { 189 190 int iSingleBitValue = iValue & (1 << bit); 191 192 // Check if current bit is set 193 if (!iSingleBitValue) { 194 195 continue; 196 } 197 198 // Simple translation 199 std::string strSingleValue; 200 201 if (!getLiteralValue(iSingleBitValue, strSingleValue)) { 202 // Numeric value not part supported values for this criterion type. 203 continue; 204 } 205 206 if (bFirst) { 207 208 bFirst = false; 209 } else { 210 strFormattedState += "|"; 211 } 212 213 strFormattedState += strSingleValue; 214 } 215 216 } else { 217 // Simple translation 218 getLiteralValue(iValue, strFormattedState); 219 } 220 221 // Sometimes nothing is set 222 if (strFormattedState.empty()) { 223 224 strFormattedState = "<none>"; 225 } 226 227 return strFormattedState; 228 } 229 230 // From IXmlSource 231 void CSelectionCriterionType::toXml(CXmlElement &xmlElement, 232 CXmlSerializingContext &serializingContext) const 233 { 234 // Type Kind 235 xmlElement.setAttribute("Kind", isTypeInclusive() ? "Inclusive" : "Exclusive"); 236 237 // Value pairs as children 238 NumToLitMapConstIt it; 239 240 for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) { 241 242 CXmlElement childValuePairElement; 243 244 xmlElement.createChild(childValuePairElement, "ValuePair"); 245 // Literal 246 childValuePairElement.setAttribute("Literal", it->first); 247 // Numerical 248 childValuePairElement.setAttribute("Numerical", it->second); 249 } 250 251 base::toXml(xmlElement, serializingContext); 252 } 253