LCOV - code coverage report
Current view: top level - dom/xslt/base - txDouble.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 95 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "mozilla/FloatingPoint.h"
       7             : 
       8             : #include "nsString.h"
       9             : #include "txCore.h"
      10             : #include "txXMLUtils.h"
      11             : #include <math.h>
      12             : #include <stdlib.h>
      13             : #include <algorithm>
      14             : #ifdef WIN32
      15             : #include <float.h>
      16             : #endif
      17             : #include "prdtoa.h"
      18             : 
      19             : /*
      20             :  * Utility class for doubles
      21             :  */
      22             : 
      23             : /*
      24             :  * Converts the given String to a double, if the String value does not
      25             :  * represent a double, NaN will be returned
      26             :  */
      27           0 : class txStringToDouble
      28             : {
      29             : public:
      30             :     typedef char16_t input_type;
      31             :     typedef char16_t value_type;
      32           0 :     txStringToDouble(): mState(eWhitestart), mSign(ePositive) {}
      33             : 
      34             :     void
      35           0 :     write(const input_type* aSource, uint32_t aSourceLength)
      36             :     {
      37           0 :         if (mState == eIllegal) {
      38           0 :             return;
      39             :         }
      40           0 :         uint32_t i = 0;
      41             :         char16_t c;
      42           0 :         for ( ; i < aSourceLength; ++i) {
      43           0 :             c = aSource[i];
      44           0 :             switch (mState) {
      45             :                 case eWhitestart:
      46           0 :                     if (c == '-') {
      47           0 :                         mState = eDecimal;
      48           0 :                         mSign = eNegative;
      49             :                     }
      50           0 :                     else if (c >= '0' && c <= '9') {
      51           0 :                         mState = eDecimal;
      52           0 :                         mBuffer.Append((char)c);
      53             :                     }
      54           0 :                     else if (c == '.') {
      55           0 :                         mState = eMantissa;
      56           0 :                         mBuffer.Append((char)c);
      57             :                     }
      58           0 :                     else if (!XMLUtils::isWhitespace(c)) {
      59           0 :                         mState = eIllegal;
      60           0 :                         return;
      61             :                     }
      62           0 :                     break;
      63             :                 case eDecimal:
      64           0 :                     if (c >= '0' && c <= '9') {
      65           0 :                         mBuffer.Append((char)c);
      66             :                     }
      67           0 :                     else if (c == '.') {
      68           0 :                         mState = eMantissa;
      69           0 :                         mBuffer.Append((char)c);
      70             :                     }
      71           0 :                     else if (XMLUtils::isWhitespace(c)) {
      72           0 :                         mState = eWhiteend;
      73             :                     }
      74             :                     else {
      75           0 :                         mState = eIllegal;
      76           0 :                         return;
      77             :                     }
      78           0 :                     break;
      79             :                 case eMantissa:
      80           0 :                     if (c >= '0' && c <= '9') {
      81           0 :                         mBuffer.Append((char)c);
      82             :                     }
      83           0 :                     else if (XMLUtils::isWhitespace(c)) {
      84           0 :                         mState = eWhiteend;
      85             :                     }
      86             :                     else {
      87           0 :                         mState = eIllegal;
      88           0 :                         return;
      89             :                     }
      90           0 :                     break;
      91             :                 case eWhiteend:
      92           0 :                     if (!XMLUtils::isWhitespace(c)) {
      93           0 :                         mState = eIllegal;
      94           0 :                         return;
      95             :                     }
      96           0 :                     break;
      97             :                 default:
      98           0 :                     break;
      99             :             }
     100             :         }
     101             :     }
     102             : 
     103             :     double
     104           0 :     getDouble()
     105             :     {
     106           0 :         if (mState == eIllegal || mBuffer.IsEmpty() ||
     107           0 :             (mBuffer.Length() == 1 && mBuffer[0] == '.')) {
     108           0 :             return mozilla::UnspecifiedNaN<double>();
     109             :         }
     110           0 :         return mSign*PR_strtod(mBuffer.get(), 0);
     111             :     }
     112             : private:
     113             :     nsAutoCString mBuffer;
     114             :     enum {
     115             :         eWhitestart,
     116             :         eDecimal,
     117             :         eMantissa,
     118             :         eWhiteend,
     119             :         eIllegal
     120             :     } mState;
     121             :     enum {
     122             :         eNegative = -1,
     123             :         ePositive = 1
     124             :     } mSign;
     125             : };
     126             : 
     127           0 : double txDouble::toDouble(const nsAString& aSrc)
     128             : {
     129           0 :     txStringToDouble sink;
     130           0 :     nsAString::const_iterator fromBegin, fromEnd;
     131           0 :     copy_string(aSrc.BeginReading(fromBegin), aSrc.EndReading(fromEnd), sink);
     132           0 :     return sink.getDouble();
     133             : }
     134             : 
     135             : /*
     136             :  * Converts the value of the given double to a String, and places
     137             :  * The result into the destination String.
     138             :  * @return the given dest string
     139             :  */
     140           0 : void txDouble::toString(double aValue, nsAString& aDest)
     141             : {
     142             : 
     143             :     // check for special cases
     144             : 
     145           0 :     if (mozilla::IsNaN(aValue)) {
     146           0 :         aDest.AppendLiteral("NaN");
     147           0 :         return;
     148             :     }
     149           0 :     if (mozilla::IsInfinite(aValue)) {
     150           0 :         if (aValue < 0)
     151           0 :             aDest.Append(char16_t('-'));
     152           0 :         aDest.AppendLiteral("Infinity");
     153           0 :         return;
     154             :     }
     155             : 
     156             :     // Mantissa length is 17, so this is plenty
     157           0 :     const int buflen = 20;
     158             :     char buf[buflen];
     159             : 
     160             :     int intDigits, sign;
     161             :     char* endp;
     162           0 :     PR_dtoa(aValue, 0, 0, &intDigits, &sign, &endp, buf, buflen - 1);
     163             : 
     164             :     // compute length
     165           0 :     int32_t length = endp - buf;
     166           0 :     if (length > intDigits) {
     167             :         // decimal point needed
     168           0 :         ++length;
     169           0 :         if (intDigits < 1) {
     170             :             // leading zeros, -intDigits + 1
     171           0 :             length += 1 - intDigits;
     172             :         }
     173             :     }
     174             :     else {
     175             :         // trailing zeros, total length given by intDigits
     176           0 :         length = intDigits;
     177             :     }
     178           0 :     if (aValue < 0)
     179           0 :         ++length;
     180             :     // grow the string
     181           0 :     uint32_t oldlength = aDest.Length();
     182           0 :     if (!aDest.SetLength(oldlength + length, mozilla::fallible))
     183           0 :         return; // out of memory
     184           0 :     nsAString::iterator dest;
     185           0 :     aDest.BeginWriting(dest).advance(int32_t(oldlength));
     186           0 :     if (aValue < 0) {
     187           0 :         *dest = '-'; ++dest;
     188             :     }
     189             :     int i;
     190             :     // leading zeros
     191           0 :     if (intDigits < 1) {
     192           0 :         *dest = '0'; ++dest;
     193           0 :         *dest = '.'; ++dest;
     194           0 :         for (i = 0; i > intDigits; --i) {
     195           0 :             *dest = '0'; ++dest;
     196             :         }
     197             :     }
     198             :     // mantissa
     199           0 :     int firstlen = std::min<size_t>(intDigits, endp - buf);
     200           0 :     for (i = 0; i < firstlen; i++) {
     201           0 :         *dest = buf[i]; ++dest;
     202             :     }
     203           0 :     if (i < endp - buf) {
     204           0 :         if (i > 0) {
     205           0 :             *dest = '.'; ++dest;
     206             :         }
     207           0 :         for (; i < endp - buf; i++) {
     208           0 :             *dest = buf[i]; ++dest;
     209             :         }
     210             :     }
     211             :     // trailing zeros
     212           0 :     for (; i < intDigits; i++) {
     213           0 :         *dest = '0'; ++dest;
     214             :     }
     215             : }

Generated by: LCOV version 1.13