EMANE  1.2.1
parameterconvert.inl
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2016 - Adjacent Link LLC, Bridgewater, New Jersey
3  * Copyright (c) 2009,2012 - DRS CenGen, LLC, Columbia, Maryland
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of DRS CenGen, LLC nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sstream>
35 #include <cstdlib>
36 #include <cstring>
37 
38 namespace
39 {
40  std::string scaleNumericalStringRepresentation(const std::string & sValue)
41  {
42  std::string sTmpParameter(sValue);
43 
44  std::uint8_t u8PowerOf10 = 0;
45 
46  switch(*(sValue.end() - 1))
47  {
48  case 'G':
49  sTmpParameter.assign(sValue,0,sValue.size() - 1);
50  u8PowerOf10 = 9;
51  break;
52 
53  case 'M':
54  sTmpParameter.assign(sValue,0,sValue.size() - 1);
55  u8PowerOf10 = 6;
56  break;
57 
58  case 'K':
59  sTmpParameter.assign(sValue,0,sValue.size() - 1);
60  u8PowerOf10 = 3;
61  break;
62  }
63 
64  if(u8PowerOf10 != 0)
65  {
66  // strip any leading whitespace
67  std::string::size_type notWhiteSpace{sTmpParameter.find_first_not_of(" \t")};
68 
69  if(notWhiteSpace != std::string::npos)
70  {
71  sTmpParameter = sTmpParameter.substr(notWhiteSpace,std::string::npos);
72  }
73 
74  // location of decimal point, if exists
75  std::string::size_type indexPoint = sTmpParameter.find(".",0);
76 
77  if(indexPoint != std::string::npos)
78  {
79  std::string::size_type numberOfDigitsAfterPoint =
80  sTmpParameter.size() - indexPoint - 1;
81 
82  if(numberOfDigitsAfterPoint > u8PowerOf10)
83  {
84  // need to move the decimal point, enough digits are present
85  sTmpParameter.insert(indexPoint + u8PowerOf10,".");
86  }
87  else
88  {
89  // need to append 0s
90  sTmpParameter.append(u8PowerOf10 - numberOfDigitsAfterPoint,'0');
91  }
92 
93  // remove original decimal point
94  sTmpParameter.erase(indexPoint,1);
95  }
96  else
97  {
98  // need to append 0s
99  sTmpParameter.append(u8PowerOf10,'0');
100  }
101 
102  // strip any leading zeros but be mindful of sign
103  std::string sSign{};
104 
105  if(sTmpParameter.front() == '+' ||
106  sTmpParameter.front() == '-')
107  {
108  sSign = sTmpParameter.front();
109  }
110 
111  std::string::size_type not0Index{sTmpParameter.find_first_not_of("0",sSign.size())};
112 
113  if(not0Index != sSign.size())
114  {
115  sTmpParameter = sSign + sTmpParameter.substr(not0Index,std::string::npos);
116  }
117  }
118 
119  return sTmpParameter;
120  }
121 }
122 
123 inline
124 EMANE::Utils::ParameterConvert::ParameterConvert(const std::string & sParameter):
125  sParameter_{sParameter}{}
126 
127 inline
129 
130 inline
131 std::int64_t EMANE::Utils::ParameterConvert::toINT64(std::int64_t i64Min, std::int64_t i64Max) const
132 {
133  long long llValue = 0;
134 
135  if(sParameter_.empty())
136  {
137  throw ConversionException("Empty string in numeric conversion");
138  }
139  else
140  {
141  std::string sTmpParameter(scaleNumericalStringRepresentation(sParameter_));
142 
143  char * pEnd = 0;
144 
145  //Clear errno before making call because Ubuntu does not
146  //clear it when a call is made
147  errno = 0;
148 
149  llValue = std::strtoll(sTmpParameter.c_str(),&pEnd,0);
150 
151  if(errno == ERANGE ||
152  llValue < i64Min ||
153  llValue > i64Max)
154  {
155  std::stringstream sstream;
156  sstream<<sParameter_<<" out of range ["<<i64Min<<","<<i64Max<<"]"<<std::ends;
157  throw ConversionException(sstream.str());
158  }
159  else if(pEnd != 0 && *pEnd !='\0')
160  {
161  std::stringstream sstream;
162  sstream<<sParameter_<<" invalid character in numeric: '"<<*pEnd<<"'"<<std::ends;
163  throw ConversionException(sstream.str());
164  }
165  }
166 
167  return llValue;
168 }
169 
170 inline
171 std::uint64_t EMANE::Utils::ParameterConvert::toUINT64(std::uint64_t u64Min, std::uint64_t u64Max) const
172 {
173  unsigned long long ullValue = 0;
174 
175  if(sParameter_.empty())
176  {
177  throw ConversionException("Empty string in numeric conversion");
178  }
179  else
180  {
181  std::string sTmpParameter(scaleNumericalStringRepresentation(sParameter_));
182 
183  char * pEnd = 0;
184 
185  //Clear errno before making call because Ubuntu does not
186  //clear it when a call is made
187  errno = 0;
188 
189  ullValue = strtoull(sTmpParameter.c_str(),&pEnd,0);
190 
191  if(errno == ERANGE ||
192  ullValue < u64Min ||
193  ullValue > u64Max)
194  {
195  std::stringstream sstream;
196  sstream<<sParameter_<<" out of range ["<<u64Min<<","<<u64Max<<"]"<<std::ends;
197  throw ConversionException(sstream.str());
198  }
199  else if(pEnd != 0 && *pEnd !='\0')
200  {
201  std::stringstream sstream;
202  sstream<<sParameter_<<" invalid character in numeric: '"<<*pEnd<<"'"<<std::ends;
203  throw ConversionException(sstream.str());
204  }
205  }
206 
207  return ullValue;
208 }
209 
210 inline
211 std::int32_t EMANE::Utils::ParameterConvert::toINT32(std::int32_t i32Min, std::int32_t i32Max) const
212 {
213  return static_cast<std::int32_t>(toINT64(i32Min,i32Max));
214 }
215 
216 inline
217 std::uint32_t EMANE::Utils::ParameterConvert::toUINT32(std::uint32_t u32Min , std::uint32_t u32Max) const
218 {
219  return static_cast<std::uint32_t>(toUINT64(u32Min,u32Max));
220 }
221 
222 inline
223 std::int16_t EMANE::Utils::ParameterConvert::toINT16(std::int16_t i16Min, std::int16_t i16Max) const
224 {
225  return static_cast<std::int16_t>(toINT64(i16Min,i16Max));
226 }
227 
228 inline
229 std::uint16_t EMANE::Utils::ParameterConvert::toUINT16(std::uint16_t u16Min , std::uint16_t u16Max) const
230 {
231  return static_cast<std::uint16_t>(toUINT64(u16Min,u16Max));
232 }
233 
234 inline
235 std::int8_t EMANE::Utils::ParameterConvert::toINT8(std::int8_t i8Min, std::int8_t i8Max) const
236 {
237  return static_cast<std::int8_t>(toINT64(i8Min,i8Max));
238 }
239 
240 inline
241 std::uint8_t EMANE::Utils::ParameterConvert::toUINT8(std::uint8_t u8Min , std::uint8_t u8Max) const
242 {
243  return static_cast<std::uint8_t>(toUINT64(u8Min,u8Max));
244 }
245 
246 inline
248 {
249  if(!strcasecmp(sParameter_.c_str(),"on") ||
250  !strcasecmp(sParameter_.c_str(),"yes") ||
251  !strcasecmp(sParameter_.c_str(),"true") ||
252  !strcasecmp(sParameter_.c_str(),"1"))
253  {
254  return true;
255  }
256  else if(!strcasecmp(sParameter_.c_str(),"off") ||
257  !strcasecmp(sParameter_.c_str(),"no") ||
258  !strcasecmp(sParameter_.c_str(),"false") ||
259  !strcasecmp(sParameter_.c_str(),"0"))
260  {
261  return false;
262  }
263  else
264  {
265  std::stringstream sstream;
266  sstream<<"'"<<sParameter_<<"' invalid boolean conversion"<<std::ends;
267  throw ConversionException(sstream.str());
268  }
269 }
270 
271 inline
273 {
274  INETAddr addr;
275 
276  try
277  {
278  addr.set(sParameter_);
279  }
280  catch(...)
281  {
282  std::stringstream sstream;
283  sstream<<"'"<<sParameter_<<"' Invalid IP Address"<<std::ends;
284  throw ConversionException(sstream.str());
285  }
286 
287  return addr;
288 }
289 
290 inline
291 double EMANE::Utils::ParameterConvert::toDouble(double dMin, double dMax) const
292 {
293  double dValue = 0;
294 
295  if(sParameter_.empty())
296  {
297  throw ConversionException("Empty string in numeric conversion");
298  }
299  else
300  {
301  std::string sTmpParameter(scaleNumericalStringRepresentation(sParameter_));
302 
303  char * pEnd = 0;
304 
305  //Clear errno before making call because Ubuntu does not
306  //clear it when a call is made
307  errno = 0;
308 
309  dValue = std::strtod(sTmpParameter.c_str(),&pEnd);
310 
311  if(errno == ERANGE ||
312  dValue < dMin ||
313  dValue > dMax)
314  {
315  std::stringstream sstream;
316  sstream<<sParameter_<<" out of range ["<<dMin<<","<<dMax<<"]"<<std::ends;
317  throw ConversionException(sstream.str());
318  }
319  else if(pEnd != 0 && *pEnd !='\0')
320  {
321  std::stringstream sstream;
322  sstream<<sParameter_<<" invalid character in numeric: '"<<*pEnd<<"'"<<std::ends;
323  throw ConversionException(sstream.str());
324  }
325  }
326 
327  return dValue;
328 }
329 
330 inline
331 float EMANE::Utils::ParameterConvert::toFloat(float fMin, float fMax) const
332 {
333  return static_cast<float>(toDouble(fMin,fMax));
334 }
std::int8_t toINT8(std::int8_t i8Min=std::numeric_limits< std::int8_t >::min(), std::int8_t i8Max=std::numeric_limits< std::int8_t >::max()) const
std::uint8_t toUINT8(std::uint8_t u8Min=std::numeric_limits< std::uint8_t >::min(), std::uint8_t u8Max=std::numeric_limits< std::uint8_t >::max()) const
Parameter conversion exception class.
std::uint16_t toUINT16(std::uint16_t u16Min=std::numeric_limits< std::uint16_t >::min(), std::uint16_t u16Max=std::numeric_limits< std::uint16_t >::max()) const
float toFloat(float fMin=std::numeric_limits< float >::lowest(), float fMax=std::numeric_limits< float >::max()) const
std::uint64_t toUINT64(std::uint64_t u64Min=std::numeric_limits< std::uint64_t >::min(), std::uint64_t u64Max=std::numeric_limits< std::uint64_t >::max()) const
std::uint32_t toUINT32(std::uint32_t u32Min=std::numeric_limits< std::uint32_t >::min(), std::uint32_t u32Max=std::numeric_limits< std::uint32_t >::max()) const
double toDouble(double dMin=std::numeric_limits< double >::lowest(), double dMax=std::numeric_limits< double >::max()) const
void set(const std::string &sAddress, std::uint16_t u16Port)
Definition: inetaddr.cc:368
ParameterConvert(const std::string &sParameter)
std::int16_t toINT16(std::int16_t i16Min=std::numeric_limits< std::int16_t >::min(), std::int16_t i16Max=std::numeric_limits< std::int16_t >::max()) const
std::int32_t toINT32(std::int32_t i32Min=std::numeric_limits< std::int32_t >::min(), std::int32_t i32Max=std::numeric_limits< std::int32_t >::max()) const
std::int64_t toINT64(std::int64_t i64Min=std::numeric_limits< std::int64_t >::min(), std::int64_t i64Max=std::numeric_limits< std::int64_t >::max()) const