/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Id: XMLAbstractDoubleFloat.cpp 568078 2007-08-21 11:43:25Z amassari $
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLAbstractDoubleFloat.hpp>
#include <xercesc/util/XMLBigDecimal.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/NumberFormatException.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/Janitor.hpp>

#include <locale.h>
#include <float.h>
#include <errno.h>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  local data member
// ---------------------------------------------------------------------------
static const int BUF_LEN = 64;

static XMLCh expSign[] = {chLatin_e, chLatin_E, chNull};

// ---------------------------------------------------------------------------
//  ctor/dtor
// ---------------------------------------------------------------------------
XMLAbstractDoubleFloat::XMLAbstractDoubleFloat(MemoryManager* const manager)
: fValue(0)
, fType(Normal)
, fDataConverted(false)
, fDataOverflowed(false)
, fSign(0)
, fRawData(0)
, fFormattedString(0)
, fMemoryManager(manager)
{
}

XMLAbstractDoubleFloat::~XMLAbstractDoubleFloat()
{
     fMemoryManager->deallocate(fRawData);//delete [] fRawData;
     fMemoryManager->deallocate(fFormattedString);//delete [] fFormattedString;
}

void XMLAbstractDoubleFloat::init(const XMLCh* const strValue)
{
    if ((!strValue) || (!*strValue))
        ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_emptyString, fMemoryManager);

    fRawData = XMLString::replicate(strValue, fMemoryManager);   // preserve the raw data form

    XMLCh* tmpStrValue = XMLString::replicate(strValue, fMemoryManager);
    ArrayJanitor<XMLCh> janTmpName(tmpStrValue, fMemoryManager);
    XMLString::trim(tmpStrValue);

    if (!*tmpStrValue) 
        ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_emptyString, fMemoryManager);

    normalizeZero(tmpStrValue);

    if (XMLString::equals(tmpStrValue, XMLUni::fgNegINFString) )
    {
        fType = NegINF;
        fSign = -1;
    }
    else if (XMLString::equals(tmpStrValue, XMLUni::fgPosINFString) )
    {
        fType = PosINF;
        fSign = 1;
    }
    else if (XMLString::equals(tmpStrValue, XMLUni::fgNaNString) )
    {
        fType = NaN;
        fSign = 1;
    }
    else
        //
        // Normal case
        //
    {
        // Use a stack-based buffer when possible.  Since all
        // valid doubles or floats will only contain ASCII
        // digits, a decimal point,  or the exponent character,
        // they will all be single byte characters, and this will
        // work.
        static const unsigned int  maxStackSize = 100;

        unsigned int  lenTempStrValue = 0;

        
        // Need to check that the string only contains valid schema characters
        // since the call to strtod may allow other values.  For example, AIX
        // allows "infinity" and "+INF"
        XMLCh curChar;
        while (curChar = tmpStrValue[lenTempStrValue]) {            
            if (!((curChar >= chDigit_0 &&
                   curChar <= chDigit_9) ||
                  curChar == chPeriod  ||
                  curChar == chDash    ||
                  curChar == chPlus    ||
                  curChar == chLatin_E ||
                  curChar == chLatin_e)) {                
                ThrowXMLwithMemMgr(
                    NumberFormatException,
                    XMLExcepts::XMLNUM_Inv_chars,
                    getMemoryManager());
            }            
            lenTempStrValue++;
        }
       
        if (lenTempStrValue < maxStackSize)
        {
            char    buffer[maxStackSize + 1];

            XMLString::transcode(
                tmpStrValue,
                buffer,
                sizeof(buffer) - 1,
                getMemoryManager());

            // Do this for safety, because we've
            // no guarantee we didn't overrun the
            // capacity of the buffer when transcoding
            // a bogus value.
            buffer[maxStackSize] = '\0';

            // If they aren't the same length, then some
            // non-ASCII multibyte character was present.
            // This will only happen in the case where the
            // string has a bogus character, and it's long
            // enough to overrun this buffer, but we need
            // to check, even if it's unlikely to happen.
            if (XMLString::stringLen(buffer) != lenTempStrValue)
            {
                ThrowXMLwithMemMgr(
                    NumberFormatException,
                    XMLExcepts::XMLNUM_Inv_chars,
                    getMemoryManager());
            }

            checkBoundary(buffer);
        }
        else
        {
            char *nptr = XMLString::transcode(tmpStrValue, getMemoryManager());
            const ArrayJanitor<char> janStr(nptr, fMemoryManager);

            checkBoundary(nptr);
        }
    }

}

//
// 
//
XMLCh*  XMLAbstractDoubleFloat::toString() const
{
    // Return data using global operator new
    return XMLString::replicate(fRawData);
}

XMLCh*  XMLAbstractDoubleFloat::getRawData() const
{
    return fRawData;
}

