dbertoni    01/01/15 18:42:14

  Modified:    c/src/PlatformSupport DOMStringHelper.cpp DoubleSupport.cpp
                        DoubleSupport.hpp
  Log:
  Added validation function for converting string to double.
  
  Revision  Changes    Path
  1.50      +14 -1     xml-xalan/c/src/PlatformSupport/DOMStringHelper.cpp
  
  Index: DOMStringHelper.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/PlatformSupport/DOMStringHelper.cpp,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- DOMStringHelper.cpp       2001/01/08 18:15:30     1.49
  +++ DOMStringHelper.cpp       2001/01/16 02:42:13     1.50
  @@ -1242,14 +1242,21 @@
                        const XalanDOMChar*             theString,
                        Type                                    /* theDummy */)
   {
  -     if (theString == 0)
  +     if (theString == 0 || DoubleSupport::isValid(theString) == false)
        {
                return Type(0);
        }
        else
        {
  +             // OK, now we know we have a valid string, so start 
converting...
                Type    theResult = 0;
   
  +             // Consume any leading whitespace (which we allow)
  +             while(isXMLWhitespace(*theString) == true)
  +             {
  +                     ++theString;
  +             }
  +
                const bool      isNegative = *theString == 
XalanUnicode::charHyphenMinus ? true : false;
   
                if (isNegative == true)
  @@ -1267,8 +1274,14 @@
   
                                ++theString;
                        }
  +                     else if (isXMLWhitespace(*theString) == true)
  +                     {
  +                             // This must be trailing whitespace...
  +                             break;
  +                     }
                        else
                        {
  +                             // An non-numeric character was encountered, so 
stop...
                                return 0;
                        }
                }
  
  
  
  1.18      +220 -23   xml-xalan/c/src/PlatformSupport/DoubleSupport.cpp
  
  Index: DoubleSupport.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/PlatformSupport/DoubleSupport.cpp,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- DoubleSupport.cpp 2000/12/01 21:36:00     1.17
  +++ DoubleSupport.cpp 2001/01/16 02:42:13     1.18
  @@ -363,9 +363,7 @@
   
   
   
  -#if 1
  -
  -void
  +static void
   consumeNumbers(const XalanDOMChar*&  theString)
   {
        while(*theString &&
  @@ -378,12 +376,177 @@
   
   
   
  +static bool
  +doValidate(
  +                     const XalanDOMChar*             theString,
  +                     bool&                                   
fGotDecimalPoint)
  +{
  +     assert(theString != 0);
  +
  +     bool    fError = false;
  +     bool    fGotDigit = false;
  +     bool    fGotMinus = false;
  +     bool    fGotWhitespace = false;
  +
  +     const XalanDOMChar*             theCurrent = theString;
  +
  +     // trim any whitespace
  +     consumeWhitespace(theCurrent);
  +
  +     while(*theCurrent != 0 && fError == false)
  +     {
  +             switch(*theCurrent)
  +             {
  +             case XalanUnicode::charFullStop:
  +                     if (fGotDecimalPoint == true || // can't have more than 
one...
  +                             fGotWhitespace == true) // can't have one after 
whitespace...
  +                     {
  +                             fError = true;
  +                     }
  +                     else
  +                     {
  +                             fGotDecimalPoint = true;
  +
  +                             ++theCurrent;
  +                     }
  +                     break;
  +
  +             case XalanUnicode::charHyphenMinus:
  +                     if (fGotDecimalPoint == true ||
  +                             fGotMinus == true ||
  +                             fGotDigit == true ||
  +                             fGotWhitespace == true)
  +                     {
  +                             // Error -- more than one, or in bad position.
  +                             fError = true;
  +                     }
  +                     else
  +                     {
  +                             fGotMinus = true;
  +
  +                             ++theCurrent;
  +                     }
  +                     break;
  +
  +             case XalanUnicode::charDigit_0:
  +             case XalanUnicode::charDigit_1:
  +             case XalanUnicode::charDigit_2:
  +             case XalanUnicode::charDigit_3:
  +             case XalanUnicode::charDigit_4:
  +             case XalanUnicode::charDigit_5:
  +             case XalanUnicode::charDigit_6:
  +             case XalanUnicode::charDigit_7:
  +             case XalanUnicode::charDigit_8:
  +             case XalanUnicode::charDigit_9:
  +                     if (fGotWhitespace == true)
  +                     {
  +                             fError = true;
  +                     }
  +                     else
  +                     {
  +                             fGotDigit = true;
  +
  +                             consumeNumbers(theCurrent);
  +                     }
  +                     break;
  +
  +             case XalanUnicode::charSpace:
  +             case XalanUnicode::charCR:
  +             case XalanUnicode::charHTab:
  +             case XalanUnicode::charLF:
  +                     if (fGotWhitespace == true)
  +                     {
  +                             fError = true;
  +                     }
  +                     else
  +                     {
  +                             fGotWhitespace = true;
  +
  +                             consumeWhitespace(theCurrent);
  +                     }
  +                     break;
  +
  +             default:
  +                     fError = true;
  +                     break;
  +             }
  +     }
  +
  +     // If there was no error, check to see that we got
  +     // at least one digit.  Otherwise, return false if
  +     // there was an error.
  +     return fError == false ? fGotDigit : false;
  +}
  +
  +
  +
  +static bool
  +doValidate(const XalanDOMChar*       theString)
  +{
  +     bool    fDummy = false;
  +
  +     return doValidate(theString, fDummy);
  +}
  +
  +
  +
  +inline double
  +convertHelper(
  +                     const XalanDOMChar*             theString,
  +                     bool                                    
fGotDecimalPoint)
  +{
  +     // This is a big hack.  If the length of the
  +     // string is less than n characters, we'll convert
  +     // it as a long and coerce that to a double.  This
  +     // is _much_ cheaper...
  +     const unsigned int      theLongHackThreshold = 11;
  +
  +     const unsigned int      theLength = length(theString);
  +
  +     if (fGotDecimalPoint == false && theLength < theLongHackThreshold)
  +     {
  +             return double(WideStringToLong(theString));
  +     }
  +     else
  +     {
  +             // Use a stack-based buffer, when possible...
  +             const unsigned int      theBufferSize = 200u;
  +
  +             if (theLength < theBufferSize)
  +             {
  +                     char    theBuffer[theBufferSize];
  +
  +                     for(unsigned int i = 0; i < theLength; ++i)
  +                     {
  +                             theBuffer[i] = char(theString[i]);
  +                     }
  +
  +                     theBuffer[theLength] = '\0';
  +
  +                     return atof(theBuffer);
  +             }
  +             else
  +             {
  +                     CharVectorType  theVector;
  +
  +                     theVector.reserve(theLength + 1);
  +
  +                     CopyWideStringToVector(theString, theVector);
  +
  +                     return atof(&*theVector.begin());
  +             }
  +     }
  +}
  +
  +
  +
   double
   doConvert(const XalanDOMChar*        theString)
   {
        assert(theString != 0);
        assert(*theString != 0);
   
  +#if 0
        bool    fError = false;
        bool    fGotDecimalPoint = false;
        bool    fGotDigit = false;
  @@ -485,17 +648,67 @@
   
                return wcstod(theString, &theDummy);
   #else
  -             CharVectorType  theVector;
  +             return convertHelper(theString, fGotDecimalPoint);
  +#endif
  +     }
  +#else
  +     bool    fGotDecimalPoint = false;
   
  -             CopyWideStringToVector(theString, theVector);
  +     if (doValidate(theString, fGotDecimalPoint) == false)
  +     {
  +             return DoubleSupport::getNaN();
  +     }
  +     else
  +     {
  +#if defined(XALAN_FULL_WCHAR_SUPPORT) && defined(XALAN_USE_WCHAR_SUPPORT)
  +             XalanDOMChar*   theDummy;
   
  -             return atof(&theVector.front());
  +             return wcstod(theString, &theDummy);
  +#else
  +             return convertHelper(theString, fGotDecimalPoint);
   #endif
        }
  +#endif
   }
   
  -#else
   
  +
  +double
  +DoubleSupport::toDouble(const XalanDOMChar*          theString)
  +{
  +     if (theString == 0 ||
  +             *theString == 0)
  +     {
  +             return getNaN();
  +     }
  +     else
  +     {
  +             return doConvert(theString);
  +     }
  +}
  +
  +
  +
  +bool
  +DoubleSupport::isValid(const XalanDOMString          theString)
  +{
  +     return isValid(c_wstr(theString));
  +}
  +
  +
  +
  +bool
  +DoubleSupport::isValid(const XalanDOMChar*           theString)
  +{
  +     bool    fDummy = false;
  +
  +     return doValidate(theString);
  +}
  +
  +
  +
  +#if 0
  +
   // This version is disabled because it turns out that
   // an unsigned long is not large enough to accumulate
   // all values (duh!).  Perhaps on 64-bit platforms, we
  @@ -670,19 +883,3 @@
   }
   
   #endif
  -
  -
  -
  -double
  -DoubleSupport::toDouble(const XalanDOMChar*          theString)
  -{
  -     if (theString == 0 ||
  -             *theString == 0)
  -     {
  -             return getNaN();
  -     }
  -     else
  -     {
  -             return doConvert(theString);
  -     }
  -}
  
  
  
  1.10      +36 -0     xml-xalan/c/src/PlatformSupport/DoubleSupport.hpp
  
  Index: DoubleSupport.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/PlatformSupport/DoubleSupport.hpp,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DoubleSupport.hpp 2000/12/01 21:36:00     1.9
  +++ DoubleSupport.hpp 2001/01/16 02:42:13     1.10
  @@ -551,9 +551,45 @@
                }
        };
   
  +     /**
  +      * Determine whether or not a string contains
  +      * a valid floating point number.
  +      *
  +      * @param theString The string to check.
  +      * @return true if the string is valid, false if not.
  +      */
  +     static bool
  +     isValid(const XalanDOMString    theString);
  +
  +     /**
  +      * Determine whether or not a string contains
  +      * a valid floating point number.
  +      *
  +      * @param theString The string to check.
  +      * @return true if the string is valid, false if not.
  +      */
  +     static bool
  +     isValid(const XalanDOMChar*             theString);
  +
  +     /**
  +      * Convert a string to a double value.  Returns
  +      * NaN if the string is not a valid floating
  +      * point number.
  +      *
  +      * @param theString The string to convert.
  +      * @return The result of the conversion
  +      */
        static double
        toDouble(const XalanDOMString&  theString);
   
  +     /**
  +      * Convert a string to a double value.  Returns
  +      * NaN if the string is not a valid floating
  +      * point number.
  +      *
  +      * @param theString The string to convert.
  +      * @return The result of the conversion
  +      */
        static double
        toDouble(const XalanDOMChar*    theString);
   
  
  
  

Reply via email to