[studxml-users] Suggestion to extend the attribute template per compiler definiton

Omar Medina omar.medina at web.de
Thu Dec 8 19:16:51 EST 2016


Hello dear Studxml-Users,

my suggestion (below) involves a long known use-case, that impacts 
developers, when they are handling the read hexadecimal values from 
XML-data. They hex-string (0x...) needs to be previously processed 
before it will be converted. The same problems occurs with the provided 
attribute template of libstudxml, which can not handle directly hex-string

The following code will thrown an exception, if the read string-value is 
described in the XML-file as a hex-string.
Code
	XML
p.next_expect(xml::parser::start_element,"drm");
p.content(xml::parser::content_type::complex);
do
{
   p.next_expect(xml::parser::start_element);
   p.content(xml::parser::content_type::complex);
   p.attribute<int>("min"),
   p.attribute<int>("max"),
   p.attribute<int>("mean",0),
   p.attribute<int>("factor",1),
   p.attribute<int>("divisor",1),
}
p.next_expect(xml::parser::end_element);
	<drm>
   <range ID="2" min="1" max="0x5"/>
</drm>


My suggestion: Either a compiler-definiton or an Api-Interface makes 
available the following code in the file "value-traits.txx"
Current
	Suggestion
-
	  /* simple string trim function */
    static bool is_not_whitespace(int c)
     {
       if (
          (c == ' ')  || /* whitespace */
          (c == '\t') || /* tab */
          (c == '\n') || /* linefeed */
          (c == '\r') || /* carriage-return */
          (c == '\f') || /* formfeed */
          (c == '\v')    /* vertical-tab */
          ) return false;
       return true;
     }

     // trim from end
     static inline std::string &trimr(std::string &s)
     {
       s.erase(std::find_if(s.rbegin(), s.rend(), 
is_not_whitespace).base(), s.end());
       return s;
     }

     // trim from begin
     static inline std::string &triml(std::string &s)
     {
       s.erase(s.begin(), std::find_if(s.begin(), s.end(), 
is_not_whitespace));
       return s;
     }

     // trim from both ends
     static inline std::string &trim(std::string &s)
     {
       return trimr(triml(s));
     }
   template <typename T>
   T default_value_traits<T>::
   parse (std::string s, const parser& p)
   {
     T r;
     std::istringstream is (s);
     if (!(is >> r && is.eof ()) )
       throw parsing (p, "invalid value '" + s + "'");
     return r;
   }
	  template <typename T>
   T default_value_traits<T>::
   parse (std::string s, const parser& p)
   {
     bool h =false;
     T r;
     std::string ss = s;
     triml(ss);
     if((ss.length() > 2) && ((ss[0]=='0') && ((ss[1]=='x')||(ss[1]=='X'))))
     {
       ss[0]=' ';
       ss[1]=' ';
       h = true;
     }

     std::istringstream is (((h == true)? ss : s));
     if (h == true)
     {
       if (!((is >> std::hex >> r) && is.eof ()) )
       {
         throw parsing (p, "invalid value '" + s + "'");
       }
     }
     else
     {
       if (!((is >> r) && is.eof ()) )
       {
         throw parsing (p, "invalid value '" + s + "'");
       }
     }
     return r;
   }


By the way i want to take the opportunity to say thanks for the libstudxml.

Best regards
Omar

-- -------------------------- Omar Martin Medina Izaguirre 
--------------------------



More information about the studxml-users mailing list