?? xmldatetime.cpp
字號:
//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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -