dbertoni    00/07/09 18:04:09

  Modified:    c/src/PlatformSupport DOMStringHelper.cpp DoubleSupport.cpp
                        DoubleSupport.hpp
  Log:
  New wide string to double conversion routine.  Still experimental.
  
  Revision  Changes    Path
  1.27      +4 -0      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.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- DOMStringHelper.cpp       2000/06/29 19:56:31     1.26
  +++ DOMStringHelper.cpp       2000/07/10 01:04:08     1.27
  @@ -948,6 +948,9 @@
   XALAN_PLATFORMSUPPORT_EXPORT_FUNCTION(double)
   WideStringToDouble(const XalanDOMChar*       theString)
   {
  +#if 1
  +     return DoubleSupport::toDouble(theString);
  +#else
        double  theResult = DoubleSupport::getNaN();
   
        // This extra test is here because of all the difficulties
  @@ -995,6 +998,7 @@
        }
   
        return theResult;
  +#endif
   }
   
   
  
  
  
  1.8       +195 -0    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.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- DoubleSupport.cpp 2000/05/05 15:06:50     1.7
  +++ DoubleSupport.cpp 2000/07/10 01:04:08     1.8
  @@ -69,7 +69,10 @@
   #endif
   
   
  +#include "DOMStringHelper.hpp"
   
  +
  +
   #if defined(NO_STD_LIMITS)
   #if defined(__GNUC__)
   const double DoubleSupport::s_NaN = NAN;
  @@ -325,5 +328,197 @@
        else
        {
                return -theDouble;
  +     }
  +}
  +
  +
  +
  +double
  +DoubleSupport::toDouble(const XalanDOMString&        theString)
  +{
  +     return toDouble(c_wstr(theString));
  +}
  +
  +
  +
  +void
  +processWhitespace(const XalanDOMChar*&       theString)
  +{
  +     while(*theString != 0 && isSpace(*theString) == true)
  +     {
  +             ++theString;
  +     }
  +}
  +
  +
  +
  +void
  +accumulateNumbers(
  +                     const XalanDOMChar*&    theString,
  +                     double&                                 theResult,
  +                     bool                                    fAfterDecimal)
  +{
  +     if (fAfterDecimal == false)
  +     {
  +             assert(theResult == 0.0);
  +
  +             // accumulate as an integer, to avoid
  +             // rounding issues.  It's also much
  +             // faster...
  +             unsigned long   temp = 0;
  +
  +             while(*theString && isDigit(*theString) == true)
  +             {
  +                     temp *= 10;
  +                     temp += char(*theString) - '0';
  +
  +                     ++theString;
  +             }
  +
  +             theResult = temp;
  +     }
  +     else
  +     {
  +             // Accumulate a divisor, so we can divide at the end.
  +             unsigned long   theDivisor = 1;
  +
  +             // accumulate as an integer, to avoid
  +             // rounding issues.  It's also much
  +             // faster...
  +             unsigned long   temp = 0;
  +
  +             while(*theString && isDigit(*theString) == true)
  +             {
  +                     theDivisor *= 10;
  +
  +                     temp *= 10;
  +                     temp += char(*theString) - '0';
  +
  +                     ++theString;
  +             }
  +
  +             if (temp > 0 && theDivisor > 1)
  +             {
  +                     const double    theFactionalPart =
  +                             double(temp) / double(theDivisor);
  +
  +                     theResult += theFactionalPart;
  +             }
  +     }
  +}
  +
  +
  +
  +double
  +doConvert(const XalanDOMChar*        theString)
  +{
  +     assert(theString != 0);
  +     assert(*theString != 0);
  +
  +     double  theResult = 0.0;
  +
  +     bool    fError = false;
  +     bool    fGotDecimalPoint = false;
  +     bool    fGotDigit = false;
  +     bool    fGotMinus = false;
  +     bool    fGotWhitespace = false;
  +
  +     const XalanDOMChar*             theCurrent = theString;
  +
  +     // trim any whitespace
  +     processWhitespace(theCurrent);
  +
  +     while(*theCurrent != 0 && fError == false)
  +     {
  +             switch(*theCurrent)
  +             {
  +             case '.':
  +                     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 '-':
  +                     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 '0':
  +             case '1':
  +             case '2':
  +             case '3':
  +             case '4':
  +             case '5':
  +             case '6':
  +             case '7':
  +             case '8':
  +             case '9':
  +                     if (fGotWhitespace == true)
  +                     {
  +                             fError = true;
  +                     }
  +                     else
  +                     {
  +                             fGotDigit = true;
  +
  +                             accumulateNumbers(theCurrent, theResult, 
fGotDecimalPoint);
  +                     }
  +                     break;
  +
  +             case ' ':
  +             case '\t':
  +                     fGotWhitespace = true;
  +                     processWhitespace(theCurrent);
  +                     break;
  +
  +             default:
  +                     fError = true;
  +                     break;
  +             }
  +     }
  +
  +     if (fError == true || fGotDigit == false)
  +     {
  +             return DoubleSupport::getNaN();
  +     }
  +     else
  +     {
  +             return fGotMinus == true ? -theResult : theResult;
  +     }
  +}
  +
  +
  +
  +double
  +DoubleSupport::toDouble(const XalanDOMChar*          theString)
  +{
  +     if (theString == 0 ||
  +             *theString == 0)
  +     {
  +             return getNaN();
  +     }
  +     else
  +     {
  +             return doConvert(theString);
        }
   }
  
  
  
  1.5       +10 -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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DoubleSupport.hpp 2000/05/05 15:06:50     1.4
  +++ DoubleSupport.hpp 2000/07/10 01:04:09     1.5
  @@ -68,6 +68,10 @@
   
   
   
  +#include <XalanDOM/XalanDOMString.hpp>
  +
  +
  +
   // A class to help us support IEEE 754.
   class XALAN_PLATFORMSUPPORT_EXPORT DoubleSupport
   {
  @@ -506,6 +510,12 @@
                        return negative(theDouble);
                }
        };
  +
  +     static double
  +     toDouble(const XalanDOMString&  theString);
  +
  +     static double
  +     toDouble(const XalanDOMChar*    theString);
   
   private:
   
  
  
  

Reply via email to