xmldatetime.cpp

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

CPP
1,784
字号
    //find 'Y'    int end = indexOf(fStart, endDate, DURATION_Y);    if ( end != NOT_FOUND )    {        //scan year        fValue[CentYear] = negate * parseInt(fStart, end);        fStart = end+1;        designator = true;    }    end = indexOf(fStart, endDate, DURATION_M);    if ( end != NOT_FOUND )    {        //scan month        fValue[Month] = negate * parseInt(fStart, end);        fStart = end+1;        designator = true;    }    end = indexOf(fStart, endDate, DURATION_D);    if ( end != NOT_FOUND )    {        //scan day        fValue[Day] = negate * parseInt(fStart,end);        fStart = end+1;        designator = true;    }    if ( (fEnd == endDate) &&   // 'T' absent         (fStart != fEnd)   )   // something after Day    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_dur_inv_b4T                , fBuffer                , fMemoryManager);    }    if ( fEnd != endDate ) // 'T' present    {        //scan hours, minutes, seconds        //        // skip 'T' first        end = indexOf(++fStart, fEnd, DURATION_H);        if ( end != NOT_FOUND )        {            //scan hours            fValue[Hour] = negate * parseInt(fStart, end);            fStart = end+1;            designator = true;        }        end = indexOf(fStart, fEnd, DURATION_M);        if ( end != NOT_FOUND )        {            //scan min            fValue[Minute] = negate * parseInt(fStart, end);            fStart = end+1;            designator = true;        }        end = indexOf(fStart, fEnd, DURATION_S);        if ( end != NOT_FOUND )        {            //scan seconds            int mlsec = indexOf (fStart, end, MILISECOND_SEPARATOR);            /***             * Schema Errata: E2-23             * at least one digit must follow the decimal point if it appears.              * That is, the value of the seconds component must conform              * to the following pattern: [0-9]+(.[0-9]+)?              */            if ( mlsec != NOT_FOUND )            {                /***                 * make usure there is something after the '.' and before the end.                 */                if ( mlsec+1 == end )                {                    ThrowXMLwithMemMgr1(SchemaDateTimeException                            , XMLExcepts::DateTime_dur_inv_seconds                            , fBuffer                            , fMemoryManager);                }                fValue[Second]     = negate * parseInt(fStart, mlsec);                fMiliSecond        = negate * parseMiliSecond(mlsec+1, end);            }            else            {                fValue[Second] = negate * parseInt(fStart,end);            }            fStart = end+1;            designator = true;        }        // no additional data should appear after last item        // P1Y1M1DT is illigal value as well        if ( (fStart != fEnd) ||              fBuffer[--fStart] == DATETIME_SEPARATOR )        {            ThrowXMLwithMemMgr1(SchemaDateTimeException                    , XMLExcepts::DateTime_dur_NoTimeAfterT                    , fBuffer                    , fMemoryManager);        }    }    if ( !designator )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_dur_NoElementAtAll                , fBuffer                , fMemoryManager);    }}// ---------------------------------------------------------------------------//  Scanners// ---------------------------------------------------------------------------//// [-]{CCYY-MM-DD}//// Note: CCYY could be more than 4 digits//       Assuming fStart point to the beginning of the Date Section//       fStart updated to point to the position right AFTER the second 'D'//       Since the lenght of CCYY might be variable, we can't check format upfront//void XMLDateTime::getDate(){    // Ensure enough chars in buffer    if ( (fStart+YMD_MIN_SIZE) > fEnd)        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_date_incomplete                , fBuffer                , fMemoryManager);    getYearMonth();    // Scan YearMonth and                       // fStart point to the next '-'    if (fBuffer[fStart++] != DATE_SEPARATOR)    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_date_invalid                , fBuffer                , fMemoryManager);        //("CCYY-MM must be followed by '-' sign");    }    fValue[Day] = parseInt(fStart, fStart+2);    fStart += 2 ;  //fStart points right after the Day    return;}//// hh:mm:ss[.msssss]['Z']// hh:mm:ss[.msssss][['+'|'-']hh:mm]// 012345678//// Note: Assuming fStart point to the beginning of the Time Section//       fStart updated to point to the position right AFTER the second 's'//                                                  or ms if any//void XMLDateTime::getTime(){    // Ensure enough chars in buffer    if ( (fStart+TIME_MIN_SIZE) > fEnd)        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_time_incomplete                , fBuffer                , fMemoryManager);        //"Imcomplete Time Format"    // check (fixed) format first    if ((fBuffer[fStart + 2] != TIME_SEPARATOR) ||        (fBuffer[fStart + 5] != TIME_SEPARATOR)  )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_time_invalid                , fBuffer                , fMemoryManager);        //("Error in parsing time" );    }    //    // get hours, minute and second    //    fValue[Hour]   = parseInt(fStart + 0, fStart + 2);    fValue[Minute] = parseInt(fStart + 3, fStart + 5);    fValue[Second] = parseInt(fStart + 6, fStart + 8);    fStart += 8;    // to see if any ms and/or utc part after that    if (fStart >= fEnd)        return;    //find UTC sign if any    int sign = findUTCSign(fStart);    //parse miliseconds    int milisec = (fBuffer[fStart] == MILISECOND_SEPARATOR)? fStart : NOT_FOUND;    if ( milisec != NOT_FOUND )    {        fStart++;   // skip the '.'        // make sure we have some thing between the '.' and fEnd        if (fStart >= fEnd)        {            ThrowXMLwithMemMgr1(SchemaDateTimeException                    , XMLExcepts::DateTime_ms_noDigit                    , fBuffer                    , fMemoryManager);            //("ms shall be present once '.' is present" );        }        if ( sign == NOT_FOUND )        {            fMiliSecond = parseMiliSecond(fStart, fEnd);  //get ms between '.' and fEnd            fStart = fEnd;        }        else        {            fMiliSecond = parseMiliSecond(fStart, sign);  //get ms between UTC sign and fEnd        }	}    else if(sign == 0 || sign != fStart)    {        // seconds has more than 2 digits        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_min_invalid                , fBuffer                , fMemoryManager);    }    //parse UTC time zone (hh:mm)    if ( sign > 0 ) {        getTimeZone(sign);    }}//// [-]{CCYY-MM}//// Note: CCYY could be more than 4 digits//       fStart updated to point AFTER the second 'M' (probably meet the fEnd)//void XMLDateTime::getYearMonth(){    // Ensure enough chars in buffer    if ( (fStart+YMONTH_MIN_SIZE) > fEnd)        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_ym_incomplete                , fBuffer                , fMemoryManager);        //"Imcomplete YearMonth Format";    // skip the first leading '-'    int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;    //    // search for year separator '-'    //    int yearSeparator = indexOf(start, fEnd, DATE_SEPARATOR);    if ( yearSeparator == NOT_FOUND)        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_ym_invalid                , fBuffer                , fMemoryManager);        //("Year separator is missing or misplaced");    fValue[CentYear] = parseIntYear(yearSeparator);    fStart = yearSeparator + 1;  //skip the '-' and point to the first M    //    //gonna check we have enough byte for month    //    if ((fStart + 2) > fEnd )        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_ym_noMonth                , fBuffer                , fMemoryManager);        //"no month in buffer"    fValue[Month] = parseInt(fStart, yearSeparator + 3);    fStart += 2;  //fStart points right after the MONTH    return;}void XMLDateTime::parseTimeZone(){    if ( fStart < fEnd )    {        int sign = findUTCSign(fStart);        if ( sign < 0 )        {            ThrowXMLwithMemMgr1(SchemaDateTimeException                    , XMLExcepts::DateTime_tz_noUTCsign                    , fBuffer                    , fMemoryManager);            //("Error in month parsing");        }        else        {            getTimeZone(sign);        }    }    return;}//// 'Z'// ['+'|'-']hh:mm//// Note: Assuming fStart points to the beginning of TimeZone section//       fStart updated to meet fEnd//void XMLDateTime::getTimeZone(const int sign){    if ( fBuffer[sign] == UTC_STD_CHAR )    {        if ((sign + 1) != fEnd )        {            ThrowXMLwithMemMgr1(SchemaDateTimeException                    , XMLExcepts::DateTime_tz_stuffAfterZ                    , fBuffer                    , fMemoryManager);            //"Error in parsing time zone");        }		        return;	    }    //    // otherwise, it has to be this format    // '[+|-]'hh:mm    //    1   23456 7    //   sign      fEnd    //    if ( ( ( sign + TIMEZONE_SIZE + 1) != fEnd )      ||         ( fBuffer[sign + 3] != TIMEZONE_SEPARATOR ) )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_tz_invalid                , fBuffer                , fMemoryManager);        //("Error in parsing time zone");    }    fTimeZone[hh] = parseInt(sign+1, sign+3);		    fTimeZone[mm] = parseInt(sign+4, fEnd);        		    return;}// ---------------------------------------------------------------------------//  Validator and normalizer// ---------------------------------------------------------------------------/** * If timezone present - normalize dateTime  [E Adding durations to dateTimes] * * @param date   CCYY-MM-DDThh:mm:ss+03 * @return CCYY-MM-DDThh:mm:ssZ */void XMLDateTime::normalize(){    if ((fValue[utc] == UTC_UNKNOWN) ||        (fValue[utc] == UTC_STD)      )        return;    int negate = (fValue[utc] == UTC_POS)? -1: 1;    // add mins    int temp = fValue[Minute] + negate * fTimeZone[mm];    int carry = fQuotient(temp, 60);    fValue[Minute] = mod(temp, 60, carry);    //add hours    temp = fValue[Hour] + negate * fTimeZone[hh] + carry;    carry = fQuotient(temp, 24);    fValue[Hour] = mod(temp, 24, carry);    fValue[Day] += carry;    while (1)    {        temp = maxDayInMonthFor(fValue[CentYear], fValue[Month]);        if (fValue[Day] < 1)        {            fValue[Day] += maxDayInMonthFor(fValue[CentYear], fValue[Month] - 1);            carry = -1;        }        else if ( fValue[Day] > temp )        {            fValue[Day] -= temp;            carry = 1;        }        else        {            break;        }        temp = fValue[Month] + carry;        fValue[Month] = modulo(temp, 1, 13);        fValue[CentYear] += fQuotient(temp, 1, 13);    }    // set to normalized    fValue[utc] = UTC_STD;    return;}void XMLDateTime::validateDateTime() const{    //REVISIT: should we throw an exception for not valid dates    //          or reporting an error message should be sufficient?    if ( fValue[CentYear] == 0 )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_year_zero                , fBuffer                , fMemoryManager);        //"The year \"0000\" is an illegal year value");    }    if ( fValue[Month] < 1  ||         fValue[Month] > 12  )    {        ThrowXMLwithMemMgr1(SchemaDateTimeException                , XMLExcepts::DateTime_mth_invalid                , fBuffer                , fMemoryManager);

⌨️ 快捷键说明

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