blob: 3354702a2fb1379510bc35eecf877c10b7ebe24f [file] [log] [blame]
/*
* Copyright (c) 2011-2015, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "SelectionCriterionType.h"
#include "Tokenizer.h"
#include <sstream>
#include <climits>
#define base CElement
const std::string CSelectionCriterionType::_strDelimiter = "|";
CSelectionCriterionType::CSelectionCriterionType(bool bIsInclusive) : _bInclusive(bIsInclusive)
{
// For inclusive criterion type, appends the pair none,0 by default.
if (_bInclusive) {
_numToLitMap["none"] = 0;
}
}
std::string CSelectionCriterionType::getKind() const
{
return "SelectionCriterionType";
}
// From ISelectionCriterionTypeInterface
bool CSelectionCriterionType::addValuePair(int iValue, const std::string &strValue,
std::string &strError)
{
// Check 1 bit set only for inclusive types
if (_bInclusive && (!iValue || (iValue & (iValue - 1)))) {
std::ostringstream error;
error << "Rejecting value pair association: 0x" << std::hex << iValue << " - " << strValue
<< " for Selection Criterion Type " << getName();
strError = error.str();
return false;
}
// Check already inserted
if (_numToLitMap.find(strValue) != _numToLitMap.end()) {
std::ostringstream error;
error << "Rejecting value pair association (literal already present): 0x" << std::hex
<< iValue << " - " << strValue << " for Selection Criterion Type " << getName();
strError = error.str();
return false;
}
for (NumToLitMapConstIt it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
if (it->second == iValue) {
std::ostringstream error;
error << "Rejecting value pair association (numerical already present):"
<< " 0x" << std::hex << iValue << " - " << strValue
<< " for Selection Criterion Type " << getName();
strError = error.str();
return false;
}
}
_numToLitMap[strValue] = iValue;
return true;
}
bool CSelectionCriterionType::getNumericalValue(const std::string &strValue, int &iValue) const
{
if (_bInclusive) {
Tokenizer tok(strValue, _strDelimiter);
std::vector<std::string> astrValues = tok.split();
size_t uiNbValues = astrValues.size();
int iResult = 0;
size_t uiValueIndex;
iValue = 0;
// Looping on each std::string delimited by "|" token and adding the associated value
for (uiValueIndex = 0; uiValueIndex < uiNbValues; uiValueIndex++) {
if (!getAtomicNumericalValue(astrValues[uiValueIndex], iResult)) {
return false;
}
iValue |= iResult;
}
return true;
}
return getAtomicNumericalValue(strValue, iValue);
}
bool CSelectionCriterionType::getAtomicNumericalValue(const std::string &strValue,
int &iValue) const
{
NumToLitMapConstIt it = _numToLitMap.find(strValue);
if (it != _numToLitMap.end()) {
iValue = it->second;
return true;
}
return false;
}
bool CSelectionCriterionType::getLiteralValue(int iValue, std::string &strValue) const
{
NumToLitMapConstIt it;
for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
if (it->second == iValue) {
strValue = it->first;
return true;
}
}
return false;
}
bool CSelectionCriterionType::isTypeInclusive() const
{
return _bInclusive;
}
// Value list
std::string CSelectionCriterionType::listPossibleValues() const
{
std::string strValueList = "{";
// Get comma seprated list of values
NumToLitMapConstIt it;
bool bFirst = true;
for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
if (bFirst) {
bFirst = false;
} else {
strValueList += ", ";
}
strValueList += it->first;
}
strValueList += "}";
return strValueList;
}
// Formatted state
std::string CSelectionCriterionType::getFormattedState(int iValue) const
{
std::string strFormattedState;
if (_bInclusive) {
// Need to go through all set bit
bool bFirst = true;
for (size_t bit = 0; bit < sizeof(iValue) * CHAR_BIT; bit++) {
int iSingleBitValue = iValue & (1 << bit);
// Check if current bit is set
if (!iSingleBitValue) {
continue;
}
// Simple translation
std::string strSingleValue;
if (!getLiteralValue(iSingleBitValue, strSingleValue)) {
// Numeric value not part supported values for this criterion type.
continue;
}
if (bFirst) {
bFirst = false;
} else {
strFormattedState += "|";
}
strFormattedState += strSingleValue;
}
} else {
// Simple translation
getLiteralValue(iValue, strFormattedState);
}
// Sometimes nothing is set
if (strFormattedState.empty()) {
strFormattedState = "<none>";
}
return strFormattedState;
}
// From IXmlSource
void CSelectionCriterionType::toXml(CXmlElement &xmlElement,
CXmlSerializingContext &serializingContext) const
{
// Type Kind
xmlElement.setAttribute("Kind", isTypeInclusive() ? "Inclusive" : "Exclusive");
// Value pairs as children
NumToLitMapConstIt it;
for (it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) {
CXmlElement childValuePairElement;
xmlElement.createChild(childValuePairElement, "ValuePair");
// Literal
childValuePairElement.setAttribute("Literal", it->first);
// Numerical
childValuePairElement.setAttribute("Numerical", it->second);
}
base::toXml(xmlElement, serializingContext);
}