1 /*
2  * Copyright (c) 2011-2014, 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 
33 #define base CElement
34 
35 const std::string CSelectionCriterionType::_strDelimiter = "|";
36 
CSelectionCriterionType(bool bIsInclusive)37 CSelectionCriterionType::CSelectionCriterionType(bool bIsInclusive) : _bInclusive(bIsInclusive)
38 {
39     // For inclusive criterion type, appends the pair none,0 by default.
40     if (_bInclusive) {
41 
42         _numToLitMap["none"] = 0;
43     }
44 }
45 
getKind() const46 std::string CSelectionCriterionType::getKind() const
47 {
48     return "SelectionCriterionType";
49 }
50 
51 // From ISelectionCriterionTypeInterface
addValuePair(int iValue,const std::string & strValue)52 bool CSelectionCriterionType::addValuePair(int iValue, const std::string& strValue)
53 {
54     // Check 1 bit set only for inclusive types
55     if (_bInclusive && (!iValue || (iValue & (iValue - 1)))) {
56 
57         log_warning("Rejecting value pair association: 0x%X - %s for Selection Criterion Type %s", iValue, strValue.c_str(), getName().c_str());
58 
59         return false;
60     }
61 
62     // Check already inserted
63     if (_numToLitMap.find(strValue) != _numToLitMap.end()) {
64 
65         log_warning("Rejecting value pair association (literal already present): 0x%X - %s for Selection Criterion Type %s", iValue, strValue.c_str(), getName().c_str());
66 
67         return false;
68     }
69     _numToLitMap[strValue] = iValue;
70 
71     return true;
72 }
73 
getNumericalValue(const std::string & strValue,int & iValue) const74 bool CSelectionCriterionType::getNumericalValue(const std::string& strValue, int& iValue) const
75 {
76     if (_bInclusive) {
77 
78         Tokenizer tok(strValue, _strDelimiter);
79         std::vector<std::string> astrValues = tok.split();
80         size_t uiNbValues = astrValues.size();
81         int iResult = 0;
82         size_t uiValueIndex;
83         iValue = 0;
84 
85         // Looping on each std::string delimited by "|" token and adding the associated value
86         for (uiValueIndex = 0; uiValueIndex < uiNbValues; uiValueIndex++) {
87 
88             if (!getAtomicNumericalValue(astrValues[uiValueIndex], iResult)) {
89 
90                 return false;
91             }
92             iValue |= iResult;
93         }
94         return true;
95     }
96     return getAtomicNumericalValue(strValue, iValue);
97 }
98 
getAtomicNumericalValue(const std::string & strValue,int & iValue) const99 bool CSelectionCriterionType::getAtomicNumericalValue(const std::string& strValue, int& iValue) const
100 {
101     NumToLitMapConstIt it = _numToLitMap.find(strValue);
102 
103     if (it != _numToLitMap.end()) {
104 
105         iValue = it->second;
106 
107         return true;
108     }
109     return false;
110 }
111 
getLiteralValue(int iValue,std::string & strValue) const112 bool CSelectionCriterionType::getLiteralValue(int iValue, std::string& strValue) const
113 {
114     NumToLitMapConstIt it;
115 
116     for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
117 
118         if (it->second == iValue) {
119 
120             strValue = it->first;
121 
122             return true;
123         }
124     }
125     return false;
126 }
127 
isTypeInclusive() const128 bool CSelectionCriterionType::isTypeInclusive() const
129 {
130     return _bInclusive;
131 }
132 
133 // Value list
listPossibleValues() const134 std::string CSelectionCriterionType::listPossibleValues() const
135 {
136     std::string strValueList = "{";
137 
138     // Get comma seprated list of values
139     NumToLitMapConstIt it;
140     bool bFirst = true;
141 
142     for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
143 
144         if (bFirst) {
145 
146             bFirst = false;
147         } else {
148             strValueList += ", ";
149         }
150         strValueList += it->first;
151     }
152 
153     strValueList += "}";
154 
155     return strValueList;
156 }
157 
158 // Formatted state
getFormattedState(int iValue) const159 std::string CSelectionCriterionType::getFormattedState(int iValue) const
160 {
161     std::string strFormattedState;
162 
163     if (_bInclusive) {
164 
165         // Need to go through all set bit
166         uint32_t uiBit;
167         bool bFirst = true;
168 
169         for (uiBit = 0; uiBit < sizeof(iValue) * 8; uiBit++) {
170 
171             int iSingleBitValue = iValue & (1 << uiBit);
172 
173             // Check if current bit is set
174             if (!iSingleBitValue) {
175 
176                 continue;
177             }
178 
179             // Simple translation
180             std::string strSingleValue;
181 
182             if (!getLiteralValue(iSingleBitValue, strSingleValue)) {
183                 // Numeric value not part supported values for this criterion type.
184                 continue;
185             }
186 
187             if (bFirst) {
188 
189                 bFirst = false;
190             } else {
191                 strFormattedState += "|";
192             }
193 
194             strFormattedState += strSingleValue;
195         }
196 
197     } else {
198         // Simple translation
199         getLiteralValue(iValue, strFormattedState);
200     }
201 
202     // Sometimes nothing is set
203     if (strFormattedState.empty()) {
204 
205         strFormattedState = "<none>";
206     }
207 
208     return strFormattedState;
209 }
210 
211 // From IXmlSource
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const212 void CSelectionCriterionType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
213 {
214     // Type Kind
215     xmlElement.setAttributeString("Kind", isTypeInclusive() ? "Inclusive" : "Exclusive");
216 
217     // Value pairs as children
218     NumToLitMapConstIt it;
219 
220     for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
221 
222         CXmlElement childValuePairElement;
223 
224         xmlElement.createChild(childValuePairElement, "ValuePair");
225         // Literal
226         childValuePairElement.setAttributeString("Literal", it->first);
227         // Numerical
228         childValuePairElement.setAttributeSignedInteger("Numerical", it->second);
229     }
230 
231     base::toXml(xmlElement, serializingContext);
232 }
233