const XMLCh*  XMLAbstractDoubleFloat::getFormattedString() const
{
    if (!fDataConverted)
    {
        return fRawData;
    }
    else 
    {
        if (!fFormattedString)    	
        {
            XMLAbstractDoubleFloat *temp = (XMLAbstractDoubleFloat *) this;
            temp->formatString();
        }

        return fFormattedString;           
    }

}

void XMLAbstractDoubleFloat::formatString()
{

    unsigned int rawDataLen = XMLString::stringLen(fRawData);
    fFormattedString = (XMLCh*) fMemoryManager->allocate
    (
        (rawDataLen + 8) * sizeof(XMLCh)
    );//new XMLCh [ rawDataLen + 8];
    for (unsigned int i = 0; i < rawDataLen + 8; i++)
        fFormattedString[i] = chNull;

    XMLString::copyString(fFormattedString, fRawData);

    fFormattedString[rawDataLen] = chSpace;
    fFormattedString[rawDataLen + 1] = chOpenParen;

    switch (fType)
    {
    case NegINF:       
        XMLString::catString(fFormattedString, XMLUni::fgNegINFString);
        break;
    case PosINF:
        XMLString::catString(fFormattedString, XMLUni::fgPosINFString);
        break;
    case NaN:
        XMLString::catString(fFormattedString, XMLUni::fgNaNString);
        break;
    default:
        // its zero
        XMLString::catString(fFormattedString, XMLUni::fgPosZeroString);
        break;
    }

    fFormattedString[XMLString::stringLen(fFormattedString)] = chCloseParen;

}

int XMLAbstractDoubleFloat::getSign() const
{
    return fSign;
}

//
//
//
int XMLAbstractDoubleFloat::compareValues(const XMLAbstractDoubleFloat* const lValue
                                        , const XMLAbstractDoubleFloat* const rValue
                                        , MemoryManager* const manager)
{
    //
    // case#1: lValue normal
    //         rValue normal
    //
    if ((!lValue->isSpecialValue()) &&
        (!rValue->isSpecialValue())  )
    {
        if (lValue->fValue == rValue->fValue)
            return EQUAL;
        else
            return (lValue->fValue > rValue->fValue) ? GREATER_THAN : LESS_THAN;

    }
    //
    // case#2: lValue special
    //         rValue special
    //
    // Schema Errata E2-40
    // 
    // Positive Infinity is greater than all other non-NAN value.
    // Nan equals itself but is not comparable with (neither greater than nor less than)
    //     any other value in the value space
    // Negative Infinity is less than all other non-NAN values.
    //
    else
    if ((lValue->isSpecialValue()) &&
        (rValue->isSpecialValue())  )
    {
        if (lValue->fType == rValue->fType)
            return EQUAL;
        else
        {
            if ((lValue->fType == NaN) ||
                (rValue->fType == NaN)  )
            {
                return INDETERMINATE;
            }
            else
            {
                return (lValue->fType > rValue->fType) ? GREATER_THAN : LESS_THAN;
            }
        }

    }
    //
    // case#3: lValue special
    //         rValue normal
    //
    else
    if ((lValue->isSpecialValue()) &&
        (!rValue->isSpecialValue())  )
    {
        return compareSpecial(lValue, manager);
    }
    //
    // case#4: lValue normal
    //         rValue special
    //
    else
    {
        return (-1) * compareSpecial(rValue, manager);
    }

    return 0;
}

int XMLAbstractDoubleFloat::compareSpecial(const XMLAbstractDoubleFloat* const specialValue                                         
                                         , MemoryManager* const manager)
{
    switch (specialValue->fType)
    {
    case NegINF:
        return LESS_THAN;
    case PosINF:
        return GREATER_THAN;
    case NaN:
        // NaN is not comparable to any other value
        return INDETERMINATE;

    default:
        XMLCh value1[BUF_LEN+1];
        XMLString::binToText(specialValue->fType, value1, 16, 10, manager);
        ThrowXMLwithMemMgr1(NumberFormatException
                , XMLExcepts::XMLNUM_DBL_FLT_InvalidType
                , value1, manager);
        //internal error
        return 0;
    }
}

