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
CSelectionCriterionType(bool bIsInclusive)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
getKind() const48 std::string CSelectionCriterionType::getKind() const
49 {
50 return "SelectionCriterionType";
51 }
52
53 // From ISelectionCriterionTypeInterface
addValuePair(uint64_t iValue,const std::string & strValue,std::string & strError)54 bool CSelectionCriterionType::addValuePair(uint64_t 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 << "CSelectionCriterionType Rejecting value pair association: 0x" << std::hex
62 << iValue << " - " << strValue
63 << " for Selection Criterion Type " << getName();
64 strError = error.str();
65
66 return false;
67 }
68
69 // Check already inserted
70 if (_numToLitMap.find(strValue) != _numToLitMap.end()) {
71
72 std::ostringstream error;
73 error << "Rejecting value pair association (literal already present): 0x" << std::hex
74 << iValue << " - " << strValue << " for Selection Criterion Type " << getName();
75 strError = error.str();
76
77 return false;
78 }
79 for (NumToLitMapConstIt it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
80 if (it->second == iValue) {
81 std::ostringstream error;
82 error << "Rejecting value pair association (numerical already present):"
83 << " 0x" << std::hex << iValue << " - " << strValue
84 << " for Selection Criterion Type " << getName();
85 strError = error.str();
86 return false;
87 }
88 }
89 _numToLitMap[strValue] = iValue;
90
91 return true;
92 }
93
getNumericalValue(const std::string & strValue,uint64_t & iValue) const94 bool CSelectionCriterionType::getNumericalValue(const std::string &strValue, uint64_t &iValue) const
95 {
96 if (_bInclusive) {
97
98 Tokenizer tok(strValue, _strDelimiter);
99 std::vector<std::string> astrValues = tok.split();
100 size_t uiNbValues = astrValues.size();
101 uint64_t iResult = 0;
102 size_t uiValueIndex;
103 iValue = 0;
104
105 // Looping on each std::string delimited by "|" token and adding the associated value
106 for (uiValueIndex = 0; uiValueIndex < uiNbValues; uiValueIndex++) {
107
108 if (!getAtomicNumericalValue(astrValues[uiValueIndex], iResult)) {
109
110 return false;
111 }
112 iValue |= iResult;
113 }
114 return true;
115 }
116 return getAtomicNumericalValue(strValue, iValue);
117 }
118
getAtomicNumericalValue(const std::string & strValue,uint64_t & iValue) const119 bool CSelectionCriterionType::getAtomicNumericalValue(const std::string &strValue,
120 uint64_t &iValue) const
121 {
122 auto it = _numToLitMap.find(strValue);
123
124 if (it != _numToLitMap.end()) {
125
126 iValue = it->second;
127
128 return true;
129 }
130 return false;
131 }
132
getLiteralValue(uint64_t iValue,std::string & strValue) const133 bool CSelectionCriterionType::getLiteralValue(uint64_t iValue, std::string &strValue) const
134 {
135 NumToLitMapConstIt it;
136
137 for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
138
139 if (it->second == iValue) {
140
141 strValue = it->first;
142
143 return true;
144 }
145 }
146 return false;
147 }
148
isTypeInclusive() const149 bool CSelectionCriterionType::isTypeInclusive() const
150 {
151 return _bInclusive;
152 }
153
154 // Value list
listPossibleValues() const155 std::string CSelectionCriterionType::listPossibleValues() const
156 {
157 std::string strValueList = "{";
158
159 // Get comma seprated list of values
160 NumToLitMapConstIt it;
161 bool bFirst = true;
162
163 for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
164
165 if (bFirst) {
166
167 bFirst = false;
168 } else {
169 strValueList += ", ";
170 }
171 strValueList += it->first;
172 }
173
174 strValueList += "}";
175
176 return strValueList;
177 }
178
179 // Formatted state
getFormattedState(uint64_t iValue) const180 std::string CSelectionCriterionType::getFormattedState(uint64_t iValue) const
181 {
182 std::string strFormattedState;
183
184 if (_bInclusive) {
185
186 // Need to go through all set bit
187 bool bFirst = true;
188
189 for (size_t bit = 0; bit < sizeof(iValue) * CHAR_BIT; bit++) {
190
191 uint64_t iSingleBitValue = iValue & (0x1ull << bit);
192
193 // Check if current bit is set
194 if (!iSingleBitValue) {
195
196 continue;
197 }
198
199 // Simple translation
200 std::string strSingleValue;
201
202 if (!getLiteralValue(iSingleBitValue, strSingleValue)) {
203 // Numeric value not part supported values for this criterion type.
204 continue;
205 }
206
207 if (bFirst) {
208
209 bFirst = false;
210 } else {
211 strFormattedState += "|";
212 }
213
214 strFormattedState += strSingleValue;
215 }
216
217 } else {
218 // Simple translation
219 getLiteralValue(iValue, strFormattedState);
220 }
221
222 // Sometimes nothing is set
223 if (strFormattedState.empty()) {
224
225 strFormattedState = "<none>";
226 }
227
228 return strFormattedState;
229 }
230
231 // From IXmlSource
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const232 void CSelectionCriterionType::toXml(CXmlElement &xmlElement,
233 CXmlSerializingContext &serializingContext) const
234 {
235 // Type Kind
236 xmlElement.setAttribute("Kind", isTypeInclusive() ? "Inclusive" : "Exclusive");
237
238 // Value pairs as children
239 NumToLitMapConstIt it;
240
241 for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
242
243 CXmlElement childValuePairElement;
244
245 xmlElement.createChild(childValuePairElement, "ValuePair");
246 // Literal
247 childValuePairElement.setAttribute("Literal", it->first);
248 // Numerical
249 childValuePairElement.setAttribute("Numerical", it->second);
250 }
251
252 base::toXml(xmlElement, serializingContext);
253 }
254