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(int iValue,const std::string & strValue,std::string & strError)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 
getNumericalValue(const std::string & strValue,int & iValue) const93 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 
getAtomicNumericalValue(const std::string & strValue,int & iValue) const118 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 
getLiteralValue(int iValue,std::string & strValue) const132 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 
isTypeInclusive() const148 bool CSelectionCriterionType::isTypeInclusive() const
149 {
150     return _bInclusive;
151 }
152 
153 // Value list
listPossibleValues() const154 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
getFormattedState(int iValue) const179 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
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const231 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