//
//  Assumption: no leading space
//
//  1. The valid char set is "+-.0"
//  2. There shall be only one sign at the first position, if there is one.
//  3. There shall be only one dot '.', if there is one.
//
//  Return:
//
//  for input comforming to [+]? [0]* '.'? [0]*,
//            normalize the input to positive zero string
//  for input comforming to '-' [0]* '.'? [0]*,
//            normalize the input to negative zero string
//  otherwise, do nothing
//
void XMLAbstractDoubleFloat::normalizeZero(XMLCh* const inData)
{

	// do a quick check
	if (!inData  ||
		!*inData ||
        (XMLString::equals(inData, XMLUni::fgNegZeroString) ) ||
        (XMLString::equals(inData, XMLUni::fgPosZeroString) )  )
        return;

    XMLCh*   srcStr = inData;
	bool     minusSeen = false;
    bool     dotSeen = false;

	// process sign if any
	if (*srcStr == chDash)
	{
		minusSeen = true;
		srcStr++;
        if (!*srcStr)
        {
            ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars, getMemoryManager());
        }
	}
	else if (*srcStr == chPlus)
	{
		srcStr++;
        if (!*srcStr)
        {
            ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars, getMemoryManager());
        }
	}
    else if (*srcStr == chPeriod)
    {
        dotSeen = true;
        srcStr++;
        if (!*srcStr)
        {
            ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars, getMemoryManager());
        }
    }

	// scan the string
	
	bool  isValidStr = true;
    XMLCh theChar;
	while ((theChar=*srcStr++) && isValidStr)
	{
		if ( theChar != chPeriod && theChar != chDigit_0 )
			isValidStr = false;           		// invalid char
        else if (theChar == chPeriod)           // process dot
			dotSeen ? isValidStr = false : dotSeen = true;
	}

	// need not to worry about the memory problem
	// since either fgNegZeroString or fgPosZeroString
	// is the canonical form (meaning the shortest in length)
	// of their category respectively.
	if (isValidStr)
	{
		if (minusSeen)
			XMLString::copyString(inData, XMLUni::fgNegZeroString);
		else
			XMLString::copyString(inData, XMLUni::fgPosZeroString);
	}
    else
    {
        // we got to set the sign first, since this string may
        // eventaully turn out to be beyond the minimum representable 
        // number and reduced to -0 or +0.
        fSign = minusSeen ? -1 : 1;
    }

    return;
} 

void XMLAbstractDoubleFloat::normalizeDecimalPoint(char* const toNormal)
{
    // find the locale-specific decimal point delimiter
    lconv* lc = localeconv();
    char delimiter = *lc->decimal_point;

    // replace '.' with the locale-specific decimal point delimiter
    if ( delimiter != '.' )
    {
        char* period = strchr( toNormal, '.' );
        if ( period )
        {
            *period = delimiter;
        }
    }
}


void
XMLAbstractDoubleFloat::convert(char* const strValue)
{
    normalizeDecimalPoint(strValue);

    char *endptr = 0;
    errno = 0;
    fValue = strtod(strValue, &endptr);

    // check if all chars are valid char.  If they are, endptr will
    // pointer to the null terminator.
    if (*endptr != '\0')
    {
        ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars, getMemoryManager());
    }

    // check if overflow/underflow occurs
    if (errno == ERANGE)
    {
            
        fDataConverted = true;

        if ( fValue < 0 )
        {
            if (fValue > (-1)*DBL_MIN)
            {
                fValue = 0;
            }
            else
            {
                fType = NegINF;
                fDataOverflowed = true;
            }
        }
        else if ( fValue > 0)
        {
            if (fValue < DBL_MIN )
            {
                fValue = 0;
            }
            else
            {
                fType = PosINF;
                fDataOverflowed = true;
            }
        }
    }
}



/***
 * E2-40
 *
 *   3.2.4 float
 *   3.2.5 double
 *
 * . the exponent must be indicated by "E". 
 *   if the exponent is zero, it must be indicated by "E0". 
 *
 * . For the mantissa, 
 *      the preceding optional "+" sign is prohibited and 
 *      the decimal point is required. 
 *
 * . For the exponent, 
 *      the preceding optional "+" sign is prohibited. 
 *      Leading zeroes are prohibited.
 *      
 * . Leading and trailing zeroes are prohibited subject to the following: 
 *   number representations must be normalized such that 
 *     . there is a single digit, which is non-zero, to the left of the decimal point and
 *     . at least a single digit to the right of the decimal point.
 *     . unless the value being represented is zero. 
 *       The canonical representation for zero is 0.0E0
 *
 ***/     
