Scarab  v1.6.2
Project 8 C++ Utility Library
parsable.cc
Go to the documentation of this file.
1 #define SCARAB_API_EXPORTS
2 
3 #include "parsable.hh"
4 
5 #include "logger.hh"
6 
7 #include <sstream>
8 
9 
10 namespace scarab
11 {
12  LOGGER( dlog, "parsable" );
13 
15  param_node()
16  {}
17 
18  parsable::parsable( const std::string& a_addr_with_value ) :
19  param_node()
20  {
21  size_t t_val_pos = a_addr_with_value.find_first_of( f_value_separator );
22  if( t_val_pos != std::string::npos )
23  {
24  add_next( this, a_addr_with_value.substr( 0, t_val_pos ), a_addr_with_value.substr( t_val_pos + 1 ) );
25  }
26  else
27  {
28  add_next( this, a_addr_with_value, "" );
29  }
30  }
31 
32  parsable::parsable( const std::string& a_addr, const std::string& a_value ) :
33  param_node()
34  {
35  add_next( this, a_addr, a_value );
36  }
37 
38  parsable::parsable( const parsable& a_orig ) :
39  param_node( a_orig )
40  {}
41 
43  {
44  }
45 
46  void parsable::add_next( param_node* a_parent, const std::string& a_addr, const std::string& a_value )
47  {
48  size_t t_div_pos = a_addr.find( f_node_separator );
49  if( t_div_pos == a_addr.npos )
50  {
51  // we've found the value; now check if it's a number or a string
52  if( a_value.empty() )
53  {
54  a_parent->add( a_addr, new param() );
55  LDEBUG( dlog, "Parsed value as NULL" << *this );
56  }
57  // if "true" or "false", then bool
58  else if( a_value == "true" )
59  {
60  a_parent->add( a_addr, new param_value( true ) );
61  LDEBUG( dlog, "Parsed value (" << a_value << ") as bool(true)" << *this );
62  }
63  else if( a_value == "false" )
64  {
65  a_parent->add( a_addr, new param_value( false ) );
66  LDEBUG( dlog, "Parsed value (" << a_value << ") as bool(false):" << *this );
67  }
68  else
69  {
70  // To test if the string is numeric:
71  // 1. if it has 2 decimal points, it's not numeric (IP addresses, for example, would pass the second test)
72  // 2. double is the most general form of number, so if it fails that conversion, it's not numeric.
73  double t_double;
74  std::stringstream t_conv_double( a_value );
75  if( a_value.find( '.' ) == a_value.rfind( '.' ) &&
76  a_value.find( '-' ) == a_value.rfind( '-' ) &&
77  ! (t_conv_double >> t_double).fail() )
78  {
79  // now we know the value is numeric
80  if( a_value.find( '.' ) != std::string::npos ||
81  a_value.find( 'e' ) != std::string::npos ||
82  a_value.find( 'E' ) != std::string::npos )
83  {
84  // value is a floating-point number, since it has a decimal point
85  a_parent->add( a_addr, new param_value( t_double ) );
86  LDEBUG( dlog, "Parsed value (" << a_value << ") as double(" << t_double << "):" << *this );
87  }
88  else if( a_value[ 0 ] == '-' )
89  {
90  // value is a signed integer if it's negative
91  a_parent->add( a_addr, new param_value( (int64_t)t_double ) );
92  LDEBUG( dlog, "Parsed value (" << a_value << ") as int(" << (int64_t)t_double << "):" << *this );
93  }
94  else
95  {
96  // value is assumed to be unsigned if it's positive
97  a_parent->add( a_addr, new param_value( (uint64_t)t_double ) );
98  LDEBUG( dlog, "Parsed value (" << a_value << ") as uint(" << (uint64_t)t_double << ");" << *this );
99  }
100  }
101  else
102  {
103  // value is not numeric; treat as a string
104  a_parent->add( a_addr, new param_value( a_value ) );
105  LDEBUG( dlog, "Parsed value (" << a_value << ") as a string:" << *this );
106  }
107  }
108  return;
109  }
110  param_node* t_new_node = new param_node();
111  a_parent->add( a_addr.substr( 0, t_div_pos ), t_new_node );
112  add_next( t_new_node, a_addr.substr( t_div_pos + 1 ), a_value );
113  return;
114  }
115 
116 }
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
#define LDEBUG(...)
Definition: logger.hh:360
static const char f_node_separator
Definition: parsable.hh:26
static const char f_value_separator
Definition: parsable.hh:25
bool add(const std::string &a_name, const param &a_value)
creates a copy of a_value
Definition: param.hh:1120
void add_next(param_node *a_parent, const std::string &a_addr, const std::string &a_value)
Definition: parsable.cc:46
LOGGER(mtlog,"authentication")