1 /*
2 * CParameterMap.cc
3 *
4 * Copyright 2014-2018 D. Mitch Bailey cvc at shuharisystem dot com
5 *
6 * This file is part of cvc.
7 *
8 * cvc is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * cvc is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with cvc. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * You can download cvc from https://github.com/d-m-bailey/cvc.git
22 */
23
24 #include "CParameterMap.hh"
25
CreateParameterMap(string theParameterString)26 void CParameterMap::CreateParameterMap(string theParameterString) {
27 string myParameterName;
28 string myParameterValue;
29 size_t myEqualIndex;
30 size_t myStringBegin = 0;
31 size_t myStringEnd;
32 if (theParameterString.length() > 0) {
33 do {
34 myStringEnd = theParameterString.find(" ", myStringBegin);
35 myEqualIndex = theParameterString.find("=", myStringBegin);
36 myParameterName = theParameterString.substr(myStringBegin, myEqualIndex - myStringBegin);
37 if ( myParameterName[0] == '$' ) myParameterName = myParameterName.substr(1);
38 toupper_(myParameterName);
39 myParameterValue = theParameterString.substr(myEqualIndex + 1, myStringEnd - (myEqualIndex + 1));
40 (*this)[myParameterName] = myParameterValue;
41 myStringBegin = myStringEnd + 1;
42 } while (myStringEnd < theParameterString.length());
43 }
44 }
45
Print(string theIndentation,string theHeading)46 void CParameterMap::Print(string theIndentation, string theHeading) {
47 string myIndentation = theIndentation + " ";
48 cout << theIndentation << theHeading << endl;
49 cout << myIndentation << "Parameters:";
50 for (CParameterMap::iterator parameterPair_pit = begin(); parameterPair_pit != end(); parameterPair_pit++) {
51 cout << " " << parameterPair_pit->first << ":" << parameterPair_pit->second;
52 }
53 cout << endl;
54 }
55
CalculateResistance(string theEquation)56 resistance_t CParameterMap::CalculateResistance(string theEquation) {
57 list<string> * myTokenList_p;
58 // exceptions cause memory leaks
59 if ( IsValidVoltage_(theEquation) ) {
60 myTokenList_p = new(list<string>);
61 myTokenList_p->push_back(theEquation);
62 } else {
63 myTokenList_p = postfix(theEquation);
64 }
65 list<double> myResistanceStack;
66 double myResistance;
67 string myOperators = "+-/*<>";
68 for ( auto token_pit = myTokenList_p->begin(); token_pit != myTokenList_p->end(); token_pit++ ) {
69 if ( myOperators.find(*token_pit) < myOperators.length() ) {
70 if ( myResistanceStack.size() < 2 ) throw EPowerError("invalid equation: " + theEquation);
71 myResistance = myResistanceStack.back();
72 myResistanceStack.pop_back();
73 if ( *token_pit == "+" ) {
74 myResistanceStack.back() += myResistance;
75 } else if ( *token_pit == "-" ) {
76 myResistanceStack.back() -= myResistance;
77 } else if ( *token_pit == "*" ) {
78 myResistanceStack.back() *= myResistance;
79 } else if ( *token_pit == "/" ) {
80 myResistanceStack.back() /= myResistance;
81 } else if ( *token_pit == "<" ) {
82 myResistanceStack.back() = min(myResistanceStack.back(), myResistance);
83 } else if ( *token_pit == ">" ) {
84 myResistanceStack.back() = max(myResistanceStack.back(), myResistance);
85 } else throw EPowerError("invalid operator: " + *token_pit);
86 } else if ( isalpha((*token_pit)[0]) ) { // parameter name
87 string myParameter = *token_pit;
88 toupper_(myParameter);
89 if ( this->count(myParameter) > 0 ) { // parameter definition exists
90 CNormalValue myParameterValue((*this)[myParameter]);
91 myResistanceStack.push_back(myParameterValue.RealValue());
92 } else {
93 throw EResistanceError("missing parameter: " + *token_pit + " in " + theEquation);
94 }
95 } else if ( IsValidVoltage_(*token_pit) ) {
96 myResistanceStack.push_back(from_string<float>(*token_pit));
97 } else {
98 throw EResistanceError("invalid resistance calculation token: " + *token_pit + " in " + theEquation);
99 }
100 }
101 if ( myResistanceStack.size() != 1 ) EResistanceError("invalid equation: " + theEquation);
102 delete myTokenList_p;
103 if ( myResistanceStack.front() >= MAX_RESISTANCE ) {
104 return ( MAX_RESISTANCE );
105 } else {
106 return ( max(1, round(myResistanceStack.front())) ); // minimum resistance is 1 ohm
107 }
108 }
109