any STL/string function available for determing string contains numeric

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • nishit.gupta@st.com

    any STL/string function available for determing string contains numeric


    Is their any single fuction available in C++ that can determine that a
    string
    contains a numeric value.
    The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
    "0xffff" , It can also contain zero

  • Ian Collins

    #2
    Re: any STL/string function available for determing string containsnumeric

    nishit.gupta@st .com wrote:
    Is their any single fuction available in C++ that can determine that a
    string
    contains a numeric value.
    The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
    "0xffff" , It can also contain zero
    >
    No. You would have to try one of the C library numeric conversion
    functions on the string's contents.

    --
    Ian Collins.

    Comment

    • nishit.gupta@st.com

      #3
      Re: any STL/string function available for determing string contains numeric

      No even that(strtoul, strtod) would not be possible as strtoul ask for
      base(16 for hex, 10 for dec)
      and my string can containg a non valid format as "0xffff12yz z" or
      "0xaa_AMERI CA" or "AMERICA" or "0xffff"
      I just want to check for the rigth possible numeric value.....
      Its content does not matter to me
      Ian Collins wrote:
      nishit.gupta@st .com wrote:
      Is their any single fuction available in C++ that can determine that a
      string
      contains a numeric value.
      The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
      "0xffff" , It can also contain zero
      No. You would have to try one of the C library numeric conversion
      functions on the string's contents.
      >
      --
      Ian Collins.

      Comment

      • Jacek Dziedzic

        #4
        Re: any STL/string function available for determing string containsnumeric

        nishit.gupta@st .com wrote:
        No even that(strtoul, strtod) would not be possible as strtoul ask for
        base(16 for hex, 10 for dec)
        and my string can containg a non valid format as "0xffff12yz z" or
        "0xaa_AMERI CA" or "AMERICA" or "0xffff"
        I just want to check for the rigth possible numeric value.....
        Its content does not matter to me
        Ian Collins wrote:
        >nishit.gupta@st .com wrote:
        >>Is their any single fuction available in C++ that can determine that a
        >>string
        >>contains a numeric value.
        >>The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
        >>"0xffff" , It can also contain zero
        How about outputting the string to a stringstream and then
        trying to read a double? If it reads sucessfully and the
        stream does not have any characters left in it, it is a
        number. I'm not sure if this will work for hex numbers
        though, but you might try reading an integer as a side-check.

        HTH,
        - J.

        Comment

        • Ian Collins

          #5
          Re: any STL/string function available for determing string containsnumeric

          nishit.gupta@st .com wrote:

          Please don't top-post.
          Ian Collins wrote:
          >
          >>nishit.gupta@ st.com wrote:
          >>
          >>>Is their any single fuction available in C++ that can determine that a
          >>>string
          >>>contains a numeric value.
          >>>The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
          >>>"0xffff" , It can also contain zero
          >>>
          >>
          >>No. You would have to try one of the C library numeric conversion
          >>functions on the string's contents.
          >>
          No even that(strtoul, strtod) would not be possible as strtoul ask for
          base(16 for hex, 10 for dec)
          and my string can containg a non valid format as "0xffff12yz z" or
          "0xaa_AMERI CA" or "AMERICA" or "0xffff"
          I just want to check for the rigth possible numeric value.....
          Its content does not matter to me
          Then you'll have to parse the string scanning for valid number patterns.

          --
          Ian Collins.

          Comment

          • verdverm

            #6
            Re: any STL/string function available for determing string contains numeric

            On Apr 4, 12:22 am, nishit.gu...@st .com wrote:
            Is their any single fuction available in C++ that can determine that a
            string
            contains a numeric value.
            The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
            "0xffff" , It can also contain zero

            you could try regexp's
            Free, secure and fast downloads from the largest Open Source applications and software directory - SourceForge.net


            bool isValidNumber( string str ) {

            if( str[1] == 'x' ) {
            verify proper hex chars
            some func to convert to hex
            return true
            }
            else {
            ostringstream oss( str )
            double num;
            num << oss;

            if( num is valid )
            return true
            else
            return false
            }

            } // end of isValidNumber

            you could even return an int or enumeration to determine what type
            with further tests


            Comment

            • James Kanze

              #7
              Re: any STL/string function available for determing string contains numeric

              On Apr 4, 6:22 am, nishit.gu...@st .com wrote:
              Is their any single fuction available in C++ that can determine that a
              string
              contains a numeric value.
              The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
              "0xffff" , It can also contain zero
              Boost::regex.

              --
              James Kanze (GABI Software) email:james.kan ze@gmail.com
              Conseils en informatique orientée objet/
              Beratung in objektorientier ter Datenverarbeitu ng
              9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

              Comment

              • Jacek Dziedzic

                #8
                Re: any STL/string function available for determing string containsnumeric

                verdverm wrote:
                On Apr 4, 12:22 am, nishit.gu...@st .com wrote:
                >Is their any single fuction available in C++ that can determine that a
                >string
                >contains a numeric value.
                >The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
                >"0xffff" , It can also contain zero
                >
                >
                you could try regexp's
                Free, secure and fast downloads from the largest Open Source applications and software directory - SourceForge.net

                >
                bool isValidNumber( string str ) {
                >
                if(str.length() <2) // do something or the next line crashes
                if( str[1] == 'x' ) {
                verify proper hex chars
                some func to convert to hex
                return true
                }
                else {
                ostringstream oss( str )
                double num;
                num << oss;
                >
                if( num is valid )
                return true
                else
                return false
                Not really. For the string "123ZZZ" num is valid,
                while "123ZZZ" is not a valid number.

                Conversely, for the string "123" num may go eof
                after reading and hence become invalid, while "123"
                is a valid number.
                }
                >
                } // end of isValidNumber
                >
                you could even return an int or enumeration to determine what type
                with further tests
                - J.

                Comment

                • James Kanze

                  #9
                  Re: any STL/string function available for determing string contains numeric

                  On Apr 4, 5:40 pm, Jacek Dziedzic
                  <jacek.dziedzic .n.o.s.p....@gm ail.comwrote:
                  verdverm wrote:
                  On Apr 4, 12:22 am, nishit.gu...@st .com wrote:
                  Is their any single fuction available in C++ that can determine that a
                  string
                  contains a numeric value.
                  The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
                  "0xffff" , It can also contain zero
                  bool isValidNumber( string str ) {
                  >
                  if(str.length() <2) // do something or the next line crashes
                  if( str[1] == 'x' ) {
                  verify proper hex chars
                  some func to convert to hex
                  return true
                  }
                  else {
                  ostringstream oss( str )
                  double num;
                  num << oss;
                  >
                  if( num is valid )
                  return true
                  else
                  return false
                  Not really. For the string "123ZZZ" num is valid,
                  while "123ZZZ" is not a valid number.
                  The usual formulation in such cases is:

                  return oss >num >std::ws && oss.get() == EOF ;

                  If you don't want to allow whitespace, do
                  oss.unsetf( std::ios::skipw s ) ;
                  before, and drop the "<< std::ws".

                  The problem here is that there is no one target type which will
                  accept all possible numbers. If you're willing to use two
                  streams, however, something like the following should work:

                  std::ostringstr eam si( str ) ;
                  si.unsetf( std::ios::basef ield ) ;
                  std::ostringstr eam sd( str ) ;
                  int i ;
                  double d ;
                  return (si >i >std::ws && si.get() == EOF)
                  || (sd >d >std::ws && sd.get() == EOF) ;

                  Personally, I'd go with something like:

                  static boost::regex const
                  number( "^[:space:]*[+-]?"
                  "(" "([1-9][0-9]*)"
                  "|" "(0[0-7]*)"
                  "|" "(0[xX][0-9a-fA-F]+)"
                  "|" "([0-9]+\.[0-9]*([Ee][+-]?[0-9]+)?)"
                  "|" "(\.[0-9]+([Ee][+-]?[0-9]+)?)"
                  "|" "([0-9]+[Ee][+-]?[0-9]+)"
                  ")[:space:]*$" ) ;
                  return regex_match( str, number ) ;
                  Conversely, for the string "123" num may go eof
                  after reading and hence become invalid, while "123"
                  is a valid number.
                  The eofbit will be set after reading "123", but this doesn't
                  mean that the stream has failed. It only means that any further
                  attempt to read the stream will fail. (Note that std::ws is a
                  manipulator, which never "fails", i.e. it never sets failbit.)
                  }
                  } // end of isValidNumber
                  you could even return an int or enumeration to determine what type
                  with further tests
                  With boost::regex, you can capture the substrings which matched
                  parts of the regular expression in parentheses. Within the
                  or's, only one should not be empty, and which one tells you
                  which or matched.

                  My own regular expression class allows matching several regular
                  expressions in parallel, with the return code indicating which
                  one matched:


                  static Gabi::RegularEx pression const
                  number =
                  Gabi::RegularEx pression( "[+-]?[1-9][0-9]*", 10 ) ;
                  | Gabi::RegularEx pression( "[+-]?0[0-7]*", 8 ) ;
                  | Gabi::RegularEx pression( "[+-]?0[Xx][0-9a-fA-F]+", 16 )
                  | Gabi::RegularEx pression( "[+-]?[0-9]+\.[0-9]*([Ee][+-]?
                  [0-9]+)?", 0 )
                  | Gabi::RegularEx pression( "[+-]?\.[0-9]+([Ee][+-]?
                  [0-9]+)?", 0 )
                  | Gabi::RegularEx pression( "[+-]?[0-9]+[Ee][+-]?[0-9]+",
                  0 ) ;

                  std::pair< int, std::string::co nst_iterator >
                  result
                  = number.match( str.begin(), str.end() ) ;
                  return result.second == str.end()
                  ? result.first
                  : -1 ;

                  This would return -1 if no match, 0 for a floating point value,
                  and the base for an integer value. (I've since added features
                  to force an error if the match doesn't go to the end of the
                  string, so you could just use "return number.match(.. .).first;",
                  but this version isn't yet present at my site.)

                  --
                  James Kanze (GABI Software) email:james.kan ze@gmail.com
                  Conseils en informatique orientée objet/
                  Beratung in objektorientier ter Datenverarbeitu ng
                  9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                  Comment

                  • nishit.gupta@st.com

                    #10
                    Re: any STL/string function available for determing string contains numeric

                    Thanx James...1 more query..is regex a part of standard C++???
                    James Kanze wrote:
                    On Apr 4, 5:40 pm, Jacek Dziedzic
                    <jacek.dziedzic .n.o.s.p....@gm ail.comwrote:
                    verdverm wrote:
                    On Apr 4, 12:22 am, nishit.gu...@st .com wrote:
                    >Is their any single fuction available in C++ that can determine thata
                    >string
                    >contains a numeric value.
                    >The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
                    >"0xffff" , It can also contain zero
                    >>
                    bool isValidNumber( string str ) {
                    if(str.length() <2) // do something or the next line crashes
                    >
                    if( str[1] == 'x' ) {
                    verify proper hex chars
                    some func to convert to hex
                    return true
                    }
                    else {
                    ostringstream oss( str )
                    double num;
                    num << oss;
                    if( num is valid )
                    return true
                    else
                    return false
                    >
                    Not really. For the string "123ZZZ" num is valid,
                    while "123ZZZ" is not a valid number.
                    >
                    The usual formulation in such cases is:
                    >
                    return oss >num >std::ws && oss.get() == EOF ;
                    >
                    If you don't want to allow whitespace, do
                    oss.unsetf( std::ios::skipw s ) ;
                    before, and drop the "<< std::ws".
                    >
                    The problem here is that there is no one target type which will
                    accept all possible numbers. If you're willing to use two
                    streams, however, something like the following should work:
                    >
                    std::ostringstr eam si( str ) ;
                    si.unsetf( std::ios::basef ield ) ;
                    std::ostringstr eam sd( str ) ;
                    int i ;
                    double d ;
                    return (si >i >std::ws && si.get() == EOF)
                    || (sd >d >std::ws && sd.get() == EOF) ;
                    >
                    Personally, I'd go with something like:
                    >
                    static boost::regex const
                    number( "^[:space:]*[+-]?"
                    "(" "([1-9][0-9]*)"
                    "|" "(0[0-7]*)"
                    "|" "(0[xX][0-9a-fA-F]+)"
                    "|" "([0-9]+\.[0-9]*([Ee][+-]?[0-9]+)?)"
                    "|" "(\.[0-9]+([Ee][+-]?[0-9]+)?)"
                    "|" "([0-9]+[Ee][+-]?[0-9]+)"
                    ")[:space:]*$" ) ;
                    return regex_match( str, number ) ;
                    >
                    Conversely, for the string "123" num may go eof
                    after reading and hence become invalid, while "123"
                    is a valid number.
                    >
                    The eofbit will be set after reading "123", but this doesn't
                    mean that the stream has failed. It only means that any further
                    attempt to read the stream will fail. (Note that std::ws is a
                    manipulator, which never "fails", i.e. it never sets failbit.)
                    >
                    }
                    >
                    } // end of isValidNumber
                    >
                    you could even return an int or enumeration to determine what type
                    with further tests
                    >
                    With boost::regex, you can capture the substrings which matched
                    parts of the regular expression in parentheses. Within the
                    or's, only one should not be empty, and which one tells you
                    which or matched.
                    >
                    My own regular expression class allows matching several regular
                    expressions in parallel, with the return code indicating which
                    one matched:
                    >
                    >
                    static Gabi::RegularEx pression const
                    number =
                    Gabi::RegularEx pression( "[+-]?[1-9][0-9]*", 10 ) ;
                    | Gabi::RegularEx pression( "[+-]?0[0-7]*", 8 ) ;
                    | Gabi::RegularEx pression( "[+-]?0[Xx][0-9a-fA-F]+", 16 )
                    | Gabi::RegularEx pression( "[+-]?[0-9]+\.[0-9]*([Ee][+-]?
                    [0-9]+)?", 0 )
                    | Gabi::RegularEx pression( "[+-]?\.[0-9]+([Ee][+-]?
                    [0-9]+)?", 0 )
                    | Gabi::RegularEx pression( "[+-]?[0-9]+[Ee][+-]?[0-9]+",
                    0 ) ;
                    >
                    std::pair< int, std::string::co nst_iterator >
                    result
                    = number.match( str.begin(), str.end() ) ;
                    return result.second == str.end()
                    ? result.first
                    : -1 ;
                    >
                    This would return -1 if no match, 0 for a floating point value,
                    and the base for an integer value. (I've since added features
                    to force an error if the match doesn't go to the end of the
                    string, so you could just use "return number.match(.. .).first;",
                    but this version isn't yet present at my site.)
                    >
                    --
                    James Kanze (GABI Software) email:james.kan ze@gmail.com
                    Conseils en informatique orientée objet/
                    Beratung in objektorientier ter Datenverarbeitu ng
                    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                    Comment

                    • Jacek Dziedzic

                      #11
                      Re: any STL/string function available for determing string containsnumeric

                      James Kanze wrote:
                      >
                      Personally, I'd go with something like:
                      >
                      static boost::regex const
                      number( "^[:space:]*[+-]?"
                      "(" "([1-9][0-9]*)"
                      "|" "(0[0-7]*)"
                      "|" "(0[xX][0-9a-fA-F]+)"
                      "|" "([0-9]+\.[0-9]*([Ee][+-]?[0-9]+)?)"
                      "|" "(\.[0-9]+([Ee][+-]?[0-9]+)?)"
                      "|" "([0-9]+[Ee][+-]?[0-9]+)"
                      ")[:space:]*$" ) ;
                      return regex_match( str, number ) ;
                      That's clever. I _think_ this should be extended with a
                      "Dd", though -- isn't it a valid exponent delimiter for double
                      precision values? Like 2.34D+56?
                      > Conversely, for the string "123" num may go eof
                      >after reading and hence become invalid, while "123"
                      >is a valid number.
                      >
                      The eofbit will be set after reading "123", but this doesn't
                      mean that the stream has failed. It only means that any further
                      attempt to read the stream will fail. (Note that std::ws is a
                      manipulator, which never "fails", i.e. it never sets failbit.)
                      Thanks for clarifying that, I was of the impression that
                      eof() automatically triggers fail().

                      cheers,
                      - J.

                      Comment

                      • James Kanze

                        #12
                        Re: any STL/string function available for determing string contains numeric

                        On Apr 5, 2:28 pm, Jacek Dziedzic
                        <jacek.dziedzic .n.o.s.p....@gm ail.comwrote:
                        James Kanze wrote:
                        Personally, I'd go with something like:
                        static boost::regex const
                        number( "^[:space:]*[+-]?"
                        "(" "([1-9][0-9]*)"
                        "|" "(0[0-7]*)"
                        "|" "(0[xX][0-9a-fA-F]+)"
                        "|" "([0-9]+\.[0-9]*([Ee][+-]?[0-9]+)?)"
                        "|" "(\.[0-9]+([Ee][+-]?[0-9]+)?)"
                        "|" "([0-9]+[Ee][+-]?[0-9]+)"
                        ")[:space:]*$" ) ;
                        return regex_match( str, number ) ;
                        That's clever. I _think_ this should be extended with a
                        "Dd", though -- isn't it a valid exponent delimiter for double
                        precision values? Like 2.34D+56?
                        Not in C++. On the other hand, you can have suffixes which
                        specify the type more precisely: U, L or LL for integers, and F
                        or L for floating point. (Lower case is also accepted, and U
                        can combine with L or LL.) Thus, 3.14: double, 3.14F: float and
                        3.14L: long double. I don't know whether the original poster
                        wanted to accept these or not.

                        Note that it might be clearer if you specified some of the parts
                        as constant strings, and build the strings up, rather than
                        repeating things like "[Ee][+-]?[0-9]+" umpteam times. And
                        also, that my knowledge of regular expressions was acquired
                        many, many years ago, and hasn't been updated; I think that
                        Boost (and some others) accept things like \d for [0-9], \w for
                        [:space:], etc. (But don't forget that for regex to see the \
                        in a string literal, you have to double it.) Before using
                        something like this, I would strongly recommend reading the
                        documentation for the regular expression package you use.
                        Conversely, for the string "123" num may go eof
                        after reading and hence become invalid, while "123"
                        is a valid number.
                        The eofbit will be set after reading "123", but this doesn't
                        mean that the stream has failed. It only means that any further
                        attempt to read the stream will fail. (Note that std::ws is a
                        manipulator, which never "fails", i.e. it never sets failbit.)
                        Thanks for clarifying that, I was of the impression that
                        eof() automatically triggers fail().
                        Only at the start of conversion. Otherwise, think of the
                        problems: reading "123" into an int would fail.

                        The conditions in ios (the base class of istream and ostream)
                        aren't all that clear: the function good(), for example, does
                        consider eof(), so something like "if ( stream.good() )" after
                        an attempted read can fail, even though the read succeeded.
                        This is one of the reasons why one normally just uses the
                        conversion to bool (actualy, void*): it tests what you have to
                        test to know whether the conversion succeeded, and it doesn't
                        test anything else.

                        On top of that, the rules for unformatted input are somewhat
                        different, and the fact that the read "fails" doesn't mean that
                        it really failed. It only really failed if "! stream &&
                        stream.gcount() == 0".

                        --
                        James Kanze (Gabi Software) email: james.kanze@gma il.com
                        Conseils en informatique orientée objet/
                        Beratung in objektorientier ter Datenverarbeitu ng
                        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                        Comment

                        • Default User

                          #13
                          Re: any STL/string function available for determing string contains numeric - TPA

                          nishit.gupta@st .com wrote:
                          Thanx James...1 more query..is regex a part of standard C++???
                          Please don't top-post. Your replies belong following or interspersed
                          with properly trimmed quotes. See the majority of other posts in the
                          newsgroup, or the group FAQ list:
                          <http://www.parashift.c om/c++-faq-lite/how-to-post.html>

                          Comment

                          • James Kanze

                            #14
                            Re: any STL/string function available for determing string contains numeric

                            On Apr 5, 12:08 pm, nishit.gu...@st .com wrote:

                            [I thought I'd answered this, but since it's not showing
                            up...]
                            Thanx James...1 more query..is regex a part of standard C++???
                            Sort of. It's part of the TR1 (and so already available in some
                            libraries, without separately installing Boost), and it's been
                            adopted for C++0x, so it will be fully part of the standard
                            library in a couple of years.

                            In the meantime, if your compiler will support it, it's
                            definitly worth the bother of installing Boost (and installing
                            Boost is a pain, because they use a very non-standard and very
                            broken tool for building).

                            --

                            Comment

                            • Jacek Dziedzic

                              #15
                              Re: any STL/string function available for determing string containsnumeric

                              James Kanze wrote:
                              On Apr 5, 2:28 pm, Jacek Dziedzic
                              <jacek.dziedzic .n.o.s.p....@gm ail.comwrote:
                              >James Kanze wrote:
                              >
                              >>Personally, I'd go with something like:
                              >
                              >> static boost::regex const
                              >> number( "^[:space:]*[+-]?"
                              >> "(" "([1-9][0-9]*)"
                              >> "|" "(0[0-7]*)"
                              >> "|" "(0[xX][0-9a-fA-F]+)"
                              >> "|" "([0-9]+\.[0-9]*([Ee][+-]?[0-9]+)?)"
                              >> "|" "(\.[0-9]+([Ee][+-]?[0-9]+)?)"
                              >> "|" "([0-9]+[Ee][+-]?[0-9]+)"
                              >> ")[:space:]*$" ) ;
                              >> return regex_match( str, number ) ;
                              >
                              > That's clever. I _think_ this should be extended with a
                              >"Dd", though -- isn't it a valid exponent delimiter for double
                              >precision values? Like 2.34D+56?
                              >
                              Not in C++.
                              I must have gotten contaminated by Fortran, even though
                              I steer away from it :).
                              On the other hand, you can have suffixes which
                              specify the type more precisely: U, L or LL for integers, and F
                              or L for floating point. (Lower case is also accepted, and U
                              can combine with L or LL.) Thus, 3.14: double, 3.14F: float and
                              3.14L: long double. I don't know whether the original poster
                              wanted to accept these or not.
                              Right.
                              Note that it might be clearer if you specified some of the parts
                              as constant strings, and build the strings up, rather than
                              repeating things like "[Ee][+-]?[0-9]+" umpteam times. And
                              also, that my knowledge of regular expressions was acquired
                              many, many years ago, and hasn't been updated; I think that
                              Boost (and some others) accept things like \d for [0-9], \w for
                              [:space:], etc. (But don't forget that for regex to see the \
                              in a string literal, you have to double it.) Before using
                              something like this, I would strongly recommend reading the
                              documentation for the regular expression package you use.
                              OK
                              >>> Conversely, for the string "123" num may go eof
                              >>>after reading and hence become invalid, while "123"
                              >>>is a valid number.
                              >
                              >>The eofbit will be set after reading "123", but this doesn't
                              >>mean that the stream has failed. It only means that any further
                              >>attempt to read the stream will fail. (Note that std::ws is a
                              >>manipulator , which never "fails", i.e. it never sets failbit.)
                              >
                              > Thanks for clarifying that, I was of the impression that
                              >eof() automatically triggers fail().
                              >
                              Only at the start of conversion. Otherwise, think of the
                              problems: reading "123" into an int would fail.
                              >
                              The conditions in ios (the base class of istream and ostream)
                              aren't all that clear: the function good(), for example, does
                              consider eof(), so something like "if ( stream.good() )" after
                              an attempted read can fail, even though the read succeeded.
                              This is one of the reasons why one normally just uses the
                              conversion to bool (actualy, void*): it tests what you have to
                              test to know whether the conversion succeeded, and it doesn't
                              test anything else.
                              Right.
                              On top of that, the rules for unformatted input are somewhat
                              different, and the fact that the read "fails" doesn't mean that
                              it really failed. It only really failed if "! stream &&
                              stream.gcount() == 0".
                              Yes.

                              thanks,
                              - J.

                              Comment

                              Working...