XMLCh* XMLAbstractDoubleFloat::getCanonicalRepresentation(const XMLCh*         const rawData
                                                        ,       MemoryManager* const memMgr)
{
    // before anything, let's look for special tokens since that
    // breaks the calls to parse below.
    if(XMLString::equals(rawData, XMLUni::fgNegINFString) || 
       XMLString::equals(rawData, XMLUni::fgPosINFString) || 
       XMLString::equals(rawData, XMLUni::fgNaNString)     )
    {
        return XMLString::replicate(rawData, memMgr);
    }

    try 
    {
        int    strLen = XMLString::stringLen(rawData);
        XMLCh* manStr = (XMLCh*) memMgr->allocate((strLen + 1) * sizeof(XMLCh));
        ArrayJanitor<XMLCh> janManStr(manStr, memMgr);
        XMLCh* manBuf = (XMLCh*) memMgr->allocate((strLen + 1) * sizeof(XMLCh));
        ArrayJanitor<XMLCh> janManBuf(manBuf, memMgr);
        XMLCh* expStr = (XMLCh*) memMgr->allocate((strLen + 1) * sizeof(XMLCh));
        ArrayJanitor<XMLCh> janExpStr(expStr, memMgr);
        XMLCh* retBuffer = (XMLCh*) memMgr->allocate((strLen + 8) * sizeof(XMLCh));
        ArrayJanitor<XMLCh> janRetBuffer(retBuffer, memMgr);
        retBuffer[0] = 0;

        int sign, totalDigits, fractDigits, expValue = 0;

        const XMLCh* ePosition = XMLString::findAny(rawData, expSign);

        /***
         *  parse mantissa and exp separately
        ***/
        if (!ePosition)
        {
            XMLBigDecimal::parseDecimal(rawData, manBuf, sign, totalDigits, fractDigits, memMgr);
            expValue = 0;
        }
        else
        {
            int    manLen = ePosition - rawData;
            XMLString::copyNString(manStr, rawData, manLen);
            *(manStr + manLen) = chNull;
            XMLBigDecimal::parseDecimal(manStr, manBuf, sign, totalDigits, fractDigits, memMgr);

            int    expLen = strLen - manLen - 1;
            ePosition++;
            XMLString::copyNString(expStr, ePosition, expLen);
            *(expStr + expLen) = chNull;
            expValue = XMLString::parseInt(expStr); 
        }

        if ( (sign == 0) || (totalDigits == 0) )
        {
            retBuffer[0] = chDigit_0;
            retBuffer[1] = chPeriod;
            retBuffer[2] = chDigit_0;
            retBuffer[3] = chLatin_E;
            retBuffer[4] = chDigit_0;
            retBuffer[5] = chNull;
        }
        else
        {
            XMLCh* retPtr = retBuffer;

            if (sign == -1)
            {
                *retPtr++ = chDash;
            }

            *retPtr++ = manBuf[0];
            *retPtr++ = chPeriod;

            //XMLBigDecimal::parseDecimal() will eliminate trailing zeros
            // iff there is a decimal points
            // eg. 56.7800e0  -> manBuf = 5678, totalDigits = 4, fractDigits = 2
            // we print it as 5.678e1
            //
            // but it wont remove trailing zeros if there is no decimal point.
            // eg.  567800e0 -> manBuf = 567800, totalDigits = 6, fractDigits = 0
            // we print it 5.67800e5
            //
            // for the latter, we need to print it as 5.678e5 instead
            //
            XMLCh* endPtr = manBuf + totalDigits;

            if (fractDigits == 0)
            {
                while(*(endPtr - 1) == chDigit_0)
                    endPtr--;
            }

            int remainLen = endPtr - &(manBuf[1]);

            if (remainLen)
            {
                XMLString::copyNString(retPtr, &(manBuf[1]), remainLen);
                retPtr += remainLen;
            }
            else
            {
                *retPtr++ = chDigit_0;
            }

            /***
             * 
             *  . adjust expValue
             *   
             *  new_fractDigits = totalDigits - 1  
             *  new_expValue = old_expValue + (new_fractDigits - fractDigits)
             *
             ***/
            expValue += (totalDigits - 1) - fractDigits ;
            XMLString::binToText(expValue, expStr, strLen, 10, memMgr);
            *retPtr++  = chLatin_E;
            *retPtr = chNull;

            XMLString::catString(&(retBuffer[0]), expStr);
        }

        janRetBuffer.release();
        return retBuffer;
    }
    catch (const NumberFormatException&)
    {
        return 0;
    }
}        

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_NOCREATE(XMLAbstractDoubleFloat)

void XMLAbstractDoubleFloat::serialize(XSerializeEngine& serEng)
{
    //REVISIT: may not need to call base since it does nothing
    XMLNumber::serialize(serEng);

    if (serEng.isStoring())
    {
        serEng << fValue;
        serEng << fType;
        serEng << fDataConverted;
        serEng << fDataOverflowed;
        serEng << fSign;

        serEng.writeString(fRawData);

        // Do not serialize fFormattedString

    }
    else
    {
        serEng >> fValue;

        int type = 0;
        serEng >> type;
        fType = (LiteralType) type;

        serEng >> fDataConverted;
        serEng >> fDataOverflowed;
        serEng >> fSign;

        serEng.readString(fRawData);

        // Set it to 0 force it to re-format if needed
        fFormattedString = 0;

    }

}

XERCES_CPP_NAMESPACE_END
