You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by pe...@apache.org on 2003/12/11 22:38:13 UTC

cvs commit: xml-xerces/c/src/xercesc/util XMLAbstractDoubleFloat.cpp XMLAbstractDoubleFloat.hpp XMLBigDecimal.cpp XMLBigDecimal.hpp XMLBigInteger.cpp XMLBigInteger.hpp XMLDateTime.cpp XMLDateTime.hpp

peiyongz    2003/12/11 13:38:13

  Modified:    c/src/xercesc/util XMLAbstractDoubleFloat.cpp
                        XMLAbstractDoubleFloat.hpp XMLBigDecimal.cpp
                        XMLBigDecimal.hpp XMLBigInteger.cpp
                        XMLBigInteger.hpp XMLDateTime.cpp XMLDateTime.hpp
  Log:
  support for Canonical Representation for Datatype
  
  Revision  Changes    Path
  1.18      +125 -1    xml-xerces/c/src/xercesc/util/XMLAbstractDoubleFloat.cpp
  
  Index: XMLAbstractDoubleFloat.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLAbstractDoubleFloat.cpp,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- XMLAbstractDoubleFloat.cpp	15 Oct 2003 14:50:01 -0000	1.17
  +++ XMLAbstractDoubleFloat.cpp	11 Dec 2003 21:38:12 -0000	1.18
  @@ -57,6 +57,9 @@
   /*
    * $Id$
    * $Log$
  + * Revision 1.18  2003/12/11 21:38:12  peiyongz
  + * support for Canonical Representation for Datatype
  + *
    * Revision 1.17  2003/10/15 14:50:01  peiyongz
    * Bugzilla#22821: locale-sensitive function used to validate 'double' type, patch
    * from jsweeney@spss.com (Jeff Sweeney)
  @@ -123,6 +126,7 @@
   //  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>
  @@ -138,6 +142,8 @@
   static const int BUF_LEN = 64;
   static XMLCh value1[BUF_LEN+1];
   
  +static XMLCh expSign[] = {chLatin_e, chLatin_E, chNull};
  +
   // ---------------------------------------------------------------------------
   //  ctor/dtor
   // ---------------------------------------------------------------------------
  @@ -455,6 +461,123 @@
           }
       }
   }
  +
  +/***
  + * 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)
  +{
  +    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> janExp(expStr, memMgr);
  +
  +    int sign, totalDigits, fractDigits;
  +    int expValue = 0;
  +
  +    XMLCh* retBuffer = (XMLCh*) memMgr->allocate((strLen + 8) * sizeof(XMLCh));
  +
  +    const XMLCh* ePosition = XMLString::findAny(rawData, expSign);
  +
  +    /***
  +     *  parse mantissa and exp separately
  +     ***/
  +    if (!ePosition)
  +    {
  +        XMLBigDecimal::parseDecimal(rawData, manBuf, sign, totalDigits, fractDigits);
  +        expValue = 0;
  +    }
  +    else
  +    {
  +        int    manLen = ePosition - rawData;
  +        XMLString::copyNString(manStr, rawData, manLen);
  +        *(manStr + manLen) = chNull;
  +        XMLBigDecimal::parseDecimal(manStr, manBuf, sign, totalDigits, fractDigits);
  +
  +        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;
  +
  +        if (totalDigits - 1 > 0)
  +        {
  +            XMLString::copyNString(retPtr, &(manBuf[1]), totalDigits - 1);
  +            retPtr += (totalDigits - 1);
  +        }
  +        else
  +        {
  +            *retPtr++ = chDigit_0;
  +        }
  +
  +        *retPtr++  = chLatin_E;
  +        *retPtr = chNull;
  +
  +        /***
  +         * 
  +         *  . adjust expValue
  +         *   
  +         *  new_fractDigits = totalDigits - 1  
  +         *  new_expValue = old_expValue + (new_fractDigits - fractDigits)
  +         *
  +         ***/
  +        expValue += (totalDigits - 1) - fractDigits ;
  +        XMLString::binToText(expValue, expStr, strLen, 10);
  +        XMLString::catString(&(retBuffer[0]), expStr);
  +
  +    }
  +
  +    return retBuffer;
  +}        
   
   /***
    * Support for Serialization/De-serialization
  
  
  
  1.16      +11 -1     xml-xerces/c/src/xercesc/util/XMLAbstractDoubleFloat.hpp
  
  Index: XMLAbstractDoubleFloat.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLAbstractDoubleFloat.hpp,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- XMLAbstractDoubleFloat.hpp	15 Oct 2003 14:50:01 -0000	1.15
  +++ XMLAbstractDoubleFloat.hpp	11 Dec 2003 21:38:12 -0000	1.16
  @@ -57,6 +57,9 @@
   /*
    * $Id$
    * $Log$
  + * Revision 1.16  2003/12/11 21:38:12  peiyongz
  + * support for Canonical Representation for Datatype
  + *
    * Revision 1.15  2003/10/15 14:50:01  peiyongz
    * Bugzilla#22821: locale-sensitive function used to validate 'double' type, patch
    * from jsweeney@spss.com (Jeff Sweeney)
  @@ -170,6 +173,12 @@
       };
   
       virtual ~XMLAbstractDoubleFloat();
  +
  +    static XMLCh* getCanonicalRepresentation
  +                        (
  +                          const XMLCh*         const rawData
  +                        ,       MemoryManager* const memMgr = XMLPlatformUtils::fgMemoryManager
  +                        );
   
       /**
        *
  
  
  
  1.15      +109 -23   xml-xerces/c/src/xercesc/util/XMLBigDecimal.cpp
  
  Index: XMLBigDecimal.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLBigDecimal.cpp,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- XMLBigDecimal.cpp	1 Oct 2003 16:32:39 -0000	1.14
  +++ XMLBigDecimal.cpp	11 Dec 2003 21:38:12 -0000	1.15
  @@ -56,6 +56,9 @@
   
   /*
    * $Log$
  + * Revision 1.15  2003/12/11 21:38:12  peiyongz
  + * support for Canonical Representation for Datatype
  + *
    * Revision 1.14  2003/10/01 16:32:39  neilg
    * improve handling of out of memory conditions, bug #23415.  Thanks to David Cargill.
    *
  @@ -128,10 +131,12 @@
   //  Includes
   // ---------------------------------------------------------------------------
   #include <xercesc/util/XMLBigDecimal.hpp>
  +#include <xercesc/util/XMLBigInteger.hpp>
   #include <xercesc/util/TransService.hpp>
   #include <xercesc/util/NumberFormatException.hpp>
   #include <xercesc/util/XMLChar.hpp>
   #include <xercesc/util/OutOfMemoryException.hpp>
  +#include <xercesc/util/Janitor.hpp>
   
   XERCES_CPP_NAMESPACE_BEGIN
   
  @@ -173,7 +178,7 @@
           );
           memcpy(fRawData, strValue, (fRawDataLen+1) * sizeof(XMLCh));
           fIntVal = fRawData + fRawDataLen + 1;
  -        parseBigDecimal(strValue, fRawDataLen);
  +        parseDecimal(strValue, fIntVal, fSign, (int&) fTotalDigits, (int&) fScale);
       }
       catch(const OutOfMemoryException&)
       {
  @@ -217,51 +222,132 @@
       }
   
       memcpy(fRawData, strValue, (valueLen + 1) * sizeof(XMLCh));
  -    parseBigDecimal(strValue, valueLen);
  +    parseDecimal(strValue, fIntVal, fSign, (int&) fTotalDigits, (int&) fScale);
  +
   }
   
  -void XMLBigDecimal::parseBigDecimal(const XMLCh* const toConvert
  -                                    , unsigned int     toConvertLen)
  +/***
  + * 3.2.3 decimal  
  + *
  + * . the preceding optional "+" sign is prohibited. 
  + * . The decimal point is required. 
  + * . Leading and trailing zeroes are prohibited subject to the following: 
  + *   there must be at least one digit to the right and to the left of the decimal point which may be a zero.
  + *
  + ***/
  +XMLCh* XMLBigDecimal::getCanonicalRepresentation(const XMLCh*         const rawData
  +                                               ,       MemoryManager* const memMgr)
   {
  -    // Scan past any whitespace. If we hit the end, then return failure
  -    const XMLCh* startPtr = toConvert;
  +    XMLCh* retBuf = (XMLCh*) memMgr->allocate( XMLString::stringLen(rawData) * sizeof(XMLCh));
  +    ArrayJanitor<XMLCh> janName(retBuf, memMgr);
  +    int   sign, totalDigits, fractDigits;
  +
  +    XMLBigDecimal::parseDecimal(rawData, retBuf, sign, totalDigits, fractDigits);
  +
  +    //Extra space reserved in case strLen is zero
  +    int    strLen = XMLString::stringLen(retBuf);
  +    XMLCh* retBuffer = (XMLCh*) memMgr->allocate( (strLen + 4) * sizeof(XMLCh));
  +
  +    if ( (sign == 0) || (totalDigits == 0))
  +    {
  +        retBuffer[0] = chDigit_0;
  +        retBuffer[1] = chPeriod;
  +        retBuffer[2] = chDigit_0;
  +        retBuffer[3] = chNull;
  +    }
  +    else
  +    {
  +        XMLCh* retPtr = retBuffer;
  +
  +        if (sign == -1)
  +        {
  +            *retPtr++ = chDash;
  +        }
  +
  +        if (fractDigits == totalDigits)   // no integer
  +        {           
  +            *retPtr++ = chDigit_0;
  +            *retPtr++ = chPeriod;
  +            XMLString::copyNString(retPtr, retBuf, strLen);
  +            retPtr += strLen;
  +            *retPtr = chNull;
  +        }
  +        else if (fractDigits == 0)        // no fraction
  +        {
  +            XMLString::copyNString(retPtr, retBuf, strLen);
  +            retPtr += strLen;
  +            *retPtr++ = chPeriod;
  +            *retPtr++ = chDigit_0;
  +            *retPtr   = chNull;
  +        }
  +        else  // normal
  +        {
  +            int intLen = totalDigits - fractDigits;
  +            XMLString::copyNString(retPtr, retBuf, intLen);
  +            retPtr += intLen;
  +            *retPtr++ = chPeriod;
  +            XMLString::copyNString(retPtr, &(retBuf[intLen]), fractDigits);
  +            retPtr += fractDigits;
  +            *retPtr = chNull;
  +        }
  +
  +    }
  +            
  +    return retBuffer;
  +
  +}
  +
  +void  XMLBigDecimal::parseDecimal(const XMLCh* const toParse
  +                               ,        XMLCh* const retBuffer
  +                               ,        int&         sign
  +                               ,        int&         totalDigits
  +                               ,        int&         fractDigits)
  +{
  +    //init
  +    retBuffer[0] = chNull;
  +    totalDigits = 0;
  +    fractDigits = 0;
  +
  +    // Strip leading white space, if any. 
  +    const XMLCh* startPtr = toParse;
       while (XMLChar1_0::isWhitespace(*startPtr))
           startPtr++;
   
  +    // If we hit the end, then return failure
       if (!*startPtr)
           ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_WSString);
   
  -    // Start at the end and work back through any whitespace
  -    const XMLCh* endPtr = toConvert + XMLString::stringLen(toConvert);
  +    // Strip tailing white space, if any.
  +    const XMLCh* endPtr = toParse + XMLString::stringLen(toParse);
       while (XMLChar1_0::isWhitespace(*(endPtr - 1)))
           endPtr--;
   
       // '+' or '-' is allowed only at the first position
  -    fSign = 1;
  +    // and is NOT included in the return parsed string
  +    sign = 1;
       if (*startPtr == chDash)
       {
  -        fSign = -1;
  +        sign = -1;
           startPtr++;
       }
       else if (*startPtr == chPlus)
       {
  -        startPtr++;        // skip the '+'
  +        startPtr++;
       }
   
  -    // remove leading zeros
  +    // Strip leading zeros
       while (*startPtr == chDigit_0)
           startPtr++;
   
       // containning zero, only zero, nothing but zero
       // it is a zero, indeed
  -    if (!*startPtr)
  +    if (startPtr >= endPtr)
       {
  -        fSign = 0;
  -        fIntVal[0] = chNull;
  +        sign = 0;
           return;
       }
   
  -    XMLCh* retPtr = fIntVal;
  +    XMLCh* retPtr = (XMLCh*) retBuffer;
   
       // Scan data
       bool   dotSignFound = false;
  @@ -269,10 +355,10 @@
       {
           if (*startPtr == chPeriod)
           {
  -            if (dotSignFound == false)
  +            if (!dotSignFound)
               {
                   dotSignFound = true;
  -                fScale = endPtr - startPtr - 1;
  +                fractDigits = endPtr - startPtr - 1;
                   startPtr++;
                   continue;
               }
  @@ -286,7 +372,7 @@
   
           // copy over
           *retPtr++ = *startPtr++;
  -        fTotalDigits++;
  +        totalDigits++;
       }
   
       /***
  @@ -298,18 +384,17 @@
           normalization: remove all trailing zero after the '.'
                          and adjust the scaleValue as well.
       ***/
  -    while ((fScale > 0) && (*(retPtr-1) == chDigit_0))          
  +    while ((fractDigits > 0) && (*(retPtr-1) == chDigit_0))          
       {
           retPtr--;
  -        fScale--;
  -        fTotalDigits--;
  +        fractDigits--;
  +        totalDigits--;
       }
   
       *retPtr = chNull;   //terminated
       return;
   }
   
  -
   int XMLBigDecimal::compareValues( const XMLBigDecimal* const lValue
                                   , const XMLBigDecimal* const rValue)
   {
  @@ -371,6 +456,7 @@
       }
   
   }
  +
   
   /***
    * Support for Serialization/De-serialization
  
  
  
  1.14      +17 -3     xml-xerces/c/src/xercesc/util/XMLBigDecimal.hpp
  
  Index: XMLBigDecimal.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLBigDecimal.hpp,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- XMLBigDecimal.hpp	1 Dec 2003 23:23:27 -0000	1.13
  +++ XMLBigDecimal.hpp	11 Dec 2003 21:38:12 -0000	1.14
  @@ -94,6 +94,21 @@
       static int            compareValues(const XMLBigDecimal* const lValue
                                         , const XMLBigDecimal* const rValue);
   
  +    static XMLCh* getCanonicalRepresentation
  +                  (
  +                   const XMLCh*         const rawData
  +                 ,       MemoryManager* const memMgr = XMLPlatformUtils::fgMemoryManager
  +                  );
  +
  +    static void  parseDecimal
  +                ( 
  +                   const XMLCh* const toParse
  +                ,        XMLCh* const retBuffer
  +                ,        int&         sign
  +                ,        int&         totalDigits
  +                ,        int&         fractDigits
  +                );
  +
       /**
        *
        *  Deprecated: please use getRawData
  @@ -138,8 +153,7 @@
       XMLBigDecimal(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
   
   private:
  -    void  parseBigDecimal( const XMLCh* const strValue
  -                         , unsigned int       strValueLen);
  +
       void  cleanUp();
       
       // -----------------------------------------------------------------------
  
  
  
  1.7       +29 -1     xml-xerces/c/src/xercesc/util/XMLBigInteger.cpp
  
  Index: XMLBigInteger.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLBigInteger.cpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XMLBigInteger.cpp	22 May 2003 02:10:52 -0000	1.6
  +++ XMLBigInteger.cpp	11 Dec 2003 21:38:12 -0000	1.7
  @@ -56,6 +56,9 @@
   
   /*
    * $Log$
  + * Revision 1.7  2003/12/11 21:38:12  peiyongz
  + * support for Canonical Representation for Datatype
  + *
    * Revision 1.6  2003/05/22 02:10:52  knoaman
    * Default the memory manager.
    *
  @@ -110,6 +113,31 @@
   
   XERCES_CPP_NAMESPACE_BEGIN
   
  +XMLCh* XMLBigInteger::getCanonicalRepresentation(const XMLCh*         const rawData
  +                                               ,       MemoryManager* const memMgr)
  +{
  +    XMLCh* retBuf = (XMLCh*) memMgr->allocate( XMLString::stringLen(rawData) * sizeof(XMLCh));
  +    int    sign = 0;
  +
  +    XMLBigInteger::parseBigInteger(rawData, retBuf, sign);
  +
  +    if (sign == 0)
  +    {
  +        retBuf[0] = chDigit_0;
  +        retBuf[1] = chNull;
  +    }
  +    else if (sign == -1)
  +    {
  +        XMLCh* retBuffer = (XMLCh*) memMgr->allocate( (XMLString::stringLen(retBuf) + 2) * sizeof(XMLCh));
  +        retBuffer[0] = chDash;
  +        XMLString::copyString(&(retBuffer[1]), retBuf);
  +        memMgr->deallocate(retBuf);
  +        return retBuffer;
  +    }
  +
  +    return retBuf;
  +}
  +
   /***
      *
      *  Leading and trailing whitespaces are allowed, and trimmed
  @@ -187,7 +215,7 @@
       while (*startPtr == chDigit_0)
           startPtr++;
   
  -    if (!*startPtr)
  +    if (startPtr >= endPtr)
       {
           signValue = 0;
           // containning zero, only zero, nothing but zero
  
  
  
  1.10      +7 -1      xml-xerces/c/src/xercesc/util/XMLBigInteger.hpp
  
  Index: XMLBigInteger.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLBigInteger.hpp,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- XMLBigInteger.hpp	1 Dec 2003 23:23:27 -0000	1.9
  +++ XMLBigInteger.hpp	11 Dec 2003 21:38:12 -0000	1.10
  @@ -92,6 +92,12 @@
   
       XMLBigInteger(const XMLBigInteger& toCopy);
   
  +    static XMLCh* getCanonicalRepresentation
  +                        (
  +                          const XMLCh*         const rawData
  +                        ,       MemoryManager* const memMgr = XMLPlatformUtils::fgMemoryManager
  +                        );
  +
       static void parseBigInteger(const XMLCh* const toConvert
                                 , XMLCh* const       retBuffer
                                 , int&   signValue);
  
  
  
  1.17      +169 -1    xml-xerces/c/src/xercesc/util/XMLDateTime.cpp
  
  Index: XMLDateTime.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLDateTime.cpp,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- XMLDateTime.cpp	25 Sep 2003 22:24:28 -0000	1.16
  +++ XMLDateTime.cpp	11 Dec 2003 21:38:12 -0000	1.17
  @@ -57,6 +57,9 @@
   /*
    * $Id$
    * $Log$
  + * Revision 1.17  2003/12/11 21:38:12  peiyongz
  + * support for Canonical Representation for Datatype
  + *
    * Revision 1.16  2003/09/25 22:24:28  peiyongz
    * Using writeString/readString
    *
  @@ -1080,6 +1083,11 @@
           }
           else
           {
  +            //to do: parseInt would eliminate any leading zeros
  +            //       therefore for 12:01:01.0034
  +            //       fValue[MiliSecond] would catch 34
  +            //       rather than 0034
  +            //
               fValue[MiliSecond] = parseInt(fStart, sign);  //get ms between UTC sign and fEnd
           }
   	}
  @@ -1438,6 +1446,166 @@
       bool negative = (fBuffer[0] == chDash);
       int  yearVal = parseInt((negative ? 1 : 0), end);
       return ( negative ? (-1) * yearVal : yearVal );
  +}
  +
  +/***
  + * E2-41
  + *
  + *  3.2.7.2 Canonical representation
  + * 
  + *  Except for trailing fractional zero digits in the seconds representation, 
  + *  '24:00:00' time representations, and timezone (for timezoned values), 
  + *  the mapping from literals to values is one-to-one. Where there is more 
  + *  than one possible representation, the canonical representation is as follows: 
  + *  redundant trailing zero digits in fractional-second literals are prohibited. 
  + *  An hour representation of '24' is prohibited. Timezoned values are canonically
  + *  represented by appending 'Z' to the nontimezoned representation. (All 
  + *  timezoned dateTime values are UTC.) 
  + *
  + *  .'24:00:00' -> '00:00:00'
  + *  .milisecond: trailing zeros removed
  + *  .'Z'
  + *
  + ***/
  +XMLCh* XMLDateTime::getDateTimeCanonicalRepresentation(MemoryManager* const memMgr) const
  +{
  +    XMLCh *miliStartPtr, *miliEndPtr;
  +    searchMiliSeconds(miliStartPtr, miliEndPtr);
  +    int miliSecondsLen = miliEndPtr - miliStartPtr;
  +
  +    MemoryManager* toUse = memMgr? memMgr : fMemoryManager;
  +    XMLCh* retBuf = (XMLCh*) toUse->allocate( (21 + miliSecondsLen + 2) * sizeof(XMLCh));
  +    XMLCh* retPtr = retBuf;
  +
  +    // ccyy-mm-dd'T'hh:mm:ss'Z'    ('.'s+)?
  +    //   10       1      8   1
  +    //
  +    fillString(retPtr, CentYear, 4);
  +    *retPtr++ = DATE_SEPARATOR;
  +    fillString(retPtr, Month, 2);
  +    *retPtr++ = DATE_SEPARATOR;
  +    fillString(retPtr, Day, 2);
  +    *retPtr++ = DATETIME_SEPARATOR;
  +
  +    fillString(retPtr, Hour, 2);
  +    if (fValue[Hour] == 24)
  +    {
  +        *(retPtr - 2) = chDigit_0;
  +        *(retPtr - 1) = chDigit_0;
  +    }
  +    *retPtr++ = TIME_SEPARATOR;
  +    fillString(retPtr, Minute, 2);
  +    *retPtr++ = TIME_SEPARATOR;
  +    fillString(retPtr, Second, 2);
  +
  +    if (miliSecondsLen)
  +    {
  +        *retPtr++ = chPeriod;
  +        XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);
  +        retPtr += miliSecondsLen;
  +    }
  +
  +    *retPtr++ = UTC_STD_CHAR;
  +    *retPtr = chNull;
  +
  +    return retBuf;
  +}
  +
  +/***
  + * 3.2.8 time
  + *
  + *  . either the time zone must be omitted or, 
  + *    if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z".   
  + *
  + *  . Additionally, the canonical representation for midnight is 00:00:00.
  + *
  +***/
  +XMLCh* XMLDateTime::getTimeCanonicalRepresentation(MemoryManager* const memMgr) const
  +{
  +    XMLCh *miliStartPtr, *miliEndPtr;
  +    searchMiliSeconds(miliStartPtr, miliEndPtr);
  +    int miliSecondsLen = miliEndPtr - miliStartPtr;
  +
  +    MemoryManager* toUse = memMgr? memMgr : fMemoryManager;
  +    XMLCh* retBuf = (XMLCh*) toUse->allocate( (10 + miliSecondsLen + 2) * sizeof(XMLCh));
  +    XMLCh* retPtr = retBuf;
  +
  +    // 'hh:mm:ss'Z'    ('.'s+)?
  +    //      8    1
  +    //
  +
  +    fillString(retPtr, Hour, 2);
  +    if (fValue[Hour] == 24)
  +    {
  +        *(retPtr - 2) = chDigit_0;
  +        *(retPtr - 1) = chDigit_0;
  +    }
  +    *retPtr++ = TIME_SEPARATOR;
  +    fillString(retPtr, Minute, 2);
  +    *retPtr++ = TIME_SEPARATOR;
  +    fillString(retPtr, Second, 2);
  +
  +    if (miliSecondsLen)
  +    {
  +        *retPtr++ = chPeriod;
  +        XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);
  +        retPtr += miliSecondsLen;
  +    }
  +
  +    *retPtr++ = UTC_STD_CHAR;
  +    *retPtr = chNull;
  +
  +    return retBuf;
  +}
  +
  +void XMLDateTime::fillString(XMLCh*& ptr, valueIndex ind, int expLen) const
  +{
  +    XMLCh strBuffer[16];
  +    XMLString::binToText(fValue[ind], strBuffer, expLen, 10);
  +    int   actualLen = XMLString::stringLen(strBuffer);
  +    int   i;
  +    //append leading zeros
  +    for (i = 0; i < expLen - actualLen; i++)
  +    {
  +        *ptr++ = chDigit_0;
  +    }
  +
  +    for (i = 0; i < actualLen; i++)
  +    {
  +        *ptr++ = strBuffer[i];
  +    }
  +
  +}
  +
  +/***
  + *
  + *   .check if the rawData has the mili second component
  + *   .capture the substring
  + *
  + ***/
  +void XMLDateTime::searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const
  +{
  +    miliStartPtr = miliEndPtr = 0;
  +
  +    int milisec = XMLString::indexOf(fBuffer, MILISECOND_SEPARATOR);
  +    if (milisec == -1)
  +        return;
  +
  +    miliStartPtr = fBuffer + milisec + 1;
  +    miliEndPtr   = miliStartPtr;
  +    while (*miliEndPtr)
  +    {
  +        if ((*miliEndPtr < chDigit_0) || (*miliEndPtr > chDigit_9))
  +            break;
  +
  +        miliEndPtr++;
  +    }
  +
  +    //remove trailing zeros
  +    while( *(miliEndPtr - 1) == chDigit_0)
  +        miliEndPtr--;
  +
  +    return;
   }
   
   /***
  
  
  
  1.11      +16 -1     xml-xerces/c/src/xercesc/util/XMLDateTime.hpp
  
  Index: XMLDateTime.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLDateTime.hpp,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- XMLDateTime.hpp	23 Sep 2003 18:16:07 -0000	1.10
  +++ XMLDateTime.hpp	11 Dec 2003 21:38:12 -0000	1.11
  @@ -57,6 +57,9 @@
   /*
    * $Id$
    * $Log$
  + * Revision 1.11  2003/12/11 21:38:12  peiyongz
  + * support for Canonical Representation for Datatype
  + *
    * Revision 1.10  2003/09/23 18:16:07  peiyongz
    * Inplementation for Serialization/Deserialization
    *
  @@ -174,6 +177,14 @@
       virtual int           getSign() const;
   
       // -----------------------------------------------------------------------
  +    // Canonical Representation
  +    // -----------------------------------------------------------------------
  +
  +    XMLCh*                getDateTimeCanonicalRepresentation(MemoryManager* const memMgr) const;
  +
  +    XMLCh*                getTimeCanonicalRepresentation(MemoryManager* const memMgr)     const;
  +
  +    // -----------------------------------------------------------------------
       // parsers
       // -----------------------------------------------------------------------
   
  @@ -296,6 +307,10 @@
       void                  validateDateTime()          const;
   
       void                  normalize();
  +
  +    void                  fillString(XMLCh*& ptr, valueIndex ind, int expLen) const;
  +
  +    void                  searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const;
   
       // -----------------------------------------------------------------------
       // Unimplemented operator ==
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org