xmldatetime.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,784 行 · 第 1/4 页

CPP
1,784
字号
		//"The month must have values 1 to 12");    }    //validate days    if ( fValue[Day] > maxDayInMonthFor( fValue[CentYear], fValue[Month]) ||         fValue[Day] == 0 )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_day_invalid                , fBuffer                , fMemoryManager);        //"The day must have values 1 to 31");    }    //validate hours    if ((fValue[Hour] < 0)  ||        (fValue[Hour] > 24) ||        ((fValue[Hour] == 24) && ((fValue[Minute] !=0) ||                                  (fValue[Second] !=0) ||                                  (fMiliSecond    !=0))))    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_hour_invalid                , fBuffer                , fMemoryManager);        //("Hour must have values 0-23");    }    //validate minutes    if ( fValue[Minute] < 0 ||         fValue[Minute] > 59 )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_min_invalid                , fBuffer                , fMemoryManager);        //"Minute must have values 0-59");    }    //validate seconds    if ( fValue[Second] < 0 ||         fValue[Second] > 60 )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_second_invalid                , fBuffer                , fMemoryManager);        //"Second must have values 0-60");    }    //validate time-zone hours    if ( (abs(fTimeZone[hh]) > 14) ||         ((abs(fTimeZone[hh]) == 14) && (fTimeZone[mm] != 0)) )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_tz_hh_invalid                , fBuffer                , fMemoryManager);        //"Time zone should have range -14..+14");    }    //validate time-zone minutes    if ( abs(fTimeZone[mm]) > 59 )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_min_invalid                , fBuffer                , fMemoryManager);        //("Minute must have values 0-59");    }	    return;}// -----------------------------------------------------------------------// locator and converter// -----------------------------------------------------------------------int XMLDateTime::indexOf(const int start, const int end, const XMLCh ch) const{    for ( int i = start; i < end; i++ )        if ( fBuffer[i] == ch )            return i;    return NOT_FOUND;}int XMLDateTime::findUTCSign (const int start){    int  pos;    for ( int index = start; index < fEnd; index++ )    {        pos = XMLString::indexOf(UTC_SET, fBuffer[index]);        if ( pos != NOT_FOUND)        {            fValue[utc] = pos+1;   // refer to utcType, there is 1 diff            return index;        }    }    return NOT_FOUND;}//// Note://    start: starting point in fBuffer//    end:   ending point in fBuffer (exclusive)//    fStart NOT updated//int XMLDateTime::parseInt(const int start, const int end) const{    unsigned int retVal = 0;    for (int i=start; i < end; i++) {        if (fBuffer[i] < chDigit_0 || fBuffer[i] > chDigit_9)            ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars, fMemoryManager);        retVal = (retVal * 10) + (unsigned int) (fBuffer[i] - chDigit_0);    }    return (int) retVal;}//// Note://    start: pointing to the first digit after the '.'//    end:   pointing to one position after the last digit//    fStart NOT updated//double XMLDateTime::parseMiliSecond(const int start, const int end) const{    unsigned int  miliSecLen = (end-1) - (start-1) + 1; //to include the '.'    XMLCh* miliSecData = (XMLCh*) fMemoryManager->allocate( (miliSecLen + 1) * sizeof(XMLCh));    ArrayJanitor<XMLCh> janMili(miliSecData, fMemoryManager);    XMLString::copyNString(miliSecData, &(fBuffer[start-1]), miliSecLen);    *(miliSecData + miliSecLen) = chNull;    char *nptr = XMLString::transcode(miliSecData, fMemoryManager);    ArrayJanitor<char> jan(nptr, fMemoryManager);    int   strLen = strlen(nptr);    char *endptr = 0;    errno = 0;    //printf("milisec=<%s>\n", nptr);    double retVal = strtod(nptr, &endptr);    // check if all chars are valid char    if ( (endptr - nptr) != strLen)        ThrowXMLwithMemMgr(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars, fMemoryManager);    // we don't check underflow occurs since    // nothing we can do about it.    return retVal;}//// [-]CCYY//// Note: start from fStart//       end (exclusive)//       fStart NOT updated//int XMLDateTime::parseIntYear(const int end) const{    // skip the first leading '-'    int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;    int length = end - start;    if (length < 4)    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_year_tooShort                , fBuffer                , fMemoryManager);        //"Year must have 'CCYY' format");    }    else if (length > 4 &&             fBuffer[start] == chDigit_0)    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_year_leadingZero                , fBuffer                , fMemoryManager);        //"Leading zeros are required if the year value would otherwise have fewer than four digits;        // otherwise they are forbidden");    }    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;    // (-?) cc+yy-mm-dd'T'hh:mm:ss'Z'    ('.'s+)?    //      2+  8       1      8   1    //    int additionalLen = fillYearString(retPtr, CentYear);    if(additionalLen != 0)    {        // very bad luck; have to resize the buffer...        XMLCh *tmpBuf = (XMLCh*) toUse->allocate( (additionalLen+21+miliSecondsLen +2) * sizeof(XMLCh));        XMLString::moveChars(tmpBuf, retBuf, 4+additionalLen);        retPtr = tmpBuf+(retPtr-retBuf);        toUse->deallocate(retBuf);        retBuf = tmpBuf;    }    *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];    assert(expLen < 16);    XMLString::binToText(fValue[ind], strBuffer, expLen, 10, fMemoryManager);    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];    }}int XMLDateTime::fillYearString(XMLCh*& ptr, valueIndex ind) const{    XMLCh strBuffer[16];    // let's hope we get no years of 15 digits...    XMLString::binToText(fValue[ind], strBuffer, 15, 10, fMemoryManager);    int   actualLen = XMLString::stringLen(strBuffer);    // don't forget that years can be negative...    int negativeYear = 0;    if(strBuffer[0] == chDash)    {        *ptr++ = strBuffer[0];        negativeYear = 1;    }    int   i;    //append leading zeros    for (i = 0; i < 4 - actualLen+negativeYear; i++)    {        *ptr++ = chDigit_0;    }    for (i = negativeYear; i < actualLen; i++)    {        *ptr++ = strBuffer[i];    }    if(actualLen > 4)        return actualLen-4;    return 0;}/*** * *   .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;}/*** * Support for Serialization/De-serialization ***/IMPL_XSERIALIZABLE_TOCREATE(XMLDateTime)void XMLDateTime::serialize(XSerializeEngine& serEng){    //REVISIT: may not need to call base since it does nothing    XMLNumber::serialize(serEng);    int i = 0;    if (serEng.isStoring())    {        for (i = 0; i < TOTAL_SIZE; i++)        {            serEng<<fValue[i];        }        for (i = 0; i < TIMEZONE_ARRAYSIZE; i++)        {            serEng<<fTimeZone[i];        }        serEng<<fStart;        serEng<<fEnd;        serEng.writeString(fBuffer, fBufferMaxLen, XSerializeEngine::toWriteBufferLen);    }    else    {        for (i = 0; i < TOTAL_SIZE; i++)        {            serEng>>fValue[i];        }        for (i = 0; i < TIMEZONE_ARRAYSIZE; i++)        {            serEng>>fTimeZone[i];        }        serEng>>fStart;        serEng>>fEnd;        int dataLen = 0;        serEng.readString(fBuffer, fBufferMaxLen, dataLen ,XSerializeEngine::toReadBufferLen);    }}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?